lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
cpp0x.h
00001 /*****************************************************/
00002 /* lean C++0x Config            (c) Tobias Zirr 2011 */
00003 /*****************************************************/
00004 
00005 #ifndef LEAN_CPP0X
00006 #define LEAN_CPP0X
00007 
00008 #include "macros.h"
00009 
00013 
00014 #ifdef DOXYGEN_READ_THIS
00015 
00016 
00017     #define LEAN0X_DISABLE
00018 #endif
00019 
00020 
00021 // Disable all C++0x features by default when working with older C++ standards
00022 #if (201100L > __cplusplus) || defined(LEAN0X_DISABLE)
00023 
00024     #define LEAN0X_NO_NULLPTR
00025 
00026     #define LEAN0X_NO_RVALUE_REFERENCES
00027 
00028     #define LEAN0X_NO_STATIC_ASSERT
00029 
00030     #define LEAN0X_NO_ALIGN
00031 
00032     #define LEAN0X_NO_DELETE_METHODS
00033 
00034     #define LEAN0X_NO_STL
00035 #endif
00036 
00037 #ifndef LEAN0X_DISABLE
00038 
00039     // Enable Visual Studio 2010 C++0x features
00040     #if (_MSC_VER >= 1600) && defined(_MSC_EXTENSIONS)
00041         #undef LEAN0X_NO_NULLPTR
00042         #undef LEAN0X_NO_RVALUE_REFERENCES
00043         #undef LEAN0X_NO_STATIC_ASSERT
00044         #undef LEAN0X_NO_STL
00045     #endif
00046 
00047 #endif
00048 
00049 // Fix missing nullptr
00050 #if defined(LEAN0X_NO_NULLPTR) && !defined(nullptr)
00051     #define nullptr 0
00052 #endif
00053 
00054 // Emulate static_assert
00055 #if defined(LEAN0X_NO_STATIC_ASSERT) && !defined(static_assert)
00056 
00057 #ifndef DOXYGEN_SKIP_THIS
00058     namespace lean
00059     {
00060         struct static_assertion_error;
00061 
00062         namespace impl
00063         {
00064             // Accepts literal to circumvent the requirement of typename (which dependens on context)
00065             template <bool Triggered>
00066             struct emit_static_assertion_error;
00067 
00068             template <bool Assertion, class Error>
00069             struct trigger_static_assertion_error
00070             {
00071                 static const bool triggered = false;
00072             };
00073 
00074             template <class Error>
00075             struct trigger_static_assertion_error<false, Error>
00076             {
00077                 // Defines literal instead of type to circumvent the requirement of typename (which dependens on context)
00078                 static const bool triggered = sizeof(Error) || true;
00079             };
00080         }
00081     }
00082 #endif
00083     
00085     #define LEAN_STATIC_ASSERT(expr) typedef \
00086         ::lean::impl::emit_static_assertion_error< \
00087             ::lean::impl::trigger_static_assertion_error<(expr), ::lean::static_assertion_error>::triggered \
00088         > LEAN_JOIN_VALUES(static_assertion_error_, __LINE__)
00089 
00091     #define LEAN_STATIC_ASSERT_MSG(expr, msg) typedef \
00092         ::lean::impl::emit_static_assertion_error< \
00093             ::lean::impl::trigger_static_assertion_error<(expr), ::lean::static_assertion_error>::triggered \
00094         > LEAN_JOIN_VALUES(static_assertion_error_, __LINE__)
00095 
00097     #define LEAN_STATIC_ASSERT_MSG_ALT(expr, msg, msgtype) struct static_assertion_error__##msgtype; typedef \
00098         ::lean::impl::emit_static_assertion_error< \
00099             ::lean::impl::trigger_static_assertion_error<(expr), static_assertion_error__##msgtype>::triggered \
00100         > LEAN_JOIN_VALUES(static_assertion_error_, __LINE__)
00101 
00102     // Emulate static_assert
00103     #define static_assert(expr, msg) LEAN_STATIC_ASSERT_MSG(expr, msg)
00104 
00105 #else
00106 
00107     #define LEAN_STATIC_ASSERT(expr) static_assert(expr, #expr)
00108     
00110     #define LEAN_STATIC_ASSERT_MSG(expr, msg) static_assert(expr, msg)
00111     
00113     #define LEAN_STATIC_ASSERT_MSG_ALT(expr, msg, msgtype) static_assert(expr, msg)
00114 #endif
00115 
00116 #ifndef LEAN0X_NO_RVALUE_REFERENCES
00117     // Automatically include utility for move semantics
00118     #include <utility>
00119 
00121     #define LEAN_FW_REF &&
00122 
00124     #define LEAN_FORWARD(type, arg) std::forward<type>(arg)
00125 
00127     #define LEAN_MOVE(arg) std::move(arg)
00128 #else
00129 
00130     #define LEAN_FW_REF const &
00131 
00133     #define LEAN_FORWARD(type, arg) arg
00134 
00136     #define LEAN_MOVE(arg) arg
00137 #endif
00138 
00139 // Emulate next & prev if unavailable
00140 #ifdef LEAN0X_NO_STL
00141 
00142 namespace lean
00143 {
00144 
00146 template <class Iterator>
00147 LEAN_INLINE Iterator next(Iterator iterator)
00148 {
00149     return ++iterator;
00150 }
00151 
00153 template <class Iterator>
00154 LEAN_INLINE Iterator prev(Iterator iterator)
00155 {
00156     return --iterator;
00157 }
00158 
00159 } // namespace
00160 
00161 #else
00162 
00163 #include <iterator>
00164 
00165 namespace lean
00166 {
00167     using std::next;
00168     using std::prev;
00169 
00170 } // namespace
00171 
00172 #endif
00173 
00174 
00176 
00177 #ifdef DOXYGEN_READ_THIS
00178     // Re-enable move semantics for documentation
00179     #undef LEAN0X_DISABLE
00180     #undef LEAN0X_NO_RVALUE_REFERENCES
00181 #endif
00182 
00183 #endif