00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef COH_COMPATIBILITY_HPP
00017 #define COH_COMPATIBILITY_HPP
00018
00019
00020
00021 #include <typeinfo>
00022
00023
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>
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
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
00116
00117
00118
00119
00120
00121
00122
00123 #if defined(COH_CC_MSVC)
00124 #define COH_PRAGMA_PUSH \
00125 __pragma(warning(push)) \
00126 \
00127 __pragma(warning(disable : 4250)) \
00128 \
00129 __pragma(warning(disable : 4251)) \
00130 \
00131 __pragma(warning(disable : 4275)) \
00132 \
00133 __pragma(warning(disable : 4521)) \
00134 \
00135 __pragma(warning(disable : 4522)) \
00136
00137 \
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
00148
00149
00150
00151 #define COH_NO_WARN(STMT) COH_PRAGMA_PUSH STMT COH_PRAGMA_POP
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
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
00185
00186
00187
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
00231
00232
00233
00234
00235
00236
00237
00238
00239
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
00253
00254
00255
00256
00257
00258
00259
00260
00261
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
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
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
00292
00293
00294
00295
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
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
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
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
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
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
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
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
00401
00402
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
00411
00412
00413
00414
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
00437
00438
00439
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
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
00480
00481
00482
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
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
00553
00554
00555
00556
00557
00558 #define COH_INT64(HIGH, LOW) int64_t(uint64_t(HIGH) << 32 | uint64_t(LOW))
00559
00560
00561 #define COH_SYMB_STRING(SYMB) #SYMB
00562 #define COH_SYMB_TO_STRING(SYMB) COH_SYMB_STRING(SYMB)
00563
00564
00565
00566
00567 #include <typeinfo>
00568 COH_OPEN_NAMESPACE2(coherence,lang)
00569 class Class;
00570
00571 typedef void (*coh_static_initializer)();
00572
00573
00574
00575
00576 extern COH_EXPORT void coh_register_initializer(
00577 coh_static_initializer pInit, bool fAdd);
00578
00579
00580
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
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
00616
00617
00618
00619
00620
00621 template<class A, class B>
00622 class assignment
00623 {
00624 protected:
00625 typedef char PathA;
00626 class Other {char unused[2];};
00627 static PathA route(A*);
00628 static Other route(...);
00629 static B* test();
00630
00631 public:
00632
00633
00634
00635 static A* safe(A* a)
00636 {
00637 return a;
00638 }
00639
00640
00641
00642
00643 static A* safe(...)
00644 {
00645 coh_throw_illegal_state("unsafe cast");
00646 return 0;
00647 }
00648
00649 public:
00650
00651
00652
00653 enum {allowed = (sizeof(route(test())) == sizeof(PathA))};
00654 };
00655
00656
00657
00658
00659 template<class A>
00660 class constness
00661 {
00662 public:
00663 enum {applied = assignment<A, const A>::allowed};
00664 };
00665
00666
00667
00668 #if defined(COH_CC_MSVC)
00669
00670
00671
00672
00673
00674
00675
00676
00677 typedef const std::type_info& coh_class_id;
00678
00679
00680
00681
00682 #define COH_CLASS_ID(CLASS) CLASS::_classId()
00683
00684
00685
00686
00687
00688
00689 #define COH_GENERATE_CLASS_ID(T) \
00690 static coh_class_id _classId() \
00691 { \
00692 return typeid(T); \
00693 }
00694 #else
00695
00696
00697
00698
00699
00700
00701
00702 typedef void (*coh_class_id)();
00703
00704
00705
00706
00707 #define COH_CLASS_ID(CLASS) &CLASS::_classId
00708
00709
00710
00711
00712
00713
00714 #define COH_GENERATE_CLASS_ID(T) static void _classId() {}
00715 #endif
00716
00717 COH_CLOSE_NAMESPACE2
00718
00719
00720
00721 #endif // COH_COMPATIBILITY_HPP