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