• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //  endian_test.cpp  ---------------------------------------------------------//
2 
3 //  Copyright Beman Dawes 1999-2008
4 
5 //  Distributed under the Boost Software License, Version 1.0.
6 //  See http://www.boost.org/LICENSE_1_0.txt
7 
8 //  See library home page at http://www.boost.org/libs/endian
9 
10 //----------------------------------------------------------------------------//
11 
12 //  This test probes for correct endianness, size, and value.
13 
14 //  See endian_operations_test for tests of operator correctness and interaction
15 //  between operand types.
16 
17 //----------------------------------------------------------------------------//
18 
19 #include <boost/endian/detail/disable_warnings.hpp>
20 
21 #include <boost/endian/arithmetic.hpp>
22 #include <boost/cstdint.hpp>
23 
24 #include <iostream>
25 #include <limits>
26 #include <climits>
27 #include <cstdlib>    // for atoi(), exit()
28 #include <cstring>    // for memcmp()
29 
30 #if defined(_MSC_VER)
31 # pragma warning(disable: 4127)  // conditional expression is constant
32 #endif
33 
34 using namespace std;             // Not the best programming practice, but I
35 using namespace boost;           //   want to verify this combination of using
36 using namespace boost::endian;   //   namespaces works. See endian_operations_test
37 //                               //   for tests that don't do "using namespace".
38 
39 #define VERIFY(predicate) verify( predicate, __LINE__ )
40 #define VERIFY_SIZE(actual, expected) verify_size( actual, expected, __LINE__ )
41 #define VERIFY_VALUE_AND_OPS(endian_t,expected_t,expected) verify_value_and_ops<endian_t, expected_t>( expected, __LINE__ )
42 #define VERIFY_BIG_REPRESENTATION(t) verify_representation<t>( true, __LINE__ )
43 #define VERIFY_LITTLE_REPRESENTATION(t) verify_representation<t>( false, __LINE__ )
44 #define VERIFY_NATIVE_REPRESENTATION(t) verify_native_representation<t>( __LINE__ )
45 
46 namespace
47 {
48   int err_count;
49 
verify(bool x,int line)50   void verify( bool x, int line )
51   {
52     if ( x ) return;
53     ++err_count;
54     cout << "Error: verify failed on line " << line << endl;
55   }
56 
verify_size(size_t actual,size_t expected,int line)57   void verify_size( size_t actual, size_t expected, int line )
58   {
59     if ( actual == expected ) return;
60     ++err_count;
61     cout << "Error: verify size failed on line " << line << endl;
62     cout << " A structure with an expected sizeof() " << expected
63          << " had an actual sizeof() " << actual
64          << "\n This will cause uses of endian types to fail\n";
65   }
66 
67   template <class Endian, class Base>
verify_value_and_ops(const Base & expected,int line)68   void verify_value_and_ops( const Base & expected, int line )
69   {
70     Endian v( expected );
71     verify( v == expected, line );
72 
73     Endian v2;
74     v2.operator=( expected );
75     verify( v2 == expected, line );
76 
77     ++v; // verify integer_cover_operators being applied to this type -
78          // will fail to compile if no endian<> specialization is present
79 
80     Endian v3( static_cast<Base>( 1 ) );
81 
82     Endian x(static_cast<typename Endian::value_type>(v2+v3));
83     if ( x == x ) // silence warning
84       return;
85   }
86 
87   const char * big_rep    = "\x12\x34\x56\x78\x9A\xBC\xDE\xF0";
88   const char * little_rep = "\xF0\xDE\xBC\x9A\x78\x56\x34\x12";
89 
90   template <class Endian>
verify_representation(bool is_big,int line)91   void verify_representation( bool is_big, int line )
92   {
93     int silence = 0;
94     Endian x ( static_cast<typename Endian::value_type>
95       (0x123456789abcdef0LL + silence) ); // will truncate
96 
97     if ( is_big )
98       verify( memcmp( &x,
99         reinterpret_cast<const char*>(big_rep)+8-sizeof(Endian),
100           sizeof(Endian) ) == 0, line );
101     else
102       verify( memcmp( &x, little_rep, sizeof(Endian) ) == 0, line );
103   }
104 
105   template <class Endian>
verify_native_representation(int line)106   inline void verify_native_representation( int line )
107   {
108     verify_representation<Endian>( order::native == order::big, line );
109   }
110 
111   //  detect_order  -----------------------------------------------------//
112 
detect_order()113   void detect_order()
114   {
115     union View
116     {
117       long long i;
118       unsigned char c[8];
119     };
120 
121     View v = { 0x0102030405060708LL };  // initialize v.i
122 
123     if ( memcmp( v.c, "\x8\7\6\5\4\3\2\1", 8) == 0 )
124     {
125       cout << "This machine is little-endian.\n";
126       if( order::native != order::little )
127       {
128         cout << "yet boost::endian::order::native does not equal boost::endian::order::little.\n"
129           "The Boost Endian library must be revised to work correctly on this system.\n"
130           "Please report this problem to the Boost mailing list.\n";
131         exit(1);
132       }
133     }
134     else if ( memcmp( v.c, "\1\2\3\4\5\6\7\x8", 8) == 0 )
135     {
136       cout << "This machine is big-endian.\n";
137       if( order::native != order::big )
138       {
139         cout << "yet boost::endian::order::native does not equal boost::endian::order::big.\n"
140           "The Boost Endian library must be revised to work correctly on this system.\n"
141           "Please report this problem to the Boost mailing list.\n";
142         exit(1);
143       }
144     }
145     else
146     {
147       cout << "This machine is neither strict big-endian nor strict little-endian\n"
148         "The Boost Endian library must be revised to work correctly on this system.\n"
149           "Please report this problem to the Boost mailing list.\n";
150       exit(1);
151     }
152     cout << "That should not matter and is presented for your information only.\n";
153   } // detect_order
154 
155   //  check_data  ------------------------------------------------------------//
156 
check_data()157   void check_data()
158   {
159     big_int8_t big_8;
160     big_int16_t big_16;
161     big_int24_t big_24;
162     big_int32_t big_32;
163     big_int40_t big_40;
164     big_int48_t big_48;
165     big_int56_t big_56;
166     big_int64_t big_64;
167 
168     big_uint8_t big_u8;
169     big_uint16_t big_u16;
170     big_uint24_t big_u24;
171     big_uint32_t big_u32;
172     big_uint40_t big_u40;
173     big_uint48_t big_u48;
174     big_uint56_t big_u56;
175     big_uint64_t big_u64;
176 
177     little_int8_t little_8;
178     little_int16_t little_16;
179     little_int24_t little_24;
180     little_int32_t little_32;
181     little_int40_t little_40;
182     little_int48_t little_48;
183     little_int56_t little_56;
184     little_int64_t little_64;
185 
186     little_uint8_t little_u8;
187     little_uint16_t little_u16;
188     little_uint24_t little_u24;
189     little_uint32_t little_u32;
190     little_uint40_t little_u40;
191     little_uint48_t little_u48;
192     little_uint56_t little_u56;
193     little_uint64_t little_u64;
194 
195     native_int8_t native_8;
196     native_int16_t native_16;
197     native_int24_t native_24;
198     native_int32_t native_32;
199     native_int40_t native_40;
200     native_int48_t native_48;
201     native_int56_t native_56;
202     native_int64_t native_64;
203 
204     native_uint8_t native_u8;
205     native_uint16_t native_u16;
206     native_uint24_t native_u24;
207     native_uint32_t native_u32;
208     native_uint40_t native_u40;
209     native_uint48_t native_u48;
210     native_uint56_t native_u56;
211     native_uint64_t native_u64;
212 
213     big_int16_at  big_align_int16;
214     big_int32_at  big_align_int32;
215     big_int64_at  big_align_int64;
216 
217     big_uint16_at big_align_uint16;
218     big_uint32_at big_align_uint32;
219     big_uint64_at big_align_uint64;
220 
221     little_int16_at  little_align_int16;
222     little_int32_at  little_align_int32;
223     little_int64_at  little_align_int64;
224 
225     little_uint16_at little_align_uint16;
226     little_uint32_at little_align_uint32;
227     little_uint64_at little_align_uint64;
228 
229     VERIFY(big_8.data() == reinterpret_cast<const unsigned char *>(&big_8));
230     VERIFY(big_16.data() == reinterpret_cast<const unsigned char *>(&big_16));
231     VERIFY(big_24.data() == reinterpret_cast<const unsigned char *>(&big_24));
232     VERIFY(big_32.data() == reinterpret_cast<const unsigned char *>(&big_32));
233     VERIFY(big_40.data() == reinterpret_cast<const unsigned char *>(&big_40));
234     VERIFY(big_48.data() == reinterpret_cast<const unsigned char *>(&big_48));
235     VERIFY(big_56.data() == reinterpret_cast<const unsigned char *>(&big_56));
236     VERIFY(big_64.data() == reinterpret_cast<const unsigned char *>(&big_64));
237 
238     VERIFY(big_u8.data() == reinterpret_cast<const unsigned char *>(&big_u8));
239     VERIFY(big_u16.data() == reinterpret_cast<const unsigned char *>(&big_u16));
240     VERIFY(big_u24.data() == reinterpret_cast<const unsigned char *>(&big_u24));
241     VERIFY(big_u32.data() == reinterpret_cast<const unsigned char *>(&big_u32));
242     VERIFY(big_u40.data() == reinterpret_cast<const unsigned char *>(&big_u40));
243     VERIFY(big_u48.data() == reinterpret_cast<const unsigned char *>(&big_u48));
244     VERIFY(big_u56.data() == reinterpret_cast<const unsigned char *>(&big_u56));
245     VERIFY(big_u64.data() == reinterpret_cast<const unsigned char *>(&big_u64));
246 
247     VERIFY(little_8.data() == reinterpret_cast<const unsigned char *>(&little_8));
248     VERIFY(little_16.data() == reinterpret_cast<const unsigned char *>(&little_16));
249     VERIFY(little_24.data() == reinterpret_cast<const unsigned char *>(&little_24));
250     VERIFY(little_32.data() == reinterpret_cast<const unsigned char *>(&little_32));
251     VERIFY(little_40.data() == reinterpret_cast<const unsigned char *>(&little_40));
252     VERIFY(little_48.data() == reinterpret_cast<const unsigned char *>(&little_48));
253     VERIFY(little_56.data() == reinterpret_cast<const unsigned char *>(&little_56));
254     VERIFY(little_64.data() == reinterpret_cast<const unsigned char *>(&little_64));
255 
256     VERIFY(little_u8.data() == reinterpret_cast<const unsigned char *>(&little_u8));
257     VERIFY(little_u16.data() == reinterpret_cast<const unsigned char *>(&little_u16));
258     VERIFY(little_u24.data() == reinterpret_cast<const unsigned char *>(&little_u24));
259     VERIFY(little_u32.data() == reinterpret_cast<const unsigned char *>(&little_u32));
260     VERIFY(little_u40.data() == reinterpret_cast<const unsigned char *>(&little_u40));
261     VERIFY(little_u48.data() == reinterpret_cast<const unsigned char *>(&little_u48));
262     VERIFY(little_u56.data() == reinterpret_cast<const unsigned char *>(&little_u56));
263     VERIFY(little_u64.data() == reinterpret_cast<const unsigned char *>(&little_u64));
264 
265     VERIFY(native_8.data() == reinterpret_cast<const unsigned char *>(&native_8));
266     VERIFY(native_16.data() == reinterpret_cast<const unsigned char *>(&native_16));
267     VERIFY(native_24.data() == reinterpret_cast<const unsigned char *>(&native_24));
268     VERIFY(native_32.data() == reinterpret_cast<const unsigned char *>(&native_32));
269     VERIFY(native_40.data() == reinterpret_cast<const unsigned char *>(&native_40));
270     VERIFY(native_48.data() == reinterpret_cast<const unsigned char *>(&native_48));
271     VERIFY(native_56.data() == reinterpret_cast<const unsigned char *>(&native_56));
272     VERIFY(native_64.data() == reinterpret_cast<const unsigned char *>(&native_64));
273 
274     VERIFY(native_u8.data() == reinterpret_cast<const unsigned char *>(&native_u8));
275     VERIFY(native_u16.data() == reinterpret_cast<const unsigned char *>(&native_u16));
276     VERIFY(native_u24.data() == reinterpret_cast<const unsigned char *>(&native_u24));
277     VERIFY(native_u32.data() == reinterpret_cast<const unsigned char *>(&native_u32));
278     VERIFY(native_u40.data() == reinterpret_cast<const unsigned char *>(&native_u40));
279     VERIFY(native_u48.data() == reinterpret_cast<const unsigned char *>(&native_u48));
280     VERIFY(native_u56.data() == reinterpret_cast<const unsigned char *>(&native_u56));
281     VERIFY(native_u64.data() == reinterpret_cast<const unsigned char *>(&native_u64));
282 
283     VERIFY(big_align_int16.data() == reinterpret_cast<const unsigned char *>(&big_align_int16));
284     VERIFY(big_align_int32.data() == reinterpret_cast<const unsigned char *>(&big_align_int32));
285     VERIFY(big_align_int64.data() == reinterpret_cast<const unsigned char *>(&big_align_int64));
286 
287     VERIFY(big_align_uint16.data() == reinterpret_cast<const unsigned char *>(&big_align_uint16));
288     VERIFY(big_align_uint32.data() == reinterpret_cast<const unsigned char *>(&big_align_uint32));
289     VERIFY(big_align_uint64.data() == reinterpret_cast<const unsigned char *>(&big_align_uint64));
290 
291     VERIFY(little_align_int16.data() == reinterpret_cast<const unsigned char *>(&little_align_int16));
292     VERIFY(little_align_int32.data() == reinterpret_cast<const unsigned char *>(&little_align_int32));
293     VERIFY(little_align_int64.data() == reinterpret_cast<const unsigned char *>(&little_align_int64));
294 
295     VERIFY(little_align_uint16.data() == reinterpret_cast<const unsigned char *>(&little_align_uint16));
296     VERIFY(little_align_uint32.data() == reinterpret_cast<const unsigned char *>(&little_align_uint32));
297     VERIFY(little_align_uint64.data() == reinterpret_cast<const unsigned char *>(&little_align_uint64));
298 
299   }
300 
301   //  check_size  ------------------------------------------------------------//
302 
check_size()303   void check_size()
304   {
305     VERIFY( numeric_limits<signed char>::digits == 7 );
306     VERIFY( numeric_limits<unsigned char>::digits == 8 );
307 
308     VERIFY_SIZE( sizeof( big_int8_t ), 1 );
309     VERIFY_SIZE( sizeof( big_int16_t ), 2 );
310     VERIFY_SIZE( sizeof( big_int24_t ), 3 );
311     VERIFY_SIZE( sizeof( big_int32_t ), 4 );
312     VERIFY_SIZE( sizeof( big_int40_t ), 5 );
313     VERIFY_SIZE( sizeof( big_int48_t ), 6 );
314     VERIFY_SIZE( sizeof( big_int56_t ), 7 );
315     VERIFY_SIZE( sizeof( big_int64_t ), 8 );
316 
317     VERIFY_SIZE( sizeof( big_uint8_t ), 1 );
318     VERIFY_SIZE( sizeof( big_uint16_t ), 2 );
319     VERIFY_SIZE( sizeof( big_uint24_t ), 3 );
320     VERIFY_SIZE( sizeof( big_uint32_t ), 4 );
321     VERIFY_SIZE( sizeof( big_uint40_t ), 5 );
322     VERIFY_SIZE( sizeof( big_uint48_t ), 6 );
323     VERIFY_SIZE( sizeof( big_uint56_t ), 7 );
324     VERIFY_SIZE( sizeof( big_uint64_t ), 8 );
325 
326     VERIFY_SIZE( sizeof( little_int8_t ), 1 );
327     VERIFY_SIZE( sizeof( little_int16_t ), 2 );
328     VERIFY_SIZE( sizeof( little_int24_t ), 3 );
329     VERIFY_SIZE( sizeof( little_int32_t ), 4 );
330     VERIFY_SIZE( sizeof( little_int40_t ), 5 );
331     VERIFY_SIZE( sizeof( little_int48_t ), 6 );
332     VERIFY_SIZE( sizeof( little_int56_t ), 7 );
333     VERIFY_SIZE( sizeof( little_int64_t ), 8 );
334 
335     VERIFY_SIZE( sizeof( little_uint8_t ), 1 );
336     VERIFY_SIZE( sizeof( little_uint16_t ), 2 );
337     VERIFY_SIZE( sizeof( little_uint24_t ), 3 );
338     VERIFY_SIZE( sizeof( little_uint32_t ), 4 );
339     VERIFY_SIZE( sizeof( little_uint40_t ), 5 );
340     VERIFY_SIZE( sizeof( little_uint48_t ), 6 );
341     VERIFY_SIZE( sizeof( little_uint56_t ), 7 );
342     VERIFY_SIZE( sizeof( little_uint64_t ), 8 );
343 
344     VERIFY_SIZE( sizeof( native_int8_t ), 1 );
345     VERIFY_SIZE( sizeof( native_int16_t ), 2 );
346     VERIFY_SIZE( sizeof( native_int24_t ), 3 );
347     VERIFY_SIZE( sizeof( native_int32_t ), 4 );
348     VERIFY_SIZE( sizeof( native_int40_t ), 5 );
349     VERIFY_SIZE( sizeof( native_int48_t ), 6 );
350     VERIFY_SIZE( sizeof( native_int56_t ), 7 );
351     VERIFY_SIZE( sizeof( native_int64_t ), 8 );
352 
353     VERIFY_SIZE( sizeof( native_uint8_t ), 1 );
354     VERIFY_SIZE( sizeof( native_uint16_t ), 2 );
355     VERIFY_SIZE( sizeof( native_uint24_t ), 3 );
356     VERIFY_SIZE( sizeof( native_uint32_t ), 4 );
357     VERIFY_SIZE( sizeof( native_uint40_t ), 5 );
358     VERIFY_SIZE( sizeof( native_uint48_t ), 6 );
359     VERIFY_SIZE( sizeof( native_uint56_t ), 7 );
360     VERIFY_SIZE( sizeof( native_uint64_t ), 8 );
361 
362     VERIFY_SIZE(sizeof(big_int8_at), 1);
363     VERIFY_SIZE(sizeof(big_int16_at), 2);
364     VERIFY_SIZE( sizeof( big_int32_at ), 4 );
365     VERIFY_SIZE( sizeof( big_int64_at ), 8 );
366 
367     VERIFY_SIZE(sizeof(big_uint8_at), 1);
368     VERIFY_SIZE(sizeof(big_uint16_at), 2);
369     VERIFY_SIZE( sizeof( big_uint32_at ), 4 );
370     VERIFY_SIZE( sizeof( big_uint64_at ), 8 );
371 
372     VERIFY_SIZE(sizeof(little_int8_at), 1);
373     VERIFY_SIZE(sizeof(little_int16_at), 2);
374     VERIFY_SIZE( sizeof( little_int32_at ), 4 );
375     VERIFY_SIZE( sizeof( little_int64_at ), 8 );
376 
377     VERIFY_SIZE(sizeof(little_uint8_at), 1);
378     VERIFY_SIZE(sizeof(little_uint16_at), 2);
379     VERIFY_SIZE( sizeof( little_uint32_at ), 4 );
380     VERIFY_SIZE( sizeof( little_uint64_at ), 8 );
381   } // check_size
382 
383   //  check_alignment  -------------------------------------------------------//
384 
check_alignment()385   void check_alignment()
386   {
387     // structs with offsets % 2 == 1 for type of size > 1 to ensure no alignment
388     // bytes added for any size > 1
389 
390     struct big_struct
391     {
392       big_int8_t    v0;
393       big_int16_t    v1;
394       big_int24_t    v3;
395       char      v6;
396       big_int32_t    v7;
397       big_int40_t    v11;
398       char      v16;
399       big_int48_t    v17;
400       big_int56_t    v23;
401       char      v30;
402       big_int64_t    v31;
403     };
404 
405     struct big_u_struct
406     {
407       big_uint8_t    v0;
408       big_uint16_t    v1;
409       big_uint24_t    v3;
410       char       v6;
411       big_uint32_t    v7;
412       big_uint40_t    v11;
413       char       v16;
414       big_uint48_t    v17;
415       big_uint56_t    v23;
416       char       v30;
417       big_uint64_t    v31;
418     };
419 
420     struct little_struct
421     {
422       little_int8_t    v0;
423       little_int16_t    v1;
424       little_int24_t    v3;
425       char         v6;
426       little_int32_t    v7;
427       little_int40_t    v11;
428       char         v16;
429       little_int48_t    v17;
430       little_int56_t    v23;
431       char         v30;
432       little_int64_t    v31;
433     };
434 
435     struct little_u_struct
436     {
437       little_uint8_t    v0;
438       little_uint16_t    v1;
439       little_uint24_t    v3;
440       char          v6;
441       little_uint32_t    v7;
442       little_uint40_t    v11;
443       char          v16;
444       little_uint48_t    v17;
445       little_uint56_t    v23;
446       char          v30;
447       little_uint64_t    v31;
448     };
449 
450     struct native_struct
451     {
452       native_int8_t    v0;
453       native_int16_t    v1;
454       native_int24_t    v3;
455       char         v6;
456       native_int32_t    v7;
457       native_int40_t    v11;
458       char         v16;
459       native_int48_t    v17;
460       native_int56_t    v23;
461       char         v30;
462       native_int64_t    v31;
463     };
464 
465     struct native_u_struct
466     {
467       native_uint8_t    v0;
468       native_uint16_t    v1;
469       native_uint24_t    v3;
470       char          v6;
471       native_uint32_t    v7;
472       native_uint40_t    v11;
473       char          v16;
474       native_uint48_t    v17;
475       native_uint56_t    v23;
476       char          v30;
477       native_uint64_t    v31;
478     };
479 
480     //  aligned test cases
481 
482     struct big_aligned_struct
483     {
484       big_int16_at    v0;
485       big_int32_at    v1;
486       char          v3;
487       // on a 32-bit system, the padding here may be 3 rather than 7 bytes
488       big_int64_at    v4;
489     };
490 
491     struct little_aligned_struct
492     {
493       little_int16_at    v0;
494       little_int32_at    v1;
495       char          v3;
496       // on a 32-bit system, the padding here may be 3 rather than 7 bytes
497       little_int64_at    v4;
498     };
499 
500     int saved_err_count = err_count;
501 
502     VERIFY_SIZE( sizeof(big_struct), 39 );
503     VERIFY_SIZE( sizeof(big_u_struct), 39 );
504     VERIFY_SIZE( sizeof(little_struct), 39 );
505     VERIFY_SIZE( sizeof(little_u_struct), 39 );
506     VERIFY_SIZE( sizeof(native_struct), 39 );
507     VERIFY_SIZE( sizeof(native_u_struct), 39 );
508     VERIFY( sizeof(big_aligned_struct) <= 24 );
509     VERIFY( sizeof(little_aligned_struct) <= 24 );
510 
511     if ( saved_err_count == err_count )
512     {
513       cout <<
514         "Size and alignment for structures of endian types are as expected.\n";
515     }
516   } // check_alignment
517 
518   //  check_representation_and_range_and_ops  --------------------------------//
519 
check_representation_and_range_and_ops()520   void check_representation_and_range_and_ops()
521   {
522     // unaligned integer types
523     VERIFY_BIG_REPRESENTATION( big_int8_t );
524     VERIFY_VALUE_AND_OPS( big_int8_t, int_least8_t,  0x7e );
525     VERIFY_VALUE_AND_OPS( big_int8_t, int_least8_t, -0x80 );
526 
527     VERIFY_BIG_REPRESENTATION( big_int16_t );
528     VERIFY_VALUE_AND_OPS( big_int16_t, int_least16_t,  0x7ffe );
529     VERIFY_VALUE_AND_OPS( big_int16_t, int_least16_t, -0x8000 );
530 
531     VERIFY_BIG_REPRESENTATION( big_int24_t );
532     VERIFY_VALUE_AND_OPS( big_int24_t, int_least32_t,  0x7ffffe );
533     VERIFY_VALUE_AND_OPS( big_int24_t, int_least32_t, -0x800000 );
534 
535     VERIFY_BIG_REPRESENTATION( big_int32_t );
536     VERIFY_VALUE_AND_OPS( big_int32_t, int_least32_t,  0x7ffffffe );
537     VERIFY_VALUE_AND_OPS( big_int32_t, int_least32_t, -0x7fffffff-1 );
538 
539     VERIFY_BIG_REPRESENTATION( big_int40_t );
540     VERIFY_VALUE_AND_OPS( big_int40_t, int_least64_t,  0x7ffffffffeLL );
541     VERIFY_VALUE_AND_OPS( big_int40_t, int_least64_t, -0x8000000000LL );
542 
543     VERIFY_BIG_REPRESENTATION( big_int48_t );
544     VERIFY_VALUE_AND_OPS( big_int48_t, int_least64_t,  0x7ffffffffffeLL );
545     VERIFY_VALUE_AND_OPS( big_int48_t, int_least64_t, -0x800000000000LL );
546 
547     VERIFY_BIG_REPRESENTATION( big_int56_t );
548     VERIFY_VALUE_AND_OPS( big_int56_t, int_least64_t,  0x7ffffffffffffeLL );
549     VERIFY_VALUE_AND_OPS( big_int56_t, int_least64_t, -0x80000000000000LL );
550 
551     VERIFY_BIG_REPRESENTATION( big_int64_t );
552     VERIFY_VALUE_AND_OPS( big_int64_t, int_least64_t,  0x7ffffffffffffffeLL );
553     VERIFY_VALUE_AND_OPS( big_int64_t, int_least64_t, -0x7fffffffffffffffLL-1 );
554 
555     VERIFY_BIG_REPRESENTATION( big_uint8_t );
556     VERIFY_VALUE_AND_OPS( big_uint8_t, uint_least8_t,  0xff );
557 
558     VERIFY_BIG_REPRESENTATION( big_uint16_t );
559     VERIFY_VALUE_AND_OPS( big_uint16_t, uint_least16_t, 0xffff );
560 
561     VERIFY_BIG_REPRESENTATION( big_uint24_t );
562     VERIFY_VALUE_AND_OPS( big_uint24_t, uint_least32_t, 0xffffff );
563 
564     VERIFY_BIG_REPRESENTATION( big_uint32_t );
565     VERIFY_VALUE_AND_OPS( big_uint32_t, uint_least32_t, 0xffffffff );
566 
567     VERIFY_BIG_REPRESENTATION( big_uint40_t );
568     VERIFY_VALUE_AND_OPS( big_uint40_t, uint_least64_t, 0xffffffffffLL );
569 
570     VERIFY_BIG_REPRESENTATION( big_uint48_t );
571     VERIFY_VALUE_AND_OPS( big_uint48_t, uint_least64_t, 0xffffffffffffLL );
572 
573     VERIFY_BIG_REPRESENTATION( big_uint56_t );
574     VERIFY_VALUE_AND_OPS( big_uint56_t, uint_least64_t, 0xffffffffffffffLL );
575 
576     VERIFY_BIG_REPRESENTATION( big_uint64_t );
577     VERIFY_VALUE_AND_OPS( big_uint64_t, uint_least64_t, 0xffffffffffffffffULL );
578 
579     VERIFY_LITTLE_REPRESENTATION( little_int8_t );
580     VERIFY_VALUE_AND_OPS( little_int8_t, int_least8_t,   0x7e );
581     VERIFY_VALUE_AND_OPS( little_int8_t, int_least8_t,  -0x80 );
582 
583     VERIFY_LITTLE_REPRESENTATION( little_int16_t );
584     VERIFY_VALUE_AND_OPS( little_int16_t, int_least16_t,  0x7ffe );
585     VERIFY_VALUE_AND_OPS( little_int16_t, int_least16_t, -0x8000 );
586 
587     VERIFY_LITTLE_REPRESENTATION( little_int24_t );
588     VERIFY_VALUE_AND_OPS( little_int24_t, int_least32_t,  0x7ffffe );
589     VERIFY_VALUE_AND_OPS( little_int24_t, int_least32_t, -0x800000 );
590 
591     VERIFY_LITTLE_REPRESENTATION( little_int32_t );
592     VERIFY_VALUE_AND_OPS( little_int32_t, int_least32_t,  0x7ffffffe );
593     VERIFY_VALUE_AND_OPS( little_int32_t, int_least32_t, -0x7fffffff-1 );
594 
595     VERIFY_LITTLE_REPRESENTATION( little_int40_t );
596     VERIFY_VALUE_AND_OPS( little_int40_t, int_least64_t,  0x7ffffffffeLL );
597     VERIFY_VALUE_AND_OPS( little_int40_t, int_least64_t, -0x8000000000LL );
598 
599     VERIFY_LITTLE_REPRESENTATION( little_int48_t );
600     VERIFY_VALUE_AND_OPS( little_int48_t, int_least64_t,  0x7ffffffffffeLL );
601     VERIFY_VALUE_AND_OPS( little_int48_t, int_least64_t, -0x800000000000LL );
602 
603     VERIFY_LITTLE_REPRESENTATION( little_int56_t );
604     VERIFY_VALUE_AND_OPS( little_int56_t, int_least64_t,  0x7ffffffffffffeLL );
605     VERIFY_VALUE_AND_OPS( little_int56_t, int_least64_t, -0x80000000000000LL );
606 
607     VERIFY_LITTLE_REPRESENTATION( little_int64_t );
608     VERIFY_VALUE_AND_OPS( little_int64_t, int_least64_t,  0x7ffffffffffffffeLL );
609     VERIFY_VALUE_AND_OPS( little_int64_t, int_least64_t, -0x7fffffffffffffffLL-1 );
610 
611     VERIFY_LITTLE_REPRESENTATION( little_uint8_t );
612     VERIFY_VALUE_AND_OPS( little_uint8_t, uint_least8_t, 0xff );
613 
614     VERIFY_LITTLE_REPRESENTATION( little_uint16_t );
615     VERIFY_VALUE_AND_OPS( little_uint16_t, uint_least16_t, 0xffff );
616 
617     VERIFY_LITTLE_REPRESENTATION( little_uint24_t );
618     VERIFY_VALUE_AND_OPS( little_uint24_t, uint_least32_t, 0xffffff );
619 
620     VERIFY_LITTLE_REPRESENTATION( little_uint32_t );
621     VERIFY_VALUE_AND_OPS( little_uint32_t, uint_least32_t, 0xffffffff );
622 
623     VERIFY_LITTLE_REPRESENTATION( little_uint40_t );
624     VERIFY_VALUE_AND_OPS( little_uint40_t, uint_least64_t, 0xffffffffffLL );
625 
626     VERIFY_LITTLE_REPRESENTATION( little_uint48_t );
627     VERIFY_VALUE_AND_OPS( little_uint48_t, uint_least64_t, 0xffffffffffffLL );
628 
629     VERIFY_LITTLE_REPRESENTATION( little_uint56_t );
630     VERIFY_VALUE_AND_OPS( little_uint56_t, uint_least64_t, 0xffffffffffffffLL );
631 
632     VERIFY_LITTLE_REPRESENTATION( little_uint64_t );
633     VERIFY_VALUE_AND_OPS( little_uint64_t, uint_least64_t, 0xffffffffffffffffULL );
634 
635     VERIFY_NATIVE_REPRESENTATION( native_int8_t );
636     VERIFY_VALUE_AND_OPS( native_int8_t, int_least8_t,   0x7e );
637     VERIFY_VALUE_AND_OPS( native_int8_t, int_least8_t,  -0x80 );
638 
639     VERIFY_NATIVE_REPRESENTATION( native_int16_t );
640     VERIFY_VALUE_AND_OPS( native_int16_t, int_least16_t,  0x7ffe );
641     VERIFY_VALUE_AND_OPS( native_int16_t, int_least16_t, -0x8000 );
642 
643     VERIFY_NATIVE_REPRESENTATION( native_int24_t );
644     VERIFY_VALUE_AND_OPS( native_int24_t, int_least32_t,  0x7ffffe );
645     VERIFY_VALUE_AND_OPS( native_int24_t, int_least32_t, -0x800000 );
646 
647     VERIFY_NATIVE_REPRESENTATION( native_int32_t );
648     VERIFY_VALUE_AND_OPS( native_int32_t, int_least32_t,  0x7ffffffe );
649     VERIFY_VALUE_AND_OPS( native_int32_t, int_least32_t, -0x7fffffff-1 );
650 
651     VERIFY_NATIVE_REPRESENTATION( native_int40_t );
652     VERIFY_VALUE_AND_OPS( native_int40_t, int_least64_t,  0x7ffffffffeLL );
653     VERIFY_VALUE_AND_OPS( native_int40_t, int_least64_t, -0x8000000000LL );
654 
655     VERIFY_NATIVE_REPRESENTATION( native_int48_t );
656     VERIFY_VALUE_AND_OPS( native_int48_t, int_least64_t,  0x7ffffffffffeLL );
657     VERIFY_VALUE_AND_OPS( native_int48_t, int_least64_t, -0x800000000000LL );
658 
659     VERIFY_NATIVE_REPRESENTATION( native_int56_t );
660     VERIFY_VALUE_AND_OPS( native_int56_t, int_least64_t,  0x7ffffffffffffeLL );
661     VERIFY_VALUE_AND_OPS( native_int56_t, int_least64_t, -0x80000000000000LL );
662 
663     VERIFY_NATIVE_REPRESENTATION( native_int64_t );
664     VERIFY_VALUE_AND_OPS( native_int64_t, int_least64_t,  0x7ffffffffffffffeLL );
665     VERIFY_VALUE_AND_OPS( native_int64_t, int_least64_t, -0x7fffffffffffffffLL-1 );
666 
667     VERIFY_NATIVE_REPRESENTATION( native_uint8_t );
668     VERIFY_VALUE_AND_OPS( native_uint8_t, uint_least8_t, 0xff );
669 
670     VERIFY_NATIVE_REPRESENTATION( native_uint16_t );
671     VERIFY_VALUE_AND_OPS( native_uint16_t, uint_least16_t, 0xffff );
672 
673     VERIFY_NATIVE_REPRESENTATION( native_uint24_t );
674     VERIFY_VALUE_AND_OPS( native_uint24_t, uint_least32_t, 0xffffff );
675 
676     VERIFY_NATIVE_REPRESENTATION( native_uint32_t );
677     VERIFY_VALUE_AND_OPS( native_uint32_t, uint_least32_t, 0xffffffff );
678 
679     VERIFY_NATIVE_REPRESENTATION( native_uint40_t );
680     VERIFY_VALUE_AND_OPS( native_uint40_t, uint_least64_t, 0xffffffffffLL );
681 
682     VERIFY_NATIVE_REPRESENTATION( native_uint48_t );
683     VERIFY_VALUE_AND_OPS( native_uint48_t, uint_least64_t, 0xffffffffffffLL );
684 
685     VERIFY_NATIVE_REPRESENTATION( native_uint56_t );
686     VERIFY_VALUE_AND_OPS( native_uint56_t, uint_least64_t, 0xffffffffffffffLL );
687 
688     VERIFY_NATIVE_REPRESENTATION( native_uint64_t );
689     VERIFY_VALUE_AND_OPS( native_uint64_t, uint_least64_t, 0xffffffffffffffffULL );
690 
691     // aligned integer types
692     VERIFY_BIG_REPRESENTATION( big_int16_at );
693     VERIFY_VALUE_AND_OPS( big_int16_at, int_least16_t,  0x7ffe );
694     VERIFY_VALUE_AND_OPS( big_int16_at, int_least16_t, -0x8000 );
695 
696     VERIFY_BIG_REPRESENTATION( big_int32_at );
697     VERIFY_VALUE_AND_OPS( big_int32_at, int_least32_t,  0x7ffffffe );
698     VERIFY_VALUE_AND_OPS( big_int32_at, int_least32_t, -0x7fffffff-1 );
699 
700     VERIFY_BIG_REPRESENTATION( big_int64_at );
701     VERIFY_VALUE_AND_OPS( big_int64_at, int_least64_t,  0x7ffffffffffffffeLL );
702     VERIFY_VALUE_AND_OPS( big_int64_at, int_least64_t, -0x7fffffffffffffffLL-1 );
703 
704     VERIFY_BIG_REPRESENTATION( big_uint16_at );
705     VERIFY_VALUE_AND_OPS( big_uint16_at, uint_least16_t, 0xffff );
706 
707     VERIFY_BIG_REPRESENTATION( big_uint32_at );
708     VERIFY_VALUE_AND_OPS( big_uint32_at, uint_least32_t, 0xffffffff );
709 
710     VERIFY_BIG_REPRESENTATION( big_uint64_at );
711     VERIFY_VALUE_AND_OPS( big_uint64_at, uint_least64_t, 0xffffffffffffffffULL );
712 
713     VERIFY_LITTLE_REPRESENTATION( little_int16_at );
714     VERIFY_VALUE_AND_OPS( little_int16_at, int_least16_t,  0x7ffe );
715     VERIFY_VALUE_AND_OPS( little_int16_at, int_least16_t, -0x8000 );
716 
717     VERIFY_LITTLE_REPRESENTATION( little_int32_at );
718     VERIFY_VALUE_AND_OPS( little_int32_at, int_least32_t,  0x7ffffffe );
719     VERIFY_VALUE_AND_OPS( little_int32_at, int_least32_t, -0x7fffffff-1 );
720 
721     VERIFY_LITTLE_REPRESENTATION( little_int64_at );
722     VERIFY_VALUE_AND_OPS( little_int64_at, int_least64_t,  0x7ffffffffffffffeLL );
723     VERIFY_VALUE_AND_OPS( little_int64_at, int_least64_t, -0x7fffffffffffffffLL-1 );
724 
725     VERIFY_LITTLE_REPRESENTATION( little_uint16_at );
726     VERIFY_VALUE_AND_OPS( little_uint16_at, uint_least16_t, 0xffff );
727 
728     VERIFY_LITTLE_REPRESENTATION( little_uint32_at );
729     VERIFY_VALUE_AND_OPS( little_uint32_at, uint_least32_t, 0xffffffff );
730 
731     VERIFY_LITTLE_REPRESENTATION( little_uint64_at );
732     VERIFY_VALUE_AND_OPS( little_uint64_at, uint_least64_t, 0xffffffffffffffffULL );
733 
734   } // check_representation_and_range
735 
736 /*
737 
738   class MyInt
739   {
740     int32_t mx;
741   public:
742     MyInt(int32_t x = 0) : mx(x) {}
743     operator int32_t() const {return mx;}
744 
745     //friend int32_t operator+(const MyInt& x) {return x;}
746   };
747 
748   void check_udt()
749   {
750     typedef boost::endian::endian_arithmetic< order::big, MyInt, 32 >  mybig_int32_ut;
751 
752     mybig_int32_ut v(10);
753     cout << "+v is " << +v << endl;
754     v += 1;
755     cout << "v is " << +v << endl;
756     v -= 2;
757     cout << "v is " << +v << endl;
758     v *= 2;
759     cout << "v is " << +v << endl;
760     ++v;
761     cout << "v is " << +v << endl;
762     --v;
763     cout << "v is " << +v << endl;
764 //    cout << "v+v is " << +(v+v) << endl;
765   }
766 
767   void check_udt_le()
768   {
769     typedef boost::endian::endian_arithmetic< order::little, MyInt, 32 >  mylittle_int32_ut;
770 
771     mylittle_int32_ut v(10);
772     cout << "+v is " << +v << endl;
773     v += 1;
774     cout << "v is " << +v << endl;
775     v -= 2;
776     cout << "v is " << +v << endl;
777     v *= 2;
778     cout << "v is " << +v << endl;
779     ++v;
780     cout << "v is " << +v << endl;
781     --v;
782     cout << "v is " << +v << endl;
783 //    cout << "v+v is " << +(v+v) << endl;
784   }
785 
786 */
787 
788   long iterations = 10000;
789 
790   template< class Endian >
timing_test(const char * s)791   Endian timing_test( const char * s)
792   {
793     cout << s << " timing test, " << iterations << " iterations: ";
794 //    progress_timer t;
795 
796     Endian v = 1;
797     for ( long i = 0; i < iterations; ++i )
798     {
799       v += 1;
800       v *= 3;
801       ++v;
802       v *= i;
803       if ( i == 0 ) VERIFY_VALUE_AND_OPS( Endian, typename Endian::value_type, 21 );
804     }
805     return v;
806   }
807 
808 } // unnamed namespace
809 
810 //  main  ------------------------------------------------------------------------------//
811 
cpp_main(int argc,char * argv[])812 int cpp_main( int argc, char * argv[] )
813 {
814   cout << "Usage: "
815        << argv[0] << " [#],\n where # specifies iteration count\n"
816           " default iteration count is " << iterations << endl;
817 
818   if ( argc > 1 )
819     iterations = atol( argv[1] );
820   if ( iterations < 1 ) iterations = 1;
821 
822   detect_order();
823   check_size();
824   check_alignment();
825   check_representation_and_range_and_ops();
826   check_data();
827   //check_udt();
828   //check_udt_le();
829 
830   //timing_test<big_int32_t> ( "big_int32_t" );
831   //timing_test<big_int32_at>( "big_int32_at" );
832   //timing_test<little_int32_t> ( "little_int32_t" );
833   //timing_test<little_int32_at>( "little_int32_at" );
834 
835   cout << "\n" << err_count << " errors detected\nTest "
836        << (err_count==0 ? "passed\n\n" : "failed\n\n");
837 
838   return err_count ? 1 : 0;
839 } // main
840 
main(int argc,char * argv[])841 int main( int argc, char* argv[] )
842 {
843     try
844     {
845         return cpp_main( argc, argv );
846     }
847     catch( std::exception const & x )
848     {
849         std::cout << "Exception: " << x.what() << std::endl;
850         return 1;
851     }
852 }
853