Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "mozilla/Assertions.h"
6 #include "mozilla/Attributes.h"
7 #include "mozilla/TypedEnum.h"
8 #include "mozilla/TypedEnumBits.h"
10 #include <stdint.h>
12 // A rough feature check for is_literal_type. Not very carefully checked.
13 // Feel free to amend as needed.
14 // We leave ANDROID out because it's using stlport which doesn't have std::is_literal_type.
15 #if __cplusplus >= 201103L && !defined(ANDROID)
16 # if defined(__clang__)
17 /*
18 * Per Clang documentation, "Note that marketing version numbers should not
19 * be used to check for language features, as different vendors use different
20 * numbering schemes. Instead, use the feature checking macros."
21 */
22 # ifndef __has_extension
23 # define __has_extension __has_feature /* compatibility, for older versions of clang */
24 # endif
25 # if __has_extension(is_literal) && __has_include(<type_traits>)
26 # define MOZ_HAVE_IS_LITERAL
27 # endif
28 # elif defined(__GNUC__)
29 # if defined(__GXX_EXPERIMENTAL_CXX0X__)
30 # if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0)
31 # define MOZ_HAVE_IS_LITERAL
32 # endif
33 # endif
34 # elif defined(_MSC_VER)
35 # if _MSC_VER >= 1700
36 # define MOZ_HAVE_IS_LITERAL
37 # endif
38 # endif
39 #endif
41 #ifdef MOZ_HAVE_IS_LITERAL
42 #include <type_traits>
43 template<typename T>
44 void
45 RequireLiteralType()
46 {
47 static_assert(std::is_literal_type<T>::value, "Expected a literal type");
48 }
49 #else // not MOZ_HAVE_IS_LITERAL
50 template<typename T>
51 void
52 RequireLiteralType()
53 {
54 }
55 #endif
57 template<typename T>
58 void
59 RequireLiteralType(const T&)
60 {
61 RequireLiteralType<T>();
62 }
64 MOZ_BEGIN_ENUM_CLASS(AutoEnum)
65 A,
66 B = -3,
67 C
68 MOZ_END_ENUM_CLASS(AutoEnum)
70 MOZ_BEGIN_ENUM_CLASS(CharEnum, char)
71 A,
72 B = 3,
73 C
74 MOZ_END_ENUM_CLASS(CharEnum)
76 MOZ_BEGIN_ENUM_CLASS(AutoEnumBitField)
77 A = 0x10,
78 B = 0x20,
79 C
80 MOZ_END_ENUM_CLASS(AutoEnumBitField)
82 MOZ_BEGIN_ENUM_CLASS(CharEnumBitField, char)
83 A = 0x10,
84 B,
85 C = 0x40
86 MOZ_END_ENUM_CLASS(CharEnumBitField)
88 struct Nested
89 {
90 MOZ_BEGIN_NESTED_ENUM_CLASS(AutoEnum)
91 A,
92 B,
93 C = -1
94 MOZ_END_NESTED_ENUM_CLASS(AutoEnum)
96 MOZ_BEGIN_NESTED_ENUM_CLASS(CharEnum, char)
97 A = 4,
98 B,
99 C = 1
100 MOZ_END_NESTED_ENUM_CLASS(CharEnum)
102 MOZ_BEGIN_NESTED_ENUM_CLASS(AutoEnumBitField)
103 A,
104 B = 0x20,
105 C
106 MOZ_END_NESTED_ENUM_CLASS(AutoEnumBitField)
108 MOZ_BEGIN_NESTED_ENUM_CLASS(CharEnumBitField, char)
109 A = 1,
110 B = 1,
111 C = 1
112 MOZ_END_NESTED_ENUM_CLASS(CharEnumBitField)
113 };
115 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AutoEnumBitField)
116 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(CharEnumBitField)
117 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Nested::AutoEnumBitField)
118 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Nested::CharEnumBitField)
120 #define MAKE_STANDARD_BITFIELD_FOR_TYPE(IntType) \
121 MOZ_BEGIN_ENUM_CLASS(BitFieldFor_##IntType, IntType) \
122 A = 1, \
123 B = 2, \
124 C = 4, \
125 MOZ_END_ENUM_CLASS(BitFieldFor_##IntType) \
126 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(BitFieldFor_##IntType)
128 MAKE_STANDARD_BITFIELD_FOR_TYPE(int8_t)
129 MAKE_STANDARD_BITFIELD_FOR_TYPE(uint8_t)
130 MAKE_STANDARD_BITFIELD_FOR_TYPE(int16_t)
131 MAKE_STANDARD_BITFIELD_FOR_TYPE(uint16_t)
132 MAKE_STANDARD_BITFIELD_FOR_TYPE(int32_t)
133 MAKE_STANDARD_BITFIELD_FOR_TYPE(uint32_t)
134 MAKE_STANDARD_BITFIELD_FOR_TYPE(int64_t)
135 MAKE_STANDARD_BITFIELD_FOR_TYPE(uint64_t)
136 MAKE_STANDARD_BITFIELD_FOR_TYPE(char)
137 typedef signed char signed_char;
138 MAKE_STANDARD_BITFIELD_FOR_TYPE(signed_char)
139 typedef unsigned char unsigned_char;
140 MAKE_STANDARD_BITFIELD_FOR_TYPE(unsigned_char)
141 MAKE_STANDARD_BITFIELD_FOR_TYPE(short)
142 typedef unsigned short unsigned_short;
143 MAKE_STANDARD_BITFIELD_FOR_TYPE(unsigned_short)
144 MAKE_STANDARD_BITFIELD_FOR_TYPE(int)
145 typedef unsigned int unsigned_int;
146 MAKE_STANDARD_BITFIELD_FOR_TYPE(unsigned_int)
147 MAKE_STANDARD_BITFIELD_FOR_TYPE(long)
148 typedef unsigned long unsigned_long;
149 MAKE_STANDARD_BITFIELD_FOR_TYPE(unsigned_long)
150 typedef long long long_long;
151 MAKE_STANDARD_BITFIELD_FOR_TYPE(long_long)
152 typedef unsigned long long unsigned_long_long;
153 MAKE_STANDARD_BITFIELD_FOR_TYPE(unsigned_long_long)
155 #undef MAKE_STANDARD_BITFIELD_FOR_TYPE
157 template<typename T>
158 void
159 TestNonConvertibilityForOneType()
160 {
161 using mozilla::IsConvertible;
163 #if defined(MOZ_HAVE_CXX11_STRONG_ENUMS) && defined(MOZ_HAVE_EXPLICIT_CONVERSION)
164 static_assert(!IsConvertible<T, bool>::value, "should not be convertible");
165 static_assert(!IsConvertible<T, int>::value, "should not be convertible");
166 static_assert(!IsConvertible<T, uint64_t>::value, "should not be convertible");
167 #endif
169 static_assert(!IsConvertible<bool, T>::value, "should not be convertible");
170 static_assert(!IsConvertible<int, T>::value, "should not be convertible");
171 static_assert(!IsConvertible<uint64_t, T>::value, "should not be convertible");
172 }
174 template<typename TypedEnum>
175 void
176 TestTypedEnumBasics()
177 {
178 const TypedEnum a = TypedEnum::A;
179 int unused = int(a);
180 (void) unused;
181 RequireLiteralType(TypedEnum::A);
182 RequireLiteralType(a);
183 TestNonConvertibilityForOneType<TypedEnum>();
184 }
186 // Op wraps a bitwise binary operator, passed as a char template parameter,
187 // and applies it to its arguments (t1, t2). For example,
188 //
189 // Op<'|'>(t1, t2)
190 //
191 // is the same as
192 //
193 // t1 | t2.
194 //
195 template<char o, typename T1, typename T2>
196 auto Op(const T1& t1, const T2& t2)
197 -> decltype(t1 | t2) // See the static_assert's below --- the return type
198 // depends solely on the operands type, not on the
199 // choice of operation.
200 {
201 using mozilla::IsSame;
202 static_assert(IsSame<decltype(t1 | t2), decltype(t1 & t2)>::value,
203 "binary ops should have the same result type");
204 static_assert(IsSame<decltype(t1 | t2), decltype(t1 ^ t2)>::value,
205 "binary ops should have the same result type");
207 static_assert(o == '|' ||
208 o == '&' ||
209 o == '^', "unexpected operator character");
211 return o == '|' ? t1 | t2
212 : o == '&' ? t1 & t2
213 : t1 ^ t2;
214 }
216 // OpAssign wraps a bitwise binary operator, passed as a char template
217 // parameter, and applies the corresponding compound-assignment operator to its
218 // arguments (t1, t2). For example,
219 //
220 // OpAssign<'|'>(t1, t2)
221 //
222 // is the same as
223 //
224 // t1 |= t2.
225 //
226 template<char o, typename T1, typename T2>
227 T1& OpAssign(T1& t1, const T2& t2)
228 {
229 static_assert(o == '|' ||
230 o == '&' ||
231 o == '^', "unexpected operator character");
233 switch (o) {
234 case '|': return t1 |= t2;
235 case '&': return t1 &= t2;
236 case '^': return t1 ^= t2;
237 default: MOZ_CRASH();
238 }
239 }
241 // Tests a single binary bitwise operator, using a single set of three operands.
242 // The operations tested are:
243 //
244 // result = t1 Op t2;
245 // result Op= t3;
246 //
247 // Where Op is the operator specified by the char template parameter 'o' and can
248 // be any of '|', '&', '^'.
249 //
250 // Note that the operands t1, t2, t3 are intentionally passed with free types
251 // (separate template parameters for each) because their type may actually be
252 // different from TypedEnum:
253 // 1) Their type could be CastableTypedEnumResult<TypedEnum> if they are
254 // the result of a bitwise operation themselves;
255 // 2) In the non-c++11 legacy path, the type of enum values is also
256 // different from TypedEnum.
257 //
258 template<typename TypedEnum, char o, typename T1, typename T2, typename T3>
259 void TestBinOp(const T1& t1, const T2& t2, const T3& t3)
260 {
261 typedef typename mozilla::detail::UnsignedIntegerTypeForEnum<TypedEnum>::Type
262 UnsignedIntegerType;
264 // Part 1:
265 // Test the bitwise binary operator i.e.
266 // result = t1 Op t2;
267 auto result = Op<o>(t1, t2);
269 typedef decltype(result) ResultType;
271 RequireLiteralType<ResultType>();
272 TestNonConvertibilityForOneType<ResultType>();
274 UnsignedIntegerType unsignedIntegerResult
275 = Op<o>(UnsignedIntegerType(t1), UnsignedIntegerType(t2));
277 MOZ_RELEASE_ASSERT(unsignedIntegerResult == UnsignedIntegerType(result));
278 MOZ_RELEASE_ASSERT(TypedEnum(unsignedIntegerResult) == TypedEnum(result));
279 MOZ_RELEASE_ASSERT((!unsignedIntegerResult) == (!result));
280 MOZ_RELEASE_ASSERT((!!unsignedIntegerResult) == (!!result));
281 MOZ_RELEASE_ASSERT(bool(unsignedIntegerResult) == bool(result));
283 // Part 2:
284 // Test the compound-assignment operator, i.e.
285 // result Op= t3;
286 TypedEnum newResult = result;
287 OpAssign<o>(newResult, t3);
288 UnsignedIntegerType unsignedIntegerNewResult = unsignedIntegerResult;
289 OpAssign<o>(unsignedIntegerNewResult, UnsignedIntegerType(t3));
290 MOZ_RELEASE_ASSERT(TypedEnum(unsignedIntegerNewResult) == newResult);
292 // Part 3:
293 // Test additional boolean operators that we unfortunately had to add to
294 // CastableTypedEnumResult at some point to please some compiler,
295 // even though bool convertibility should have been enough.
296 MOZ_RELEASE_ASSERT(result == TypedEnum(result));
297 MOZ_RELEASE_ASSERT(!(result != TypedEnum(result)));
298 MOZ_RELEASE_ASSERT((result && true) == bool(result));
299 MOZ_RELEASE_ASSERT((result && false) == false);
300 MOZ_RELEASE_ASSERT((true && result) == bool(result));
301 MOZ_RELEASE_ASSERT((false && result && false) == false);
302 MOZ_RELEASE_ASSERT((result || false) == bool(result));
303 MOZ_RELEASE_ASSERT((result || true) == true);
304 MOZ_RELEASE_ASSERT((false || result) == bool(result));
305 MOZ_RELEASE_ASSERT((true || result) == true);
306 }
308 // Similar to TestBinOp but testing the unary ~ operator.
309 template<typename TypedEnum, typename T>
310 void TestTilde(const T& t)
311 {
312 typedef typename mozilla::detail::UnsignedIntegerTypeForEnum<TypedEnum>::Type
313 UnsignedIntegerType;
315 auto result = ~t;
317 typedef decltype(result) ResultType;
319 RequireLiteralType<ResultType>();
320 TestNonConvertibilityForOneType<ResultType>();
322 UnsignedIntegerType unsignedIntegerResult = ~(UnsignedIntegerType(t));
324 MOZ_RELEASE_ASSERT(unsignedIntegerResult == UnsignedIntegerType(result));
325 MOZ_RELEASE_ASSERT(TypedEnum(unsignedIntegerResult) == TypedEnum(result));
326 MOZ_RELEASE_ASSERT((!unsignedIntegerResult) == (!result));
327 MOZ_RELEASE_ASSERT((!!unsignedIntegerResult) == (!!result));
328 MOZ_RELEASE_ASSERT(bool(unsignedIntegerResult) == bool(result));
329 }
331 // Helper dispatching a given triple of operands to all operator-specific
332 // testing functions.
333 template<typename TypedEnum, typename T1, typename T2, typename T3>
334 void TestAllOpsForGivenOperands(const T1& t1, const T2& t2, const T3& t3)
335 {
336 TestBinOp<TypedEnum, '|'>(t1, t2, t3);
337 TestBinOp<TypedEnum, '&'>(t1, t2, t3);
338 TestBinOp<TypedEnum, '^'>(t1, t2, t3);
339 TestTilde<TypedEnum>(t1);
340 }
342 // Helper building various triples of operands using a given operator,
343 // and testing all operators with them.
344 template<typename TypedEnum, char o>
345 void TestAllOpsForOperandsBuiltUsingGivenOp()
346 {
347 // The type of enum values like TypedEnum::A may be different from
348 // TypedEnum. That is the case in the legacy non-C++11 path. We want to
349 // ensure good test coverage even when these two types are distinct.
350 // To that effect, we have both 'auto' typed variables, preserving the
351 // original type of enum values, and 'plain' typed variables, that
352 // are plain TypedEnum's.
354 const TypedEnum a_plain = TypedEnum::A;
355 const TypedEnum b_plain = TypedEnum::B;
356 const TypedEnum c_plain = TypedEnum::C;
358 auto a_auto = TypedEnum::A;
359 auto b_auto = TypedEnum::B;
360 auto c_auto = TypedEnum::C;
362 auto ab_plain = Op<o>(a_plain, b_plain);
363 auto bc_plain = Op<o>(b_plain, c_plain);
364 auto ab_auto = Op<o>(a_auto, b_auto);
365 auto bc_auto = Op<o>(b_auto, c_auto);
367 // On each row below, we pass a triple of operands. Keep in mind that this
368 // is going to be received as (t1, t2, t3) and the actual tests performed
369 // will be of the form
370 //
371 // result = t1 Op t2;
372 // result Op= t3;
373 //
374 // For this reason, we carefully ensure that the values of (t1, t2)
375 // systematically cover all types of such pairs; to limit complexity,
376 // we are not so careful with t3, and we just try to pass t3's
377 // that may lead to nontrivial bitwise operations.
378 TestAllOpsForGivenOperands<TypedEnum>(a_plain, b_plain, c_plain);
379 TestAllOpsForGivenOperands<TypedEnum>(a_plain, bc_plain, b_auto);
380 TestAllOpsForGivenOperands<TypedEnum>(ab_plain, c_plain, a_plain);
381 TestAllOpsForGivenOperands<TypedEnum>(ab_plain, bc_plain, a_auto);
383 TestAllOpsForGivenOperands<TypedEnum>(a_plain, b_auto, c_plain);
384 TestAllOpsForGivenOperands<TypedEnum>(a_plain, bc_auto, b_auto);
385 TestAllOpsForGivenOperands<TypedEnum>(ab_plain, c_auto, a_plain);
386 TestAllOpsForGivenOperands<TypedEnum>(ab_plain, bc_auto, a_auto);
388 TestAllOpsForGivenOperands<TypedEnum>(a_auto, b_plain, c_plain);
389 TestAllOpsForGivenOperands<TypedEnum>(a_auto, bc_plain, b_auto);
390 TestAllOpsForGivenOperands<TypedEnum>(ab_auto, c_plain, a_plain);
391 TestAllOpsForGivenOperands<TypedEnum>(ab_auto, bc_plain, a_auto);
393 TestAllOpsForGivenOperands<TypedEnum>(a_auto, b_auto, c_plain);
394 TestAllOpsForGivenOperands<TypedEnum>(a_auto, bc_auto, b_auto);
395 TestAllOpsForGivenOperands<TypedEnum>(ab_auto, c_auto, a_plain);
396 TestAllOpsForGivenOperands<TypedEnum>(ab_auto, bc_auto, a_auto);
397 }
399 // Tests all bitwise operations on a given TypedEnum bitfield.
400 template<typename TypedEnum>
401 void
402 TestTypedEnumBitField()
403 {
404 TestTypedEnumBasics<TypedEnum>();
406 TestAllOpsForOperandsBuiltUsingGivenOp<TypedEnum, '|'>();
407 TestAllOpsForOperandsBuiltUsingGivenOp<TypedEnum, '&'>();
408 TestAllOpsForOperandsBuiltUsingGivenOp<TypedEnum, '^'>();
409 }
411 // Checks that enum bitwise expressions have the same non-convertibility properties as
412 // c++11 enum classes do, i.e. not implicitly convertible to anything
413 // (though *explicitly* convertible).
414 void TestNoConversionsBetweenUnrelatedTypes()
415 {
416 using mozilla::IsConvertible;
418 // Two typed enum classes having the same underlying integer type, to ensure that
419 // we would catch bugs accidentally allowing conversions in that case.
420 typedef CharEnumBitField T1;
421 typedef Nested::CharEnumBitField T2;
423 static_assert(!IsConvertible<T1, T2>::value,
424 "should not be convertible");
425 static_assert(!IsConvertible<T1, decltype(T2::A)>::value,
426 "should not be convertible");
427 static_assert(!IsConvertible<T1, decltype(T2::A | T2::B)>::value,
428 "should not be convertible");
430 static_assert(!IsConvertible<decltype(T1::A), T2>::value,
431 "should not be convertible");
432 static_assert(!IsConvertible<decltype(T1::A), decltype(T2::A)>::value,
433 "should not be convertible");
434 static_assert(!IsConvertible<decltype(T1::A), decltype(T2::A | T2::B)>::value,
435 "should not be convertible");
437 // The following are #ifdef MOZ_HAVE_EXPLICIT_CONVERSION because
438 // without support for explicit conversion operators, we can't easily have these
439 // bad conversions completely removed. They still do fail to compile in practice,
440 // but not in a way that we can static_assert on.
441 #ifdef MOZ_HAVE_EXPLICIT_CONVERSION
442 static_assert(!IsConvertible<decltype(T1::A | T1::B), T2>::value,
443 "should not be convertible");
444 static_assert(!IsConvertible<decltype(T1::A | T1::B), decltype(T2::A)>::value,
445 "should not be convertible");
446 static_assert(!IsConvertible<decltype(T1::A | T1::B), decltype(T2::A | T2::B)>::value,
447 "should not be convertible");
448 #endif
449 }
451 MOZ_BEGIN_ENUM_CLASS(Int8EnumWithHighBits, int8_t)
452 A = 0x20,
453 B = 0x40
454 MOZ_END_ENUM_CLASS(Int8EnumWithHighBits)
455 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int8EnumWithHighBits)
457 MOZ_BEGIN_ENUM_CLASS(Uint8EnumWithHighBits, uint8_t)
458 A = 0x40,
459 B = 0x80
460 MOZ_END_ENUM_CLASS(Uint8EnumWithHighBits)
461 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Uint8EnumWithHighBits)
463 MOZ_BEGIN_ENUM_CLASS(Int16EnumWithHighBits, int16_t)
464 A = 0x2000,
465 B = 0x4000
466 MOZ_END_ENUM_CLASS(Int16EnumWithHighBits)
467 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int16EnumWithHighBits)
469 MOZ_BEGIN_ENUM_CLASS(Uint16EnumWithHighBits, uint16_t)
470 A = 0x4000,
471 B = 0x8000
472 MOZ_END_ENUM_CLASS(Uint16EnumWithHighBits)
473 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Uint16EnumWithHighBits)
475 MOZ_BEGIN_ENUM_CLASS(Int32EnumWithHighBits, int32_t)
476 A = 0x20000000,
477 B = 0x40000000
478 MOZ_END_ENUM_CLASS(Int32EnumWithHighBits)
479 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int32EnumWithHighBits)
481 MOZ_BEGIN_ENUM_CLASS(Uint32EnumWithHighBits, uint32_t)
482 A = 0x40000000u,
483 B = 0x80000000u
484 MOZ_END_ENUM_CLASS(Uint32EnumWithHighBits)
485 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Uint32EnumWithHighBits)
487 MOZ_BEGIN_ENUM_CLASS(Int64EnumWithHighBits, int64_t)
488 A = 0x2000000000000000ll,
489 B = 0x4000000000000000ll
490 MOZ_END_ENUM_CLASS(Int64EnumWithHighBits)
491 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Int64EnumWithHighBits)
493 MOZ_BEGIN_ENUM_CLASS(Uint64EnumWithHighBits, uint64_t)
494 A = 0x4000000000000000ull,
495 B = 0x8000000000000000ull
496 MOZ_END_ENUM_CLASS(Uint64EnumWithHighBits)
497 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(Uint64EnumWithHighBits)
499 // Checks that we don't accidentally truncate high bits by coercing to the wrong
500 // integer type internally when implementing bitwise ops.
501 template<typename EnumType, typename IntType>
502 void TestIsNotTruncated()
503 {
504 EnumType a = EnumType::A;
505 EnumType b = EnumType::B;
506 MOZ_RELEASE_ASSERT(IntType(a));
507 MOZ_RELEASE_ASSERT(IntType(b));
508 MOZ_RELEASE_ASSERT(a | EnumType::B);
509 MOZ_RELEASE_ASSERT(a | b);
510 MOZ_RELEASE_ASSERT(EnumType::A | EnumType::B);
511 EnumType c = EnumType::A | EnumType::B;
512 MOZ_RELEASE_ASSERT(IntType(c));
513 MOZ_RELEASE_ASSERT(c & c);
514 MOZ_RELEASE_ASSERT(c | c);
515 MOZ_RELEASE_ASSERT(c == (EnumType::A | EnumType::B));
516 MOZ_RELEASE_ASSERT(a != (EnumType::A | EnumType::B));
517 MOZ_RELEASE_ASSERT(b != (EnumType::A | EnumType::B));
518 MOZ_RELEASE_ASSERT(c & EnumType::A);
519 MOZ_RELEASE_ASSERT(c & EnumType::B);
520 EnumType d = EnumType::A;
521 d |= EnumType::B;
522 MOZ_RELEASE_ASSERT(d == c);
523 }
525 int
526 main()
527 {
528 TestTypedEnumBasics<AutoEnum>();
529 TestTypedEnumBasics<CharEnum>();
530 TestTypedEnumBasics<Nested::AutoEnum>();
531 TestTypedEnumBasics<Nested::CharEnum>();
533 TestTypedEnumBitField<AutoEnumBitField>();
534 TestTypedEnumBitField<CharEnumBitField>();
535 TestTypedEnumBitField<Nested::AutoEnumBitField>();
536 TestTypedEnumBitField<Nested::CharEnumBitField>();
538 TestTypedEnumBitField<BitFieldFor_uint8_t>();
539 TestTypedEnumBitField<BitFieldFor_int8_t>();
540 TestTypedEnumBitField<BitFieldFor_uint16_t>();
541 TestTypedEnumBitField<BitFieldFor_int16_t>();
542 TestTypedEnumBitField<BitFieldFor_uint32_t>();
543 TestTypedEnumBitField<BitFieldFor_int32_t>();
544 TestTypedEnumBitField<BitFieldFor_uint64_t>();
545 TestTypedEnumBitField<BitFieldFor_int64_t>();
546 TestTypedEnumBitField<BitFieldFor_char>();
547 TestTypedEnumBitField<BitFieldFor_signed_char>();
548 TestTypedEnumBitField<BitFieldFor_unsigned_char>();
549 TestTypedEnumBitField<BitFieldFor_short>();
550 TestTypedEnumBitField<BitFieldFor_unsigned_short>();
551 TestTypedEnumBitField<BitFieldFor_int>();
552 TestTypedEnumBitField<BitFieldFor_unsigned_int>();
553 TestTypedEnumBitField<BitFieldFor_long>();
554 TestTypedEnumBitField<BitFieldFor_unsigned_long>();
555 TestTypedEnumBitField<BitFieldFor_long_long>();
556 TestTypedEnumBitField<BitFieldFor_unsigned_long_long>();
558 TestNoConversionsBetweenUnrelatedTypes();
560 TestIsNotTruncated<Int8EnumWithHighBits, int8_t>();
561 TestIsNotTruncated<Int16EnumWithHighBits, int16_t>();
562 TestIsNotTruncated<Int32EnumWithHighBits, int32_t>();
563 TestIsNotTruncated<Int64EnumWithHighBits, int64_t>();
564 TestIsNotTruncated<Uint8EnumWithHighBits, uint8_t>();
565 TestIsNotTruncated<Uint16EnumWithHighBits, uint16_t>();
566 TestIsNotTruncated<Uint32EnumWithHighBits, uint32_t>();
567 TestIsNotTruncated<Uint64EnumWithHighBits, uint64_t>();
569 return 0;
570 }