DAW JSON Link
Loading...
Searching...
No Matches
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
12
14
15#include <daw/daw_attributes.h>
16#include <daw/daw_cpp_feature_check.h>
17#include <daw/daw_likely.h>
18#include <daw/daw_not_null.h>
19
20#include <cstddef>
21#include <daw/stdinc/move_fwd_exch.h>
22#include <exception>
23#include <string_view>
24#include <utility>
25
26#if defined( DAW_JSON_SHOW_ERROR_BEFORE_TERMINATE )
27#include <iostream>
28#endif
29
30namespace daw::json {
31#if defined( DAW_USE_EXCEPTIONS )
32 inline constexpr bool use_daw_json_exceptions_v = true;
33#else
34 inline constexpr bool use_daw_json_exceptions_v = false;
35#endif
36
37 static thread_local void *daw_json_error_handler_data = nullptr;
38
39#if defined( DAW_USE_EXCEPTIONS )
40 [[noreturn, maybe_unused]] DAW_ATTRIB_NOINLINE inline void
41 default_error_handler_throwing( json_exception &&jex, void * ) {
42 throw std::move( jex );
43 }
44#endif
45
46 [[noreturn, maybe_unused]] DAW_ATTRIB_NOINLINE inline void
47 default_error_handler_terminating( json_exception &&jex, void * ) {
48#if defined( DAW_JSON_SHOW_ERROR_BEFORE_TERMINATE )
49 std::cerr << "Error: " << jex.reason( ) << '\n';
50#else
51 (void)jex;
52#endif
53 std::terminate( );
54 }
55
57 daw::not_null<void ( * )( json_exception &&, void * )>;
58
59#if defined( DAW_USE_EXCEPTIONS )
61 default_error_handler_throwing;
62#else
65#endif
66
67 inline namespace DAW_JSON_VER {
68 namespace json_details {
69#if defined( DAW_ATTRIB_ENABLE_IF )
70#if defined( DAW_HAS_CPP26_DELETED_REASON )
71 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
72 handle_error( bool b, json_exception &&jex )
73 DAW_ATTRIB_ENABLE_IF( __builtin_constant_p( b ) and b,
74 "daw_json_ensure check failed" ) =
75 delete( "daw_json_ensure check failed" );
76#endif
77 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
78 handle_error( bool b, json_exception &&jex )
79 DAW_ATTRIB_ENABLE_IF( __builtin_constant_p( b ) and not b,
80 "daw_json_ensure check failed" ) {
81 daw_json_error_handler.get( )( std::move( jex ),
83 DAW_UNREACHABLE( );
84 }
85
86 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
87 handle_error( bool b, json_exception &&jex )
88 DAW_ATTRIB_ENABLE_IF( not __builtin_constant_p( b ), " " ) {
89 daw_json_error_handler.get( )( std::move( jex ),
91 DAW_UNREACHABLE( );
92 }
93#else
94 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
95 handle_error( bool, json_exception &&jex ) {
96 daw_json_error_handler.get( )( std::move( jex ),
98 DAW_UNREACHABLE( );
99 }
100#endif
101 } // namespace json_details
102
103 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
104 daw_json_error( bool b, ErrorReason reason ) {
105 json_details::handle_error( b, json_exception( reason ) );
106 }
107
108 template<typename ParseState>
109 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
110 daw_json_error( bool b, ErrorReason reason, ParseState const &location ) {
111 if( location.first ) {
112 json_details::handle_error( b,
113 json_exception( reason, location.first ) );
114 }
115 if( location.class_first ) {
116 json_details::handle_error(
117 b, json_exception( reason, location.class_first ) );
118 }
119 json_details::handle_error( b, json_exception( reason ) );
120 }
121
122 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
123 daw_json_error( bool b, json_details::missing_member reason ) {
124 json_details::handle_error( b, json_exception( reason ) );
125 }
126
127 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
128 daw_json_error( bool b, json_details::missing_token reason ) {
129 json_details::handle_error( b, json_exception( reason ) );
130 }
131
132 template<typename ParseState>
133 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
134 daw_json_error( bool b, json_details::missing_member reason,
135 ParseState const &location ) {
136 if( location.class_first and location.first ) {
137 static constexpr std::size_t max_len = 150;
138 std::size_t const len = [&]( ) -> std::size_t {
139 if( location.first == nullptr or location.class_first == nullptr ) {
140 if( location.class_first == nullptr or
141 location.class_last == nullptr ) {
142 return 0;
143 }
144 auto const dist = static_cast<std::size_t>( location.class_last -
145 location.class_first );
146 if( dist < max_len ) {
147 return dist;
148 }
149 return max_len;
150 }
151 auto const dist = static_cast<std::size_t>( location.class_first -
152 location.first + 1 );
153 if( dist < max_len ) {
154 return dist;
155 }
156 return max_len;
157 }( );
158 json_details::handle_error(
159 b,
160 json_exception( reason,
161 std::string_view( location.class_first, len ) ) );
162 }
163 json_details::handle_error( b, json_exception( reason ) );
164 }
165
166 template<typename ParseState>
167 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
168 daw_json_error( bool b, json_details::missing_token reason,
169 ParseState const &location ) {
170 if( location.first ) {
171 json_details::handle_error( b,
172 json_exception( reason, location.first ) );
173 }
174 if( location.class_first ) {
175 json_details::handle_error(
176 b, json_exception( reason, location.class_first ) );
177 }
178 json_details::handle_error( b, json_exception( reason ) );
179 }
180 } // namespace DAW_JSON_VER
181} // namespace daw::json
182
185#define daw_json_ensure( Bool, ... ) \
186 do { \
187 if( DAW_UNLIKELY( not( Bool ) ) ) { \
188 daw_json_error( not( Bool ), __VA_ARGS__ ); \
189 } \
190 } while( false )
191
194#if defined( DAW_HAS_IF_CONSTEVAL )
195#define daw_json_assert_weak( Bool, ... ) \
196 do { \
197 if consteval { \
198 if( DAW_UNLIKELY( not( Bool ) ) ) { \
199 daw_json_error( not( Bool ), __VA_ARGS__ ); \
200 } \
201 } else { \
202 if constexpr( not ParseState::is_unchecked_input ) { \
203 if( DAW_UNLIKELY( not( Bool ) ) ) { \
204 daw_json_error( not( Bool ), __VA_ARGS__ ); \
205 } \
206 } \
207 } \
208 } while( false )
209#elif defined( DAW_HAS_IS_CONSTANT_EVALUATED )
210#define daw_json_assert_weak( Bool, ... ) \
211 do { \
212 if( DAW_IS_CONSTANT_EVALUATED( ) ) { \
213 if( DAW_UNLIKELY( not( Bool ) ) ) { \
214 daw_json_error( not( Bool ), __VA_ARGS__ ); \
215 } \
216 } else { \
217 if constexpr( not ParseState::is_unchecked_input ) { \
218 if( DAW_UNLIKELY( not( Bool ) ) ) { \
219 daw_json_error( not( Bool ), __VA_ARGS__ ); \
220 } \
221 } \
222 } \
223 } while( false )
224#else
225#define daw_json_assert_weak( Bool, ... ) \
226 do { \
227 if constexpr( not ParseState::is_unchecked_input ) { \
228 if( DAW_UNLIKELY( not( Bool ) ) ) { \
229 daw_json_error( not( Bool ), __VA_ARGS__ ); \
230 } \
231 } \
232 } while( false )
233#endif
DAW_ATTRIB_NOINLINE void daw_json_error(bool b, ErrorReason reason)
Customization point traits.
daw::not_null< void(*)(json_exception &&, void *)> daw_json_error_handler_t
constexpr bool use_daw_json_exceptions_v
DAW_ATTRIB_NOINLINE void default_error_handler_terminating(json_exception &&jex, void *)
static thread_local daw_json_error_handler_t daw_json_error_handler
static thread_local void * daw_json_error_handler_data
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20