1 /*
2  * Distributed under the Boost Software License, Version 1.0.
3  * (See accompanying file LICENSE_1_0.txt or copy at
4  * http://www.boost.org/LICENSE_1_0.txt)
5  *
6  * Copyright (c) 2014 Andrey Semashev
7  */
8 /*!
9  * \file   atomic/detail/int_sizes.hpp
10  *
11  * This header defines macros for testing buitin integer type sizes
12  */
13 
14 #ifndef BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_
15 #define BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_
16 
17 #include <boost/atomic/detail/config.hpp>
18 
19 #ifdef BOOST_HAS_PRAGMA_ONCE
20 #pragma once
21 #endif
22 
23 // GCC and compatible compilers define internal macros with builtin type traits
24 #if defined(__SIZEOF_SHORT__)
25 #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT __SIZEOF_SHORT__
26 #endif
27 #if defined(__SIZEOF_INT__)
28 #define BOOST_ATOMIC_DETAIL_SIZEOF_INT __SIZEOF_INT__
29 #endif
30 #if defined(__SIZEOF_LONG__)
31 #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG __SIZEOF_LONG__
32 #endif
33 #if defined(__SIZEOF_LONG_LONG__)
34 #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG __SIZEOF_LONG_LONG__
35 #endif
36 #if defined(__SIZEOF_WCHAR_T__)
37 #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__
38 #endif
39 #if defined(__SIZEOF_POINTER__)
40 #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER __SIZEOF_POINTER__
41 #elif defined(_MSC_VER)
42 #if defined(_M_AMD64) || defined(_M_ARM64) || defined(_M_IA64)
43 #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 8
44 #else
45 #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 4
46 #endif
47 #endif
48 
49 #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\
50     !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG) ||\
51     !defined(BOOST_ATOMIC_DETAIL_SIZEOF_POINTER)
52 
53 // Try to deduce sizes from limits
54 #include <limits.h>
55 #if defined(__has_include)
56 #if __has_include(<stdint.h>)
57 #include <stdint.h>
58 #endif
59 #endif
60 #include <boost/cstdint.hpp>
61 
62 #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT)
63 #if (USHRT_MAX + 0) == 0xff
64 #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 1
65 #elif (USHRT_MAX + 0) == 0xffff
66 #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 2
67 #elif (USHRT_MAX + 0) == 0xffffffff
68 #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 4
69 #elif (USHRT_MAX + 0) == UINT64_C(0xffffffffffffffff)
70 #define BOOST_ATOMIC_DETAIL_SIZEOF_SHORT 8
71 #endif
72 #endif // !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT)
73 
74 #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT)
75 #if (UINT_MAX + 0) == 0xff
76 #define BOOST_ATOMIC_DETAIL_SIZEOF_INT 1
77 #elif (UINT_MAX + 0) == 0xffff
78 #define BOOST_ATOMIC_DETAIL_SIZEOF_INT 2
79 #elif (UINT_MAX + 0) == 0xffffffff
80 #define BOOST_ATOMIC_DETAIL_SIZEOF_INT 4
81 #elif (UINT_MAX + 0) == UINT64_C(0xffffffffffffffff)
82 #define BOOST_ATOMIC_DETAIL_SIZEOF_INT 8
83 #endif
84 #endif // !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT)
85 
86 #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG)
87 #if (ULONG_MAX + 0) == 0xff
88 #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 1
89 #elif (ULONG_MAX + 0) == 0xffff
90 #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 2
91 #elif (ULONG_MAX + 0) == 0xffffffff
92 #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 4
93 #elif (ULONG_MAX + 0) == UINT64_C(0xffffffffffffffff)
94 #define BOOST_ATOMIC_DETAIL_SIZEOF_LONG 8
95 #endif
96 #endif // !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG)
97 
98 #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG)
99 #if defined(__hpux) // HP-UX's value of ULONG_LONG_MAX is unusable in preprocessor expressions
100 #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 8
101 #else
102 
103 // The list of the non-standard macros (the ones except ULLONG_MAX) is taken from cstdint.hpp
104 #if defined(ULLONG_MAX)
105 #define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULLONG_MAX
106 #elif defined(ULONG_LONG_MAX)
107 #define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULONG_LONG_MAX
108 #elif defined(ULONGLONG_MAX)
109 #define BOOST_ATOMIC_DETAIL_ULLONG_MAX ULONGLONG_MAX
110 #elif defined(_LLONG_MAX) // strangely enough, this one seems to be holding the limit for the unsigned integer
111 #define BOOST_ATOMIC_DETAIL_ULLONG_MAX _LLONG_MAX
112 #endif
113 
114 #if (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xff
115 #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 1
116 #elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xffff
117 #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 2
118 #elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == 0xffffffff
119 #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 4
120 #elif (BOOST_ATOMIC_DETAIL_ULLONG_MAX + 0) == UINT64_C(0xffffffffffffffff)
121 #define BOOST_ATOMIC_DETAIL_SIZEOF_LLONG 8
122 #endif
123 
124 #endif // defined(__hpux)
125 #endif // !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG)
126 
127 #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_POINTER) && defined(UINTPTR_MAX)
128 #if (UINTPTR_MAX + 0) == 0xffff
129 #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 2
130 #elif (UINTPTR_MAX + 0) == 0xffffffff
131 #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 4
132 #elif (UINTPTR_MAX + 0) == UINT64_C(0xffffffffffffffff)
133 #define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 8
134 #endif
135 #endif // !defined(BOOST_ATOMIC_DETAIL_SIZEOF_POINTER) && defined(UINTPTR_MAX)
136 
137 #endif
138 
139 #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T)
140 
141 #include <wchar.h>
142 #include <boost/cstdint.hpp>
143 
144 #if defined(_MSC_VER) && (_MSC_VER <= 1310 || defined(UNDER_CE) && _MSC_VER <= 1500)
145 // MSVC 7.1 and MSVC 8 (arm) define WCHAR_MAX to a value not suitable for constant expressions
146 #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 2
147 #elif (WCHAR_MAX + 0) == 0xff || (WCHAR_MAX + 0) == 0x7f
148 #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 1
149 #elif (WCHAR_MAX + 0) == 0xffff || (WCHAR_MAX + 0) == 0x7fff
150 #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 2
151 #elif (WCHAR_MAX + 0) == 0xffffffff || (WCHAR_MAX + 0) == 0x7fffffff
152 #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 4
153 #elif (WCHAR_MAX + 0) == UINT64_C(0xffffffffffffffff) || (WCHAR_MAX + 0) == INT64_C(0x7fffffffffffffff)
154 #define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T 8
155 #endif
156 #endif
157 
158 #if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\
159     !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG) ||\
160     !defined(BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T)
161 #error Boost.Atomic: Failed to determine builtin integer sizes, the target platform is not supported. Please, report to the developers (patches are welcome).
162 #endif
163 
164 #endif // BOOST_ATOMIC_DETAIL_INT_SIZES_HPP_INCLUDED_
165