DAW JSON Link
daw_count_digits.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/daw_attributes.h>
14 #include <daw/daw_cxmath.h>
15 #include <daw/daw_simple_array.h>
16 #include <daw/daw_uint_buffer.h>
17 
18 #include <cstdint>
19 
20 namespace daw::json {
21  inline namespace DAW_JSON_VER {
22  namespace json_details {
23  inline constexpr auto is_digit =
24  []( char c ) DAW_JSON_CPP23_STATIC_CALL_OP -> daw::UInt8 {
25  return static_cast<unsigned>( static_cast<unsigned char>( c ) ) -
26  static_cast<unsigned>(
27  static_cast<unsigned char>( '0' ) ) <
28  10U
29  ? daw::UInt8{ 0 }
30  : daw::UInt8{ 0xFFU };
31  };
32 
33  template<typename Predicate>
34  DAW_ATTRIB_FLATINLINE DAW_ATTRIB_NONNULL() inline constexpr std::int32_t
35  count_4digits( char const * first, Predicate pred ) {
36  daw::simple_array<daw::UInt8, 4> const buff{
37  pred( first[3] ), pred( first[2] ), pred( first[2] ),
38  pred( first[1] ) };
39  auto const v = DAW_BIT_CAST( std::uint32_t, buff );
40  if( v != 0 ) {
41  auto result = daw::cxmath::count_leading_zeroes( v );
42  result /= 8;
43  return static_cast<std::int32_t>( result );
44  }
45  return -1;
46  }
47 
48  template<typename Predicate>
49  DAW_ATTRIB_FLATINLINE DAW_ATTRIB_NONNULL() inline constexpr std::int32_t
50  count_8digits( char const * first, Predicate pred ) {
51  daw::simple_array<daw::UInt8, 8> const buff{
52  pred( first[7] ), pred( first[6] ), pred( first[5] ),
53  pred( first[4] ), pred( first[3] ), pred( first[2] ),
54  pred( first[1] ), pred( first[0] ) };
55 
56  auto const v = DAW_BIT_CAST( std::uint64_t, buff );
57  if( v != 0 ) {
58  auto result = daw::cxmath::count_leading_zeroes( v );
59  result /= 8;
60  return static_cast<std::int32_t>( result );
61  }
62  return -1;
63  }
64 
65  template<typename CharT>
66  DAW_ATTRIB_FLATTEN DAW_ATTRIB_RET_NONNULL
67  DAW_ATTRIB_NONNULL( )
68  inline constexpr CharT *count_digits(
69  CharT *first, CharT *last ) {
70  while( DAW_LIKELY( last - first >= 8 ) ) {
71  auto const v = count_8digits( first, is_digit );
72  if( v >= 0 ) {
73  return first + v;
74  }
75  first += 8;
76  }
77  while( last - first >= 4 ) {
78  auto const v = count_4digits( first, is_digit );
79  if( v >= 0 ) {
80  return first + v;
81  }
82  first += 4;
83  }
84 
85  while( first != last ) {
86  if( static_cast<unsigned>( *first ) -
87  static_cast<unsigned>( static_cast<unsigned char>( '0' ) ) >=
88  10U ) {
89  return first;
90  }
91  ++first;
92  }
93  return first;
94  }
95  } // namespace json_details
96  } // namespace DAW_JSON_VER
97 } // namespace daw::json
#define DAW_JSON_CPP23_STATIC_CALL_OP
This is in addition to the parse policy. Always do a full name match instead of sometimes relying on ...
Customization point traits.
#define DAW_JSON_VER
The version string used in namespace definitions. Must be a valid namespace name.
Definition: version.h:25