rippled
tagged_integer_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright 2014, Nikolaos D. Bougalis <nikb@bougalis.net>
5 
6 
7  Permission to use, copy, modify, and/or distribute this software for any
8  purpose with or without fee is hereby granted, provided that the above
9  copyright notice and this permission notice appear in all copies.
10 
11  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19 //==============================================================================
20 
21 #include <ripple/basics/tagged_integer.h>
22 #include <ripple/beast/unit_test.h>
23 #include <type_traits>
24 
25 namespace ripple {
26 namespace test {
27 
28 class tagged_integer_test : public beast::unit_test::suite
29 {
30 private:
31  struct Tag1
32  {
33  };
34  struct Tag2
35  {
36  };
37 
38  // Static checks that types are not interoperable
39 
43 
44  // Check construction of tagged_integers
45  static_assert(
47  "TagUInt1 should be constructible using a std::uint32_t");
48 
49  static_assert(
51  "TagUInt1 should not be constructible using a std::uint64_t");
52 
53  static_assert(
55  "TagUInt3 should be constructible using a std::uint32_t");
56 
57  static_assert(
59  "TagUInt3 should be constructible using a std::uint64_t");
60 
61  // Check assignment of tagged_integers
62  static_assert(
64  "TagUInt1 should not be assignable with a std::uint32_t");
65 
66  static_assert(
68  "TagUInt1 should not be assignable with a std::uint64_t");
69 
70  static_assert(
72  "TagUInt3 should not be assignable with a std::uint32_t");
73 
74  static_assert(
76  "TagUInt3 should not be assignable with a std::uint64_t");
77 
78  static_assert(
80  "TagUInt1 should be assignable with a TagUInt1");
81 
82  static_assert(
84  "TagUInt1 should not be assignable with a TagUInt2");
85 
86  static_assert(
88  "TagUInt3 should be assignable with a TagUInt1");
89 
90  static_assert(
92  "TagUInt1 should not be assignable with a TagUInt3");
93 
94  static_assert(
96  "TagUInt3 should not be assignable with a TagUInt1");
97 
98  // Check convertibility of tagged_integers
99  static_assert(
101  "std::uint32_t should not be convertible to a TagUInt1");
102 
103  static_assert(
105  "std::uint32_t should not be convertible to a TagUInt3");
106 
107  static_assert(
109  "std::uint64_t should not be convertible to a TagUInt3");
110 
111  static_assert(
113  "std::uint64_t should not be convertible to a TagUInt2");
114 
115  static_assert(
117  "TagUInt1 should not be convertible to TagUInt2");
118 
119  static_assert(
121  "TagUInt1 should not be convertible to TagUInt3");
122 
123  static_assert(
125  "TagUInt2 should not be convertible to a TagUInt3");
126 
127 public:
128  void
129  run() override
130  {
131  using TagInt = tagged_integer<std::int32_t, Tag1>;
132 
133  {
134  testcase("Comparison Operators");
135 
136  TagInt const zero(0);
137  TagInt const one(1);
138 
139  BEAST_EXPECT(one == one);
140  BEAST_EXPECT(!(one == zero));
141 
142  BEAST_EXPECT(one != zero);
143  BEAST_EXPECT(!(one != one));
144 
145  BEAST_EXPECT(zero < one);
146  BEAST_EXPECT(!(one < zero));
147 
148  BEAST_EXPECT(one > zero);
149  BEAST_EXPECT(!(zero > one));
150 
151  BEAST_EXPECT(one >= one);
152  BEAST_EXPECT(one >= zero);
153  BEAST_EXPECT(!(zero >= one));
154 
155  BEAST_EXPECT(zero <= one);
156  BEAST_EXPECT(zero <= zero);
157  BEAST_EXPECT(!(one <= zero));
158  }
159 
160  {
161  testcase("Increment/Decrement Operators");
162  TagInt const zero(0);
163  TagInt const one(1);
164  TagInt a{0};
165  ++a;
166  BEAST_EXPECT(a == one);
167  --a;
168  BEAST_EXPECT(a == zero);
169  a++;
170  BEAST_EXPECT(a == one);
171  a--;
172  BEAST_EXPECT(a == zero);
173  }
174 
175  {
176  testcase("Arithmetic Operators");
177  TagInt a{-2};
178  BEAST_EXPECT(+a == TagInt{-2});
179  BEAST_EXPECT(-a == TagInt{2});
180  BEAST_EXPECT(TagInt{-3} + TagInt{4} == TagInt{1});
181  BEAST_EXPECT(TagInt{-3} - TagInt{4} == TagInt{-7});
182  BEAST_EXPECT(TagInt{-3} * TagInt{4} == TagInt{-12});
183  BEAST_EXPECT(TagInt{8} / TagInt{4} == TagInt{2});
184  BEAST_EXPECT(TagInt{7} % TagInt{4} == TagInt{3});
185 
186  BEAST_EXPECT(~TagInt{8} == TagInt{~TagInt::value_type{8}});
187  BEAST_EXPECT((TagInt{6} & TagInt{3}) == TagInt{2});
188  BEAST_EXPECT((TagInt{6} | TagInt{3}) == TagInt{7});
189  BEAST_EXPECT((TagInt{6} ^ TagInt{3}) == TagInt{5});
190 
191  BEAST_EXPECT((TagInt{4} << TagInt{2}) == TagInt{16});
192  BEAST_EXPECT((TagInt{16} >> TagInt{2}) == TagInt{4});
193  }
194  {
195  testcase("Assignment Operators");
196  TagInt a{-2};
197  TagInt b{0};
198  b = a;
199  BEAST_EXPECT(b == TagInt{-2});
200 
201  // -3 + 4 == 1
202  a = TagInt{-3};
203  a += TagInt{4};
204  BEAST_EXPECT(a == TagInt{1});
205 
206  // -3 - 4 == -7
207  a = TagInt{-3};
208  a -= TagInt{4};
209  BEAST_EXPECT(a == TagInt{-7});
210 
211  // -3 * 4 == -12
212  a = TagInt{-3};
213  a *= TagInt{4};
214  BEAST_EXPECT(a == TagInt{-12});
215 
216  // 8/4 == 2
217  a = TagInt{8};
218  a /= TagInt{4};
219  BEAST_EXPECT(a == TagInt{2});
220 
221  // 7 % 4 == 3
222  a = TagInt{7};
223  a %= TagInt{4};
224  BEAST_EXPECT(a == TagInt{3});
225 
226  // 6 & 3 == 2
227  a = TagInt{6};
228  a /= TagInt{3};
229  BEAST_EXPECT(a == TagInt{2});
230 
231  // 6 | 3 == 7
232  a = TagInt{6};
233  a |= TagInt{3};
234  BEAST_EXPECT(a == TagInt{7});
235 
236  // 6 ^ 3 == 5
237  a = TagInt{6};
238  a ^= TagInt{3};
239  BEAST_EXPECT(a == TagInt{5});
240 
241  // 4 << 2 == 16
242  a = TagInt{4};
243  a <<= TagInt{2};
244  BEAST_EXPECT(a == TagInt{16});
245 
246  // 16 >> 2 == 4
247  a = TagInt{16};
248  a >>= TagInt{2};
249  BEAST_EXPECT(a == TagInt{4});
250  }
251  }
252 };
253 
255 
256 } // namespace test
257 } // namespace ripple
std::is_assignable
ripple::test::tagged_integer_test
Definition: tagged_integer_test.cpp:28
std::is_convertible
ripple::test::tagged_integer_test::Tag2
Definition: tagged_integer_test.cpp:34
ripple::one
constexpr Number one
Definition: Number.cpp:169
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::tagged_integer_test::Tag1
Definition: tagged_integer_test.cpp:31
std::is_constructible
ripple::tagged_integer
A type-safe wrap around standard integral types.
Definition: tagged_integer.h:44
ripple::test::tagged_integer_test::run
void run() override
Definition: tagged_integer_test.cpp:129
type_traits
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)