DAW JSON Link
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
11#include "daw_json_exec_modes.h"
14
15#include <daw/daw_is_constant_evaluated.h>
16#include <daw/daw_likely.h>
17#include <daw/daw_traits.h>
18
19#include <cstring>
20
21#if defined( __GNUC__ )
22#define DAW_CAN_CONSTANT_EVAL( ... ) \
23 ( __builtin_constant_p( __VA_ARGS__ ) == 1 )
24#else
25#define DAW_CAN_CONSTANT_EVAL( ... ) true
26#endif
27
28namespace daw::json {
29 inline namespace DAW_JSON_VER {
30 namespace json_details {
40 template<char c, typename ExecTag, bool expect_long, typename CharT>
41 DAW_ATTRIB_FLATINLINE inline constexpr CharT *
42 memchr_unchecked( CharT *first, CharT *last ) {
43#if DAW_HAS_BUILTIN( __builtin_char_memchr )
44 if constexpr( expect_long ) {
45 return __builtin_char_memchr(
46 first, '"', static_cast<std::size_t>( last - first ) );
47 } else
48#else
49#if defined( DAW_IS_CONSTANT_EVALUATED )
50 bool is_cxeval =
51 DAW_IS_CONSTANT_EVALUATED( ) | DAW_CAN_CONSTANT_EVAL( first );
52#else
53 bool is_cxeval = DAW_CAN_CONSTANT_EVAL( first );
54#endif
55 if constexpr( expect_long ) {
56 if( ( not is_cxeval ) |
57 daw::traits::not_same_v<ExecTag, constexpr_exec_tag> ) {
58 return static_cast<CharT *>(
59 std::memchr( static_cast<void const *>( first ), '"',
60 static_cast<std::size_t>( last - first ) ) );
61 }
62 (void)last;
63 while( *first != c ) {
64 ++first;
65 }
66 return first;
67 } else
68#endif
69 {
70 (void)last;
71 while( *first != c ) {
72 ++first;
73 }
74 return first;
75 }
76 }
77
87 template<char c, typename ExecTag, bool expect_long, typename CharT>
88 DAW_ATTRIB_FLATINLINE inline constexpr CharT *
89 memchr_checked( CharT *first, CharT *last ) {
90#if DAW_HAS_BUILTIN( __builtin_char_memchr )
91 if constexpr( expect_long ) {
92 return __builtin_char_memchr(
93 first, '"', static_cast<std::size_t>( last - first ) );
94 } else
95#else
96#if defined( DAW_IS_CONSTANT_EVALUATED )
97 bool is_cxeval =
98 DAW_IS_CONSTANT_EVALUATED( ) | DAW_CAN_CONSTANT_EVAL( first );
99#else
100 bool is_cxeval = DAW_CAN_CONSTANT_EVAL( first );
101#endif
102 if constexpr( expect_long ) {
103 if( ( not is_cxeval ) |
104 daw::traits::not_same_v<ExecTag, constexpr_exec_tag> ) {
105 return static_cast<CharT *>(
106 std::memchr( static_cast<void const *>( first ), '"',
107 static_cast<std::size_t>( last - first ) ) );
108 }
109 while( DAW_LIKELY( first < last ) and *first != c ) {
110 ++first;
111 }
112 return first;
113 } else
114#endif
115 {
116 while( DAW_LIKELY( first < last ) and *first != c ) {
117 ++first;
118 }
119 return first;
120 }
121 }
122
123 template<typename ExecTag, bool expect_long, char... chars,
124 typename CharT>
125 DAW_ATTRIB_FLATINLINE inline constexpr CharT *
126 mempbrk_unchecked( CharT *first, CharT * /*last*/ ) {
127#if DAW_HAS_BUILTIN( __builtin_strpbrk )
128 if constexpr( expect_long ) {
129 constexpr char const needles[]{ chars..., '\0' };
130 CharT *res = __builtin_strpbrk( first, needles );
131#if not defined( NDEBUG )
132 daw_json_assert( res != nullptr, ErrorReason::UnexpectedEndOfData );
133#endif
134 return res;
135 } else
136#else
137#if defined( DAW_IS_CONSTANT_EVALUATED )
138 bool is_cxeval =
139 DAW_IS_CONSTANT_EVALUATED( ) | DAW_CAN_CONSTANT_EVAL( first );
140#else
141 bool is_cxeval = DAW_CAN_CONSTANT_EVAL( first );
142#endif
143 if constexpr( expect_long ) {
144 if( ( not is_cxeval ) |
145 daw::traits::not_same_v<ExecTag, constexpr_exec_tag> ) {
146 constexpr char const needles[]{ chars..., '\0' };
147 CharT *res = std::strpbrk( first, needles );
148#if not defined( NDEBUG )
149 daw_json_assert( res != nullptr, ErrorReason::UnexpectedEndOfData );
150#endif
151 return res;
152 }
153 while( not parse_policy_details::in<chars...>( *first ) ) {
154 ++first;
155 }
156 return first;
157 } else
158#endif
159 {
160 while( not parse_policy_details::in<chars...>( *first ) ) {
161 ++first;
162 }
163 return first;
164 }
165 }
166
167 template<typename ExecTag, bool expect_long, char... chars,
168 typename CharT>
169 DAW_ATTRIB_FLATINLINE inline constexpr CharT *
170 mempbrk_checked( CharT *first, CharT *last ) {
171 if constexpr( expect_long ) {
172#if defined( DAW_IS_CONSTANT_EVALUATED )
173 bool is_cxeval =
174 DAW_IS_CONSTANT_EVALUATED( ) | DAW_CAN_CONSTANT_EVAL( first );
175#else
176 bool is_cxeval = DAW_CAN_CONSTANT_EVAL( first );
177#endif
178 if( ( not is_cxeval ) |
179 daw::traits::not_same_v<ExecTag, constexpr_exec_tag> ) {
180
181 return mem_move_to_next_of<false, chars...>( first, last );
182 }
183 while( DAW_LIKELY( first < last ) and
184 not parse_policy_details::in<chars...>( *first ) ) {
185 ++first;
186 }
187 return first;
188 } else {
189 while( DAW_LIKELY( first < last ) and
190 not parse_policy_details::in<chars...>( *first ) ) {
191 ++first;
192 }
193 return first;
194 }
195 }
196
197 template<bool is_unchecked_input, typename ExecTag, bool expect_long,
198 char... chars, typename CharT>
199 DAW_ATTRIB_FLATINLINE inline constexpr CharT *mempbrk( CharT *first,
200 CharT *last ) {
201
202 if constexpr( is_unchecked_input ) {
203 return mempbrk_unchecked<ExecTag, expect_long, chars...>( first,
204 last );
205 } else {
206 return mempbrk_unchecked<ExecTag, expect_long, chars...>( first,
207 last );
208 }
209 }
210 } // namespace json_details
211 } // namespace DAW_JSON_VER
212} // namespace daw::json
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:179
#define DAW_CAN_CONSTANT_EVAL(...)
Definition: daw_json_string_util.h:25
DAW_ATTRIB_INLINE CharT * mem_move_to_next_of(runtime_exec_tag, CharT *first, CharT *last)
Definition: daw_not_const_ex_functions.h:353
constexpr DAW_ATTRIB_FLATINLINE CharT * memchr_checked(CharT *first, CharT *last)
Search for a character in a string.
Definition: daw_json_string_util.h:89
constexpr DAW_ATTRIB_FLATINLINE CharT * mempbrk(CharT *first, CharT *last)
Definition: daw_json_string_util.h:199
constexpr DAW_ATTRIB_FLATINLINE CharT * mempbrk_unchecked(CharT *first, CharT *)
Definition: daw_json_string_util.h:126
constexpr DAW_ATTRIB_FLATINLINE CharT * memchr_unchecked(CharT *first, CharT *last)
Search for a character in a string.
Definition: daw_json_string_util.h:42
constexpr DAW_ATTRIB_FLATINLINE CharT * mempbrk_checked(CharT *first, CharT *last)
Definition: daw_json_string_util.h:170
constexpr DAW_ATTRIB_FLATINLINE bool in(char c)
Definition: daw_json_parse_policy_policy_details.h:19
Definition: daw_from_json.h:22
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:16