1 #pragma once
2 
3 #include <utility> // pair
4 
5 // This file contains all internal macro definitions
6 // You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them
7 
8 // exclude unsupported compilers
9 #if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK)
10     #if defined(__clang__)
11         #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400
12             #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers"
13         #endif
14     #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER))
15         #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800
16             #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers"
17         #endif
18     #endif
19 #endif
20 
21 // disable float-equal warnings on GCC/clang
22 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
23     #pragma GCC diagnostic push
24     #pragma GCC diagnostic ignored "-Wfloat-equal"
25 #endif
26 
27 // disable documentation warnings on clang
28 #if defined(__clang__)
29     #pragma GCC diagnostic push
30     #pragma GCC diagnostic ignored "-Wdocumentation"
31 #endif
32 
33 // allow for portable deprecation warnings
34 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
35     #define JSON_DEPRECATED __attribute__((deprecated))
36 #elif defined(_MSC_VER)
37     #define JSON_DEPRECATED __declspec(deprecated)
38 #else
39     #define JSON_DEPRECATED
40 #endif
41 
42 // allow for portable nodiscard warnings
43 #if defined(__has_cpp_attribute)
44     #if __has_cpp_attribute(nodiscard)
45         #define JSON_NODISCARD [[nodiscard]]
46     #elif __has_cpp_attribute(gnu::warn_unused_result)
47         #define JSON_NODISCARD [[gnu::warn_unused_result]]
48     #else
49         #define JSON_NODISCARD
50     #endif
51 #else
52     #define JSON_NODISCARD
53 #endif
54 
55 // allow to disable exceptions
56 #if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION)
57     #define JSON_THROW(exception) throw exception
58     #define JSON_TRY try
59     #define JSON_CATCH(exception) catch(exception)
60     #define JSON_INTERNAL_CATCH(exception) catch(exception)
61 #else
62     #include <cstdlib>
63     #define JSON_THROW(exception) std::abort()
64     #define JSON_TRY if(true)
65     #define JSON_CATCH(exception) if(false)
66     #define JSON_INTERNAL_CATCH(exception) if(false)
67 #endif
68 
69 // override exception macros
70 #if defined(JSON_THROW_USER)
71     #undef JSON_THROW
72     #define JSON_THROW JSON_THROW_USER
73 #endif
74 #if defined(JSON_TRY_USER)
75     #undef JSON_TRY
76     #define JSON_TRY JSON_TRY_USER
77 #endif
78 #if defined(JSON_CATCH_USER)
79     #undef JSON_CATCH
80     #define JSON_CATCH JSON_CATCH_USER
81     #undef JSON_INTERNAL_CATCH
82     #define JSON_INTERNAL_CATCH JSON_CATCH_USER
83 #endif
84 #if defined(JSON_INTERNAL_CATCH_USER)
85     #undef JSON_INTERNAL_CATCH
86     #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER
87 #endif
88 
89 // manual branch prediction
90 #if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
91     #define JSON_LIKELY(x)      __builtin_expect(x, 1)
92     #define JSON_UNLIKELY(x)    __builtin_expect(x, 0)
93 #else
94     #define JSON_LIKELY(x)      x
95     #define JSON_UNLIKELY(x)    x
96 #endif
97 
98 // C++ language standard detection
99 #if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
100     #define JSON_HAS_CPP_17
101     #define JSON_HAS_CPP_14
102 #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
103     #define JSON_HAS_CPP_14
104 #endif
105 
106 /*!
107 @brief macro to briefly define a mapping between an enum and JSON
108 @def NLOHMANN_JSON_SERIALIZE_ENUM
109 @since version 3.4.0
110 */
111 #define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...)                                           \
112     template<typename BasicJsonType>                                                           \
113     inline void to_json(BasicJsonType& j, const ENUM_TYPE& e)                                  \
114     {                                                                                          \
115         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");         \
116         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                    \
117         auto it = std::find_if(std::begin(m), std::end(m),                                     \
118                                [e](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
119         {                                                                                      \
120             return ej_pair.first == e;                                                         \
121         });                                                                                    \
122         j = ((it != std::end(m)) ? it : std::begin(m))->second;                                \
123     }                                                                                          \
124     template<typename BasicJsonType>                                                           \
125     inline void from_json(const BasicJsonType& j, ENUM_TYPE& e)                                \
126     {                                                                                          \
127         static_assert(std::is_enum<ENUM_TYPE>::value, #ENUM_TYPE " must be an enum!");         \
128         static const std::pair<ENUM_TYPE, BasicJsonType> m[] = __VA_ARGS__;                    \
129         auto it = std::find_if(std::begin(m), std::end(m),                                     \
130                                [j](const std::pair<ENUM_TYPE, BasicJsonType>& ej_pair) -> bool \
131         {                                                                                      \
132             return ej_pair.second == j;                                                        \
133         });                                                                                    \
134         e = ((it != std::end(m)) ? it : std::begin(m))->first;                                 \
135     }
136 
137 // Ugly macros to avoid uglier copy-paste when specializing basic_json. They
138 // may be removed in the future once the class is split.
139 
140 #define NLOHMANN_BASIC_JSON_TPL_DECLARATION                                \
141     template<template<typename, typename, typename...> class ObjectType,   \
142              template<typename, typename...> class ArrayType,              \
143              class StringType, class BooleanType, class NumberIntegerType, \
144              class NumberUnsignedType, class NumberFloatType,              \
145              template<typename> class AllocatorType,                       \
146              template<typename, typename = void> class JSONSerializer>
147 
148 #define NLOHMANN_BASIC_JSON_TPL                                            \
149     basic_json<ObjectType, ArrayType, StringType, BooleanType,             \
150     NumberIntegerType, NumberUnsignedType, NumberFloatType,                \
151     AllocatorType, JSONSerializer>
152