Oracle Coherence for C++ API
Release 3.7.1.0

E22845-01

coherence/lang/compatibility.hpp

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