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

E77779-01

coherence/lang/compatibility.hpp

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