Oracle® Fusion Middleware C++ API Reference for Oracle Coherence
12c (12.2.1.3.0)

E80355-01

coherence/lang/compatibility.hpp

00001 /*
00002 * compatibility.hpp
00003 *
00004 * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
00005 *
00006 * Oracle is a registered trademarks of Oracle Corporation and/or its
00007 * affiliates.
00008 *
00009 * This software is the confidential and proprietary information of Oracle
00010 * Corporation. You shall not disclose such confidential and proprietary
00011 * information and shall use it only in accordance with the terms of the
00012 * license agreement you entered into with Oracle.
00013 *
00014 * This notice may not be removed or altered.
00015 */
00016 #ifndef COH_COMPATIBILITY_HPP
00017 #define COH_COMPATIBILITY_HPP
00018 
00019 /// @cond EXCLUDE
00020 
00021 #include <typeinfo>
00022 
00023 // ----- identify operating system ------------------------------------------
00024 
00025 #if defined(_WIN32)
00026 #   define COH_OS_WINDOWS
00027 #   define COH_LIB_PREFIX ""
00028 #   define COH_LIB_SUFFIX ".dll"
00029 #   if defined(_WIN64)
00030 #      define COH_OS_WIN64
00031 #      define COH_PLATFORM Microsoft Windows x64
00032 #   else
00033 #      define COH_OS_WIN32
00034 #      define COH_PLATFORM Microsoft Windows x86
00035 #   endif
00036 #elif defined(__sun) || defined(sun)
00037 #   define COH_OS_SOLARIS // Oracle Solaris
00038 #   define COH_OS_UNIX
00039 #   define COH_LIB_PREFIX "lib"
00040 #   define COH_LIB_SUFFIX ".so"
00041 #   include <sys/types.h> // for _LP64 definition
00042 #   if defined(__sparc)
00043 #       if defined(_LP64)
00044 #           define COH_OS_SOLARIS64
00045 #           define COH_PLATFORM Oracle Solaris SPARC 64b
00046 #       else
00047 #           define COH_OS_SOLARIS32
00048 #           define COH_PLATFORM Oracle Solaris SPARC 32b
00049 #       endif
00050 #   elif defined(__x86)
00051 #       if defined(_LP64)
00052 #           define COH_OS_SOLARIS64
00053 #           define COH_PLATFORM Oracle Solaris x64
00054 #       else
00055 #           define COH_OS_SOLARIS32
00056 #           define COH_PLATFORM Oracle Solaris x86
00057 #       endif
00058 #   endif
00059 #elif defined(__linux__)
00060 #   define COH_OS_LINUX // Linux
00061 #   define COH_LIB_PREFIX "lib"
00062 #   define COH_LIB_SUFFIX ".so"
00063 #   define COH_OS_UNIX
00064 #   if defined(__x86_64__) || defined(__amd64__)
00065 #       define COH_OS_LINUX64
00066 #       define COH_PLATFORM Linux x64
00067 #   elif defined(__x86_32__) || defined(__i386__)
00068 #       define COH_OS_LINUX32
00069 #       define COH_PLATFORM Linux x86
00070 #   endif
00071 #elif defined(__APPLE__)
00072 #   define COH_OS_DARWIN // OS X
00073 #   define COH_OS_UNIX
00074 #   define COH_LIB_PREFIX "lib"
00075 #   define COH_LIB_SUFFIX ".dylib"
00076 #   if defined(__x86_64__) || defined(__amd64__)
00077 #       define COH_OS_DARWIN64
00078 #       define COH_PLATFORM Apple macOS x64
00079 #   endif
00080 #endif
00081 
00082 #ifndef COH_PLATFORM
00083 #   error "Coherence for C++ does not support this platform."
00084 #endif
00085 
00086 
00087 // ----- identify compiler --------------------------------------------------
00088 
00089 #if defined(_MSC_VER) && _MSC_VER >= 1600
00090 #   define COH_CC_MSVC // Microsoft Visual C/C++
00091 #   if _MSC_VER == 1900
00092 #       define COH_CC MSVC 2015 // differentiate VS 2015 build
00093 #   else
00094 #       define COH_CC MSVC
00095 #   endif
00096 #elif defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590
00097 #   define COH_CC_SUN // Oracle Solaris Studio
00098 #   if defined (STLPORT)
00099 #       define COH_CC SunPro STLport
00100 #   else
00101 #       define COH_CC SunPro
00102 #   endif
00103 #elif defined(__GNUG__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
00104 #   define COH_CC_GNU // GNU C++
00105 #   if defined (__clang__)
00106 #       define COH_CC LLVM (clang)
00107 #   else
00108 #       define COH_CC GCC
00109 #   endif
00110 #else
00111 #   error "Coherence for C++ does not support this compiler or compiler version."
00112 #endif
00113 
00114 
00115 // ----- disable select warnings --------------------------------------------
00116 
00117 /**
00118 * Macro for disabling select warnings on MSVC. The warnings are automatically
00119 * disabled upon opening a coherence namespace (using the COH_OPEN_NAMESPACE
00120 * macros), and re-enabled when the namespace is exited via
00121 * COH_CLOSE_NAMESPACE.
00122 */
00123 #if defined(COH_CC_MSVC)
00124     #define COH_PRAGMA_PUSH \
00125     __pragma(warning(push)) \
00126     /* Allow multiple interface inheritance (inheritance via dominance) */ \
00127     __pragma(warning(disable : 4250)) \
00128     /* Allow non-exported DLL templates */ \
00129     __pragma(warning(disable : 4251)) \
00130     /* Exported class inheritance from non-exported class, needed for specs */ \
00131     __pragma(warning(disable : 4275)) \
00132     /* TypedHandle/Holder: multiple copy constructors */ \
00133     __pragma(warning(disable : 4521)) \
00134     /* Member/WeakHandle: assignment operators for const/non-const type */ \
00135     __pragma(warning(disable : 4522)) \
00136     /* Lack of return statements are being promoted to errors, when control \
00137        path results in throw */ \
00138     __pragma(warning(disable : 4715; disable : 4716))
00139 
00140     #define COH_PRAGMA_POP __pragma(warning(pop))
00141 #else
00142     #define COH_PRAGMA_PUSH
00143     #define COH_PRAGMA_POP
00144 #endif
00145 
00146 /**
00147 * Macro for temporarily disabling above warnings for the duration of a
00148 * single statement.  This is only needed for code which is not enclosed in a
00149 * COH_OPEN/CLOSE_NAMESPACE block.
00150 */
00151 #define COH_NO_WARN(STMT) COH_PRAGMA_PUSH STMT COH_PRAGMA_POP
00152 
00153 /**
00154 * These macros are used to indicate that a function will not return normally.
00155 *
00156 * Usage example:
00157 * @code
00158 * COH_NO_RETURN_PRE void doSomething() COH_NO_RETURN_POST
00159 *     {
00160 *     COH_NO_RETURN_STMT(doSomething2());
00161 *     }
00162 * @endcode
00163 */
00164 #if defined(COH_CC_MSVC)
00165     #define COH_NO_RETURN_PRE __declspec(noreturn)
00166     #define COH_NO_RETURN_POST
00167     #define COH_NO_RETURN_STMT(expr) expr
00168 #elif defined(COH_CC_GNU)
00169     #define COH_NO_RETURN_PRE
00170     #define COH_NO_RETURN_POST __attribute__((noreturn))
00171     #define COH_NO_RETURN_STMT(expr) expr
00172 #elif defined(COH_CC_SUN)
00173     #define COH_NO_RETURN_PRE
00174     #define COH_NO_RETURN_POST
00175     #define COH_NO_RETURN_STMT(expr)\
00176         do { expr; throw std::exception(); } while (0)
00177 #else
00178     #define COH_NO_RETURN_PRE
00179     #define COH_NO_RETURN_POST
00180     #define COH_NO_RETURN_STMT(expr) expr
00181 #endif
00182 
00183 
00184 // ----- namespace macros ---------------------------------------------------
00185 
00186 /**
00187 * Define the existence of the coherence::lang namespace
00188 */
00189 namespace coherence { namespace lang {}}
00190 
00191 #define COH_OPEN_NAMESPACE(ns) namespace ns { \
00192     COH_PRAGMA_PUSH \
00193     using namespace coherence::lang;
00194 
00195 #define COH_INNER_NAMESPACE(ns) namespace ns {
00196 
00197 #define COH_OPEN_NAMESPACE2(ns1, ns2)\
00198     COH_OPEN_NAMESPACE (ns1) COH_INNER_NAMESPACE (ns2)
00199 
00200 #define COH_OPEN_NAMESPACE3(ns1, ns2, ns3)\
00201     COH_OPEN_NAMESPACE2 (ns1, ns2) COH_INNER_NAMESPACE (ns3)
00202 
00203 #define COH_OPEN_NAMESPACE4(ns1, ns2, ns3, ns4)\
00204     COH_OPEN_NAMESPACE3 (ns1, ns2, ns3) COH_INNER_NAMESPACE (ns4)
00205 
00206 #define COH_OPEN_NAMESPACE5(ns1, ns2, ns3, ns4, ns5)\
00207     COH_OPEN_NAMESPACE4 (ns1, ns2, ns3, ns4) COH_INNER_NAMESPACE (ns5)
00208 
00209 #define COH_OPEN_NAMESPACE6(ns1, ns2, ns3, ns4, ns5, ns6)\
00210     COH_OPEN_NAMESPACE5 (ns1, ns2, ns3, ns4, ns5) COH_INNER_NAMESPACE (ns6)
00211 
00212 #define COH_OPEN_NAMESPACE7(ns1, ns2, ns3, ns4, ns5, ns6, ns7)\
00213     COH_OPEN_NAMESPACE6 (ns1, ns2, ns3, ns4, ns5, ns6) COH_INNER_NAMESPACE (ns7)
00214 
00215 #define COH_CLOSE_NAMESPACE COH_PRAGMA_POP }
00216 
00217 #define COH_CLOSE_NAMESPACE2 COH_PRAGMA_POP } }
00218 
00219 #define COH_CLOSE_NAMESPACE3 COH_PRAGMA_POP } } }
00220 
00221 #define COH_CLOSE_NAMESPACE4 COH_PRAGMA_POP } } } }
00222 
00223 #define COH_CLOSE_NAMESPACE5 COH_PRAGMA_POP } } } } }
00224 
00225 #define COH_CLOSE_NAMESPACE6 COH_PRAGMA_POP } } } } } }
00226 
00227 #define COH_CLOSE_NAMESPACE7 COH_PRAGMA_POP } } } } } } }
00228 
00229 /**
00230 * Pseudo-anonymous namespaces.  Starting with Visual Studio 2017 it is no
00231 * longer possible to define Coherence managed classes within an anonymous
00232 * namespace.
00233 *
00234 * The parameter NAME should be unique to the parent namespace. Generally
00235 * this can simply be the name of the primary class being defined within the
00236 * file.
00237 *
00238 * For platforms other than Visual Studio 2017 and later, these macros will
00239 * open and close a standard anonymous namespace.
00240 */
00241 #if defined(COH_CC_MSVC) && _MSC_VER >= 1900
00242     #define COH_OPEN_NAMESPACE_ANON(NAME)\
00243         namespace COH_JOIN(_anon_, NAME) {}\
00244         using namespace COH_JOIN(_anon_, NAME);\
00245         namespace COH_JOIN(_anon_, NAME) {
00246 #else
00247     #define COH_OPEN_NAMESPACE_ANON(NAME) namespace {
00248 #endif
00249 
00250 #define COH_CLOSE_NAMESPACE_ANON }
00251 
00252 // ----- general utility macros ---------------------------------------------
00253 
00254 /**
00255 * This macro "mangles" the specified @a Name, producing an identifier which
00256 * is unique in the current file.
00257 *
00258 * Note. This implementation of COH_UNIQUE_IDENTIFIER (as well as macros that
00259 * use it) won't work in MSVC 6.0 when -ZI is on! See Q199057.
00260 *
00261 * @param Name the name to produce a new identifier on its basis
00262 */
00263 #define COH_JOIN(X, Y) COH_DO_JOIN(X, Y)
00264 #define COH_DO_JOIN(X, Y) COH_DO_JOIN2(X, Y)
00265 #define COH_DO_JOIN2(X, Y) X##Y
00266 #ifdef COH_CC_MSVC_NET // MSVC 2002 and later
00267 #   define COH_UNIQUE_IDENTIFIER(Name) COH_JOIN(Name, __COUNTER__)
00268 #else
00269 #   define COH_UNIQUE_IDENTIFIER(Name) COH_JOIN(Name, __LINE__)
00270 #endif
00271 
00272 /**
00273 * This macro will ensure initialization of function local statics at library
00274 * load time. This should be used to force the initialization of statics
00275 * in a thread safe way.  The general form is:
00276 *
00277 * SomeType::Handle staticAccessorFunction()
00278 *     {
00279 *     static FinalHandle<SomeType> hStatic = SomeType::create();
00280 *     return hStatic;
00281 *     }
00282 * COH_STATIC_INIT(staticAccessorFunction());
00283 *
00284 * @param FUNC  The static function and parameters to call that requires
00285 *             initialization.
00286 */
00287 #ifdef COH_EAGER_INIT
00288 #   define COH_STATIC_INIT_EX(N, FUNC) \
00289     static const bool COH_UNIQUE_IDENTIFIER(coh_static_init_func##N##_) = (FUNC, true)
00290 #else
00291 // some platforms (Windows) have serious restrictions about what can be safely
00292 // performed during static initialization and so this variant of initializer
00293 // records the initializers in the order they would be loaded to allow for
00294 // execution after the library has been loaded. The execution can be triggered
00295 // by running System::loadLibrary(NULL)
00296 #    define COH_STATIC_INIT_EX(N, FUNC) \
00297          static void COH_UNIQUE_IDENTIFIER(coh_static_init_func##N##_)() {FUNC;} \
00298          static coherence::lang::coh_initializer \
00299                  COH_UNIQUE_IDENTIFIER(coh_static_init_reg##N##_) \
00300          (&COH_UNIQUE_IDENTIFIER(coh_static_init_func##N##_))
00301 #endif
00302 
00303 #define COH_STATIC_INIT(FUNC) COH_STATIC_INIT_EX(0, FUNC)
00304 
00305 COH_OPEN_NAMESPACE2(coherence,lang)
00306     template <bool x> struct STATIC_ASSERTION_FAILURE;
00307     template<> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
00308 COH_CLOSE_NAMESPACE2
00309 
00310 /**
00311 * This macro generates a compile time error message if the integral constant
00312 * expression @a B is not true. In other words, it is the compile time
00313 * equivalent of the @c assert macro. Note that if the condition is true, then
00314 * the macro will generate neither code nor data - and the macro can also be
00315 * used at either namespace, class or function scope. When used in a template,
00316 * the static assertion will be evaluated at the time the template is
00317 * instantiated; this is particularly useful for validating template
00318 * parameters.
00319 *
00320 * #COH_STATIC_ASSERT can be used at any place where a declaration can be
00321 * placed, that is at class, function or namespace scope.
00322 *
00323 * @param B an integral constant expression to check its trueness during
00324 *          translation phase
00325 */
00326 #define COH_STATIC_ASSERT(B)                               \
00327     enum { COH_UNIQUE_IDENTIFIER(coh_static_assert_enum_) =\
00328         sizeof(coherence::lang::STATIC_ASSERTION_FAILURE<(bool)(B)>) }
00329 
00330 /**
00331 * DLL import/export macros.
00332 */
00333 #if defined(COH_CC_MSVC)
00334     #ifdef COH_BUILD
00335         #define COH_EXPORT  __declspec(dllexport)
00336     #else
00337         #define COH_EXPORT  __declspec(dllimport)
00338     #endif
00339     #define COH_EXPORT_SPEC  __declspec(dllexport)
00340     #if _MSC_VER >= 1900
00341         #define COH_EXPORT_SPEC_MEMBER(DECL) DECL;
00342     #else
00343         #define COH_EXPORT_SPEC_MEMBER(DECL)
00344     #endif
00345 #else
00346     #define COH_EXPORT
00347     #define COH_EXPORT_SPEC
00348     #define COH_EXPORT_SPEC_MEMBER(DECL) DECL;
00349 #endif
00350 
00351 /**
00352 * This macro will strongly encourage/force inlining of a method.
00353 */
00354 #if defined(COH_CC_MSVC)
00355     #define COH_INLINE __forceinline
00356 #elif defined(COH_CC_GNU)
00357     #define COH_INLINE __attribute__((always_inline)) inline
00358 #else
00359     #define COH_INLINE __attribute__((always_inline)) inline
00360 #endif
00361 
00362 /**
00363 * This macro expands to the name and signature of the current function.
00364 */
00365 #if defined(__GNUC__)
00366     #define COH_CURRENT_FUNCTION __PRETTY_FUNCTION__
00367 #elif defined(__FUNCSIG__)
00368     #define COH_CURRENT_FUNCTION __FUNCSIG__
00369 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
00370     #define COH_CURRENT_FUNCTION __func__
00371 #else
00372     #define COH_CURRENT_FUNCTION "(unknown function)"
00373 #endif
00374 
00375 /**
00376  * This macro controls alignment
00377  */
00378 #if defined(COH_CC_GNU)
00379     #define COH_ALIGN(B, TYPE, NAME) TYPE NAME __attribute__ ((aligned (B)))
00380 #elif defined(COH_CC_SUN)
00381     #define COH_SUNPRO_PRAGMA(S) _Pragma(S)
00382     #define COH_ALIGN(B, TYPE, NAME) COH_SUNPRO_PRAGMA(COH_SYMB_STRING(align B(NAME))) TYPE NAME
00383 #elif defined(COH_CC_MSVC)
00384     #define COH_ALIGN(B, TYPE, NAME) __declspec(align(B)) TYPE NAME
00385 #else
00386     #error "No Coherence alignment macro for this compiler"
00387 #endif
00388 
00389 /**
00390  * Macro to declare whether a function throws exceptions.
00391  */
00392 #if __cplusplus > 199711L ||\
00393     defined(_MSC_VER) && _MSC_VER >= 1900
00394 #       define COH_NOEXCEPT(expr) noexcept(expr)
00395 #else
00396 #       define COH_NOEXCEPT(expr)
00397 #endif
00398 
00399 /**
00400  * Macro to use appropriate C++ language specific smart pointer.
00401  *
00402  * std::auto_ptr is deprecated in C++11 and its use may throw compiler warnings.
00403  */
00404 #if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L
00405 #   define COH_AUTO_PTR std::unique_ptr
00406 #else
00407 #   define COH_AUTO_PTR std::auto_ptr
00408 #endif
00409 
00410 // ----- fixed size types ---------------------------------------------------
00411 
00412 // We need to include an std lib header here in order to detect which library
00413 // is in use (__GLIBC__ may not be defined without this including). Use
00414 // <utility> as it's about the smallest of the std lib headers.
00415 #include <utility>
00416 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901 ||\
00417     defined(_POSIX_VERSION) && _POSIX_VERSION >= 200100 ||\
00418     defined(COH_OS_LINUX) &&\
00419         defined(__GLIBC__) &&\
00420         (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) &&\
00421         defined(__GNUC__) ||\
00422     defined(COH_OS_DARWIN) && __MACH__ && !defined(_MSL_USING_MSL_C)
00423 #       define COH_HAS_STDINT_H
00424 #endif
00425 
00426 #if defined(__GCCXML__) ||\
00427     defined(__GNUC__) ||\
00428     defined(_MSC_EXTENSIONS)
00429 #       define COH_HAS_LONG_LONG
00430 #endif
00431 
00432 #if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) &&\
00433         !defined(_GLIBCPP_USE_LONG_LONG) &&          \
00434         !defined(_GLIBCXX_USE_LONG_LONG) &&          \
00435         defined(COH_HAS_LONG_LONG)
00436     // Coming here indicates that the GNU compiler supports long long type,
00437     // but the GNU C++ runtime library does not. Particularly, no global
00438     // operator<<(std::ostream&, long long) implementation is provided. Let us
00439     // provide it, at least with minimum incomplete functionality.
00440 #   include <ostream>
00441     namespace std
00442         {
00443         template<class E, class T>
00444         inline basic_ostream<E, T>& operator<<
00445                 (basic_ostream<E, T>& out, long long l)
00446             {
00447             return out << static_cast<long>(l);
00448             }
00449         template<class E, class T>
00450         inline basic_ostream<E, T>& operator<<
00451                 (basic_ostream<E, T>& out, unsigned long long l)
00452             {
00453             return out << static_cast<unsigned long>(l);
00454             }
00455         }
00456 #   undef COH_HAS_LONG_LONG
00457 #endif
00458 
00459 #if !defined(COH_HAS_LONG_LONG) && !defined(COH_CC_MSVC)
00460 #   include <limits.h>
00461 #   if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) ||\
00462             defined(ULONGLONG_MAX)
00463 #       define COH_HAS_LONG_LONG
00464 #   endif
00465 #endif
00466 
00467 #if defined(_MSC_VER)
00468 #       define COH_HAS_MS_INT64
00469 #endif
00470 
00471 /**
00472 * Fixed width primitive types.
00473 */
00474 #if defined(COH_HAS_STDINT_H)
00475 #   include <stdint.h>
00476 #elif defined(COH_CC_SUN)
00477 #   include <inttypes.h>
00478 #else
00479 //  This platform does not support the C99 stdint.h types. This code block
00480 //  defines them in the global namespace, alternatively you may define
00481 //  COH_NAMESPACED_FIXED_INTS, in which case these definitions will be within
00482 //  the coherence::lang namespace.
00483 #   include <climits>
00484 #   ifdef COH_NAMESPACED_FIXED_INTS
00485       COH_OPEN_NAMESPACE2(coherence,lang)
00486 #   endif
00487     COH_STATIC_ASSERT(UCHAR_MAX == 0xFF);
00488     typedef signed char   int8_t;
00489     typedef unsigned char uint8_t;
00490     COH_STATIC_ASSERT(USHRT_MAX == 0xFFFF);
00491     typedef short          int16_t;
00492     typedef unsigned short uint16_t;
00493 #   if UINT_MAX == 0xFFFFFFFF
00494         typedef int          int32_t;
00495         typedef unsigned int uint32_t;
00496 #   elif ULONG_MAX == 0xFFFFFFFF
00497         typedef long          int32_t;
00498         typedef unsigned long uint32_t;
00499 #   else
00500 #       error int size not correct
00501 #   endif
00502 #   if defined(COH_HAS_LONG_LONG) &&\
00503         !defined(COH_CC_MSVC) &&\
00504         (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \
00505         (defined(ULLONG_MAX) ||\
00506             defined(ULONG_LONG_MAX) ||\
00507             defined(ULONGLONG_MAX))
00508 #               if defined(ULLONG_MAX)
00509                     COH_STATIC_ASSERT(ULLONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
00510 #               elif defined(ULONG_LONG_MAX)
00511                     COH_STATIC_ASSERT
00512                         (ULONG_LONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
00513 #               elif defined(ULONGLONG_MAX)
00514                     COH_STATIC_ASSERT
00515                         (ULONGLONG_MAX == 0xFFFFFFFFFFFFFFFFULL));
00516 #               else
00517 #                   error long long size not correct
00518 #               endif
00519                 typedef long long          int64_t;
00520                 typedef unsigned long long uint64_t;
00521 #   elif ULONG_MAX != 0xFFFFFFFF
00522         COH_STATIC_ASSERT(ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
00523         typedef long          int64_t;
00524         typedef unsigned long uint64_t;
00525 #   elif defined(__GNUC__) && defined(COH_HAS_LONG_LONG)
00526         __extension__ typedef long long          int64_t;
00527         __extension__ typedef unsigned long long uint64_t;
00528 #   elif defined(COH_HAS_MS_INT64)
00529         typedef __int64          int64_t;
00530         typedef unsigned __int64 uint64_t;
00531 #   else
00532 #       error no 64-bit integer support
00533 #   endif
00534 #   ifdef COH_NAMESPACED_FIXED_INTS
00535         COH_CLOSE_NAMESPACE2
00536 #   endif
00537 #endif
00538 
00539 /**
00540 * Non-standard primitive type definitions.
00541 */
00542 COH_OPEN_NAMESPACE2(coherence,lang)
00543     typedef unsigned char octet_t;
00544     typedef uint16_t      wchar16_t;
00545     typedef uint32_t      size32_t;
00546     typedef uint64_t      size64_t;
00547     typedef float         float32_t; COH_STATIC_ASSERT(sizeof(float32_t) >= sizeof(int32_t));
00548     typedef double        float64_t; COH_STATIC_ASSERT(sizeof(float64_t) >= sizeof(int64_t));
00549 COH_CLOSE_NAMESPACE2
00550 
00551 /**
00552 * Produce a 64b value from two 32b parts.
00553 *
00554 * This is a bit-wise construction, and the supplied values should be the
00555 * bitwise unsigned representations.  For example:
00556 * COH_INT64(0x7FFFFFFFU, 0xFFFFFFFFU) == 0x7FFFFFFFFFFFFFFFLL
00557 */
00558 #define COH_INT64(HIGH, LOW) int64_t(uint64_t(HIGH) << 32 | uint64_t(LOW))
00559 
00560 // macros for turning compiler supplied define into a string
00561 #define COH_SYMB_STRING(SYMB) #SYMB
00562 #define COH_SYMB_TO_STRING(SYMB) COH_SYMB_STRING(SYMB)
00563 
00564 
00565 // ----- helpers ------------------------------------------------------------
00566 
00567 #include <typeinfo>
00568 COH_OPEN_NAMESPACE2(coherence,lang)
00569     class Class;
00570 
00571     typedef void (*coh_static_initializer)();
00572 
00573     /**
00574     * Register an initialization function with the runtime.
00575     */
00576     extern COH_EXPORT void coh_register_initializer(
00577             coh_static_initializer pInit, bool fAdd);
00578 
00579     /**
00580      * Helper class for registering and unregistering static initializers.
00581      */
00582     class coh_initializer
00583         {
00584         public:
00585 
00586         coh_initializer(coh_static_initializer pInit)
00587             : m_pInit(pInit)
00588             {
00589             coh_register_initializer(pInit, true);
00590             }
00591 
00592         ~coh_initializer()
00593             {
00594             coh_register_initializer(m_pInit, false);
00595             }
00596 
00597         private:
00598         coh_static_initializer m_pInit;
00599         };
00600 
00601     /**
00602     * Helper functions for throwing exceptions.
00603     */
00604     extern COH_EXPORT void coh_throw_npe(const std::type_info&);
00605     extern COH_EXPORT void coh_throw_class_cast(const std::type_info&,
00606             const std::type_info&);
00607     extern COH_EXPORT void coh_throw_const_cast(const std::type_info&,
00608             const std::type_info&);
00609     extern COH_EXPORT void coh_throw_illegal_state(const char* achMsg);
00610     extern COH_EXPORT void coh_throw_illegal_argument(const char* achMsg);
00611     extern COH_EXPORT void coh_throw_unsupported_operation(const char* achMsg);
00612     extern COH_EXPORT const Class* coh_loadClassByType(const std::type_info& ti);
00613 
00614     /**
00615     * Helper class used to test for type assignment compatibility at
00616     * compile time.
00617     *
00618     * This implementation is based on the Conversion example from
00619     * Andrei Alexandrescu's Modern C++ Design.
00620     */
00621     template<class A, class B>
00622     class assignment
00623         {
00624         protected:
00625             typedef char  PathA;
00626             class   Other {char unused[2];}; // sizeof(Other) != sizeof(PathA)
00627             static  PathA route(A*); // PathA taken only for compatible types
00628             static  Other route(...); // incompatible types go this route
00629             static  B*    test(); // "generate" a test object
00630 
00631         public:
00632             /**
00633             * Convert a derived A to an A.
00634             */
00635             static A* safe(A* a)
00636                 {
00637                 return a;
00638                 }
00639 
00640             /**
00641             * Dummy conversion (should never be called)
00642             */
00643             static A* safe(...)
00644                 {
00645                 coh_throw_illegal_state("unsafe cast");
00646                 return 0;
00647                 }
00648 
00649         public:
00650             /**
00651             * True iff A = B is allowed.
00652             */
00653             enum {allowed = (sizeof(route(test())) == sizeof(PathA))};
00654         };
00655 
00656     /**
00657     * Helper class used to test if a type has been declared as const.
00658     */
00659     template<class A>
00660     class constness
00661         {
00662         public:
00663             enum {applied = assignment<A, const A>::allowed};
00664         };
00665 /**
00666  * Coherence Class and Interface ID helpers.
00667  */
00668 #if defined(COH_CC_MSVC)
00669     // MSVC utilizes identical code folding ICF, which makes the alternate
00670     // very cheap form of id generation unusable and effectively assigns
00671     // all classes the same id, thus on MSVC we fallback on standard and
00672     // slower typeid
00673 
00674     /**
00675      * Coherence class id type.
00676      */
00677     typedef const std::type_info& coh_class_id;
00678 
00679     /**
00680      * Return the class id for a given managed class.
00681      */
00682     #define COH_CLASS_ID(CLASS) CLASS::_classId()
00683 
00684     /**
00685      * @internal
00686      *
00687      * Hook for COH_CLASS_ID macro, not for direct use
00688      */
00689     #define COH_GENERATE_CLASS_ID(T) \
00690         static coh_class_id _classId() \
00691             { \
00692             return typeid(T); \
00693             }
00694 #else
00695     // For most compilers we can use the address of a class specific static
00696     // function as a unique class identifier. This is cheaper then using
00697     // the standard typeid operator, which on some platforms adds contention
00698 
00699     /**
00700      * Coherence class id type.
00701      */
00702     typedef void (*coh_class_id)();
00703 
00704     /**
00705      * Return the class id for a given managed class.
00706      */
00707     #define COH_CLASS_ID(CLASS) &CLASS::_classId
00708 
00709     /**
00710      * @internal
00711      *
00712      * Hook for COH_CLASS_ID macro, not for direct use
00713      */
00714     #define COH_GENERATE_CLASS_ID(T) static void _classId() {}
00715 #endif
00716 
00717 COH_CLOSE_NAMESPACE2
00718 
00719 /// @endcond
00720 
00721 #endif // COH_COMPATIBILITY_HPP
Copyright © 2000, 2017, Oracle and/or its affiliates. All rights reserved.