Oracle Coherence for C++ API
Release 3.6.1.0
E18813-01

- Main Page
- Namespaces
- Classes
- Files

# coherence/lang/compatibility.hpp

    00001 /*
    00002 * compatibility.hpp
    00003 *
    00004 * Copyright (c) 2000, 2010, 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 // ----- identify operating system ------------------------------------------
    00022
    00023 #if defined(_WIN32)
    00024 #   define COH_OS_WINDOWS
    00025 #   define COH_LIB_PREFIX ""
    00026 #   define COH_LIB_SUFFIX ".dll"
    00027 #   if defined(_WIN64)
    00028 #      define COH_OS_WIN64 // Windows 2003/2008/Vista
    00029 #      define COH_PLATFORM Microsoft Windows x64
    00030 #   else
    00031 #      define COH_OS_WIN32 // Windows NT/2000/XP
    00032 #      define COH_PLATFORM Microsoft Windows x86
    00033 #   endif
    00034 #elif defined(__sun) || defined(sun)
    00035 #   define COH_OS_SOLARIS // Sun Solaris
    00036 #   define COH_OS_UNIX
    00037 #   define COH_LIB_PREFIX "lib"
    00038 #   define COH_LIB_SUFFIX ".so"
    00039 #   include <sys/types.h> // for _LP64 definition
    00040 #   if defined(__sparc)
    00041 #       if defined(_LP64)
    00042 #           define COH_OS_SOLARIS64
    00043 #           define COH_PLATFORM Sun Solaris SPARC 64b
    00044 #       else
    00045 #           define COH_OS_SOLARIS32
    00046 #           define COH_PLATFORM Sun Solaris SPARC 32b
    00047 #       endif
    00048 #   elif defined(__x86)
    00049 #       if defined(_LP64)
    00050 #           define COH_OS_SOLARIS64
    00051 #           define COH_PLATFORM Sun Solaris x64
    00052 #       else
    00053 #           define COH_OS_SOLARIS32
    00054 #           define COH_PLATFORM Sun Solaris x86
    00055 #       endif
    00056 #   endif
    00057 #elif defined(__linux__)
    00058 #   define COH_OS_LINUX // Linux
    00059 #   define COH_LIB_PREFIX "lib"
    00060 #   define COH_LIB_SUFFIX ".so"
    00061 #   define COH_OS_UNIX
    00062 #   if defined(__x86_64__) || defined(__amd64__)
    00063 #       define COH_OS_LINUX64
    00064 #       define COH_PLATFORM Linux x64
    00065 #   elif defined(__x86_32__) || defined(__i386__)
    00066 #       define COH_OS_LINUX32
    00067 #       define COH_PLATFORM Linux x86
    00068 #   endif
    00069 #elif defined(__APPLE__)
    00070 #   define COH_OS_DARWIN // Mac OS X
    00071 #   define COH_OS_UNIX
    00072 #   define COH_LIB_PREFIX "lib"
    00073 #   define COH_LIB_SUFFIX ".dylib"
    00074 #   if defined(__x86_64__) || defined(__amd64__)
    00075 #       define COH_OS_DARWIN64
    00076 #       define COH_PLATFORM Apple Mac OS X x64
    00077 #   elif defined(__x86_32__) || defined(__i386__)
    00078 #       define COH_OS_DARWIN32
    00079 #       define COH_PLATFORM Apple Mac OS X x86
    00080 #   endif
    00081 #endif
    00082
    00083 #ifndef COH_PLATFORM
    00084 #   error "Coherence for C++ does not support this platform."
    00085 #endif
    00086
    00087
    00088 // ----- identify compiler --------------------------------------------------
    00089
    00090 #if defined(_MSC_VER) && _MSC_VER >= 1400
    00091 #   define COH_CC_MSVC // Microsoft Visual C/C++
    00092 #   if _MSC_VER == 1400
    00093 #       define COH_CC msvc 2005
    00094 #   elif _MSC_VER == 1500
    00095 #       define COH_CC msvc 2008
    00096 #   elif _MSC_VER == 1600
    00097 #       define COH_CC msvc 2010
    00098 #   else
    00099 #       define COH_CC msvc
    00100 #   endif
    00101 #elif defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590
    00102 #   define COH_CC_SUN // Forte Developer, or Sun Studio C++
    00103 #   define COH_CC sunpro
    00104 #elif defined(__GNUG__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
    00105 #   define COH_CC_GNU // GNU C++
    00106 #   define COH_CC g++
    00107 #else
    00108 #   error "Coherence for C++ does not support this compiler or compiler version."
    00109 #endif
    00110
    00111
    00112 // ----- disable select warnings --------------------------------------------
    00113
    00114 /**
    00115 * Macro for disabling select warnings on MSVC. The warnings are automatically
    00116 * disabled upon opening a coherence namespace (using the COH_OPEN_NAMESPACE
    00117 * macros), and re-enabled when the namespace is exited via
    00118 * COH_CLOSE_NAMESPACE.
    00119 */
    00120 #if defined(COH_CC_MSVC)
    00121     #define COH_PRAGMA_PUSH \
    00122     __pragma(warning(push)) \
    00123     /* Allow multiple interface inheritance (inheritance via dominance) */ \
    00124     __pragma(warning(disable : 4250)) \
    00125     /* Allow non-exported DLL templates */ \
    00126     __pragma(warning(disable : 4251)) \
    00127     /* Exported class inheritance from non-exported class, needed for specs */ \
    00128     __pragma(warning(disable : 4275)) \
    00129     /* TypedHandle/Holder: multiple copy constructors */ \
    00130     __pragma(warning(disable : 4521)) \
    00131     /* Member/WeakHandle: assignment operators for const/non-const type */ \
    00132     __pragma(warning(disable : 4522)) \
    00133     /* Lack of return statements are being promoted to errors, when control \
    00134        path results in throw */ \
    00135     __pragma(warning(disable : 4715; disable : 4716))
    00136
    00137     #define COH_PRAGMA_POP __pragma(warning(pop))
    00138 #else
    00139     #define COH_PRAGMA_PUSH
    00140     #define COH_PRAGMA_POP
    00141 #endif
    00142
    00143 /**
    00144 * Macro for temporarily disabling above warnings for the duration of a
    00145 * single statement.  This is only needed for code which is not enclosed in a
    00146 * COH_OPEN/CLOSE_NAMESPACE block.
    00147 */
    00148 #define COH_NO_WARN(STMT) COH_PRAGMA_PUSH STMT COH_PRAGMA_POP
    00149
    00150 /**
    00151 * These macros are used to indicate that a function will not return normally.
    00152 *
    00153 * Usage example:
    00154 * @code
    00155 * COH_NO_RETURN_PRE void doSomething() COH_NO_RETURN_POST
    00156 *     {
    00157 *     COH_NO_RETURN_STMT(doSomething2());
    00158 *     }
    00159 * @endcode
    00160 */
    00161 #if defined(COH_CC_MSVC)
    00162     #define COH_NO_RETURN_PRE __declspec(noreturn)
    00163     #define COH_NO_RETURN_POST
    00164     #define COH_NO_RETURN_STMT(expr) expr
    00165 #elif defined(COH_CC_GNU)
    00166     #define COH_NO_RETURN_PRE
    00167     #define COH_NO_RETURN_POST __attribute__((noreturn))
    00168     #define COH_NO_RETURN_STMT(expr) expr
    00169 #elif defined(COH_CC_SUN)
    00170     #define COH_NO_RETURN_PRE
    00171     #define COH_NO_RETURN_POST
    00172     #define COH_NO_RETURN_STMT(expr)\
    00173         do { expr; throw std::exception(); } while (0)
    00174 #else
    00175     #define COH_NO_RETURN_PRE
    00176     #define COH_NO_RETURN_POST
    00177     #define COH_NO_RETURN_STMT(expr) expr
    00178 #endif
    00179
    00180
    00181 // ----- namespace macros ---------------------------------------------------
    00182
    00183 /**
    00184 * Define the existence of the coherence::lang namespace
    00185 */
    00186 namespace coherence { namespace lang {}}
    00187
    00188 #define COH_OPEN_NAMESPACE(ns) namespace ns { \
    00189     COH_PRAGMA_PUSH \
    00190     using namespace coherence::lang;
    00191
    00192 #define COH_INNER_NAMESPACE(ns) namespace ns {
    00193
    00194 #define COH_OPEN_NAMESPACE2(ns1, ns2)\
    00195     COH_OPEN_NAMESPACE (ns1) COH_INNER_NAMESPACE (ns2)
    00196
    00197 #define COH_OPEN_NAMESPACE3(ns1, ns2, ns3)\
    00198     COH_OPEN_NAMESPACE2 (ns1, ns2) COH_INNER_NAMESPACE (ns3)
    00199
    00200 #define COH_OPEN_NAMESPACE4(ns1, ns2, ns3, ns4)\
    00201     COH_OPEN_NAMESPACE3 (ns1, ns2, ns3) COH_INNER_NAMESPACE (ns4)
    00202
    00203 #define COH_OPEN_NAMESPACE5(ns1, ns2, ns3, ns4, ns5)\
    00204     COH_OPEN_NAMESPACE4 (ns1, ns2, ns3, ns4) COH_INNER_NAMESPACE (ns5)
    00205
    00206 #define COH_OPEN_NAMESPACE6(ns1, ns2, ns3, ns4, ns5, ns6)\
    00207     COH_OPEN_NAMESPACE5 (ns1, ns2, ns3, ns4, ns5) COH_INNER_NAMESPACE (ns6)
    00208
    00209 #define COH_OPEN_NAMESPACE7(ns1, ns2, ns3, ns4, ns5, ns6, ns7)\
    00210     COH_OPEN_NAMESPACE6 (ns1, ns2, ns3, ns4, ns5, ns6) COH_INNER_NAMESPACE (ns7)
    00211
    00212 #define COH_CLOSE_NAMESPACE COH_PRAGMA_POP }
    00213
    00214 #define COH_CLOSE_NAMESPACE2 COH_PRAGMA_POP } }
    00215
    00216 #define COH_CLOSE_NAMESPACE3 COH_PRAGMA_POP } } }
    00217
    00218 #define COH_CLOSE_NAMESPACE4 COH_PRAGMA_POP } } } }
    00219
    00220 #define COH_CLOSE_NAMESPACE5 COH_PRAGMA_POP } } } } }
    00221
    00222 #define COH_CLOSE_NAMESPACE6 COH_PRAGMA_POP } } } } } }
    00223
    00224 #define COH_CLOSE_NAMESPACE7 COH_PRAGMA_POP } } } } } } }
    00225
    00226
    00227 // ----- general utility macros ---------------------------------------------
    00228
    00229 /**
    00230 * This macro "mangles" the specified @a Name, producing an identifier which
    00231 * is unique in the current file.
    00232 *
    00233 * Note. This implementation of COH_UNIQUE_IDENTIFIER (as well as macros that
    00234 * use it) won't work in MSVC 6.0 when -ZI is on! See Q199057.
    00235 *
    00236 * @param Name the name to produce a new identifier on its basis
    00237 */
    00238 #define COH_JOIN(X, Y) COH_DO_JOIN(X, Y)
    00239 #define COH_DO_JOIN(X, Y) COH_DO_JOIN2(X, Y)
    00240 #define COH_DO_JOIN2(X, Y) X##Y
    00241 #ifdef COH_CC_MSVC_NET // MSVC 2002 and later
    00242 #   define COH_UNIQUE_IDENTIFIER(Name) COH_JOIN(Name, __COUNTER__)
    00243 #else
    00244 #   define COH_UNIQUE_IDENTIFIER(Name) COH_JOIN(Name, __LINE__)
    00245 #endif
    00246
    00247 /**
    00248 * This macro will ensure initialization of function local statics at library
    00249 * load time. This should be used to force the initialization of statics
    00250 * in a thread safe way.  The general form is:
    00251 *
    00252 * SomeType::Handle staticAccessorFunction()
    00253 *     {
    00254 *     static FinalHandle<SomeType> hStatic = SomeType::create();
    00255 *     return hStatic;
    00256 *     }
    00257 * COH_STATIC_INIT(staticAccessorFunction());
    00258 *
    00259 * @param FUNC  The static function and parameters to call that requires
    00260 *             initialization.
    00261 */
    00262 #define COH_STATIC_INIT(FUNC) \
    00263     static const bool COH_UNIQUE_IDENTIFIER(coh_static_init_func) = (FUNC, true)
    00264
    00265 COH_OPEN_NAMESPACE2(coherence,lang)
    00266     template <bool x> struct STATIC_ASSERTION_FAILURE;
    00267     template<> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
    00268 COH_CLOSE_NAMESPACE2
    00269
    00270 /**
    00271 * This macro generates a compile time error message if the integral constant
    00272 * expression @a B is not true. In other words, it is the compile time
    00273 * equivalent of the @c assert macro. Note that if the condition is true, then
    00274 * the macro will generate neither code nor data - and the macro can also be
    00275 * used at either namespace, class or function scope. When used in a template,
    00276 * the static assertion will be evaluated at the time the template is
    00277 * instantiated; this is particularly useful for validating template
    00278 * parameters.
    00279 *
    00280 * #COH_STATIC_ASSERT can be used at any place where a declaration can be
    00281 * placed, that is at class, function or namespace scope.
    00282 *
    00283 * @param B an integral constant expression to check its trueness during
    00284 *          translation phase
    00285 */
    00286 #define COH_STATIC_ASSERT(B)                               \
    00287     enum { COH_UNIQUE_IDENTIFIER(coh_static_assert_enum_) =\
    00288         sizeof(coherence::lang::STATIC_ASSERTION_FAILURE<(bool)(B)>) }
    00289
    00290 /**
    00291 * DLL import/export macros.
    00292 */
    00293 #if defined(COH_CC_MSVC)
    00294     #ifdef COH_BUILD
    00295         #define COH_EXPORT  __declspec(dllexport)
    00296     #else
    00297         #define COH_EXPORT  __declspec(dllimport)
    00298     #endif
    00299     #define COH_EXPORT_SPEC  __declspec(dllexport)
    00300     #define COH_EXPORT_SPEC_MEMBER(DECL)
    00301 #else
    00302     #define COH_EXPORT
    00303     #define COH_EXPORT_SPEC
    00304     #define COH_EXPORT_SPEC_MEMBER(DECL) DECL;
    00305 #endif
    00306
    00307 /**
    00308 * This macro will strongly encourage/force inlining of a method.
    00309 */
    00310 #if defined(COH_CC_MSVC)
    00311     #define COH_INLINE __forceinline
    00312 #elif defined(COH_CC_GNU)
    00313     #define COH_INLINE __attribute__((always_inline)) inline
    00314 #else
    00315     #define COH_INLINE inline
    00316 #endif
    00317
    00318 /**
    00319 * This macro expands to the name and signature of the current function.
    00320 */
    00321 #if defined(__GNUC__)
    00322     #define COH_CURRENT_FUNCTION __PRETTY_FUNCTION__
    00323 #elif defined(__FUNCSIG__)
    00324     #define COH_CURRENT_FUNCTION __FUNCSIG__
    00325 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
    00326     #define COH_CURRENT_FUNCTION __func__
    00327 #else
    00328     #define COH_CURRENT_FUNCTION "(unknown function)"
    00329 #endif
    00330
    00331
    00332 // ----- fixed size types ---------------------------------------------------
    00333
    00334 // We need to include an std lib header here in order to detect which library
    00335 // is in use (__GLIBC__ may not be defined without this including). Use
    00336 // <utility> as it's about the smallest of the std lib headers.
    00337 #include <utility>
    00338 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901 ||\
    00339     defined(_POSIX_VERSION) && _POSIX_VERSION >= 200100 ||\
    00340     defined(COH_OS_LINUX) &&\
    00341         defined(__GLIBC__) &&\
    00342         (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) &&\
    00343         defined(__GNUC__) ||\
    00344     defined(COH_OS_DARWIN) && __MACH__ && !defined(_MSL_USING_MSL_C)
    00345 #       define COH_HAS_STDINT_H
    00346 #endif
    00347
    00348 #if defined(__GCCXML__) ||\
    00349     defined(__GNUC__) ||\
    00350     defined(_MSC_VER) && _MSC_VER >= 1310 && defined(_MSC_EXTENSIONS)
    00351 #       define COH_HAS_LONG_LONG
    00352 #endif
    00353
    00354 #if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) &&\
    00355         !defined(_GLIBCPP_USE_LONG_LONG) &&          \
    00356         !defined(_GLIBCXX_USE_LONG_LONG) &&          \
    00357         defined(COH_HAS_LONG_LONG)
    00358     // Coming here indicates that the GNU compiler supports long long type,
    00359     // but the GNU C++ runtime library does not. Particularly, no global
    00360     // operator<<(std::ostream&, long long) implementation is provided. Let us
    00361     // provide it, at least with minimum incomplete functionality.
    00362 #   include <ostream>
    00363     namespace std
    00364         {
    00365         template<class E, class T>
    00366         inline basic_ostream<E, T>& operator<<
    00367                 (basic_ostream<E, T>& out, long long l)
    00368             {
    00369             return out << static_cast<long>(l);
    00370             }
    00371         template<class E, class T>
    00372         inline basic_ostream<E, T>& operator<<
    00373                 (basic_ostream<E, T>& out, unsigned long long l)
    00374             {
    00375             return out << static_cast<unsigned long>(l);
    00376             }
    00377         }
    00378 #   undef COH_HAS_LONG_LONG
    00379 #endif
    00380
    00381 #if !defined(COH_HAS_LONG_LONG) && !defined(COH_CC_MSVC)
    00382 #   include <limits.h>
    00383 #   if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) ||\
    00384             defined(ULONGLONG_MAX)
    00385 #       define COH_HAS_LONG_LONG
    00386 #   endif
    00387 #endif
    00388
    00389 #if defined(_MSC_VER) && _MSC_VER >= 1200
    00390 #       define COH_HAS_MS_INT64
    00391 #endif
    00392
    00393 /**
    00394 * Fixed width primitive types.
    00395 */
    00396 #if defined(COH_HAS_STDINT_H)
    00397 #   include <stdint.h>
    00398 #elif defined(COH_CC_SUN)
    00399 #   include <inttypes.h>
    00400 #else
    00401 //  This platform does not support the C99 stdint.h types. This code block
    00402 //  defines them in the global namespace, alternatively you may define
    00403 //  COH_NAMESPACED_FIXED_INTS, in which case these definitions will be within
    00404 //  the coherence::lang namespace.
    00405 #   include <climits>
    00406 #   ifdef COH_NAMESPACED_FIXED_INTS
    00407       COH_OPEN_NAMESPACE2(coherence,lang)
    00408 #   endif
    00409     COH_STATIC_ASSERT(UCHAR_MAX == 0xFF);
    00410     typedef signed char   int8_t;
    00411     typedef unsigned char uint8_t;
    00412     COH_STATIC_ASSERT(USHRT_MAX == 0xFFFF);
    00413     typedef short          int16_t;
    00414     typedef unsigned short uint16_t;
    00415 #   if UINT_MAX == 0xFFFFFFFF
    00416         typedef int          int32_t;
    00417         typedef unsigned int uint32_t;
    00418 #   elif ULONG_MAX == 0xFFFFFFFF
    00419         typedef long          int32_t;
    00420         typedef unsigned long uint32_t;
    00421 #   else
    00422 #       error int size not correct
    00423 #   endif
    00424 #   if defined(COH_HAS_LONG_LONG) &&\
    00425         !defined(COH_CC_MSVC) &&\
    00426         (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \
    00427         (defined(ULLONG_MAX) ||\
    00428             defined(ULONG_LONG_MAX) ||\
    00429             defined(ULONGLONG_MAX))
    00430 #               if defined(ULLONG_MAX)
    00431                     COH_STATIC_ASSERT(ULLONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
    00432 #               elif defined(ULONG_LONG_MAX)
    00433                     COH_STATIC_ASSERT
    00434                         (ULONG_LONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
    00435 #               elif defined(ULONGLONG_MAX)
    00436                     COH_STATIC_ASSERT
    00437                         (ULONGLONG_MAX == 0xFFFFFFFFFFFFFFFFULL));
    00438 #               else
    00439 #                   error long long size not correct
    00440 #               endif
    00441                 typedef long long          int64_t;
    00442                 typedef unsigned long long uint64_t;
    00443 #   elif ULONG_MAX != 0xFFFFFFFF
    00444         COH_STATIC_ASSERT(ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
    00445         typedef long          int64_t;
    00446         typedef unsigned long uint64_t;
    00447 #   elif defined(__GNUC__) && defined(COH_HAS_LONG_LONG)
    00448         __extension__ typedef long long          int64_t;
    00449         __extension__ typedef unsigned long long uint64_t;
    00450 #   elif defined(COH_HAS_MS_INT64)
    00451         typedef __int64          int64_t;
    00452         typedef unsigned __int64 uint64_t;
    00453 #   else
    00454 #       error no 64-bit integer support
    00455 #   endif
    00456 #   ifdef COH_NAMESPACED_FIXED_INTS
    00457       COH_CLOSE_NAMESPACE2
    00458 #   endif
    00459 #endif
    00460
    00461 /**
    00462 * Non-standard primitive type definitions.
    00463 */
    00464 COH_OPEN_NAMESPACE2(coherence,lang)
    00465     typedef unsigned char octet_t;
    00466     typedef uint16_t      char16_t;
    00467     typedef uint32_t      size32_t;
    00468     typedef uint64_t      size64_t;
    00469     typedef float         float32_t; COH_STATIC_ASSERT(sizeof(float32_t) >= sizeof(int32_t));
    00470     typedef double        float64_t; COH_STATIC_ASSERT(sizeof(float64_t) >= sizeof(int64_t));
    00471 COH_CLOSE_NAMESPACE2
    00472
    00473 /**
    00474 * Produce a 64b value from two 32b parts.
    00475 *
    00476 * This is a bit-wise construction, and the supplied values should be the
    00477 * bitwise unsigned representations.  For example:
    00478 * COH_INT64(0x7FFFFFFFU, 0xFFFFFFFFU) == 0x7FFFFFFFFFFFFFFFLL
    00479 */
    00480 #define COH_INT64(HIGH, LOW) int64_t(uint64_t(HIGH) << 32 | uint64_t(LOW))
    00481
    00482 // macros for turning compiler supplied define into a string
    00483 #define COH_SYMB_STRING(SYMB) #SYMB
    00484 #define COH_SYMB_TO_STRING(SYMB) COH_SYMB_STRING(SYMB)
    00485
    00486
    00487 // ----- helpers ------------------------------------------------------------
    00488
    00489 #include <typeinfo>
    00490 COH_OPEN_NAMESPACE2(coherence,lang)
    00491     /**
    00492     * Helper functions for throwing exceptions.
    00493     */
    00494     extern COH_EXPORT void coh_throw_npe(const std::type_info&);
    00495     extern COH_EXPORT void coh_throw_class_cast(const std::type_info&,
    00496             const std::type_info&);
    00497     extern COH_EXPORT void coh_throw_const_cast(const std::type_info&,
    00498             const std::type_info&);
    00499     extern COH_EXPORT void coh_throw_illegal_state(const char* achMsg);
    00500     extern COH_EXPORT void coh_throw_illegal_argument(const char* achMsg);
    00501     extern COH_EXPORT void coh_throw_unsupported_operation(const char* achMsg);
    00502
    00503     /**
    00504     * Helper class used to test for type assignment compatibility at
    00505     * compile time.
    00506     *
    00507     * This implementation is based on the Conversion example from
    00508     * Andrei Alexandrescu's Modern C++ Design.
    00509     */
    00510     template<class A, class B>
    00511     class assignment
    00512         {
    00513         protected:
    00514             typedef char  PathA;
    00515             class   Other {char unused[2];}; // sizeof(Other) != sizeof(PathA)
    00516             static  PathA route(A*); // PathA taken only for compatible types
    00517             static  Other route(...); // incompatible types go this route
    00518             static  B*    test(); // "generate" a test object
    00519
    00520         public:
    00521             /**
    00522             * Convert a derived A to an A.
    00523             */
    00524             static A* safe(A* a)
    00525                 {
    00526                 return a;
    00527                 }
    00528
    00529             /**
    00530             * Dummy conversion (should never be called)
    00531             */
    00532             static A* safe(...)
    00533                 {
    00534                 coh_throw_illegal_state("unsafe cast");
    00535                 return 0;
    00536                 }
    00537
    00538         public:
    00539             /**
    00540             * True iff A = B is allowed.
    00541             */
    00542             enum {allowed = (sizeof(route(test())) == sizeof(PathA))};
    00543         };
    00544
    00545     /**
    00546     * Helper class used to test if a type has been declared as const.
    00547     */
    00548     template<class A>
    00549     class constness
    00550         {
    00551         public:
    00552             enum {applied = assignment<A, const A>::allowed};
    00553         };
    00554 COH_CLOSE_NAMESPACE2
    00555
    00556 /// @endcond
    00557
    00558 #endif // COH_COMPATIBILITY_HPP

Copyright © 2000, 2010, Oracle and/or its affiliates. All rights reserved.