DAW JSON Link
Loading...
Searching...
No Matches
daw_json_string_util.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
16
17#include <daw/daw_is_constant_evaluated.h>
18#include <daw/daw_likely.h>
19#include <daw/daw_traits.h>
20
21#include <cstring>
22
23namespace daw::json {
24 inline namespace DAW_JSON_VER {
25 namespace json_details {
26 template<char c, typename ExecTag>
27 DAW_ATTRIB_FLATINLINE static constexpr daw::not_null<char const *>
28 memchr_unchecked_long( daw::not_null<char const *> first,
29 daw::not_null<char const *> last ) {
30#if not defined( NDEBUG )
31 daw_json_ensure( first <= last, ErrorReason::Unknown );
32#endif
33#if DAW_HAS_BUILTIN( __builtin_char_memchr )
34 return __builtin_char_memchr(
35 first, '"', static_cast<std::size_t>( last - first ) );
36#else
37 if( not json_details::use_constexpr_exec_mode<ExecTag>( ) ) {
38 return static_cast<char const *>(
39 std::memchr( static_cast<void const *>( first ),
40 '"',
41 static_cast<std::size_t>( last - first ) ) );
42 }
43 (void)last;
44 while( *first != c ) {
45 ++first;
46 }
47 return first;
48#endif
49 }
50
51 template<char c>
52 DAW_ATTRIB_FLATINLINE static constexpr daw::not_null<char const *>
53 memchr_unchecked_short( daw::not_null<char const *> first ) {
54 while( *first != c ) {
55 ++first;
56 }
57 return first;
58 }
59
68 template<char c, typename ExecTag, bool expect_long>
69 DAW_ATTRIB_FLATINLINE static constexpr daw::not_null<char const *>
70 memchr_unchecked( daw::not_null<char const *> first,
71 daw::not_null<char const *> last ) {
72#if not defined( NDEBUG )
73 daw_json_ensure( first <= last, ErrorReason::Unknown );
74#endif
75 if constexpr( expect_long ) {
76 return memchr_unchecked_long<c, ExecTag>( first, last );
77 } else {
78 return memchr_unchecked_short<c>( first );
79 }
80 }
81
82 template<char c, typename ExecTag>
83 DAW_ATTRIB_FLATINLINE static constexpr daw::not_null<char const *>
84 memchr_checked_long( daw::not_null<char const *> first,
85 daw::not_null<char const *> last ) {
86#if not defined( NDEBUG )
87 daw_json_ensure( first <= last, ErrorReason::Unknown );
88#endif
89#if DAW_HAS_BUILTIN( __builtin_char_memchr )
90 return __builtin_char_memchr(
91 first, '"', static_cast<std::size_t>( last - first ) );
92#elif DAW_HAS_BUILTIN( __builtin_memchr )
93 return static_cast<char const *>( __builtin_memchr(
94 first, '"', static_cast<std::size_t>( last - first ) ) );
95#else
96 if( not json_details::use_constexpr_exec_mode<ExecTag>( ) ) {
97 return static_cast<char const *>(
98 std::memchr( static_cast<void const *>( first ),
99 '"',
100 static_cast<std::size_t>( last - first ) ) );
101 }
102 while( DAW_LIKELY( first < last ) and *first != c ) {
103 ++first;
104 }
105 return first;
106#endif
107 }
108
109 template<char c>
110 DAW_ATTRIB_INLINE static constexpr daw::not_null<char const *>
111 memchr_checked_short( daw::not_null<char const *> first,
112 daw::not_null<char const *> const last ) {
113#if not defined( NDEBUG )
114 daw_json_ensure( first <= last, ErrorReason::Unknown );
115#endif
116 while( DAW_LIKELY( first < last ) and *first != c ) {
117 ++first;
118 }
119 return first;
120 }
121
130 template<char c, typename ExecTag, bool expect_long>
131 DAW_ATTRIB_FLATINLINE static constexpr daw::not_null<char const *>
132 memchr_checked( daw::not_null<char const *> first,
133 daw::not_null<char const *> last ) {
134 if constexpr( expect_long ) {
135 return memchr_checked_long<c, ExecTag>( first, last );
136 } else {
137 return memchr_checked_short<c>( first, last );
138 }
139 }
140
141 template<typename ExecTag, char... chars>
142 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
143 mempbrk_unchecked_long( daw::not_null<char const *> first ) {
144#if DAW_HAS_BUILTIN( __builtin_strpbrk )
145 constexpr char const needles[]{ chars..., '\0' };
146 daw::not_null<char const *> res = __builtin_strpbrk( first, needles );
147 return res;
148#else
149 if( not json_details::use_constexpr_exec_mode<ExecTag>( ) ) {
150 constexpr char const needles[]{ chars..., '\0' };
151 char const *res = std::strpbrk( first, needles );
152#if not defined( NDEBUG )
153 daw_json_ensure( res != nullptr, ErrorReason::UnexpectedEndOfData );
154#endif
155 return res;
156 }
157 while( not parse_policy_details::in<chars...>( *first ) ) {
158 ++first;
159 }
160 return first;
161#endif
162 }
163
164 template<char... chars>
165 DAW_ATTRIB_INLINE constexpr daw::not_null<char const *>
166 mempbrk_unchecked_short( daw::not_null<char const *> first ) {
167 while( not parse_policy_details::in<chars...>( *first ) ) {
168 ++first;
169 }
170 return first;
171 }
172
173 template<typename ExecTag, bool expect_long, char... chars>
174 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
175 mempbrk_unchecked( daw::not_null<char const *> first ) {
176 if constexpr( expect_long ) {
177 return mempbrk_unchecked_long<ExecTag, chars...>( first );
178 } else {
179 return mempbrk_unchecked_short<chars...>( first );
180 }
181 }
182
183 template<typename ExecTag, char... chars>
184 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
185 mempbrk_checked_long( daw::not_null<char const *> first,
186 daw::not_null<char const *> last ) {
187#if not defined( NDEBUG )
188 daw_json_ensure( first <= last, ErrorReason::Unknown );
189#endif
190 if( not json_details::use_constexpr_exec_mode<ExecTag>( ) ) {
191 return mem_move_to_next_of<false, chars...>(
192 ExecTag{ }, first, last );
193 }
194 while( DAW_LIKELY( first < last ) and
195 not parse_policy_details::in<chars...>( *first ) ) {
196 ++first;
197 }
198 return first;
199 }
200
201 template<char... chars>
202 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
203 mempbrk_checked_short( daw::not_null<char const *> first,
204 daw::not_null<char const *> last ) {
205#if not defined( NDEBUG )
206 daw_json_ensure( first <= last, ErrorReason::Unknown );
207#endif
208 while( DAW_LIKELY( first < last ) and
209 not parse_policy_details::in<chars...>( *first ) ) {
210 ++first;
211 }
212 return first;
213 }
214
215 template<typename ExecTag, bool expect_long, char... chars>
216 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
217 mempbrk_checked( daw::not_null<char const *> first,
218 daw::not_null<char const *> last ) {
219 if constexpr( expect_long ) {
220 return mempbrk_checked_long<ExecTag, chars...>( first, last );
221 } else {
222 return mempbrk_checked_short<chars...>( first, last );
223 }
224 }
225
226 template<bool is_unchecked_input, typename ExecTag, bool expect_long,
227 char... chars>
228 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
229 mempbrk( daw::not_null<char const *> first,
230 daw::not_null<char const *> last ) {
231
232 if constexpr( is_unchecked_input ) {
233 return mempbrk_unchecked<ExecTag, expect_long, chars...>( first );
234 } else {
235 return mempbrk_checked<ExecTag, expect_long, chars...>( first, last );
236 }
237 }
238 } // namespace json_details
239 } // namespace DAW_JSON_VER
240} // namespace daw::json
#define daw_json_ensure(Bool,...)
Ensure that Bool is true. If false pass rest of args to daw_json_error.
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition version.h:20