15#include <daw/daw_arith_traits.h>
16#include <daw/daw_cxmath.h>
17#include <daw/daw_uint_buffer.h>
36 namespace json_details {
37 template<
typename Signed,
typename Un
signed>
39 using unsigned_t = daw::remove_cvref_t<Unsigned>;
40 if constexpr(
sizeof(
Signed ) >=
sizeof( intmax_t ) and
41 daw::is_system_integral_v<unsigned_t> and
42 daw::is_system_integral_v<Signed> and
43 sizeof(
Signed ) ==
sizeof( unsigned_t ) ) {
44 if( DAW_UNLIKELY( u == (
static_cast<unsigned_t
>(
45 ( daw::numeric_limits<Signed>::max )( ) ) +
49 return static_cast<Signed>( u );
51 return static_cast<Signed>( sign *
static_cast<Signed>( u ) );
53 return static_cast<Signed>( sign *
static_cast<Signed>( u ) );
57 [[nodiscard]]
static inline constexpr bool
62 std::byte
const buff[8]{
63 static_cast<std::byte
>( ptr[0] ),
static_cast<std::byte
>( ptr[1] ),
64 static_cast<std::byte
>( ptr[2] ),
static_cast<std::byte
>( ptr[3] ),
65 static_cast<std::byte
>( ptr[4] ),
static_cast<std::byte
>( ptr[5] ),
66 static_cast<std::byte
>( ptr[6] ),
static_cast<std::byte
>( ptr[7] ) };
68 UInt64 val = UInt64( );
69 for( std::size_t
n = 0;
n < 8; ++
n ) {
70 val |= to_uint64( buff[
n] ) << ( 8 *
n );
72 return ( ( ( val & 0xF0F0'F0F0'F0F0'F0F0_u64 ) |
73 ( ( ( val + 0x0606'0606'0606'0606_u64 ) &
74 0xF0F0'F0F0'F0F0'F0F0_u64 ) >>
75 4U ) ) == 0x3333'3333'3333'3333_u64 );
79 typename MaxArithUnsigned>
81 std::disjunction<daw::is_integral<Unsigned>,
82 std::is_enum<Unsigned>>::value,
83 std::conditional_t<(
sizeof(
Unsigned ) >
sizeof( MaxArithUnsigned ) ),
84 Unsigned, MaxArithUnsigned>,
90 auto const chunk = daw::to_uint64_buffer( str );
92 auto const lower_digits =
93 ( chunk & 0x0F'00'0F'00'0F'00'0F'00_u64 ) >> 8U;
94 auto const upper_digits =
95 ( chunk & 0x00'0F'00'0F'00'0F'00'0F_u64 ) * 10U;
96 auto const chunk2 = lower_digits + upper_digits;
99 auto const lower_digits2 =
100 ( chunk2 & 0x00'FF'00'00'00'FF'00'00_u64 ) >> 16U;
101 auto const upper_digits2 =
102 ( chunk2 & 0x00'00'00'FF'00'00'00'FF_u64 ) * 100U;
103 auto const chunk3 = lower_digits2 + upper_digits2;
106 auto const lower_digits3 =
107 ( chunk3 & 0x00'00'FF'FF'00'00'00'00_u64 ) >> 32U;
108 auto const upper_digits3 =
109 ( chunk3 & 0x00'00'00'00'00'00'FF'FF_u64 ) * 10000U;
110 auto const chunk4 = lower_digits3 + upper_digits3;
112 return chunk4 & 0xFFFF'FFFF_u64;
115 "8 digit parser does not work on this platform" );
119 return upper * 100'000'000_u64 + lower;
122 1234567890123456_u64,
123 "16 digit parser does not work on this platform" );
127 std::enable_if_t<KnownBounds, std::nullptr_t> =
nullptr>
128 [[nodiscard]]
static constexpr Unsigned
130 using CharT =
typename ParseState::CharT;
136 not
static_cast<bool>( RangeChecked ) or
137 std::is_same<uresult_t, UInt64>::value,
138 "Range checking is only supported for std integral types" );
142 uresult_t result = uresult_t( );
144 while( last - first >= 16 ) {
145 result *=
static_cast<uresult_t
>( 10'000'000'000'000'000ULL );
149 if( last - first >= 8 ) {
150 result *=
static_cast<uresult_t
>( 100'000'000ULL );
154 if constexpr( ParseState::is_zero_terminated_string ) {
163 while( first < last ) {
170 auto const count = ( daw::numeric_limits<result_t>::digits10 + 1U ) -
173 ( ( result <=
static_cast<uresult_t
>(
174 ( daw::numeric_limits<result_t>::max )( ) ) ) &
180 return daw::construct_a<Unsigned>(
static_cast<Unsigned>( result ) );
182 return daw::construct_a<Unsigned>(
183 daw::narrow_cast<Unsigned>( result ) );
190 std::enable_if_t<not KnownBounds, std::nullptr_t> =
nullptr>
191 [[nodiscard]]
static constexpr Unsigned
193 using CharT =
typename ParseState::CharT;
195 using result_t = max_unsigned_t<RangeChecked, Unsigned, UInt64>;
197 max_unsigned_t<RangeChecked, daw::make_unsigned_t<Unsigned>, UInt64>;
199 not
static_cast<bool>( RangeChecked ) or
200 std::is_same<uresult_t, UInt64>::value,
201 "Range checking is only supported for std integral types" );
205 CharT *
const orig_first = first;
208 uresult_t result = uresult_t( );
211 if( has_eight & ( last - first >= 16 ) ) {
213 while( has_sixteen ) {
214 result *=
static_cast<uresult_t
>( 10'000'000'000'000'000ULL );
226 result *=
static_cast<uresult_t
>( 100'000'000ULL );
230 if constexpr( ParseState::is_zero_terminated_string ) {
240 while( first < last and dig < 10U ) {
249 auto const count =
static_cast<std::ptrdiff_t
>(
250 daw::numeric_limits<result_t>::digits10 + 1 ) -
251 ( first - orig_first );
258 return daw::construct_a<Unsigned>(
259 static_cast<Unsigned>(
static_cast<result_t
>( result ) ) );
261 return daw::construct_a<Unsigned>(
262 daw::narrow_cast<Unsigned>( result ) );
266#if false and defined( DAW_ALLOW_SSE42 )
#define daw_json_assert_weak(Bool,...)
Definition: daw_json_assert.h:190
#define daw_json_assert(Bool,...)
Definition: daw_json_assert.h:179
ParseState & parse_state
Definition: daw_json_parse_class.h:182
static constexpr Unsigned unsigned_parser(constexpr_exec_tag, ParseState &parse_state)
Definition: daw_json_parse_unsigned_int.h:129
constexpr UInt64 parse_8_digits(const char *const str)
Definition: daw_json_parse_unsigned_int.h:89
std::conditional_t< std::disjunction< daw::is_integral< Unsigned >, std::is_enum< Unsigned > >::value, std::conditional_t<(sizeof(Unsigned) > sizeof(MaxArithUnsigned)), Unsigned, MaxArithUnsigned >, Unsigned > max_unsigned_t
Definition: daw_json_parse_unsigned_int.h:85
constexpr UInt64 parse_16_digits(const char *const str)
Definition: daw_json_parse_unsigned_int.h:116
static constexpr bool is_made_of_eight_digits_cx(const char *ptr)
Definition: daw_json_parse_unsigned_int.h:58
constexpr Signed to_signed(Unsigned &&u, Signed sign)
Definition: daw_json_parse_unsigned_int.h:38
static constexpr DAW_ATTRIB_FLATINLINE unsigned parse_digit(char c)
Definition: daw_json_parse_digit.h:19
@ Signed
Number - Floating Point.
@ Unsigned
Number - Signed Integer.
JsonRangeCheck
Definition: daw_json_type_options.h:52
Definition: daw_from_json.h:22
Definition: daw_json_exec_modes.h:19
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:16