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
11#include "version.h"
12
14
15#include <daw/daw_attributes.h>
16#include <daw/daw_likely.h>
17#include <daw/daw_not_null.h>
18
19#include <cstddef>
20#include <daw/stdinc/move_fwd_exch.h>
21#include <exception>
22#include <string_view>
23
24#if defined( DAW_JSON_SHOW_ERROR_BEFORE_TERMINATE )
25#include <iostream>
26#endif
27
28namespace daw::json {
29#if defined( 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 static thread_local void *daw_json_error_handler_data = nullptr;
36
37#if defined( DAW_USE_EXCEPTIONS )
38 [[noreturn, maybe_unused]] DAW_ATTRIB_NOINLINE inline void
39 default_error_handler_throwing( json_exception &&jex, void * ) {
40 throw std::move( jex );
41 }
42#endif
43
44 [[noreturn, maybe_unused]] DAW_ATTRIB_NOINLINE inline void
45 default_error_handler_terminating( json_exception &&jex, void * ) {
46#if defined( DAW_JSON_SHOW_ERROR_BEFORE_TERMINATE )
47 std::cerr << "Error: " << jex.reason( ) << '\n';
48#else
49 (void)jex;
50#endif
51 std::terminate( );
52 }
53
55 daw::not_null<void ( * )( json_exception &&, void * )>;
56
57#if defined( DAW_USE_EXCEPTIONS )
59 default_error_handler_throwing;
60#else
63#endif
64
65 inline namespace DAW_JSON_VER {
66 namespace json_details {
67 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
68 handle_error( json_exception &&jex ) {
69 daw_json_error_handler.get( )( std::move( jex ),
71 DAW_UNREACHABLE( );
72 }
73 } // namespace json_details
74
75 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
76 daw_json_error( ErrorReason reason ) {
77 json_details::handle_error( json_exception( reason ) );
78 }
79
80 template<typename ParseState>
81 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
82 daw_json_error( ErrorReason reason, ParseState const &location ) {
83 if( location.first ) {
84 json_details::handle_error( json_exception( reason, location.first ) );
85 }
86 if( location.class_first ) {
87 json_details::handle_error(
88 json_exception( reason, location.class_first ) );
89 }
90 json_details::handle_error( json_exception( reason ) );
91 }
92
93 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
94 daw_json_error( json_details::missing_member reason ) {
95 json_details::handle_error( json_exception( reason ) );
96 }
97
98 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
99 daw_json_error( json_details::missing_token reason ) {
100 json_details::handle_error( json_exception( reason ) );
101 }
102
103 template<typename ParseState>
104 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
105 daw_json_error( json_details::missing_member reason,
106 ParseState const &location ) {
107 if( location.class_first and location.first ) {
108 static constexpr std::size_t max_len = 150;
109 std::size_t const len = [&]( ) -> std::size_t {
110 if( location.first == nullptr or location.class_first == nullptr ) {
111 if( location.class_first == nullptr or
112 location.class_last == nullptr ) {
113 return 0;
114 }
115 auto const dist = static_cast<std::size_t>( location.class_last -
116 location.class_first );
117 if( dist < max_len ) {
118 return dist;
119 }
120 return max_len;
121 }
122 auto const dist = static_cast<std::size_t>( location.class_first -
123 location.first + 1 );
124 if( dist < max_len ) {
125 return dist;
126 }
127 return max_len;
128 }( );
129 json_details::handle_error( json_exception(
130 reason, std::string_view( location.class_first, len ) ) );
131 }
132 json_details::handle_error( json_exception( reason ) );
133 }
134
135 template<typename ParseState>
136 [[noreturn]] DAW_ATTRIB_NOINLINE inline void
137 daw_json_error( json_details::missing_token reason,
138 ParseState const &location ) {
139 if( location.first ) {
140 json_details::handle_error( json_exception( reason, location.first ) );
141 }
142 if( location.class_first ) {
143 json_details::handle_error(
144 json_exception( reason, location.class_first ) );
145 }
146 json_details::handle_error( json_exception( reason ) );
147 }
148 } // namespace DAW_JSON_VER
149} // namespace daw::json
150
153#define daw_json_ensure( Bool, ... ) \
154 do { \
155 if( DAW_UNLIKELY( not( Bool ) ) ) { \
156 daw_json_error( __VA_ARGS__ ); \
157 } \
158 } while( false )
159
162#define daw_json_assert_weak( Bool, ... ) \
163 do { \
164 if constexpr( not ParseState::is_unchecked_input ) { \
165 if( DAW_UNLIKELY( not( Bool ) ) ) { \
166 daw_json_error( __VA_ARGS__ ); \
167 } \
168 } \
169 } while( false )
DAW_ATTRIB_NOINLINE void daw_json_error(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