00001
00002
00003
00004
00005
00006
00007 #ifndef COH_COMPATIBILITY_HPP
00008 #define COH_COMPATIBILITY_HPP
00009
00010
00011
00012 #include <typeinfo>
00013
00014
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>
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
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
00107
00108
00109
00110
00111
00112
00113
00114 #if defined(COH_CC_MSVC)
00115 #define COH_PRAGMA_PUSH \
00116 __pragma(warning(push)) \
00117 \
00118 __pragma(warning(disable : 4250)) \
00119 \
00120 __pragma(warning(disable : 4251)) \
00121 \
00122 __pragma(warning(disable : 4275)) \
00123 \
00124 __pragma(warning(disable : 4521)) \
00125 \
00126 __pragma(warning(disable : 4522)) \
00127
00128 \
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
00139
00140
00141
00142 #define COH_NO_WARN(STMT) COH_PRAGMA_PUSH STMT COH_PRAGMA_POP
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
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
00176
00177
00178
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
00222
00223
00224
00225
00226
00227
00228
00229
00230
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
00244
00245
00246
00247
00248
00249
00250
00251
00252
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
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
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
00283
00284
00285
00286
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
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
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
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
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
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
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
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
00392
00393
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
00402
00403
00404
00405
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
00428
00429
00430
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
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
00471
00472
00473
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
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
00544
00545
00546
00547
00548
00549 #define COH_INT64(HIGH, LOW) int64_t(uint64_t(HIGH) << 32 | uint64_t(LOW))
00550
00551
00552 #define COH_SYMB_STRING(SYMB) #SYMB
00553 #define COH_SYMB_TO_STRING(SYMB) COH_SYMB_STRING(SYMB)
00554
00555
00556
00557
00558 #include <typeinfo>
00559 COH_OPEN_NAMESPACE2(coherence,lang)
00560 class Class;
00561
00562 typedef void (*coh_static_initializer)();
00563
00564
00565
00566
00567 extern COH_EXPORT void coh_register_initializer(
00568 coh_static_initializer pInit, bool fAdd);
00569
00570
00571
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
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
00607
00608
00609
00610
00611
00612 template<class A, class B>
00613 class assignment
00614 {
00615 protected:
00616 typedef char PathA;
00617 class Other {char unused[2];};
00618 static PathA route(A*);
00619 static Other route(...);
00620 static B* test();
00621
00622 public:
00623
00624
00625
00626 static A* safe(A* a)
00627 {
00628 return a;
00629 }
00630
00631
00632
00633
00634 static A* safe(...)
00635 {
00636 coh_throw_illegal_state("unsafe cast");
00637 return 0;
00638 }
00639
00640 public:
00641
00642
00643
00644 enum {allowed = (sizeof(route(test())) == sizeof(PathA))};
00645 };
00646
00647
00648
00649
00650 template<class A>
00651 class constness
00652 {
00653 public:
00654 enum {applied = assignment<A, const A>::allowed};
00655 };
00656
00657
00658
00659 #if defined(COH_CC_MSVC)
00660
00661
00662
00663
00664
00665
00666
00667
00668 typedef const std::type_info& coh_class_id;
00669
00670
00671
00672
00673 #define COH_CLASS_ID(CLASS) CLASS::_classId()
00674
00675
00676
00677
00678
00679
00680 #define COH_GENERATE_CLASS_ID(T) \
00681 static coh_class_id _classId() \
00682 { \
00683 return typeid(T); \
00684 }
00685 #else
00686
00687
00688
00689
00690
00691
00692
00693 typedef void (*coh_class_id)();
00694
00695
00696
00697
00698 #define COH_CLASS_ID(CLASS) &CLASS::_classId
00699
00700
00701
00702
00703
00704
00705 #define COH_GENERATE_CLASS_ID(T) static void _classId() {}
00706 #endif
00707
00708 COH_CLOSE_NAMESPACE2
00709
00710
00711
00712 #endif // COH_COMPATIBILITY_HPP