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 "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 
28 namespace 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:25