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 <daw/daw_cxmath.h>
12 #include <daw/daw_uint_buffer.h>
13 
14 #include <array>
15 #include <cstddef>
16 #include <cstdint>
17 
18 namespace daw::json {
19  inline namespace DAW_JSON_VER {
20  namespace json_details {
21  inline constexpr auto is_digit = []( char c ) -> daw::UInt8 {
22  return static_cast<unsigned>( static_cast<unsigned char>( c ) ) -
23  static_cast<unsigned>(
24  static_cast<unsigned char>( '0' ) ) <
25  10U
26  ? daw::UInt8{ 0 }
27  : daw::UInt8{ 0xFFU };
28  };
29 
30  template<typename Predicate>
31  DAW_ATTRIB_FLATINLINE inline constexpr std::int32_t
32  count_4digits( char const *first, Predicate pred ) {
33  std::array<daw::UInt8, 4> const buff{
34  pred( first[3] ), pred( first[2] ), pred( first[2] ),
35  pred( first[1] ) };
36  auto const v = DAW_BIT_CAST( std::uint32_t, buff );
37  if( v != 0 ) {
38  auto result = daw::cxmath::count_leading_zeroes( v );
39  result /= 8;
40  return static_cast<std::int32_t>( result );
41  }
42  return -1;
43  }
44 
45  template<typename Predicate>
46  DAW_ATTRIB_FLATINLINE inline constexpr std::int32_t
47  count_8digits( char const *first, Predicate pred ) {
48  std::array<daw::UInt8, 8> const buff{
49  pred( first[7] ), pred( first[6] ), pred( first[5] ),
50  pred( first[4] ), pred( first[3] ), pred( first[2] ),
51  pred( first[1] ), pred( first[0] ) };
52 
53  auto const v = DAW_BIT_CAST( std::uint64_t, buff );
54  if( v != 0 ) {
55  auto result = daw::cxmath::count_leading_zeroes( v );
56  result /= 8;
57  return static_cast<std::int32_t>( result );
58  }
59  return -1;
60  }
61 
62  template<typename CharT>
63  DAW_ATTRIB_FLATTEN inline constexpr CharT *count_digits( CharT *first,
64  CharT *last ) {
65  while( DAW_LIKELY( last - first >= 8 ) ) {
66  auto const v = count_8digits( first, is_digit );
67  if( v >= 0 ) {
68  return first + v;
69  }
70  first += 8;
71  }
72  while( last - first >= 4 ) {
73  auto const v = count_4digits( first, is_digit );
74  if( v >= 0 ) {
75  return first + v;
76  }
77  first += 4;
78  }
79 
80  while( first != last ) {
81  if( static_cast<unsigned>( *first ) -
82  static_cast<unsigned>( static_cast<unsigned char>( '0' ) ) >=
83  10U ) {
84  return first;
85  }
86  ++first;
87  }
88  return first;
89  }
90  } // namespace json_details
91  } // namespace DAW_JSON_VER
92 } // namespace daw::json
constexpr DAW_ATTRIB_FLATINLINE std::int32_t count_4digits(char const *first, Predicate pred)
Definition: daw_count_digits.h:32
constexpr DAW_ATTRIB_FLATTEN CharT * count_digits(CharT *first, CharT *last)
Definition: daw_count_digits.h:63
constexpr DAW_ATTRIB_FLATINLINE std::int32_t count_8digits(char const *first, Predicate pred)
Definition: daw_count_digits.h:47
constexpr auto is_digit
Definition: daw_count_digits.h:21
Definition: daw_from_json.h:22
#define DAW_JSON_VER
Definition: version.h:11