Turi Create  4.0
int128_types.hpp
Go to the documentation of this file.
1 /* Copyright © 2017 Apple Inc. All rights reserved.
2  *
3  * Use of this source code is governed by a BSD-3-clause license that can
4  * be found in the LICENSE.txt file or at https://opensource.org/licenses/BSD-3-Clause
5  */
6 /**
7  * \file int128_types.hpp
8  * Defines the int128_t and uint128_t type.
9  * Goes through various compiler checks to find the existance of int128_t
10  * and use it if available. Requires a particular CMake script be executed
11  * on configure to check for the int128_t variants.
12  *
13  * Also defines ostream printing, std::is_scalar, and boost::is_scalar on the
14  * int128_t, uint128_t types.
15  */
16 #ifndef _INT128_TYPES_H_
17 #define _INT128_TYPES_H_
18 #include <core/storage/serialization/is_pod.hpp>
19 #include <boost/type_traits/is_scalar.hpp>
20 #include <type_traits>
21 #include <cstdint>
22 #include <ostream>
23 #include <sstream>
24 
25 // not in turicreate source tree. try to use
26 // compiler predefines to find int128
27 #ifndef IN_TURI_SOURCE_TREE
28 #if __SIZEOF_INT128__ == 16
29 #define HAVE__int128_t
30 #define HAVE__uint128_t
31 #endif
32 #endif
33 
34 /* These macros are set by CMake in the configuration process. */
35 #ifdef HAVE__int128_t
36 typedef __int128_t int128_t;
37 #elif defined(HAVEint128_t)
38 // We're okay
39 #elif defined(HAVE__int128)
40 typedef __int128 int128_t;
41 #elif defined(HAVEint128)
42 typedef int128 int128_t;
43 #else
44 #include <boost/multiprecision/cpp_int.hpp>
45  typedef boost::multiprecision::int128_t int128_t;
46 #endif
47 
48 #ifdef HAVE__uint128_t
49 typedef __uint128_t uint128_t;
50 #elif defined(HAVEuint128_t)
51 // We're okay
52 #elif defined(HAVE__uint128)
53 typedef __uint128 uint128_t;
54 #elif defined(HAVEuint128)
55 typedef uint128 uint128_t;
56 #elif defined(HAVEunsigned__int128_t)
57 typedef unsigned __int128_t uint128_t;
58 #elif defined(HAVEunsignedint128_t)
59 typedef unsigned int128_t uint128_t;
60 #elif defined(HAVEunsigned__int128)
61 typedef unsigned __int128 uint128_t;
62 #elif defined(HAVEunsignedint128)
63 typedef unsigned int128 uint128_t;
64 #else
65 #include <boost/multiprecision/cpp_int.hpp>
66  typedef boost::multiprecision::uint128_t uint128_t;
67 #endif
68 
69 static inline uint128_t BuildUint128(uint64_t high, uint64_t low) {
70  return ((uint128_t(high) << 64) + low);
71 }
72 
73 /// Enables printing of uint128_t values
74 static inline std::ostream& operator<<(std::ostream& out, const uint128_t& x) {
75  std::ostringstream s;
76  s << std::hex << (uint64_t(x >> 64)) << uint64_t(x);
77  out << s.str();
78  return out;
79 }
80 
81 namespace boost {
82 template <>
83 struct is_scalar<uint128_t> {
84  static const bool value = true;
85 };
86 
87 template <>
88 struct is_scalar<int128_t> {
89  static const bool value = true;
90 };
91 
92 } // boost
93 
94 
95 
96 namespace std {
97 template <>
98 struct is_scalar<uint128_t> {
99  static const bool value = true;
100 };
101 
102 template <>
103 struct is_scalar<int128_t> {
104  static const bool value = true;
105 };
106 } // std
107 
108 
109 #endif /* _INT128_TYPES_H_ */
STL namespace.
static std::ostream & operator<<(std::ostream &out, const uint128_t &x)
Enables printing of uint128_t values.