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, ExecTag, chars...>( first, last );
192 }
193 while( DAW_LIKELY( first < last ) and
194 not parse_policy_details::in<chars...>( *first ) ) {
195 ++first;
196 }
197 return first;
198 }
199
200 template<char... chars>
201 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
202 mempbrk_checked_short( daw::not_null<char const *> first,
203 daw::not_null<char const *> last ) {
204#if not defined( NDEBUG )
205 daw_json_ensure( first <= last, ErrorReason::Unknown );
206#endif
207 while( DAW_LIKELY( first < last ) and
208 not parse_policy_details::in<chars...>( *first ) ) {
209 ++first;
210 }
211 return first;
212 }
213
214 template<typename ExecTag, bool expect_long, char... chars>
215 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
216 mempbrk_checked( daw::not_null<char const *> first,
217 daw::not_null<char const *> last ) {
218 if constexpr( expect_long ) {
219 return mempbrk_checked_long<ExecTag, chars...>( first, last );
220 } else {
221 return mempbrk_checked_short<chars...>( first, last );
222 }
223 }
224
225 template<bool is_unchecked_input, typename ExecTag, bool expect_long,
226 char... chars>
227 DAW_ATTRIB_FLATINLINE constexpr daw::not_null<char const *>
228 mempbrk( daw::not_null<char const *> first,
229 daw::not_null<char const *> last ) {
230
231 if constexpr( is_unchecked_input ) {
232 return mempbrk_unchecked<ExecTag, expect_long, chars...>( first );
233 } else {
234 return mempbrk_checked<ExecTag, expect_long, chars...>( first, last );
235 }
236 }
237 } // namespace json_details
238 } // namespace DAW_JSON_VER
239} // 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