coherence/lang/compatibility.hpp

00001 /*
00002 * compatibility.hpp
00003 *
00004 * Copyright 2001-2008 by Oracle. 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 #   if defined(_WIN64)
00025 #      define COH_OS_WIN64 // Windows 2003/2008/Vista
00026 #      define COH_PLATFORM Microsoft Windows x64
00027 #   else
00028 #      define COH_OS_WIN32 // Windows NT/2000/XP
00029 #      define COH_PLATFORM Microsoft Windows x86
00030 #   endif
00031 #   define COH_OS_WINDOWS
00032 #elif defined(__sun) || defined(sun) && \
00033     (defined(__x86_32__) || defined(__i386__))
00034 #   define COH_OS_SOLARIS // Sun Solaris
00035 #   define COH_OS_UNIX
00036 #   define COH_PLATFORM Sun Solaris x86
00037 #elif defined(__linux__) && \
00038     (defined(__x86_32__) || defined(__i386__) || \
00039      defined(__x86_64__) || defined(__amd64__))
00040 #   if defined(__LP64__)
00041 #       define COH_OS_LINUX64
00042 #       define COH_PLATFORM Linux x64
00043 #   else
00044 #       define COH_OS_LINUX32
00045 #       define COH_PLATFORM Linux x86
00046 #   endif
00047 #   define COH_OS_LINUX // Linux
00048 #   define COH_OS_UNIX
00049 #elif defined(__APPLE__) && \
00050     (defined(__x86_32__) || defined(__i386__) && \
00051    !(defined(__x86_64__) || defined(__amd64__)))
00052 #   define COH_OS_DARWIN // Mac OS X
00053 #   define COH_OS_UNIX
00054 #   define COH_PLATFORM Apple Mac OS X x86
00055 #else
00056 #   error "Coherence for C++ does not support this OS."
00057 #endif
00058 
00059 
00060 // ----- identify compiler --------------------------------------------------
00061 
00062 #if defined(_MSC_VER) && _MSC_VER >= 1400 // Visual C++ 2005
00063 #   define COH_CC_MSVC // Microsoft Visual C/C++
00064 #elif defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590
00065 #   define COH_CC_SUN // Forte Developer, or Sun Studio C++
00066 #elif defined(__GNUG__) && (__GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
00067 #   define COH_CC_GNU // GNU C++
00068 #else
00069 #   error "Coherence for C++ does not support this compiler or compiler version."
00070 #endif
00071 
00072 
00073 // ----- disable select warnings --------------------------------------------
00074 
00075 /**
00076 * Macro for disabling select warnings on MSVC. The warnings are automatically
00077 * disabled upon openeing a coherence namespace (using the COH_OPEN_NAMESPACE
00078 * macros), and re-enabled when the namespace is exited via
00079 * COH_CLOSE_NAMESPACE.
00080 */
00081 #if defined(COH_CC_MSVC)
00082     #define COH_PRAGMA_PUSH \
00083     __pragma(warning(push)) \
00084     /* Allow mupliple interface inheritance (inheritance via dominance) */ \
00085     __pragma(warning(disable : 4250)) \
00086     /* Allow non-exported DLL templates */ \
00087     __pragma(warning(disable : 4251)) \
00088     /* Exported class inheritance from non-exported class, needed for specs */ \
00089     __pragma(warning(disable : 4275)) \
00090     /* Member/WeakHandle: assignment operators for const/non-const type */ \
00091     __pragma(warning(disable : 4522)) \
00092     /* Lack of return statements are being promoted to errors, when control \
00093        path results in throw */ \
00094     __pragma(warning(disable : 4715; disable : 4716))
00095 
00096     #define COH_PRAGMA_POP __pragma(warning(pop))
00097 #else
00098     #define COH_PRAGMA_PUSH
00099     #define COH_PRAGMA_POP
00100 #endif
00101 
00102 /**
00103 * Macro for temporarily disabling above warnings for the duration of a
00104 * single statement.  This is only needed for code which is not enclosed in a
00105 * COH_OPEN/CLOSE_NAMESPACE block.
00106 */
00107 #define COH_NO_WARN(STMT) COH_PRAGMA_PUSH STMT COH_PRAGMA_POP
00108 
00109 /**
00110 * These macros are used to indicate that a function will not return normally.
00111 *
00112 * Usage example:
00113 * @code
00114 * COH_NO_RETURN_PRE void doSomething() COH_NO_RETURN_POST
00115 *     {
00116 *     COH_NO_RETURN_STMT(doSomething2());
00117 *     }
00118 * @endcode
00119 */
00120 #if defined(COH_CC_MSVC)
00121     #define COH_NO_RETURN_PRE __declspec(noreturn)
00122     #define COH_NO_RETURN_POST
00123     #define COH_NO_RETURN_STMT(expr) expr
00124 #elif defined(COH_CC_GNU)
00125     #define COH_NO_RETURN_PRE
00126     #define COH_NO_RETURN_POST __attribute__((noreturn))
00127     #define COH_NO_RETURN_STMT(expr) expr
00128 #elif defined(COH_CC_SUN)
00129     #define COH_NO_RETURN_PRE
00130     #define COH_NO_RETURN_POST
00131     #define COH_NO_RETURN_STMT(expr)\
00132         do { expr; throw std::exception(); } while (0)
00133 #else
00134     #define COH_NO_RETURN_PRE
00135     #define COH_NO_RETURN_POST
00136     #define COH_NO_RETURN_STMT(expr) expr
00137 #endif
00138 
00139 
00140 // ----- namespace macros ---------------------------------------------------
00141 
00142 /**
00143 * Define the existance of the coherence::lang namespace
00144 */
00145 namespace coherence { namespace lang {}}
00146 
00147 #define COH_OPEN_NAMESPACE(ns) namespace ns { \
00148     COH_PRAGMA_PUSH \
00149     using namespace coherence::lang;
00150 
00151 #define COH_INNER_NAMESPACE(ns) namespace ns {
00152 
00153 #define COH_OPEN_NAMESPACE2(ns1, ns2)\
00154     COH_OPEN_NAMESPACE (ns1) COH_INNER_NAMESPACE (ns2)
00155 
00156 #define COH_OPEN_NAMESPACE3(ns1, ns2, ns3)\
00157     COH_OPEN_NAMESPACE2 (ns1, ns2) COH_INNER_NAMESPACE (ns3)
00158 
00159 #define COH_OPEN_NAMESPACE4(ns1, ns2, ns3, ns4)\
00160     COH_OPEN_NAMESPACE3 (ns1, ns2, ns3) COH_INNER_NAMESPACE (ns4)
00161 
00162 #define COH_OPEN_NAMESPACE5(ns1, ns2, ns3, ns4, ns5)\
00163     COH_OPEN_NAMESPACE4 (ns1, ns2, ns3, ns4) COH_INNER_NAMESPACE (ns5)
00164 
00165 #define COH_OPEN_NAMESPACE6(ns1, ns2, ns3, ns4, ns5, ns6)\
00166     COH_OPEN_NAMESPACE5 (ns1, ns2, ns3, ns4, ns5) COH_INNER_NAMESPACE (ns6)
00167 
00168 #define COH_OPEN_NAMESPACE7(ns1, ns2, ns3, ns4, ns5, ns6, ns7)\
00169     COH_OPEN_NAMESPACE6 (ns1, ns2, ns3, ns4, ns5, ns6) COH_INNER_NAMESPACE (ns7)
00170 
00171 #define COH_CLOSE_NAMESPACE COH_PRAGMA_POP }
00172 
00173 #define COH_CLOSE_NAMESPACE2 COH_PRAGMA_POP } }
00174 
00175 #define COH_CLOSE_NAMESPACE3 COH_PRAGMA_POP } } }
00176 
00177 #define COH_CLOSE_NAMESPACE4 COH_PRAGMA_POP } } } }
00178 
00179 #define COH_CLOSE_NAMESPACE5 COH_PRAGMA_POP } } } } }
00180 
00181 #define COH_CLOSE_NAMESPACE6 COH_PRAGMA_POP } } } } } }
00182 
00183 #define COH_CLOSE_NAMESPACE7 COH_PRAGMA_POP } } } } } } }
00184 
00185 
00186 // ----- general utility macros ---------------------------------------------
00187 
00188 /**
00189 * This macro "mangles" the specified @a Name, producing an identifier which
00190 * is unique in the current file.
00191 *
00192 * Note. This implementation of COH_UNIQUE_IDENTIFIER (as well as macros that
00193 * use it) won't work in MSVC 6.0 when -ZI is on! See Q199057.
00194 *
00195 * @param Name the name to produce a new identifier on its basis
00196 */
00197 #define COH_JOIN(X, Y) COH_DO_JOIN(X, Y)
00198 #define COH_DO_JOIN(X, Y) COH_DO_JOIN2(X, Y)
00199 #define COH_DO_JOIN2(X, Y) X##Y
00200 #ifdef COH_CC_MSVC_NET // MSVC 2002 and later
00201 #   define COH_UNIQUE_IDENTIFIER(Name) COH_JOIN(Name, __COUNTER__)
00202 #else
00203 #   define COH_UNIQUE_IDENTIFIER(Name) COH_JOIN(Name, __LINE__)
00204 #endif
00205 
00206 /**
00207 * This macro will ensure initialization of function local statics at library
00208 * load time. This should be used to force the initialization of statics
00209 * in a thread safe way.  The general form is:
00210 *
00211 * SomeType::Handle staticAccessorFunction()
00212 *     {
00213 *     static SomeType::Handle hStatic = SomeType::create();
00214 *     return hStatic;
00215 *     }
00216 * COH_STATIC_INIT(staticAccessorFunction());
00217 *
00218 * @param FUNC  The static function and parameters to call that requires
00219 *             initialization.
00220 */
00221 #define COH_STATIC_INIT(FUNC) \
00222     static const bool COH_UNIQUE_IDENTIFIER(coh_static_init_func) = (FUNC, true)
00223 
00224 COH_OPEN_NAMESPACE2(coherence,lang)
00225     template <bool x> struct STATIC_ASSERTION_FAILURE;
00226     template<> struct STATIC_ASSERTION_FAILURE<true> { enum { value = 1 }; };
00227 COH_CLOSE_NAMESPACE2
00228 
00229 /**
00230 * This macro generates a compile time error message if the integral constant
00231 * expression @a B is not true. In other words, it is the compile time
00232 * equivalent of the @c assert macro. Note that if the condition is true, then
00233 * the macro will generate neither code nor data - and the macro can also be
00234 * used at either namespace, class or function scope. When used in a template,
00235 * the static assertion will be evaluated at the time the template is
00236 * instantiated; this is particularly useful for validating template
00237 * parameters.
00238 *
00239 * #COH_STATIC_ASSERT can be used at any place where a declaration can be
00240 * placed, that is at class, function or namespace scope.
00241 *
00242 * @param B an integral constant expression to check its trueness during
00243 *          translation phase
00244 */
00245 #define COH_STATIC_ASSERT(B)                               \
00246     enum { COH_UNIQUE_IDENTIFIER(coh_static_assert_enum_) =\
00247         sizeof(coherence::lang::STATIC_ASSERTION_FAILURE<(bool)(B)>) }
00248 
00249 /**
00250 * DLL import/export macros.
00251 */
00252 #if defined(COH_CC_MSVC)
00253     #ifdef COH_BUILD
00254         #define COH_EXPORT  __declspec(dllexport)
00255     #else
00256         #define COH_EXPORT  __declspec(dllimport)
00257     #endif
00258     #define COH_EXPORT_SPEC  __declspec(dllexport)
00259     #define COH_EXPORT_SPEC_MEMBER(DECL)
00260 #else
00261     #define COH_EXPORT
00262     #define COH_EXPORT_SPEC
00263     #define COH_EXPORT_SPEC_MEMBER(DECL) DECL;
00264 #endif
00265 
00266 
00267 
00268 /**
00269 * This macro expands to the name and signature of the current function.
00270 */
00271 #if defined(__GNUC__)
00272     #define COH_CURRENT_FUNCTION __PRETTY_FUNCTION__
00273 #elif defined(__FUNCSIG__)
00274     #define COH_CURRENT_FUNCTION __FUNCSIG__
00275 #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901)
00276     #define COH_CURRENT_FUNCTION __func__
00277 #else
00278     #define COH_CURRENT_FUNCTION "(unknown function)"
00279 #endif
00280 
00281 
00282 // ----- fixed size types ---------------------------------------------------
00283 
00284 // We need to include an std lib header here in order to detect which library
00285 // is in use (__GLIBC__ may not be defined without this including). Use
00286 // <utility> as it's about the smallest of the std lib headers.
00287 #include <utility>
00288 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901 ||\
00289     defined(_POSIX_VERSION) && _POSIX_VERSION >= 200100 ||\
00290     defined(COH_OS_LINUX) &&\
00291         defined(__GLIBC__) &&\
00292         (__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) &&\
00293         defined(__GNUC__) ||\
00294     defined(COH_OS_DARWIN) && __MACH__ && !defined(_MSL_USING_MSL_C)
00295 #       define COH_HAS_STDINT_H
00296 #endif
00297 
00298 #if defined(__GCCXML__) ||\
00299     defined(__GNUC__) ||\
00300     defined(_MSC_VER) && _MSC_VER >= 1310 && defined(_MSC_EXTENSIONS)
00301 #       define COH_HAS_LONG_LONG
00302 #endif
00303 
00304 #if (defined(__GLIBCPP__) || defined(__GLIBCXX__)) &&\
00305         !defined(_GLIBCPP_USE_LONG_LONG) &&          \
00306         !defined(_GLIBCXX_USE_LONG_LONG) &&          \
00307         defined(COH_HAS_LONG_LONG)
00308     // Coming here indicates that the GNU compiler supports long long type,
00309     // but the GNU C++ runtime library does not. Particularly, no global
00310     // operator<<(std::ostream&, long long) implementation is provided. Let us
00311     // provide it, at least with minimum incomplete functionality.
00312 #   include <ostream>
00313     namespace std
00314         {
00315         template<class E, class T>
00316         inline basic_ostream<E, T>& operator<<
00317                 (basic_ostream<E, T>& out, long long l)
00318             {
00319             return out << static_cast<long>(l);
00320             }
00321         template<class E, class T>
00322         inline basic_ostream<E, T>& operator<<
00323                 (basic_ostream<E, T>& out, unsigned long long l)
00324             {
00325             return out << static_cast<unsigned long>(l);
00326             }
00327         }
00328 #   undef COH_HAS_LONG_LONG
00329 #endif
00330 
00331 #if !defined(COH_HAS_LONG_LONG) && !defined(COH_CC_MSVC)
00332 #   include <limits.h>
00333 #   if defined(ULLONG_MAX) || defined(ULONG_LONG_MAX) ||\
00334             defined(ULONGLONG_MAX)
00335 #       define COH_HAS_LONG_LONG
00336 #   endif
00337 #endif
00338 
00339 #if defined(_MSC_VER) && _MSC_VER >= 1200
00340 #       define COH_HAS_MS_INT64
00341 #endif
00342 
00343 /**
00344 * Fixed width primitive types.
00345 */
00346 #if defined(COH_HAS_STDINT_H)
00347 #   include <stdint.h>
00348 #elif defined(COH_CC_SUN)
00349 #   include <inttypes.h>
00350 #else
00351 //  This platform does not support the C99 stdint.h types. This code block
00352 //  defines them in the global namespace, alternativaley you may define
00353 //  COH_NAMESPACED_FIXED_INTS, in which case these definitions will be within
00354 //  the coherence::lang namespace.
00355 #   include <climits>
00356 #   ifdef COH_NAMESPACED_FIXED_INTS
00357       COH_OPEN_NAMESPACE2(coherence,lang)
00358 #   endif
00359     COH_STATIC_ASSERT(UCHAR_MAX == 0xFF);
00360     typedef signed char   int8_t;
00361     typedef unsigned char uint8_t;
00362     COH_STATIC_ASSERT(USHRT_MAX == 0xFFFF);
00363     typedef short          int16_t;
00364     typedef unsigned short uint16_t;
00365 #   if UINT_MAX == 0xFFFFFFFF
00366         typedef int          int32_t;
00367         typedef unsigned int uint32_t;
00368 #   elif ULONG_MAX == 0xFFFFFFFF
00369         typedef long          int32_t;
00370         typedef unsigned long uint32_t;
00371 #   else
00372 #       error int size not correct
00373 #   endif
00374 #   if defined(COH_HAS_LONG_LONG) &&\
00375         !defined(COH_CC_MSVC) &&\
00376         (!defined(__GLIBCPP__) || defined(_GLIBCPP_USE_LONG_LONG)) && \
00377         (defined(ULLONG_MAX) ||\
00378             defined(ULONG_LONG_MAX) ||\
00379             defined(ULONGLONG_MAX))
00380 #               if defined(ULLONG_MAX)
00381                     COH_STATIC_ASSERT(ULLONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
00382 #               elif defined(ULONG_LONG_MAX)
00383                     COH_STATIC_ASSERT
00384                         (ULONG_LONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
00385 #               elif defined(ULONGLONG_MAX)
00386                     COH_STATIC_ASSERT
00387                         (ULONGLONG_MAX == 0xFFFFFFFFFFFFFFFFULL));
00388 #               else
00389 #                   error long long size not correct
00390 #               endif
00391                 typedef long long          int64_t;
00392                 typedef unsigned long long uint64_t;
00393 #   elif ULONG_MAX != 0xFFFFFFFF
00394         COH_STATIC_ASSERT(ULONG_MAX == 0xFFFFFFFFFFFFFFFFULL);
00395         typedef long          int64_t;
00396         typedef unsigned long uint64_t;
00397 #   elif defined(__GNUC__) && defined(COH_HAS_LONG_LONG)
00398         __extension__ typedef long long          int64_t;
00399         __extension__ typedef unsigned long long uint64_t;
00400 #   elif defined(COH_HAS_MS_INT64)
00401         typedef __int64          int64_t;
00402         typedef unsigned __int64 uint64_t;
00403 #   else
00404 #       error no 64-bit integer support
00405 #   endif
00406 #   ifdef COH_NAMESPACED_FIXED_INTS
00407       COH_CLOSE_NAMESPACE2
00408 #   endif
00409 #endif
00410 
00411 /**
00412 * Non-standard primitive type definitions.
00413 */
00414 COH_OPEN_NAMESPACE2(coherence,lang)
00415     typedef unsigned char octet_t;
00416     typedef uint16_t      char16_t;
00417     typedef uint32_t      size32_t;
00418     typedef uint64_t      size64_t;
00419     typedef float         float32_t; COH_STATIC_ASSERT(sizeof(float32_t) >= sizeof(int32_t));
00420     typedef double        float64_t; COH_STATIC_ASSERT(sizeof(float64_t) >= sizeof(int64_t));
00421 COH_CLOSE_NAMESPACE2
00422 
00423 /// @endcond
00424 
00425 #endif // COH_COMPATIBILITY_HPP
Copyright (c) 2000-2008 Oracle. All rights reserved.