Oracle Coherence for C++ API
Release 3.7.1.0
E22845-01
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