blob: b781054588161cc2fea6f3fd64ed8f8928627c14 [file] [log] [blame]
William A. Kennington IIIbe79c1e2021-01-25 16:06:31 -08001#include <array>
William A. Kennington IIIe0990382019-10-18 02:10:25 -07002#include <catch2/catch.hpp>
3#include <endian.h>
4#include <stdexcept>
5#include <stdplus/raw.hpp>
6#include <string_view>
7#include <vector>
8
9namespace stdplus
10{
11namespace raw
12{
13namespace
14{
15
William A. Kennington III3b35fcf2020-06-13 18:42:39 -070016TEST_CASE("Equal", "[Equal]")
17{
18 int a = 4;
19 unsigned b = 4;
20 CHECK(equal(a, b));
21 b = 5;
22 CHECK(!equal(a, b));
23}
24
William A. Kennington IIIe0990382019-10-18 02:10:25 -070025TEST_CASE("Copy From Empty", "[CopyFrom]")
26{
William A. Kennington III5c99ff42020-07-19 02:29:26 -070027 const std::string_view cs;
28 CHECK_THROWS_AS(copyFrom<int>(cs), std::runtime_error);
29 std::string_view s;
William A. Kennington IIIe0990382019-10-18 02:10:25 -070030 CHECK_THROWS_AS(copyFrom<int>(s), std::runtime_error);
William A. Kennington IIIe0990382019-10-18 02:10:25 -070031}
32
33TEST_CASE("Copy From Basic", "[CopyFrom]")
34{
35 int a = 4;
36 const std::string_view s(reinterpret_cast<char*>(&a), sizeof(a));
37 CHECK(a == copyFrom<int>(s));
38}
39
40TEST_CASE("Copy From Partial", "[CopyFrom]")
41{
42 const std::vector<char> s = {'a', 'b', 'c'};
43 CHECK('a' == copyFrom<char>(s));
44 const char s2[] = "def";
45 CHECK('d' == copyFrom<char>(s2));
46}
47
William A. Kennington III5c99ff42020-07-19 02:29:26 -070048struct Int
49{
50 uint8_t data[sizeof(int)];
51
52 inline bool operator==(const Int& other) const
53 {
54 return memcmp(data, other.data, sizeof(data)) == 0;
55 }
56};
57
58TEST_CASE("Ref From Empty", "[RefFrom]")
59{
60 const std::string_view cs;
61 CHECK_THROWS_AS(refFrom<Int>(cs), std::runtime_error);
62 std::string_view s;
63 CHECK_THROWS_AS(refFrom<Int>(s), std::runtime_error);
64}
65
66TEST_CASE("Ref From Basic", "[RefFrom]")
67{
68 Int a = {4, 0, 0, 4};
69 const std::string_view s(reinterpret_cast<char*>(&a), sizeof(a));
70 CHECK(a == refFrom<Int>(s));
71}
72
73TEST_CASE("Ref From Partial", "[RefFrom]")
74{
75 const std::vector<char> s = {'a', 'b', 'c'};
76 CHECK('a' == refFrom<char>(s));
77 const char s2[] = "def";
78 CHECK('d' == refFrom<char>(s2));
79}
80
William A. Kennington IIIe0990382019-10-18 02:10:25 -070081TEST_CASE("Extract Too Small", "[Extract]")
82{
83 std::string_view s("a");
84 CHECK_THROWS_AS(extract<int>(s), std::runtime_error);
85 CHECK(1 == s.size());
86}
87
88TEST_CASE("Extract Basic", "[Extract]")
89{
90 int a = 4;
91 std::string_view s(reinterpret_cast<char*>(&a), sizeof(a));
92 CHECK(a == extract<int>(s));
93 CHECK(s.empty());
94}
95
96TEST_CASE("Extract Partial", "[Extract]")
97{
98 std::string_view s("abc");
99 CHECK('a' == extract<char>(s));
100 CHECK(2 == s.size());
101}
102
William A. Kennington III5c99ff42020-07-19 02:29:26 -0700103TEST_CASE("Extract Ref Too Small", "[ExtractRef]")
104{
105 std::string_view s("a");
106 CHECK_THROWS_AS(extractRef<Int>(s), std::runtime_error);
107 CHECK(1 == s.size());
108}
109
110TEST_CASE("Extract Ref Basic", "[ExtractRef]")
111{
112 Int a = {4, 0, 0, 4};
113 std::string_view s(reinterpret_cast<char*>(&a), sizeof(a));
114 CHECK(a == extractRef<Int>(s));
115 CHECK(s.empty());
116}
117
118TEST_CASE("Extract Ref Partial", "[ExtractRef]")
119{
120 std::string_view s("abc");
121 CHECK('a' == extractRef<char>(s));
122 CHECK(2 == s.size());
123}
124
William A. Kennington IIIe0990382019-10-18 02:10:25 -0700125TEST_CASE("As View Byte", "[AsView]")
126{
127 int32_t a = 4;
128 auto s = asView<uint8_t>(a);
129 CHECK(a == copyFrom<int>(s));
130}
131
132TEST_CASE("As View Int", "[AsView]")
133{
134 int32_t a = 4;
135 auto s = asView<char16_t>(a);
136 CHECK(a == copyFrom<int>(s));
137}
138
139TEST_CASE("As View Arr", "[AsView]")
140{
141 std::vector<uint32_t> arr = {htole32(1), htole32(2)};
142 auto s = asView<char16_t>(arr);
143 REQUIRE(4 == s.size());
144 CHECK(htole16(1) == s[0]);
145 CHECK(htole16(0) == s[1]);
146 CHECK(htole16(2) == s[2]);
147 CHECK(htole16(0) == s[3]);
148}
149
William A. Kennington IIIba7d7542020-07-19 20:04:44 -0700150TEST_CASE("As View View", "[AsView]")
151{
152 std::string_view sv = "ab";
153 auto s = asView<uint8_t>(sv);
154 REQUIRE(s.size() == 2);
155 CHECK(s[0] == sv[0]);
156 CHECK(s[1] == sv[1]);
157}
158
William A. Kennington IIIe0990382019-10-18 02:10:25 -0700159#ifdef STDPLUS_SPAN_TYPE
160TEST_CASE("Span Extract TooSmall", "[Extract]")
161{
162 const std::vector<char> v = {'c'};
163 span<const char> s = v;
164 CHECK_THROWS_AS(extract<int>(s), std::runtime_error);
165 CHECK(1 == s.size());
166}
167
168TEST_CASE("Span Extract Basic", "[Extract]")
169{
170 const std::vector<int> v = {4};
171 span<const int> s = v;
172 CHECK(v[0] == extract<int>(s));
173 CHECK(s.empty());
174}
175
176TEST_CASE("Span Extract Larger", "[Extract]")
177{
178 const std::vector<int> v{3, 4, 5};
179 span<const int> s = v;
180 CHECK(v[0] == extract<int>(s));
181 CHECK(v.size() - 1 == s.size());
182}
183
William A. Kennington III5c99ff42020-07-19 02:29:26 -0700184TEST_CASE("Span Extract Ref TooSmall", "[ExtractRef]")
185{
186 const std::vector<char> v = {'c'};
187 span<const char> s = v;
188 CHECK_THROWS_AS(extractRef<Int>(s), std::runtime_error);
189 CHECK(1 == s.size());
190}
191
192TEST_CASE("Span Extract Ref Basic", "[ExtractRef]")
193{
194 const std::vector<Int> v = {{4, 0, 0, 4}};
195 span<const Int> s = v;
196 CHECK(v[0] == extractRef<Int>(s));
197 CHECK(s.empty());
198}
199
200TEST_CASE("Span Extract Ref Larger", "[ExtractRef]")
201{
202 const std::vector<Int> v{{3}, {4}, {5}};
203 span<const Int> s = v;
204 CHECK(v[0] == extractRef<Int>(s));
205 CHECK(v.size() - 1 == s.size());
206}
207
William A. Kennington IIIe0990382019-10-18 02:10:25 -0700208TEST_CASE("As Span const", "[AsSpan]")
209{
210 const uint64_t data = htole64(0xffff0000);
211 auto s = asSpan<uint32_t>(data);
212 CHECK(s.size() == 2);
213 CHECK(s[0] == htole32(0xffff0000));
214 CHECK(s[1] == htole32(0x00000000));
215}
216
217TEST_CASE("As Span Arr const", "[AsSpan]")
218{
219 const std::vector<uint32_t> arr = {htole32(1), htole32(2)};
220 auto s = asSpan<uint16_t>(arr);
221 REQUIRE(4 == s.size());
222 CHECK(htole16(1) == s[0]);
223 CHECK(htole16(0) == s[1]);
224 CHECK(htole16(2) == s[2]);
225 CHECK(htole16(0) == s[3]);
226}
227
228TEST_CASE("As Span", "[AsSpan]")
229{
230 uint64_t data = htole64(0xffff0000);
231 auto s = asSpan<uint16_t>(data);
232 CHECK(s.size() == 4);
233 s[2] = 0xfefe;
234 CHECK(s[0] == htole16(0x0000));
235 CHECK(s[1] == htole16(0xffff));
236 CHECK(s[2] == htole16(0xfefe));
237 CHECK(s[3] == htole16(0x0000));
238}
239
240TEST_CASE("As Span Arr", "[AsSpan]")
241{
242 std::vector<uint32_t> arr = {htole32(1), htole32(2)};
243 auto s = asSpan<uint16_t>(arr);
244 REQUIRE(4 == s.size());
245 CHECK(htole16(1) == s[0]);
246 CHECK(htole16(0) == s[1]);
247 CHECK(htole16(2) == s[2]);
248 CHECK(htole16(0) == s[3]);
249}
250
William A. Kennington IIIba7d7542020-07-19 20:04:44 -0700251TEST_CASE("As Span Span", "[AsSpan]")
252{
253 std::array<char, 2> arr = {'a', 'b'};
254 auto sp1 = span<const char>(arr);
255 auto s1 = asSpan<uint8_t>(sp1);
256 REQUIRE(s1.size() == 2);
257 CHECK(s1[0] == arr[0]);
258 CHECK(s1[1] == arr[1]);
259 auto sp2 = span<char>(arr);
260 auto s2 = asSpan<uint8_t>(sp2);
261 REQUIRE(s2.size() == 2);
262 CHECK(s2[0] == arr[0]);
263 CHECK(s2[1] == arr[1]);
264}
265
William A. Kennington IIIe0990382019-10-18 02:10:25 -0700266#endif
267
268} // namespace
269} // namespace raw
270} // namespace stdplus