lean cpp library
A lean C++ library providing efficient utility classes for high-performance C++ applications.
|
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