1 #pragma once
2 
3 #include <cstdint> // size_t
4 #include <utility> // declval
5 
6 #include <nlohmann/detail/meta/detected.hpp>
7 #include <nlohmann/detail/meta/type_traits.hpp>
8 
9 namespace nlohmann
10 {
11 namespace detail
12 {
13 template <typename T>
14 using null_function_t = decltype(std::declval<T&>().null());
15 
16 template <typename T>
17 using boolean_function_t =
18     decltype(std::declval<T&>().boolean(std::declval<bool>()));
19 
20 template <typename T, typename Integer>
21 using number_integer_function_t =
22     decltype(std::declval<T&>().number_integer(std::declval<Integer>()));
23 
24 template <typename T, typename Unsigned>
25 using number_unsigned_function_t =
26     decltype(std::declval<T &>().number_unsigned(std::declval<Unsigned>()));
27 
28 template <typename T, typename Float, typename String>
29 using number_float_function_t = decltype(std::declval<T &>().number_float(
30     std::declval<Float>(), std::declval<const String &>()));
31 
32 template <typename T, typename String>
33 using string_function_t =
34     decltype(std::declval<T &>().string(std::declval<String &>()));
35 
36 template <typename T>
37 using start_object_function_t =
38     decltype(std::declval<T &>().start_object(std::declval<std::size_t>()));
39 
40 template <typename T, typename String>
41 using key_function_t =
42     decltype(std::declval<T &>().key(std::declval<String &>()));
43 
44 template <typename T>
45 using end_object_function_t = decltype(std::declval<T &>().end_object());
46 
47 template <typename T>
48 using start_array_function_t =
49     decltype(std::declval<T &>().start_array(std::declval<std::size_t>()));
50 
51 template <typename T>
52 using end_array_function_t = decltype(std::declval<T &>().end_array());
53 
54 template <typename T, typename Exception>
55 using parse_error_function_t = decltype(std::declval<T &>().parse_error(
56     std::declval<std::size_t>(), std::declval<const std::string &>(),
57     std::declval<const Exception &>()));
58 
59 template <typename SAX, typename BasicJsonType>
60 struct is_sax
61 {
62 private:
63   static_assert(is_basic_json<BasicJsonType>::value,
64                 "BasicJsonType must be of type basic_json<...>");
65 
66   using number_integer_t = typename BasicJsonType::number_integer_t;
67   using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
68   using number_float_t = typename BasicJsonType::number_float_t;
69   using string_t = typename BasicJsonType::string_t;
70   using exception_t = typename BasicJsonType::exception;
71 
72 public:
73   static constexpr bool value =
74       is_detected_exact<bool, null_function_t, SAX>::value &&
75       is_detected_exact<bool, boolean_function_t, SAX>::value &&
76       is_detected_exact<bool, number_integer_function_t, SAX,
77                         number_integer_t>::value &&
78       is_detected_exact<bool, number_unsigned_function_t, SAX,
79                         number_unsigned_t>::value &&
80       is_detected_exact<bool, number_float_function_t, SAX, number_float_t,
81                         string_t>::value &&
82       is_detected_exact<bool, string_function_t, SAX, string_t>::value &&
83       is_detected_exact<bool, start_object_function_t, SAX>::value &&
84       is_detected_exact<bool, key_function_t, SAX, string_t>::value &&
85       is_detected_exact<bool, end_object_function_t, SAX>::value &&
86       is_detected_exact<bool, start_array_function_t, SAX>::value &&
87       is_detected_exact<bool, end_array_function_t, SAX>::value &&
88       is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value;
89 };
90 
91 template <typename SAX, typename BasicJsonType>
92 struct is_sax_static_asserts
93 {
94 private:
95   static_assert(is_basic_json<BasicJsonType>::value,
96                 "BasicJsonType must be of type basic_json<...>");
97 
98   using number_integer_t = typename BasicJsonType::number_integer_t;
99   using number_unsigned_t = typename BasicJsonType::number_unsigned_t;
100   using number_float_t = typename BasicJsonType::number_float_t;
101   using string_t = typename BasicJsonType::string_t;
102   using exception_t = typename BasicJsonType::exception;
103 
104 public:
105   static_assert(is_detected_exact<bool, null_function_t, SAX>::value,
106                 "Missing/invalid function: bool null()");
107   static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
108                 "Missing/invalid function: bool boolean(bool)");
109   static_assert(is_detected_exact<bool, boolean_function_t, SAX>::value,
110                 "Missing/invalid function: bool boolean(bool)");
111   static_assert(
112       is_detected_exact<bool, number_integer_function_t, SAX,
113                         number_integer_t>::value,
114       "Missing/invalid function: bool number_integer(number_integer_t)");
115   static_assert(
116       is_detected_exact<bool, number_unsigned_function_t, SAX,
117                         number_unsigned_t>::value,
118       "Missing/invalid function: bool number_unsigned(number_unsigned_t)");
119   static_assert(is_detected_exact<bool, number_float_function_t, SAX,
120                                   number_float_t, string_t>::value,
121                 "Missing/invalid function: bool number_float(number_float_t, const string_t&)");
122   static_assert(
123       is_detected_exact<bool, string_function_t, SAX, string_t>::value,
124       "Missing/invalid function: bool string(string_t&)");
125   static_assert(is_detected_exact<bool, start_object_function_t, SAX>::value,
126                 "Missing/invalid function: bool start_object(std::size_t)");
127   static_assert(is_detected_exact<bool, key_function_t, SAX, string_t>::value,
128                 "Missing/invalid function: bool key(string_t&)");
129   static_assert(is_detected_exact<bool, end_object_function_t, SAX>::value,
130                 "Missing/invalid function: bool end_object()");
131   static_assert(is_detected_exact<bool, start_array_function_t, SAX>::value,
132                 "Missing/invalid function: bool start_array(std::size_t)");
133   static_assert(is_detected_exact<bool, end_array_function_t, SAX>::value,
134                 "Missing/invalid function: bool end_array()");
135   static_assert(
136       is_detected_exact<bool, parse_error_function_t, SAX, exception_t>::value,
137       "Missing/invalid function: bool parse_error(std::size_t, const "
138       "std::string&, const exception&)");
139 };
140 }
141 }
142