DAW JSON Link
daw_json_assert.h
Go to the documentation of this file.
1 // Copyright (c) Darrell Wright
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE or copy at http://www.boost.org/LICENSE_1_0.txt)
5 //
6 // Official repository: https://github.com/beached/daw_json_link
7 //
8 
9 #pragma once
10 
11 #include "../daw_json_exception.h"
12 #include "version.h"
13 
14 #include <daw/daw_assume.h>
15 #include <daw/daw_attributes.h>
16 #include <daw/daw_check_exceptions.h>
17 #include <daw/daw_likely.h>
18 #include <daw/daw_string_view.h>
19 
20 #include <algorithm>
21 #include <ciso646>
22 #include <cstdio>
23 #include <cstdlib>
24 #include <memory>
25 #include <numeric>
26 #include <string>
27 #include <string_view>
28 
29 #ifdef DAW_USE_EXCEPTIONS
30 inline constexpr bool use_daw_json_exceptions_v = true;
31 #else
32 inline constexpr bool use_daw_json_exceptions_v = false;
33 #endif
34 
35 namespace daw::json {
36  inline namespace DAW_JSON_VER {
37  template<bool ShouldThrow = use_daw_json_exceptions_v>
38  [[maybe_unused, noreturn]] DAW_ATTRIB_NOINLINE void
39  daw_json_error( ErrorReason reason ) {
40 #ifdef DAW_USE_EXCEPTIONS
41  if constexpr( ShouldThrow ) {
42  throw json_exception( reason );
43  } else {
44 #endif
45  (void)ShouldThrow;
46  (void)reason;
47  std::terminate( );
48 #ifdef DAW_USE_EXCEPTIONS
49  }
50 #endif
51  }
52 
53  template<bool ShouldThrow = use_daw_json_exceptions_v, typename ParseState>
54  [[maybe_unused, noreturn]] DAW_ATTRIB_NOINLINE static void
55  daw_json_error( ErrorReason reason, ParseState const &location ) {
56 #ifdef DAW_USE_EXCEPTIONS
57  if constexpr( ShouldThrow ) {
58  if( location.first ) {
59  throw json_exception( reason, location.first );
60  }
61  if( location.class_first ) {
62  throw json_exception( reason, location.class_first );
63  }
64  throw json_exception( reason );
65  } else {
66 #endif
67  (void)ShouldThrow;
68  (void)reason;
69  (void)location;
70  std::terminate( );
71 #ifdef DAW_USE_EXCEPTIONS
72  }
73 #endif
74  }
75 
76  template<bool ShouldThrow = use_daw_json_exceptions_v>
77  [[maybe_unused, noreturn]] DAW_ATTRIB_NOINLINE static void
78  daw_json_error( json_details::missing_member reason ) {
79 #ifdef DAW_USE_EXCEPTIONS
80  if constexpr( ShouldThrow ) {
81  throw json_exception( reason );
82  } else {
83 #endif
84  (void)ShouldThrow;
85  (void)reason;
86  std::terminate( );
87 #ifdef DAW_USE_EXCEPTIONS
88  }
89 #endif
90  }
91 
92  template<bool ShouldThrow = use_daw_json_exceptions_v>
93  [[maybe_unused, noreturn]] DAW_ATTRIB_NOINLINE static void
94  daw_json_error( json_details::missing_token reason ) {
95 #ifdef DAW_USE_EXCEPTIONS
96  if constexpr( ShouldThrow ) {
97  throw json_exception( reason );
98  } else {
99 #endif
100  (void)ShouldThrow;
101  (void)reason;
102  std::terminate( );
103 #ifdef DAW_USE_EXCEPTIONS
104  }
105 #endif
106  }
107 
108  template<bool ShouldThrow = use_daw_json_exceptions_v, typename ParseState>
109  [[maybe_unused, noreturn]] DAW_ATTRIB_NOINLINE static void
110  daw_json_error( json_details::missing_member reason,
111  ParseState const &location ) {
112 #ifdef DAW_USE_EXCEPTIONS
113  if constexpr( ShouldThrow ) {
114  using namespace std::string_literals;
115  if( location.class_first and location.first ) {
116  static constexpr std::size_t max_len = 150;
117  std::size_t const len = [&]( ) -> std::size_t {
118  if( location.first == nullptr or location.class_first == nullptr ) {
119  if( location.class_first == nullptr or
120  location.class_last == nullptr ) {
121  return 0;
122  }
123  return std::min( static_cast<std::size_t>( std::distance(
124  location.class_first, location.class_last ) ),
125  max_len );
126  }
127  return std::min( static_cast<std::size_t>( std::distance(
128  location.class_first, location.first + 1 ) ),
129  max_len );
130  }( );
131  throw json_exception( reason,
132  std::string_view( location.class_first, len ) );
133  } else {
134  throw json_exception( reason );
135  }
136  } else {
137 #endif
138  (void)ShouldThrow;
139  (void)reason;
140  (void)location;
141  std::terminate( );
142 #ifdef DAW_USE_EXCEPTIONS
143  }
144 #endif
145  }
146 
147  template<bool ShouldThrow = use_daw_json_exceptions_v, typename ParseState>
148  [[maybe_unused, noreturn]] DAW_ATTRIB_NOINLINE static void
149  daw_json_error( json_details::missing_token reason,
150  ParseState const &location ) {
151 #ifdef DAW_USE_EXCEPTIONS
152  if constexpr( ShouldThrow ) {
153  using namespace std::string_literals;
154  if( location.first ) {
155  throw json_exception( reason, location.first );
156  }
157  if( location.class_first ) {
158  throw json_exception( reason, location.class_first );
159  }
160  throw json_exception( reason );
161  } else {
162 #endif
163  (void)ShouldThrow;
164  (void)reason;
165  (void)location;
166  std::terminate( );
167 #ifdef DAW_USE_EXCEPTIONS
168  }
169 #endif
170  }
171  } // namespace DAW_JSON_VER
172 } // namespace daw::json
173 
174 /***
175  * Ensure that Bool is true
176  * If false pass rest of args to daw_json_error
177  */
178 #define daw_json_assert( Bool, ... ) \
179  do { \
180  if( DAW_UNLIKELY( not( Bool ) ) ) { \
181  daw_json_error( __VA_ARGS__ ); \
182  } \
183  } while( false )
184 
185 /***
186  * Ensure that Bool is true when in Checked Input mode
187  * If false pass rest of args to daw_json_error
188  */
189 #define daw_json_assert_weak( Bool, ... ) \
190  do { \
191  if constexpr( not ParseState::is_unchecked_input ) { \
192  if( DAW_UNLIKELY( not( Bool ) ) ) { \
193  daw_json_error( __VA_ARGS__ ); \
194  } \
195  } \
196  } while( false )
constexpr bool use_daw_json_exceptions_v
Definition: daw_json_assert.h:32
DAW_ATTRIB_NOINLINE void daw_json_error(ErrorReason reason)
Definition: daw_json_assert.h:39
Definition: daw_from_json.h:22
#define DAW_JSON_VER
Definition: version.h:11