1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #ifndef ICE_UTIL_CONFIG_H
6 #define ICE_UTIL_CONFIG_H
7 
8 //
9 // Use the system headers as preferred way to detect endianness
10 // and fallback to architecture based checks.
11 //
12 //
13 #include <stdlib.h>
14 
15 #if defined(__GLIBC__)
16 #   include <endian.h>
17 #elif defined(__APPLE__)
18 #   include <machine/endian.h>
19 #elif defined(__DragonFly__)
20 #   include <sys/endian.h>
21 #endif
22 
23 #if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || \
24     (defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN))
25 
26 #   define ICE_LITTLE_ENDIAN
27 
28 #elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)) || \
29       (defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN))
30 
31 #   define ICE_BIG_ENDIAN
32 
33 #elif defined(__i386)      || \
34       defined(_M_IX86)     || \
35       defined(__x86_64)    || \
36       defined(_M_X64)      || \
37       defined(_M_IA64)     || \
38       defined(__alpha__)   || \
39       defined(__ARMEL__)   || \
40       defined(_M_ARM_FP)   || \
41       defined(__arm64)     || \
42       defined(__MIPSEL__)
43 
44 #   define ICE_LITTLE_ENDIAN
45 
46 #elif defined(__sparc)   || \
47       defined(__sparc__) || \
48       defined(__hppa)    || \
49       defined(__ppc__)   || \
50       defined(__powerpc) || \
51       defined(_ARCH_COM) || \
52       defined(__MIPSEB__)
53 
54 #   define ICE_BIG_ENDIAN
55 
56 #else
57 
58 #   error "Unknown architecture"
59 
60 #endif
61 
62 #ifdef _MSC_VER
63 
64 #   ifdef _WIN64
65 #      define ICE_64
66 #   else
67 #      define ICE_32
68 #   endif
69 
70 #else
71 
72     //
73     // Use system headers as preferred way to detect 32 or 64 bit mode and
74     // fallback to architecture based checks
75     //
76 #   include <stdint.h>
77 
78 #   if (__cplusplus >= 201103L) && defined(__WORDSIZE) && (__WORDSIZE == 64)
79 #      define ICE_64
80 #   elif (__cplusplus >= 201103L) && defined(__WORDSIZE) && (__WORDSIZE == 32)
81 #      define ICE_32
82 #   elif defined(__sun) && (defined(__sparcv9) || defined(__x86_64))  || \
83          defined(__linux) && defined(__x86_64)                        || \
84          defined(__APPLE__) && defined(__x86_64)                      || \
85          defined(__DragonFly__) && defined(__x86_64)                    || \
86          defined(__DragonFly__) && defined(__LP64__)                    || \
87          defined(__hppa) && defined(__LP64__)                         || \
88          defined(_ARCH_COM) && defined(__64BIT__)                     || \
89          defined(__alpha__)                                           || \
90          defined(_WIN64)
91 #      define ICE_64
92 #   else
93 #      define ICE_32
94 #   endif
95 #endif
96 
97 #if defined(_MSVC_LANG)
98 #   define ICE_CPLUSPLUS _MSVC_LANG
99 #else
100 #   define ICE_CPLUSPLUS __cplusplus
101 #endif
102 
103 //
104 // Check for C++ 11 support
105 //
106 // For GCC, we recognize --std=c++0x only for GCC version 4.5 and greater,
107 // as C++11 support in prior releases was too limited.
108 //
109 #if (ICE_CPLUSPLUS >= 201103) || \
110     ((defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) && ((__GNUC__* 100) + __GNUC_MINOR__) >= 405)) || \
111     (defined(_MSC_VER) && (_MSC_VER >= 1900))
112 #   define ICE_CPP11_COMPILER
113 #endif
114 
115 //
116 // Ensure the C++ compiler supports C++11 when using the C++11 mapping
117 //
118 #if defined(ICE_CPP11_MAPPING) && !defined(ICE_CPP11_COMPILER)
119 #   error "you need a C++11 capable compiler to use the C++11 mapping"
120 #endif
121 
122 #if defined(ICE_CPP11_COMPILER)
123 #   define ICE_NOEXCEPT noexcept
124 #   define ICE_NOEXCEPT_FALSE noexcept(false)
125 #   define ICE_FINAL final
126 #else
127 #   define ICE_NOEXCEPT throw()
128 #   define ICE_NOEXCEPT_FALSE /**/
129 #   define ICE_FINAL /**/
130 #endif
131 
132 //
133 // Does the C++ compiler library provide std::codecvt_utf8 and
134 // std::codecvt_utf8_utf16?
135 //
136 #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || \
137     defined(__clang__)                        || \
138     (defined(ICE_CPP11_COMPILER) && defined(__GNUC__) && (__GNUC__ >= 5))
139 #define ICE_HAS_CODECVT_UTF8
140 #endif
141 
142 //
143 // Visual Studio 2015 or later
144 //
145 #if defined(_MSC_VER) && (_MSC_VER >= 1900)
146 
147 //
148 // Check if building for UWP
149 //
150 #   include <winapifamily.h>
151 #   if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
152 #      define ICE_OS_UWP
153 #      define ICE_STATIC_LIBS
154 #   endif
155 
156 #endif
157 
158 //
159 // Support for thread-safe function local static initialization
160 // (a.k.a. "magic statics")
161 //
162 #if defined(ICE_CPP11_MAPPING) || defined(__GNUC__) || defined(__clang__) || (defined(_MSC_VER) && (_MSC_VER >= 1900))
163 #   define ICE_HAS_THREAD_SAFE_LOCAL_STATIC
164 #endif
165 
166 //
167 // Compiler extensions to export and import symbols: see the documentation
168 // for Visual Studio, Solaris Studio and GCC.
169 //
170 #if defined(_MSC_VER)
171 #   define ICE_DECLSPEC_EXPORT __declspec(dllexport)
172 #   define ICE_DECLSPEC_IMPORT __declspec(dllimport)
173 //  With Visual Studio, we can import/export member functions without importing/
174 //  exporting the whole class
175 #   define ICE_MEMBER_IMPORT_EXPORT
176 #elif defined(__GNUC__) || defined(__clang__)
177 #   define ICE_DECLSPEC_EXPORT __attribute__((visibility ("default")))
178 #   define ICE_DECLSPEC_IMPORT __attribute__((visibility ("default")))
179 #elif defined(__SUNPRO_CC)
180 #   define ICE_DECLSPEC_EXPORT __global
181 #   define ICE_DECLSPEC_IMPORT /**/
182 #else
183 #   define ICE_DECLSPEC_EXPORT /**/
184 #   define ICE_DECLSPEC_IMPORT /**/
185 #endif
186 
187 #ifdef ICE_MEMBER_IMPORT_EXPORT
188 #   define ICE_CLASS(API) /**/
189 #   define ICE_MEMBER(API) API
190 #else
191 #   define ICE_CLASS(API) API
192 #   define ICE_MEMBER(API) /**/
193 #endif
194 
195 //
196 // Let's use these extensions with Ice:
197 //
198 #ifndef ICE_API
199 #   if defined(ICE_STATIC_LIBS)
200 #      define ICE_API /**/
201 #   elif defined(ICE_API_EXPORTS)
202 #      define ICE_API ICE_DECLSPEC_EXPORT
203 #   else
204 #      define ICE_API ICE_DECLSPEC_IMPORT
205 #   endif
206 #endif
207 
208 #if defined(_MSC_VER)
209 #   define ICE_DEPRECATED_API(msg) __declspec(deprecated(msg))
210 #elif defined(__clang__)
211 #   if __has_extension(attribute_deprecated_with_message)
212 #       define ICE_DEPRECATED_API(msg) __attribute__((deprecated(msg)))
213 #   else
214 #       define ICE_DEPRECATED_API(msg) __attribute__((deprecated))
215 #   endif
216 #elif defined(__GNUC__)
217 #   if (__GNUC__ > 4 || (__GNUC__ == 4 &&  __GNUC_MINOR__ >= 5))
218 // The message option was introduced in GCC 4.5
219 #      define ICE_DEPRECATED_API(msg) __attribute__((deprecated(msg)))
220 #   else
221 #      define ICE_DEPRECATED_API(msg) __attribute__((deprecated))
222 #   endif
223 #else
224 #   define ICE_DEPRECATED_API(msg) /**/
225 #endif
226 
227 #if defined(__clang__) || defined(__GNUC__)
228 #   define ICE_MAYBE_UNUSED __attribute__((unused))
229 #else
230 #   define ICE_MAYBE_UNUSED /**/
231 #endif
232 
233 #ifdef _WIN32
234 #   include <windows.h>
235 
236 #   if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x600)
237 //
238 // Windows provides native condition variables on Vista and later
239 //
240 #      ifndef ICE_HAS_WIN32_CONDVAR
241 #          define ICE_HAS_WIN32_CONDVAR
242 #      endif
243 #   endif
244 #endif
245 
246 //
247 // Some include files we need almost everywhere.
248 //
249 #include <cassert>
250 #include <iostream>
251 #include <sstream>
252 #include <exception>
253 #include <stdexcept>
254 
255 #ifndef _WIN32
256 #   include <pthread.h>
257 #   include <errno.h>
258 #   include <unistd.h>
259 #endif
260 
261 #ifdef __APPLE__
262 #   include <TargetConditionals.h>
263 #endif
264 
265 #if defined(_AIX) && defined(_LARGE_FILES)
266     // defines macros such as open that we want to use consistently everywhere
267 #   include <fcntl.h>
268 #endif
269 
270 #ifdef __IBMCPP__
271     // TODO: better fix for this warning
272 #   pragma report(disable, "1540-0198") // private inheritance without private keyword
273 #endif
274 
275 //
276 // The Ice version.
277 //
278 #define ICE_STRING_VERSION "3.7.2" // "A.B.C", with A=major, B=minor, C=patch
279 #define ICE_INT_VERSION 30702      // AABBCC, with AA=major, BB=minor, CC=patch
280 #define ICE_SO_VERSION "37"      // "ABC", with A=major, B=minor, C=patch
281 
282 #if !defined(ICE_BUILDING_ICE) && defined(ICE_API_EXPORTS)
283 #   define ICE_BUILDING_ICE
284 #endif
285 
286 #if defined(_MSC_VER)
287 #   if !defined(ICE_STATIC_LIBS) && (!defined(_DLL) || !defined(_MT))
288 #       error "Only multi-threaded DLL libraries can be used with Ice!"
289 #   endif
290 
291 #   ifdef ICE_CPP11_MAPPING
292 #      if defined(_DEBUG)
293 #         if defined(ICE_OS_UWP)
294 #            define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "uwp++11D.lib"
295 #         else
296 #            define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "++11D.lib"
297 #         endif
298 #      else
299 #         if defined(ICE_OS_UWP)
300 #            define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "uwp++11.lib"
301 #         else
302 #            define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "++11.lib"
303 #         endif
304 #      endif
305 #   else
306 #      if defined(_DEBUG)
307 #         if defined(ICE_OS_UWP)
308 #            define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "uwpD.lib"
309 #         else
310 #            define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "D.lib"
311 #         endif
312 #      else
313 #         if defined(ICE_OS_UWP)
314 #            define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION "uwp.lib"
315 #         else
316 #            define ICE_LIBNAME(NAME) NAME ICE_SO_VERSION ".lib"
317 #         endif
318 #      endif
319 #   endif
320 
321 //
322 //  Automatically link with Ice[D|++11|++11D].lib
323 //
324 #   if !defined(ICE_BUILDING_ICE) && !defined(ICE_BUILDING_SLICE_COMPILERS)
325 #      pragma comment(lib, ICE_LIBNAME("Ice"))
326 #   endif
327 #endif
328 
329 namespace IceUtil
330 {
331 
332 //
333 // By deriving from this class, other classes are made non-copyable.
334 //
335 class ICE_API noncopyable
336 {
337 protected:
338 
noncopyable()339     noncopyable() { }
~noncopyable()340     ~noncopyable() { } // May not be virtual! Classes without virtual
341                        // operations also derive from noncopyable.
342 
343 private:
344 
345     noncopyable(const noncopyable&);
346     const noncopyable& operator=(const noncopyable&);
347 };
348 
349 typedef unsigned char Byte;
350 
351 //
352 // Int64 typedef and ICE_INT64 macro for Int64 literal values
353 //
354 // Note that on Windows, long is always 32-bit
355 //
356 #if defined(_WIN32) && defined(_MSC_VER)
357 typedef __int64 Int64;
358 #    define ICE_INT64(n) n##i64
359 #    define ICE_INT64_FORMAT "%lld"
360 #elif defined(ICE_64) && !defined(_WIN32)
361 typedef long Int64;
362 #    define ICE_INT64(n) n##L
363 #    define ICE_INT64_FORMAT "%ld"
364 #else
365 typedef long long Int64;
366 #    define ICE_INT64(n) n##LL
367 #    define ICE_INT64_FORMAT "%lld"
368 #endif
369 
370 }
371 
372 //
373 // Macros to facilitate C++98 -> C++11 transition
374 //
375 #ifdef ICE_CPP11_MAPPING // C++11 mapping
376 #   include <memory>
377 #   include <future>
378 #   define ICE_HANDLE ::std::shared_ptr
379 #   define ICE_INTERNAL_HANDLE ::std::shared_ptr
380 #   define ICE_PROXY_HANDLE ::std::shared_ptr
381 #   define ICE_MAKE_SHARED(T, ...) ::std::make_shared<T>(__VA_ARGS__)
382 #   define ICE_DEFINE_PTR(TPtr, T) using TPtr = ::std::shared_ptr<T>
383 #   define ICE_ENUM(CLASS,ENUMERATOR) CLASS::ENUMERATOR
384 #   define ICE_SCOPED_ENUM(CLASS,ENUMERATOR) CLASS::ENUMERATOR
385 #   define ICE_NULLPTR nullptr
386 #   define ICE_DYNAMIC_CAST(T,V) ::std::dynamic_pointer_cast<T>(V)
387 #   define ICE_SHARED_FROM_THIS shared_from_this()
388 #   define ICE_SHARED_FROM_CONST_THIS(T) const_cast<T*>(this)->shared_from_this()
389 #   define ICE_GET_SHARED_FROM_THIS(p) p->shared_from_this()
390 #   define ICE_CHECKED_CAST(T, ...) Ice::checkedCast<T>(__VA_ARGS__)
391 #   define ICE_UNCHECKED_CAST(T, ...) Ice::uncheckedCast<T>(__VA_ARGS__)
392 #   define ICE_DELEGATE(T) T
393 #   define ICE_IN(...) __VA_ARGS__
394 #   define ICE_SET_EXCEPTION_FROM_CLONE(T, V)  T = V
395 #else // C++98 mapping
396 #   define ICE_HANDLE ::IceUtil::Handle
397 #   define ICE_INTERNAL_HANDLE ::IceInternal::Handle
398 #   define ICE_PROXY_HANDLE ::IceInternal::ProxyHandle
399 #   define ICE_MAKE_SHARED(T, ...) new T(__VA_ARGS__)
400 #   define ICE_DEFINE_PTR(TPtr, T) typedef ::IceUtil::Handle<T> TPtr
401 #   define ICE_ENUM(CLASS,ENUMERATOR) ENUMERATOR
402 #   define ICE_SCOPED_ENUM(CLASS,ENUMERATOR) CLASS##ENUMERATOR
403 #   define ICE_NULLPTR 0
404 #   define ICE_DYNAMIC_CAST(T,V) T##Ptr::dynamicCast(V)
405 #   define ICE_SHARED_FROM_THIS this
406 #   define ICE_SHARED_FROM_CONST_THIS(T) const_cast<T*>(this)
407 #   define ICE_GET_SHARED_FROM_THIS(p) p
408 #   define ICE_CHECKED_CAST(T, ...) T::checkedCast(__VA_ARGS__)
409 #   define ICE_UNCHECKED_CAST(T, ...) T::uncheckedCast(__VA_ARGS__)
410 #   define ICE_DELEGATE(T) T##Ptr
411 #   define ICE_IN(...) const __VA_ARGS__&
412 #   define ICE_SET_EXCEPTION_FROM_CLONE(T, V) T.reset(V)
413 #endif
414 
415 #endif
416