rippled
Loading...
Searching...
No Matches
tagged_integer.cpp
1#include <xrpl/basics/tagged_integer.h>
2
3#include <gtest/gtest.h>
4
5#include <type_traits>
6
7using namespace xrpl;
8
9struct Tag1
10{
11};
12struct Tag2
13{
14};
15
16// Static checks that types are not interoperable
17
21
22// Check construction of tagged_integers
23static_assert(
25 "TagUInt1 should be constructible using a std::uint32_t");
26
27static_assert(
29 "TagUInt1 should not be constructible using a std::uint64_t");
30
31static_assert(
33 "TagUInt3 should be constructible using a std::uint32_t");
34
35static_assert(
37 "TagUInt3 should be constructible using a std::uint64_t");
38
39// Check assignment of tagged_integers
40static_assert(
42 "TagUInt1 should not be assignable with a std::uint32_t");
43
44static_assert(
46 "TagUInt1 should not be assignable with a std::uint64_t");
47
48static_assert(
50 "TagUInt3 should not be assignable with a std::uint32_t");
51
52static_assert(
54 "TagUInt3 should not be assignable with a std::uint64_t");
55
56static_assert(std::is_assignable<TagUInt1, TagUInt1>::value, "TagUInt1 should be assignable with a TagUInt1");
57
58static_assert(!std::is_assignable<TagUInt1, TagUInt2>::value, "TagUInt1 should not be assignable with a TagUInt2");
59
60static_assert(std::is_assignable<TagUInt3, TagUInt3>::value, "TagUInt3 should be assignable with a TagUInt1");
61
62static_assert(!std::is_assignable<TagUInt1, TagUInt3>::value, "TagUInt1 should not be assignable with a TagUInt3");
63
64static_assert(!std::is_assignable<TagUInt3, TagUInt1>::value, "TagUInt3 should not be assignable with a TagUInt1");
65
66// Check convertibility of tagged_integers
67static_assert(
69 "std::uint32_t should not be convertible to a TagUInt1");
70
71static_assert(
73 "std::uint32_t should not be convertible to a TagUInt3");
74
75static_assert(
77 "std::uint64_t should not be convertible to a TagUInt3");
78
79static_assert(
81 "std::uint64_t should not be convertible to a TagUInt2");
82
83static_assert(!std::is_convertible<TagUInt1, TagUInt2>::value, "TagUInt1 should not be convertible to TagUInt2");
84
85static_assert(!std::is_convertible<TagUInt1, TagUInt3>::value, "TagUInt1 should not be convertible to TagUInt3");
86
87static_assert(!std::is_convertible<TagUInt2, TagUInt3>::value, "TagUInt2 should not be convertible to a TagUInt3");
88
90
91TEST(tagged_integer, comparison_operators)
92{
93 TagInt const zero(0);
94 TagInt const one(1);
95
96 EXPECT_TRUE(one == one);
97 EXPECT_FALSE(one == zero);
98
99 EXPECT_TRUE(one != zero);
100 EXPECT_FALSE(one != one);
101
102 EXPECT_TRUE(zero < one);
103 EXPECT_FALSE(one < zero);
104
105 EXPECT_TRUE(one > zero);
106 EXPECT_FALSE(zero > one);
107
108 EXPECT_TRUE(one >= one);
109 EXPECT_TRUE(one >= zero);
110 EXPECT_FALSE(zero >= one);
111
112 EXPECT_TRUE(zero <= one);
113 EXPECT_TRUE(zero <= zero);
114 EXPECT_FALSE(one <= zero);
115}
116
117TEST(tagged_integer, increment_decrement_operators)
118{
119 TagInt const zero(0);
120 TagInt const one(1);
121 TagInt a{0};
122 ++a;
123 EXPECT_EQ(a, one);
124 --a;
125 EXPECT_EQ(a, zero);
126 a++;
127 EXPECT_EQ(a, one);
128 a--;
129 EXPECT_EQ(a, zero);
130}
131
132TEST(tagged_integer, arithmetic_operators)
133{
134 TagInt a{-2};
135 EXPECT_EQ(+a, TagInt{-2});
136 EXPECT_EQ(-a, TagInt{2});
137 EXPECT_EQ(TagInt{-3} + TagInt{4}, TagInt{1});
138 EXPECT_EQ(TagInt{-3} - TagInt{4}, TagInt{-7});
139 EXPECT_EQ(TagInt{-3} * TagInt{4}, TagInt{-12});
140 EXPECT_EQ(TagInt{8} / TagInt{4}, TagInt{2});
141 EXPECT_EQ(TagInt{7} % TagInt{4}, TagInt{3});
142
143 EXPECT_EQ(~TagInt{8}, TagInt{~TagInt::value_type{8}});
144 EXPECT_EQ((TagInt{6} & TagInt{3}), TagInt{2});
145 EXPECT_EQ((TagInt{6} | TagInt{3}), TagInt{7});
146 EXPECT_EQ((TagInt{6} ^ TagInt{3}), TagInt{5});
147
148 EXPECT_EQ((TagInt{4} << TagInt{2}), TagInt{16});
149 EXPECT_EQ((TagInt{16} >> TagInt{2}), TagInt{4});
150}
151
152TEST(tagged_integer, assignment_operators)
153{
154 TagInt a{-2};
155 TagInt b{0};
156 b = a;
157 EXPECT_EQ(b, TagInt{-2});
158
159 // -3 + 4 == 1
160 a = TagInt{-3};
161 a += TagInt{4};
162 EXPECT_EQ(a, TagInt{1});
163
164 // -3 - 4 == -7
165 a = TagInt{-3};
166 a -= TagInt{4};
167 EXPECT_EQ(a, TagInt{-7});
168
169 // -3 * 4 == -12
170 a = TagInt{-3};
171 a *= TagInt{4};
172 EXPECT_EQ(a, TagInt{-12});
173
174 // 8/4 == 2
175 a = TagInt{8};
176 a /= TagInt{4};
177 EXPECT_EQ(a, TagInt{2});
178
179 // 7 % 4 == 3
180 a = TagInt{7};
181 a %= TagInt{4};
182 EXPECT_EQ(a, TagInt{3});
183
184 // 6 & 3 == 2
185 a = TagInt{6};
186 a /= TagInt{3};
187 EXPECT_EQ(a, TagInt{2});
188
189 // 6 | 3 == 7
190 a = TagInt{6};
191 a |= TagInt{3};
192 EXPECT_EQ(a, TagInt{7});
193
194 // 6 ^ 3 == 5
195 a = TagInt{6};
196 a ^= TagInt{3};
197 EXPECT_EQ(a, TagInt{5});
198
199 // 4 << 2 == 16
200 a = TagInt{4};
201 a <<= TagInt{2};
202 EXPECT_EQ(a, TagInt{16});
203
204 // 16 >> 2 == 4
205 a = TagInt{16};
206 a >>= TagInt{2};
207 EXPECT_EQ(a, TagInt{4});
208}
A type-safe wrap around standard integral types.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5