C++ API Reference for Oracle® Coherence Community Edition
(14.1.1.0.1)

F23533-01

coherence/lang/compatibility.hpp

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