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 
13 #include <daw/daw_hide.h>
14 #include <daw/daw_string_view.h>
15 
16 #include <algorithm>
17 #include <ciso646>
18 #include <cstdio>
19 #include <cstdlib>
20 #include <memory>
21 #include <numeric>
22 #include <string>
23 #include <string_view>
24 
25 #if defined( __GNUC__ ) or defined( __clang__ )
26 #define DAW_JSON_LIKELY( Bool ) ( __builtin_expect( !!( Bool ), 1 ) )
27 #define DAW_JSON_UNLIKELY( Bool ) ( __builtin_expect( !!( Bool ), 0 ) )
28 #define DAW_JSON_NOINLINE __attribute__( ( noinline ) )
29 #elif defined( _MSC_VER )
30 #define DAW_JSON_LIKELY( Bool ) !!( Bool )
31 #define DAW_JSON_UNLIKELY( Bool ) !!( Bool )
32 #define DAW_JSON_NOINLINE __declspec( noinline )
33 #else
34 #define DAW_JSON_LIKELY( Bool ) !!( Bool )
35 #define DAW_JSON_UNLIKELY( Bool ) !!( Bool )
36 #define DAW_JSON_NOINLINE __attribute__( ( noinline ) )
37 #endif
38 
39 #if not( defined( __cpp_exceptions ) or defined( __EXCEPTIONS ) or \
40  defined( _CPPUNWIND ) ) or \
41  defined( DAW_DONT_USE_JSON_EXCEPTIONS )
42 #ifdef DAW_USE_JSON_EXCEPTIONS
43 #undef DAW_USE_JSON_EXCEPTIONS
44 #endif
45 #else
46 #ifndef DAW_USE_JSON_EXCEPTIONS
47 #define DAW_USE_JSON_EXCEPTIONS
48 #endif
49 #endif
50 
51 #ifdef DAW_USE_JSON_EXCEPTIONS
52 inline constexpr bool use_daw_json_exceptions_v = true;
53 #else
54 inline constexpr bool use_daw_json_exceptions_v = false;
55 #endif
56 
57 template<bool ShouldThrow = use_daw_json_exceptions_v>
58 [[maybe_unused, noreturn]] DAW_JSON_NOINLINE static void
59 daw_json_error( daw::json::ErrorReason reason ) {
60 #ifdef DAW_USE_JSON_EXCEPTIONS
61  if constexpr( ShouldThrow ) {
62  throw daw::json::json_exception( reason );
63  } else {
64 #endif
65  (void)ShouldThrow;
66  (void)reason;
67  std::terminate( );
68 #ifdef DAW_USE_JSON_EXCEPTIONS
69  }
70 #endif
71 }
72 
73 template<bool ShouldThrow = use_daw_json_exceptions_v, typename Range>
74 [[maybe_unused, noreturn]] DAW_JSON_NOINLINE static void
75 daw_json_error( daw::json::ErrorReason reason, Range const &location ) {
76 #ifdef DAW_USE_JSON_EXCEPTIONS
77  if constexpr( ShouldThrow ) {
78  if( location.first ) {
79  throw daw::json::json_exception( reason, location.first );
80  }
81  if( location.class_first ) {
82  throw daw::json::json_exception( reason, location.class_first );
83  }
84  throw daw::json::json_exception( reason );
85  } else {
86 #endif
87  (void)ShouldThrow;
88  (void)reason;
89  (void)location;
90  std::terminate( );
91 #ifdef DAW_USE_JSON_EXCEPTIONS
92  }
93 #endif
94 }
95 
96 template<bool ShouldThrow = use_daw_json_exceptions_v>
97 [[maybe_unused, noreturn]] DAW_JSON_NOINLINE static void
98 daw_json_error( daw::json::json_details::missing_member reason ) {
99 #ifdef DAW_USE_JSON_EXCEPTIONS
100  if constexpr( ShouldThrow ) {
101  throw daw::json::json_exception( reason );
102  } else {
103 #endif
104  (void)ShouldThrow;
105  (void)reason;
106  std::terminate( );
107 #ifdef DAW_USE_JSON_EXCEPTIONS
108  }
109 #endif
110 }
111 
112 template<bool ShouldThrow = use_daw_json_exceptions_v>
113 [[maybe_unused, noreturn]] DAW_JSON_NOINLINE static void
114 daw_json_error( daw::json::json_details::missing_token reason ) {
115 #ifdef DAW_USE_JSON_EXCEPTIONS
116  if constexpr( ShouldThrow ) {
117  throw daw::json::json_exception( reason );
118  } else {
119 #endif
120  (void)ShouldThrow;
121  (void)reason;
122  std::terminate( );
123 #ifdef DAW_USE_JSON_EXCEPTIONS
124  }
125 #endif
126 }
127 
128 template<bool ShouldThrow = use_daw_json_exceptions_v, typename Range>
129 [[maybe_unused, noreturn]] DAW_JSON_NOINLINE static void
130 daw_json_error( daw::json::json_details::missing_member reason,
131  Range const &location ) {
132 #ifdef DAW_USE_JSON_EXCEPTIONS
133  if constexpr( ShouldThrow ) {
134  using namespace std::string_literals;
135  if( location.class_first and location.first ) {
136  static constexpr std::size_t max_len = 150;
137  std::size_t const len = [&]( ) -> std::size_t {
138  if( location.first == nullptr or location.class_first == nullptr ) {
139  if( location.class_first == nullptr or
140  location.class_last == nullptr ) {
141  return 0;
142  }
143  return std::min( static_cast<std::size_t>( std::distance(
144  location.class_first, location.class_last ) ),
145  max_len );
146  }
147  return std::min( static_cast<std::size_t>( std::distance(
148  location.class_first, location.first + 1 ) ),
149  max_len );
150  }( );
151  throw daw::json::json_exception(
152  reason, std::string_view( location.class_first, len ) );
153  } else {
154  throw daw::json::json_exception( reason );
155  }
156  } else {
157 #endif
158  (void)ShouldThrow;
159  (void)reason;
160  (void)location;
161  std::terminate( );
162 #ifdef DAW_USE_JSON_EXCEPTIONS
163  }
164 #endif
165 }
166 
167 template<bool ShouldThrow = use_daw_json_exceptions_v, typename Range>
168 [[maybe_unused, noreturn]] DAW_JSON_NOINLINE static void
169 daw_json_error( daw::json::json_details::missing_token reason,
170  Range const &location ) {
171 #ifdef DAW_USE_JSON_EXCEPTIONS
172  if constexpr( ShouldThrow ) {
173  using namespace std::string_literals;
174  if( location.first ) {
175  throw daw::json::json_exception( reason, location.first );
176  }
177  if( location.class_first ) {
178  throw daw::json::json_exception( reason, location.class_first );
179  }
180  throw daw::json::json_exception( reason );
181  } else {
182 #endif
183  (void)ShouldThrow;
184  (void)reason;
185  (void)location;
186  std::terminate( );
187 #ifdef DAW_USE_JSON_EXCEPTIONS
188  }
189 #endif
190 }
191 
192 /***
193  * Ensure that Bool is true
194  * If false pass rest of args to daw_json_error
195  */
196 #define daw_json_assert( Bool, ... ) \
197  if( DAW_JSON_UNLIKELY( not( Bool ) ) ) { \
198  daw_json_error( __VA_ARGS__ ); \
199  } \
200  while( false )
201 
202 /***
203  * Ensure that Bool is true when in Checked Input mode
204  * If false pass rest of args to daw_json_error
205  */
206 #define daw_json_assert_weak( Bool, ... ) \
207  if constexpr( not Range::is_unchecked_input ) { \
208  if( DAW_JSON_UNLIKELY( not( Bool ) ) ) { \
209  daw_json_error( __VA_ARGS__ ); \
210  } \
211  } \
212  while( false )
use_daw_json_exceptions_v
constexpr bool use_daw_json_exceptions_v
Definition: daw_json_assert.h:52
daw_json_error
static DAW_JSON_NOINLINE void daw_json_error(daw::json::ErrorReason reason)
Definition: daw_json_assert.h:59
DAW_JSON_NOINLINE
#define DAW_JSON_NOINLINE
Definition: daw_json_assert.h:36