Path: blob/master/dep/rapidyaml/include/c4/language.hpp
4261 views
#ifndef _C4_LANGUAGE_HPP_1#define _C4_LANGUAGE_HPP_23/** @file language.hpp Provides language standard information macros and4* compiler agnostic utility macros: namespace facilities, function attributes,5* variable attributes, etc.6* @ingroup basic_headers */78#include "c4/preprocessor.hpp"9#include "c4/compiler.hpp"1011/* Detect C++ standard.12* @see http://stackoverflow.com/a/7132549/5875572 */13#ifndef C4_CPP14# if defined(_MSC_VER) && !defined(__clang__)15# if _MSC_VER >= 1910 // >VS2015: VS2017, VS201916# if (!defined(_MSVC_LANG))17# error _MSVC not defined18# endif19# if _MSVC_LANG >= 201705L20# define C4_CPP 2021# define C4_CPP2022# elif _MSVC_LANG == 201703L23# define C4_CPP 1724# define C4_CPP1725# elif _MSVC_LANG >= 201402L26# define C4_CPP 1427# define C4_CPP1428# elif _MSVC_LANG >= 201103L29# define C4_CPP 1130# define C4_CPP1131# else32# error C++ lesser than C++11 not supported33# endif34# else35# if _MSC_VER == 190036# define C4_CPP 14 // VS2015 is c++14 https://devblogs.microsoft.com/cppblog/c111417-features-in-vs-2015-rtm/37# define C4_CPP1438# elif _MSC_VER == 1800 // VS201339# define C4_CPP 1140# define C4_CPP1141# else42# error C++ lesser than C++11 not supported43# endif44# endif45# elif defined(__INTEL_COMPILER) // https://software.intel.com/en-us/node/52449046# ifdef __INTEL_CXX20_MODE__ // not sure about this47# define C4_CPP 2048# define C4_CPP2049# elif defined __INTEL_CXX17_MODE__ // not sure about this50# define C4_CPP 1751# define C4_CPP1752# elif defined __INTEL_CXX14_MODE__ // not sure about this53# define C4_CPP 1454# define C4_CPP1455# elif defined __INTEL_CXX11_MODE__56# define C4_CPP 1157# define C4_CPP1158# else59# error C++ lesser than C++11 not supported60# endif61# else62# ifndef __cplusplus63# error __cplusplus is not defined?64# endif65# if __cplusplus == 166# error cannot handle __cplusplus==167# elif __cplusplus >= 201709L68# define C4_CPP 2069# define C4_CPP2070# elif __cplusplus >= 201703L71# define C4_CPP 1772# define C4_CPP1773# elif __cplusplus >= 201402L74# define C4_CPP 1475# define C4_CPP1476# elif __cplusplus >= 201103L77# define C4_CPP 1178# define C4_CPP1179# elif __cplusplus >= 199711L80# error C++ lesser than C++11 not supported81# endif82# endif83#else84# ifdef C4_CPP == 2085# define C4_CPP2086# elif C4_CPP == 1787# define C4_CPP1788# elif C4_CPP == 1489# define C4_CPP1490# elif C4_CPP == 1191# define C4_CPP1192# elif C4_CPP == 9893# define C4_CPP9894# error C++ lesser than C++11 not supported95# else96# error C4_CPP must be one of 20, 17, 14, 11, 9897# endif98#endif99100#ifdef C4_CPP20101# define C4_CPP17102# define C4_CPP14103# define C4_CPP11104#elif defined(C4_CPP17)105# define C4_CPP14106# define C4_CPP11107#elif defined(C4_CPP14)108# define C4_CPP11109#endif110111/** lifted from this answer: http://stackoverflow.com/a/20170989/5875572 */112#if defined(_MSC_VER) && !defined(__clang__)113# if _MSC_VER < 1900114# define C4_CONSTEXPR11115# define C4_CONSTEXPR14116# elif _MSC_VER < 2000117# define C4_CONSTEXPR11 constexpr118# define C4_CONSTEXPR14119# else120# define C4_CONSTEXPR11 constexpr121# define C4_CONSTEXPR14 constexpr122# endif123#else124# if __cplusplus < 201103125# define C4_CONSTEXPR11126# define C4_CONSTEXPR14127# elif __cplusplus == 201103128# define C4_CONSTEXPR11 constexpr129# define C4_CONSTEXPR14130# else131# define C4_CONSTEXPR11 constexpr132# define C4_CONSTEXPR14 constexpr133# endif134#endif // _MSC_VER135136137#if C4_CPP < 17138#define C4_IF_CONSTEXPR139#define C4_INLINE_CONSTEXPR constexpr140#else141#define C4_IF_CONSTEXPR constexpr142#define C4_INLINE_CONSTEXPR inline constexpr143#endif144145#if defined(_MSC_VER) && !defined(__clang__)146# if (defined(_CPPUNWIND) && (_CPPUNWIND == 1))147# define C4_EXCEPTIONS148# endif149#else150# if defined(__EXCEPTIONS) || defined(__cpp_exceptions)151# define C4_EXCEPTIONS152# endif153#endif154155#ifdef C4_EXCEPTIONS156# define C4_IF_EXCEPTIONS_(exc_code, setjmp_code) exc_code157# define C4_IF_EXCEPTIONS(exc_code, setjmp_code) do { exc_code } while(0)158#else159# define C4_IF_EXCEPTIONS_(exc_code, setjmp_code) setjmp_code160# define C4_IF_EXCEPTIONS(exc_code, setjmp_code) do { setjmp_code } while(0)161#endif162163#if defined(_MSC_VER) && !defined(__clang__)164# if defined(_CPPRTTI)165# define C4_RTTI166# endif167#else168# if defined(__GXX_RTTI)169# define C4_RTTI170# endif171#endif172173#ifdef C4_RTTI174# define C4_IF_RTTI_(code_rtti, code_no_rtti) code_rtti175# define C4_IF_RTTI(code_rtti, code_no_rtti) do { code_rtti } while(0)176#else177# define C4_IF_RTTI_(code_rtti, code_no_rtti) code_no_rtti178# define C4_IF_RTTI(code_rtti, code_no_rtti) do { code_no_rtti } while(0)179#endif180181182//------------------------------------------------------------183184#define _C4_BEGIN_NAMESPACE(ns) namespace ns {185#define _C4_END_NAMESPACE(ns) }186187// MSVC cant handle the C4_FOR_EACH macro... need to fix this188//#define C4_BEGIN_NAMESPACE(...) C4_FOR_EACH_SEP(_C4_BEGIN_NAMESPACE, , __VA_ARGS__)189//#define C4_END_NAMESPACE(...) C4_FOR_EACH_SEP(_C4_END_NAMESPACE, , __VA_ARGS__)190#define C4_BEGIN_NAMESPACE(ns) namespace ns {191#define C4_END_NAMESPACE(ns) }192193#define C4_BEGIN_HIDDEN_NAMESPACE namespace /*hidden*/ {194#define C4_END_HIDDEN_NAMESPACE } /* namespace hidden */195196//------------------------------------------------------------197198#ifndef C4_API199# if defined(_MSC_VER) && !defined(__clang__)200# if defined(C4_EXPORT)201# define C4_API __declspec(dllexport)202# elif defined(C4_IMPORT)203# define C4_API __declspec(dllimport)204# else205# define C4_API206# endif207# else208# define C4_API209# endif210#endif211212#if defined(_MSC_VER) && !defined(__clang__)213# define C4_RESTRICT __restrict214# define C4_RESTRICT_FN __declspec(restrict)215# define C4_NO_INLINE __declspec(noinline)216# define C4_ALWAYS_INLINE inline __forceinline217/** these are not available in VS AFAIK */218# define C4_CONST219# define C4_PURE220# define C4_FLATTEN221# define C4_HOT /** @todo */222# define C4_COLD /** @todo */223# define C4_EXPECT(x, y) x /** @todo */224# define C4_LIKELY(x) x /** @todo */225# define C4_UNLIKELY(x) x /** @todo */226# define C4_UNREACHABLE() /** @todo */227# define C4_ATTR_FORMAT(...) /** */228# define C4_NORETURN /** @todo */229#else230///< @todo assuming gcc-like compiler. check it is actually so.231/** for function attributes in GCC,232* @see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes */233/** for __builtin functions in GCC,234* @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html */235# define C4_RESTRICT __restrict__236# define C4_RESTRICT_FN __attribute__((restrict))237# define C4_NO_INLINE __attribute__((noinline))238# define C4_ALWAYS_INLINE inline __attribute__((always_inline))239# define C4_CONST __attribute__((const))240# define C4_PURE __attribute__((pure))241/** force inlining of every callee function */242# define C4_FLATTEN __atribute__((flatten))243/** mark a function as hot, ie as having a visible impact in CPU time244* thus making it more likely to inline, etc245* @see http://stackoverflow.com/questions/15028990/semantics-of-gcc-hot-attribute */246# define C4_HOT __attribute__((hot))247/** mark a function as cold, ie as NOT having a visible impact in CPU time248* @see http://stackoverflow.com/questions/15028990/semantics-of-gcc-hot-attribute */249# define C4_COLD __attribute__((cold))250# define C4_EXPECT(x, y) __builtin_expect(x, y) ///< @see https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html251# define C4_LIKELY(x) __builtin_expect(x, 1)252# define C4_UNLIKELY(x) __builtin_expect(x, 0)253# define C4_UNREACHABLE() __builtin_unreachable()254# define C4_ATTR_FORMAT(...) //__attribute__((format (__VA_ARGS__))) ///< @see https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes255# define C4_NORETURN __attribute__((noreturn))256#endif257258#ifdef _MSC_VER259# define C4_FUNC __FUNCTION__260# define C4_PRETTY_FUNC __FUNCSIG__261#else /// @todo assuming gcc-like compiler. check it is actually so.262# define C4_FUNC __FUNCTION__263# define C4_PRETTY_FUNC __PRETTY_FUNCTION__264#endif265266/** prevent compiler warnings about a specific var being unused */267#define C4_UNUSED(var) (void)var268269#if C4_CPP >= 17270#define C4_STATIC_ASSERT(cond) static_assert(cond)271#else272#define C4_STATIC_ASSERT(cond) static_assert((cond), #cond)273#endif274#define C4_STATIC_ASSERT_MSG(cond, msg) static_assert((cond), #cond ": " msg)275276/** @def C4_DONT_OPTIMIZE idea lifted from GoogleBenchmark.277* @see https://github.com/google/benchmark/blob/master/include/benchmark/benchmark_api.h */278namespace c4 {279namespace detail {280#ifdef __GNUC__281# define C4_DONT_OPTIMIZE(var) c4::detail::dont_optimize(var)282template< class T >283C4_ALWAYS_INLINE void dont_optimize(T const& value) { asm volatile("" : : "g"(value) : "memory"); }284#else285# define C4_DONT_OPTIMIZE(var) c4::detail::use_char_pointer(reinterpret_cast< const char* >(&var))286void use_char_pointer(char const volatile*);287#endif288} // namespace detail289} // namespace c4290291/** @def C4_KEEP_EMPTY_LOOP prevent an empty loop from being optimized out.292* @see http://stackoverflow.com/a/7084193/5875572 */293#if defined(_MSC_VER) && !defined(__clang__)294# define C4_KEEP_EMPTY_LOOP { char c; C4_DONT_OPTIMIZE(c); }295#else296# define C4_KEEP_EMPTY_LOOP { asm(""); }297#endif298299/** @def C4_VA_LIST_REUSE_MUST_COPY300* @todo <jpmag> I strongly suspect that this is actually only in UNIX platforms. revisit this. */301#ifdef __GNUC__302# define C4_VA_LIST_REUSE_MUST_COPY303#endif304305#endif /* _C4_LANGUAGE_HPP_ */306307308