DAW JSON Link
Loading...
Searching...
No Matches
daw_json_parse_policy_policy_details.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
13#include "daw_json_assert.h"
14
15#include <daw/daw_attributes.h>
16#include <type_traits>
17
18namespace daw::json {
19 inline namespace DAW_JSON_VER {
20 namespace json_details {
21 // Translate a read-only scanner result back into the input range's
22 // pointer type. Non-null positions must belong to the same buffer.
23 template<typename Char>
24 [[nodiscard]] constexpr Char *input_pointer( Char *origin, char const *position ) {
25 if constexpr( std::is_const_v<Char> ) {
26 return position;
27 } else {
28 return position ? origin + ( position - origin ) : nullptr;
29 }
30 }
31
32 enum class SkipBracketedType { Array, Class };
33 } // namespace json_details
34
35 namespace parse_policy_details {
36 template<char... keys>
37 [[nodiscard]] DAW_ATTRIB_FLATINLINE static constexpr bool in( char c ) {
38 auto const eq = [c]( char k ) {
39 return c == k;
40 };
41 return nsc_or( eq( keys )... );
42 }
43
44 [[nodiscard]] DAW_ATTRIB_FLATINLINE static constexpr bool
45 at_end_of_item( char c ) {
46 return static_cast<bool>( static_cast<unsigned>( c == ',' ) |
47 static_cast<unsigned>( c == '}' ) |
48 static_cast<unsigned>( c == ']' ) |
49 static_cast<unsigned>( c == ':' ) |
50 static_cast<unsigned>( c <= 0x20 ) );
51 }
52
53 [[nodiscard]] DAW_ATTRIB_FLATINLINE static inline constexpr bool
54 is_number( char c ) {
55 return static_cast<unsigned>( static_cast<unsigned char>( c ) -
56 static_cast<unsigned char>( '0' ) ) < 10U;
57 }
58
59 template<typename ParseState>
60 DAW_ATTRIB_FLATINLINE static inline constexpr void
61 validate_unsigned_first( ParseState const &parse_state ) {
62 if constexpr( not ParseState::is_unchecked_input ) {
63 switch( parse_state.front( ) ) {
64 case '1':
65 case '2':
66 case '3':
67 case '4':
68 case '5':
69 case '6':
70 case '7':
71 case '8':
72 case '9':
73 return;
74 case '0':
75 if( parse_state.size( ) > 1 ) {
76 daw_json_ensure( is_number( *( parse_state.first + 1 ) ),
77 ErrorReason::InvalidNumberStart,
78 parse_state );
79 }
80 return;
81 default:
82 daw_json_error( true, ErrorReason::InvalidNumberStart, parse_state );
83 }
84 }
85 }
86
87 /***
88 * Validate that this is a valid number start(e.g. not leading zero when
89 * not zero)
90 * @return sign value
91 */
92 template<typename ParseState>
93 [[nodiscard]] DAW_ATTRIB_FLATINLINE static constexpr int
94 validate_signed_first( ParseState &parse_state ) {
95 daw_json_assert_weak( parse_state.has_more( ),
96 ErrorReason::UnexpectedEndOfData,
97 parse_state );
98 auto const c = parse_state.front( );
99 if( c == '-' ) {
100 parse_state.remove_prefix( );
101 return -1;
102 }
103 if constexpr( ParseState::is_unchecked_input ) {
104 if( DAW_LIKELY( c >= '0' ) and DAW_LIKELY( c <= '9' ) ) {
105 return 1;
106 }
107 } else {
108 if( c >= '1' and c <= '9' ) {
109 return 1;
110 }
111 if( DAW_LIKELY( c == '0' ) ) {
112 if( parse_state.size( ) > 1 ) {
113 auto const next_dig = static_cast<unsigned>(
114 static_cast<unsigned char>( *( parse_state.first + 1 ) ) );
115 auto const tst = next_dig - static_cast<unsigned char>( '0' );
116 // Cannot be a digit
118 tst >= 10U, ErrorReason::InvalidNumberStart, parse_state );
119 }
120 return 1;
121 }
122 }
123 daw_json_error( true, ErrorReason::InvalidNumberStart, parse_state );
124 }
125
126 [[nodiscard]] DAW_ATTRIB_FLATINLINE static constexpr bool
127 is_number_start( char c ) {
128 switch( c ) {
129 case '0': // TODO: CONFORMANCE We are accepting starting with zero for
130 // now
131 case '1':
132 case '2':
133 case '3':
134 case '4':
135 case '5':
136 case '6':
137 case '7':
138 case '8':
139 case '9':
140 case '-':
141 return true;
142 }
143 return false;
144 }
145 } // namespace parse_policy_details
146 } // namespace DAW_JSON_VER
147} // namespace daw::json
#define daw_json_assert_weak(Bool,...)
Assert that Bool is true when in Checked Input mode If false pass rest of args to daw_json_error.
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
DAW_ATTRIB_NOINLINE void daw_json_error(bool b, ErrorReason reason)
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20