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