boost_has_int128.ipp 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // (C) Copyright John Maddock 2012.
  2. // (C) Copyright Dynatrace 2017.
  3. // Use, modification and distribution are subject to the
  4. // Boost Software License, Version 1.0. (See accompanying file
  5. // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. // See http://www.boost.org/libs/config for most recent version.
  7. // MACRO: BOOST_HAS_INT128
  8. // TITLE: __int128
  9. // DESCRIPTION: The platform supports __int128.
  10. #include <cstdlib>
  11. #include <stdio.h>
  12. #include <limits.h>
  13. namespace boost_has_int128{
  14. #ifdef __GNUC__
  15. __extension__ typedef __int128 my_int128_t;
  16. __extension__ typedef unsigned __int128 my_uint128_t;
  17. #else
  18. typedef __int128 my_int128_t;
  19. typedef unsigned __int128 my_uint128_t;
  20. #endif
  21. my_uint128_t volatile g_ui128 = 0;
  22. unsigned long volatile g_ul = 0;
  23. int test()
  24. {
  25. my_int128_t si128 = 0;
  26. (void)&si128;
  27. // Some compilers have seriously broken __int128 implementations, so we need to do a little more than simply check if we can declare variables with __int128...
  28. // #1: check __int128 size
  29. if (sizeof(my_uint128_t) < (128 / CHAR_BIT))
  30. {
  31. fputs("Type too small.", stderr);
  32. return 1;
  33. }
  34. // #2: check result of computation with __int128
  35. my_uint128_t p1 = 1;
  36. my_uint128_t p2 = 1;
  37. unsigned int i = 0;
  38. for (; i < 180; i++)
  39. {
  40. g_ui128 = p1 + p2;
  41. if (g_ui128 < p1)
  42. {
  43. fputs("Unexpected overflow.", stderr);
  44. return 1;
  45. }
  46. p2 = p1;
  47. p1 = g_ui128;
  48. }
  49. g_ul = static_cast<unsigned long>((g_ui128 >> 92) & 0xFFFFFFFFUL);
  50. g_ul -= 1216382273UL;
  51. if (g_ul != 0)
  52. {
  53. fputs("Incorrect computation result.", stderr);
  54. return 1;
  55. }
  56. return 0;
  57. }
  58. }