/src/brpc/src/butil/strings/string_number_conversions.cc
Line | Count | Source |
1 | | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 | | // Use of this source code is governed by a BSD-style license that can be |
3 | | // found in the LICENSE file. |
4 | | |
5 | | #include "butil/strings/string_number_conversions.h" |
6 | | |
7 | | #include <ctype.h> |
8 | | #include <errno.h> |
9 | | #include <stdlib.h> |
10 | | #include <wctype.h> |
11 | | |
12 | | #include <limits> |
13 | | |
14 | | #include "butil/logging.h" |
15 | | #include "butil/numerics/safe_conversions.h" // safe_abs |
16 | | #include "butil/scoped_clear_errno.h" |
17 | | #include "butil/strings/utf_string_conversions.h" |
18 | | #include "butil/third_party/dmg_fp/dmg_fp.h" |
19 | | |
20 | | namespace butil { |
21 | | |
22 | | namespace { |
23 | | |
24 | | template <typename STR, typename INT, typename UINT, bool NEG> |
25 | | struct IntToStringT { |
26 | | // This set of templates is very similar to the above templates, but |
27 | | // for testing whether an integer is negative. |
28 | | template <typename INT2, bool NEG2> |
29 | | struct TestNegT {}; |
30 | | template <typename INT2> |
31 | | struct TestNegT<INT2, false> { |
32 | 0 | static bool TestNeg(INT2 value) { |
33 | | // value is unsigned, and can never be negative. |
34 | 0 | return false; |
35 | 0 | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int, unsigned int, false>::TestNegT<unsigned int, false>::TestNeg(unsigned int) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> >, unsigned int, unsigned int, false>::TestNegT<unsigned int, false>::TestNeg(unsigned int) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long, unsigned long, false>::TestNegT<unsigned long, false>::TestNeg(unsigned long) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> >, unsigned long, unsigned long, false>::TestNegT<unsigned long, false>::TestNeg(unsigned long) |
36 | | }; |
37 | | template <typename INT2> |
38 | | struct TestNegT<INT2, true> { |
39 | 0 | static bool TestNeg(INT2 value) { |
40 | 0 | return value < 0; |
41 | 0 | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, unsigned int, true>::TestNegT<int, true>::TestNeg(int) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> >, int, unsigned int, true>::TestNegT<int, true>::TestNeg(int) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, long, unsigned long, true>::TestNegT<long, true>::TestNeg(long) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> >, long, unsigned long, true>::TestNegT<long, true>::TestNeg(long) |
42 | | }; |
43 | | |
44 | 0 | static STR IntToString(INT value) { |
45 | | // log10(2) ~= 0.3 bytes needed per bit or per byte log10(2**8) ~= 2.4. |
46 | | // So round up to allocate 3 output characters per byte, plus 1 for '-'. |
47 | 0 | const int kOutputBufSize = 3 * sizeof(INT) + 1; |
48 | | |
49 | | // Allocate the whole string right away, we will right back to front, and |
50 | | // then return the substr of what we ended up using. |
51 | 0 | STR outbuf(kOutputBufSize, 0); |
52 | |
|
53 | 0 | bool is_neg = TestNegT<INT, NEG>::TestNeg(value); |
54 | 0 | UINT res = safe_abs(value); |
55 | |
|
56 | 0 | typename STR::iterator it(outbuf.end()); |
57 | 0 | do { |
58 | 0 | --it; |
59 | 0 | DCHECK(it != outbuf.begin()); |
60 | 0 | *it = static_cast<typename STR::value_type>((res % 10) + '0'); |
61 | 0 | res /= 10; |
62 | 0 | } while (res != 0); |
63 | 0 | if (is_neg) { |
64 | 0 | --it; |
65 | 0 | DCHECK(it != outbuf.begin()); |
66 | 0 | *it = static_cast<typename STR::value_type>('-'); |
67 | 0 | } |
68 | 0 | return STR(it, outbuf.end()); |
69 | 0 | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, unsigned int, true>::IntToString(int) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> >, int, unsigned int, true>::IntToString(int) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int, unsigned int, false>::IntToString(unsigned int) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> >, unsigned int, unsigned int, false>::IntToString(unsigned int) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, long, unsigned long, true>::IntToString(long) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> >, long, unsigned long, true>::IntToString(long) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long, unsigned long, false>::IntToString(unsigned long) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IntToStringT<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> >, unsigned long, unsigned long, false>::IntToString(unsigned long) |
70 | | }; |
71 | | |
72 | | // Utility to convert a character to a digit in a given base |
73 | | template<typename CHAR, int BASE, bool BASE_LTE_10> class BaseCharToDigit { |
74 | | }; |
75 | | |
76 | | // Faster specialization for bases <= 10 |
77 | | template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, true> { |
78 | | public: |
79 | 4.94k | static bool Convert(CHAR c, uint8_t* digit) { |
80 | 4.94k | if (c >= '0' && c < '0' + BASE) { |
81 | 4.85k | *digit = c - '0'; |
82 | 4.85k | return true; |
83 | 4.85k | } |
84 | 89 | return false; |
85 | 4.94k | } string_number_conversions.cc:butil::(anonymous namespace)::BaseCharToDigit<char, 10, true>::Convert(char, unsigned char*) Line | Count | Source | 79 | 4.94k | static bool Convert(CHAR c, uint8_t* digit) { | 80 | 4.94k | if (c >= '0' && c < '0' + BASE) { | 81 | 4.85k | *digit = c - '0'; | 82 | 4.85k | return true; | 83 | 4.85k | } | 84 | 89 | return false; | 85 | 4.94k | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseCharToDigit<unsigned short, 10, true>::Convert(unsigned short, unsigned char*) |
86 | | }; |
87 | | |
88 | | // Specialization for bases where 10 < base <= 36 |
89 | | template<typename CHAR, int BASE> class BaseCharToDigit<CHAR, BASE, false> { |
90 | | public: |
91 | 0 | static bool Convert(CHAR c, uint8_t* digit) { |
92 | 0 | if (c >= '0' && c <= '9') { |
93 | 0 | *digit = c - '0'; |
94 | 0 | } else if (c >= 'a' && c < 'a' + BASE - 10) { |
95 | 0 | *digit = c - 'a' + 10; |
96 | 0 | } else if (c >= 'A' && c < 'A' + BASE - 10) { |
97 | 0 | *digit = c - 'A' + 10; |
98 | 0 | } else { |
99 | 0 | return false; |
100 | 0 | } |
101 | 0 | return true; |
102 | 0 | } |
103 | | }; |
104 | | |
105 | 4.94k | template<int BASE, typename CHAR> bool CharToDigit(CHAR c, uint8_t* digit) { |
106 | 4.94k | return BaseCharToDigit<CHAR, BASE, BASE <= 10>::Convert(c, digit); |
107 | 4.94k | } string_number_conversions.cc:bool butil::(anonymous namespace)::CharToDigit<10, char>(char, unsigned char*) Line | Count | Source | 105 | 4.94k | template<int BASE, typename CHAR> bool CharToDigit(CHAR c, uint8_t* digit) { | 106 | 4.94k | return BaseCharToDigit<CHAR, BASE, BASE <= 10>::Convert(c, digit); | 107 | 4.94k | } |
Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::CharToDigit<10, unsigned short>(unsigned short, unsigned char*) Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::CharToDigit<16, char>(char, unsigned char*) |
108 | | |
109 | | // There is an IsWhitespace for wchars defined in string_util.h, but it is |
110 | | // locale independent, whereas the functions we are replacing were |
111 | | // locale-dependent. TBD what is desired, but for the moment let's not introduce |
112 | | // a change in behaviour. |
113 | | template<typename CHAR> class WhitespaceHelper { |
114 | | }; |
115 | | |
116 | | template<> class WhitespaceHelper<char> { |
117 | | public: |
118 | 657 | static bool Invoke(char c) { |
119 | 657 | return 0 != isspace(static_cast<unsigned char>(c)); |
120 | 657 | } |
121 | | }; |
122 | | |
123 | | template<> class WhitespaceHelper<char16> { |
124 | | public: |
125 | 0 | static bool Invoke(char16 c) { |
126 | 0 | return 0 != iswspace(c); |
127 | 0 | } |
128 | | }; |
129 | | |
130 | 657 | template<typename CHAR> bool LocalIsWhitespace(CHAR c) { |
131 | 657 | return WhitespaceHelper<CHAR>::Invoke(c); |
132 | 657 | } string_number_conversions.cc:bool butil::(anonymous namespace)::LocalIsWhitespace<char>(char) Line | Count | Source | 130 | 657 | template<typename CHAR> bool LocalIsWhitespace(CHAR c) { | 131 | 657 | return WhitespaceHelper<CHAR>::Invoke(c); | 132 | 657 | } |
Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::LocalIsWhitespace<unsigned short>(unsigned short) |
133 | | |
134 | | // IteratorRangeToNumberTraits should provide: |
135 | | // - a typedef for iterator_type, the iterator type used as input. |
136 | | // - a typedef for value_type, the target numeric type. |
137 | | // - static functions min, max (returning the minimum and maximum permitted |
138 | | // values) |
139 | | // - constant kBase, the base in which to interpret the input |
140 | | template<typename IteratorRangeToNumberTraits> |
141 | | class IteratorRangeToNumber { |
142 | | public: |
143 | | typedef IteratorRangeToNumberTraits traits; |
144 | | typedef typename traits::iterator_type const_iterator; |
145 | | typedef typename traits::value_type value_type; |
146 | | |
147 | | // Generalized iterator-range-to-number conversion. |
148 | | // |
149 | | static bool Invoke(const_iterator begin, |
150 | | const_iterator end, |
151 | 408 | value_type* output) { |
152 | 408 | bool valid = true; |
153 | | |
154 | 682 | while (begin != end && LocalIsWhitespace(*begin)) { |
155 | 274 | valid = false; |
156 | 274 | ++begin; |
157 | 274 | } |
158 | | |
159 | 408 | if (begin != end && *begin == '-') { |
160 | 180 | if (!std::numeric_limits<value_type>::is_signed) { |
161 | 0 | valid = false; |
162 | 180 | } else if (!Negative::Invoke(begin + 1, end, output)) { |
163 | 104 | valid = false; |
164 | 104 | } |
165 | 228 | } else { |
166 | 228 | if (begin != end && *begin == '+') { |
167 | 1 | ++begin; |
168 | 1 | } |
169 | 228 | if (!Positive::Invoke(begin, end, output)) { |
170 | 88 | valid = false; |
171 | 88 | } |
172 | 228 | } |
173 | | |
174 | 408 | return valid; |
175 | 408 | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Invoke(char const*, char const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Invoke(unsigned short const*, unsigned short const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Invoke(char const*, char const*, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Invoke(unsigned short const*, unsigned short const*, unsigned int*) string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Invoke(char const*, char const*, long*) Line | Count | Source | 151 | 408 | value_type* output) { | 152 | 408 | bool valid = true; | 153 | | | 154 | 682 | while (begin != end && LocalIsWhitespace(*begin)) { | 155 | 274 | valid = false; | 156 | 274 | ++begin; | 157 | 274 | } | 158 | | | 159 | 408 | if (begin != end && *begin == '-') { | 160 | 180 | if (!std::numeric_limits<value_type>::is_signed) { | 161 | 0 | valid = false; | 162 | 180 | } else if (!Negative::Invoke(begin + 1, end, output)) { | 163 | 104 | valid = false; | 164 | 104 | } | 165 | 228 | } else { | 166 | 228 | if (begin != end && *begin == '+') { | 167 | 1 | ++begin; | 168 | 1 | } | 169 | 228 | if (!Positive::Invoke(begin, end, output)) { | 170 | 88 | valid = false; | 171 | 88 | } | 172 | 228 | } | 173 | | | 174 | 408 | return valid; | 175 | 408 | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Invoke(unsigned short const*, unsigned short const*, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Invoke(char const*, char const*, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Invoke(unsigned short const*, unsigned short const*, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Invoke(char const*, char const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Invoke(char const*, char const*, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Invoke(char const*, char const*, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Invoke(char const*, char const*, unsigned long*) |
176 | | |
177 | | private: |
178 | | // Sign provides: |
179 | | // - a static function, CheckBounds, that determines whether the next digit |
180 | | // causes an overflow/underflow |
181 | | // - a static function, Increment, that appends the next digit appropriately |
182 | | // according to the sign of the number being parsed. |
183 | | template<typename Sign> |
184 | | class Base { |
185 | | public: |
186 | | static bool Invoke(const_iterator begin, const_iterator end, |
187 | 408 | typename traits::value_type* output) { |
188 | 408 | *output = 0; |
189 | | |
190 | 408 | if (begin == end) { |
191 | 29 | return false; |
192 | 29 | } |
193 | | |
194 | | // Note: no performance difference was found when using template |
195 | | // specialization to remove this check in bases other than 16 |
196 | 379 | if (traits::kBase == 16 && end - begin > 2 && *begin == '0' && |
197 | 0 | (*(begin + 1) == 'x' || *(begin + 1) == 'X')) { |
198 | 0 | begin += 2; |
199 | 0 | } |
200 | | |
201 | 5.15k | for (const_iterator current = begin; current != end; ++current) { |
202 | 4.94k | uint8_t new_digit = 0; |
203 | | |
204 | 4.94k | if (!CharToDigit<traits::kBase>(*current, &new_digit)) { |
205 | 89 | return false; |
206 | 89 | } |
207 | | |
208 | 4.85k | if (current != begin) { |
209 | 4.52k | if (!Sign::CheckBounds(output, new_digit)) { |
210 | 74 | return false; |
211 | 74 | } |
212 | 4.44k | *output *= traits::kBase; |
213 | 4.44k | } |
214 | | |
215 | 4.77k | Sign::Increment(new_digit, output); |
216 | 4.77k | } |
217 | 216 | return true; |
218 | 379 | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Negative>::Invoke(char const*, char const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Positive>::Invoke(char const*, char const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Negative>::Invoke(unsigned short const*, unsigned short const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Positive>::Invoke(unsigned short const*, unsigned short const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Positive>::Invoke(char const*, char const*, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Positive>::Invoke(unsigned short const*, unsigned short const*, unsigned int*) string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Negative>::Invoke(char const*, char const*, long*) Line | Count | Source | 187 | 180 | typename traits::value_type* output) { | 188 | 180 | *output = 0; | 189 | | | 190 | 180 | if (begin == end) { | 191 | 3 | return false; | 192 | 3 | } | 193 | | | 194 | | // Note: no performance difference was found when using template | 195 | | // specialization to remove this check in bases other than 16 | 196 | 177 | if (traits::kBase == 16 && end - begin > 2 && *begin == '0' && | 197 | 0 | (*(begin + 1) == 'x' || *(begin + 1) == 'X')) { | 198 | 0 | begin += 2; | 199 | 0 | } | 200 | | | 201 | 2.56k | for (const_iterator current = begin; current != end; ++current) { | 202 | 2.48k | uint8_t new_digit = 0; | 203 | | | 204 | 2.48k | if (!CharToDigit<traits::kBase>(*current, &new_digit)) { | 205 | 35 | return false; | 206 | 35 | } | 207 | | | 208 | 2.45k | if (current != begin) { | 209 | 2.28k | if (!Sign::CheckBounds(output, new_digit)) { | 210 | 66 | return false; | 211 | 66 | } | 212 | 2.22k | *output *= traits::kBase; | 213 | 2.22k | } | 214 | | | 215 | 2.38k | Sign::Increment(new_digit, output); | 216 | 2.38k | } | 217 | 76 | return true; | 218 | 177 | } |
string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Positive>::Invoke(char const*, char const*, long*) Line | Count | Source | 187 | 228 | typename traits::value_type* output) { | 188 | 228 | *output = 0; | 189 | | | 190 | 228 | if (begin == end) { | 191 | 26 | return false; | 192 | 26 | } | 193 | | | 194 | | // Note: no performance difference was found when using template | 195 | | // specialization to remove this check in bases other than 16 | 196 | 202 | if (traits::kBase == 16 && end - begin > 2 && *begin == '0' && | 197 | 0 | (*(begin + 1) == 'x' || *(begin + 1) == 'X')) { | 198 | 0 | begin += 2; | 199 | 0 | } | 200 | | | 201 | 2.59k | for (const_iterator current = begin; current != end; ++current) { | 202 | 2.45k | uint8_t new_digit = 0; | 203 | | | 204 | 2.45k | if (!CharToDigit<traits::kBase>(*current, &new_digit)) { | 205 | 54 | return false; | 206 | 54 | } | 207 | | | 208 | 2.40k | if (current != begin) { | 209 | 2.23k | if (!Sign::CheckBounds(output, new_digit)) { | 210 | 8 | return false; | 211 | 8 | } | 212 | 2.22k | *output *= traits::kBase; | 213 | 2.22k | } | 214 | | | 215 | 2.39k | Sign::Increment(new_digit, output); | 216 | 2.39k | } | 217 | 140 | return true; | 218 | 202 | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Negative>::Invoke(unsigned short const*, unsigned short const*, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Positive>::Invoke(unsigned short const*, unsigned short const*, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Positive>::Invoke(char const*, char const*, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Positive>::Invoke(unsigned short const*, unsigned short const*, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Negative>::Invoke(char const*, char const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Positive>::Invoke(char const*, char const*, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Positive>::Invoke(char const*, char const*, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Negative>::Invoke(char const*, char const*, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Positive>::Invoke(char const*, char const*, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Positive>::Invoke(char const*, char const*, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Negative>::Invoke(char const*, char const*, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Negative>::Invoke(unsigned short const*, unsigned short const*, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Negative>::Invoke(char const*, char const*, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Negative>::Invoke(unsigned short const*, unsigned short const*, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Negative>::Invoke(char const*, char const*, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Base<butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Negative>::Invoke(char const*, char const*, unsigned long*) |
219 | | }; |
220 | | |
221 | | class Positive : public Base<Positive> { |
222 | | public: |
223 | 2.23k | static bool CheckBounds(value_type* output, uint8_t new_digit) { |
224 | 2.23k | if (*output > static_cast<value_type>(traits::max() / traits::kBase) || |
225 | 2.22k | (*output == static_cast<value_type>(traits::max() / traits::kBase) && |
226 | 8 | new_digit > traits::max() % traits::kBase)) { |
227 | 8 | *output = traits::max(); |
228 | 8 | return false; |
229 | 8 | } |
230 | 2.22k | return true; |
231 | 2.23k | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Positive::CheckBounds(int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Positive::CheckBounds(int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Positive::CheckBounds(unsigned int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Positive::CheckBounds(unsigned int*, unsigned char) string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Positive::CheckBounds(long*, unsigned char) Line | Count | Source | 223 | 2.23k | static bool CheckBounds(value_type* output, uint8_t new_digit) { | 224 | 2.23k | if (*output > static_cast<value_type>(traits::max() / traits::kBase) || | 225 | 2.22k | (*output == static_cast<value_type>(traits::max() / traits::kBase) && | 226 | 8 | new_digit > traits::max() % traits::kBase)) { | 227 | 8 | *output = traits::max(); | 228 | 8 | return false; | 229 | 8 | } | 230 | 2.22k | return true; | 231 | 2.23k | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Positive::CheckBounds(long*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Positive::CheckBounds(unsigned long*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Positive::CheckBounds(unsigned long*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Positive::CheckBounds(int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Positive::CheckBounds(unsigned int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Positive::CheckBounds(long*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Positive::CheckBounds(unsigned long*, unsigned char) |
232 | 2.39k | static void Increment(uint8_t increment, value_type* output) { |
233 | 2.39k | *output += increment; |
234 | 2.39k | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Positive::Increment(unsigned char, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Positive::Increment(unsigned char, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Positive::Increment(unsigned char, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Positive::Increment(unsigned char, unsigned int*) string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Positive::Increment(unsigned char, long*) Line | Count | Source | 232 | 2.39k | static void Increment(uint8_t increment, value_type* output) { | 233 | 2.39k | *output += increment; | 234 | 2.39k | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Positive::Increment(unsigned char, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Positive::Increment(unsigned char, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Positive::Increment(unsigned char, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Positive::Increment(unsigned char, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Positive::Increment(unsigned char, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Positive::Increment(unsigned char, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Positive::Increment(unsigned char, unsigned long*) |
235 | | }; |
236 | | |
237 | | class Negative : public Base<Negative> { |
238 | | public: |
239 | 2.28k | static bool CheckBounds(value_type* output, uint8_t new_digit) { |
240 | 2.28k | if (*output < traits::min() / traits::kBase || |
241 | 2.22k | (*output == traits::min() / traits::kBase && |
242 | 66 | new_digit > 0 - traits::min() % traits::kBase)) { |
243 | 66 | *output = traits::min(); |
244 | 66 | return false; |
245 | 66 | } |
246 | 2.22k | return true; |
247 | 2.28k | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Negative::CheckBounds(int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Negative::CheckBounds(int*, unsigned char) string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Negative::CheckBounds(long*, unsigned char) Line | Count | Source | 239 | 2.28k | static bool CheckBounds(value_type* output, uint8_t new_digit) { | 240 | 2.28k | if (*output < traits::min() / traits::kBase || | 241 | 2.22k | (*output == traits::min() / traits::kBase && | 242 | 66 | new_digit > 0 - traits::min() % traits::kBase)) { | 243 | 66 | *output = traits::min(); | 244 | 66 | return false; | 245 | 66 | } | 246 | 2.22k | return true; | 247 | 2.28k | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Negative::CheckBounds(long*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Negative::CheckBounds(int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Negative::CheckBounds(long*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Negative::CheckBounds(unsigned int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Negative::CheckBounds(unsigned int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Negative::CheckBounds(unsigned long*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Negative::CheckBounds(unsigned long*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Negative::CheckBounds(unsigned int*, unsigned char) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Negative::CheckBounds(unsigned long*, unsigned char) |
248 | 2.38k | static void Increment(uint8_t increment, value_type* output) { |
249 | 2.38k | *output -= increment; |
250 | 2.38k | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<int, 10> >::Negative::Increment(unsigned char, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<int, 10> >::Negative::Increment(unsigned char, int*) string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<long, 10> >::Negative::Increment(unsigned char, long*) Line | Count | Source | 248 | 2.38k | static void Increment(uint8_t increment, value_type* output) { | 249 | 2.38k | *output -= increment; | 250 | 2.38k | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<long, 10> >::Negative::Increment(unsigned char, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToIntTraits<char const*> >::Negative::Increment(unsigned char, int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToInt64Traits<char const*> >::Negative::Increment(unsigned char, long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned int, 10> >::Negative::Increment(unsigned char, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned int, 10> >::Negative::Increment(unsigned char, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPieceToNumberTraits<unsigned long, 10> >::Negative::Increment(unsigned char, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::StringPiece16ToNumberTraits<unsigned long, 10> >::Negative::Increment(unsigned char, unsigned long*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUIntTraits<char const*> >::Negative::Increment(unsigned char, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::IteratorRangeToNumber<butil::(anonymous namespace)::BaseHexIteratorRangeToUInt64Traits<char const*> >::Negative::Increment(unsigned char, unsigned long*) |
251 | | }; |
252 | | }; |
253 | | |
254 | | template<typename ITERATOR, typename VALUE, int BASE> |
255 | | class BaseIteratorRangeToNumberTraits { |
256 | | public: |
257 | | typedef ITERATOR iterator_type; |
258 | | typedef VALUE value_type; |
259 | 4.58k | static value_type min() { |
260 | 4.58k | return std::numeric_limits<value_type>::min(); |
261 | 4.58k | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, int, 10>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<unsigned short const*, int, 10>::min() string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, long, 10>::min() Line | Count | Source | 259 | 4.58k | static value_type min() { | 260 | 4.58k | return std::numeric_limits<value_type>::min(); | 261 | 4.58k | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<unsigned short const*, long, 10>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, int, 16>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, long, 16>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, unsigned int, 10>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<unsigned short const*, unsigned int, 10>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, unsigned long, 10>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<unsigned short const*, unsigned long, 10>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, unsigned int, 16>::min() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, unsigned long, 16>::min() |
262 | 4.47k | static value_type max() { |
263 | 4.47k | return std::numeric_limits<value_type>::max(); |
264 | 4.47k | } Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, int, 10>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<unsigned short const*, int, 10>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, unsigned int, 10>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<unsigned short const*, unsigned int, 10>::max() string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, long, 10>::max() Line | Count | Source | 262 | 4.47k | static value_type max() { | 263 | 4.47k | return std::numeric_limits<value_type>::max(); | 264 | 4.47k | } |
Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<unsigned short const*, long, 10>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, unsigned long, 10>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<unsigned short const*, unsigned long, 10>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, int, 16>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, unsigned int, 16>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, long, 16>::max() Unexecuted instantiation: string_number_conversions.cc:butil::(anonymous namespace)::BaseIteratorRangeToNumberTraits<char const*, unsigned long, 16>::max() |
265 | | static const int kBase = BASE; |
266 | | }; |
267 | | |
268 | | template<typename ITERATOR> |
269 | | class BaseHexIteratorRangeToIntTraits |
270 | | : public BaseIteratorRangeToNumberTraits<ITERATOR, int, 16> { |
271 | | }; |
272 | | |
273 | | template<typename ITERATOR> |
274 | | class BaseHexIteratorRangeToUIntTraits |
275 | | : public BaseIteratorRangeToNumberTraits<ITERATOR, uint32_t, 16> { |
276 | | }; |
277 | | |
278 | | template<typename ITERATOR> |
279 | | class BaseHexIteratorRangeToInt64Traits |
280 | | : public BaseIteratorRangeToNumberTraits<ITERATOR, int64_t, 16> { |
281 | | }; |
282 | | |
283 | | template<typename ITERATOR> |
284 | | class BaseHexIteratorRangeToUInt64Traits |
285 | | : public BaseIteratorRangeToNumberTraits<ITERATOR, uint64_t, 16> { |
286 | | }; |
287 | | |
288 | | typedef BaseHexIteratorRangeToIntTraits<StringPiece::const_iterator> |
289 | | HexIteratorRangeToIntTraits; |
290 | | |
291 | | typedef BaseHexIteratorRangeToUIntTraits<StringPiece::const_iterator> |
292 | | HexIteratorRangeToUIntTraits; |
293 | | |
294 | | typedef BaseHexIteratorRangeToInt64Traits<StringPiece::const_iterator> |
295 | | HexIteratorRangeToInt64Traits; |
296 | | |
297 | | typedef BaseHexIteratorRangeToUInt64Traits<StringPiece::const_iterator> |
298 | | HexIteratorRangeToUInt64Traits; |
299 | | |
300 | | template<typename STR> |
301 | 0 | bool HexStringToBytesT(const STR& input, std::vector<uint8_t>* output) { |
302 | 0 | DCHECK_EQ(output->size(), 0u); |
303 | 0 | size_t count = input.size(); |
304 | 0 | if (count == 0 || (count % 2) != 0) |
305 | 0 | return false; |
306 | 0 | for (uintptr_t i = 0; i < count / 2; ++i) { |
307 | 0 | uint8_t msb = 0; // most significant 4 bits |
308 | 0 | uint8_t lsb = 0; // least significant 4 bits |
309 | 0 | if (!CharToDigit<16>(input[i * 2], &msb) || |
310 | 0 | !CharToDigit<16>(input[i * 2 + 1], &lsb)) |
311 | 0 | return false; |
312 | 0 | output->push_back((msb << 4) | lsb); |
313 | 0 | } |
314 | 0 | return true; |
315 | 0 | } |
316 | | |
317 | | template <typename VALUE, int BASE> |
318 | | class StringPieceToNumberTraits |
319 | | : public BaseIteratorRangeToNumberTraits<StringPiece::const_iterator, |
320 | | VALUE, |
321 | | BASE> { |
322 | | }; |
323 | | |
324 | | template <typename VALUE> |
325 | 408 | bool StringToIntImpl(const StringPiece& input, VALUE* output) { |
326 | 408 | return IteratorRangeToNumber<StringPieceToNumberTraits<VALUE, 10> >::Invoke( |
327 | 408 | input.begin(), input.end(), output); |
328 | 408 | } Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::StringToIntImpl<int>(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, int*) Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::StringToIntImpl<unsigned int>(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, unsigned int*) string_number_conversions.cc:bool butil::(anonymous namespace)::StringToIntImpl<long>(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, long*) Line | Count | Source | 325 | 408 | bool StringToIntImpl(const StringPiece& input, VALUE* output) { | 326 | 408 | return IteratorRangeToNumber<StringPieceToNumberTraits<VALUE, 10> >::Invoke( | 327 | 408 | input.begin(), input.end(), output); | 328 | 408 | } |
Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::StringToIntImpl<unsigned long>(butil::BasicStringPiece<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > const&, unsigned long*) |
329 | | |
330 | | template <typename VALUE, int BASE> |
331 | | class StringPiece16ToNumberTraits |
332 | | : public BaseIteratorRangeToNumberTraits<StringPiece16::const_iterator, |
333 | | VALUE, |
334 | | BASE> { |
335 | | }; |
336 | | |
337 | | template <typename VALUE> |
338 | 0 | bool String16ToIntImpl(const StringPiece16& input, VALUE* output) { |
339 | 0 | return IteratorRangeToNumber<StringPiece16ToNumberTraits<VALUE, 10> >::Invoke( |
340 | 0 | input.begin(), input.end(), output); |
341 | 0 | } Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::String16ToIntImpl<int>(butil::BasicStringPiece<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> > > const&, int*) Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::String16ToIntImpl<unsigned int>(butil::BasicStringPiece<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> > > const&, unsigned int*) Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::String16ToIntImpl<long>(butil::BasicStringPiece<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> > > const&, long*) Unexecuted instantiation: string_number_conversions.cc:bool butil::(anonymous namespace)::String16ToIntImpl<unsigned long>(butil::BasicStringPiece<std::__cxx11::basic_string<unsigned short, butil::string16_char_traits, std::allocator<unsigned short> > > const&, unsigned long*) |
342 | | |
343 | | } // namespace |
344 | | |
345 | 0 | std::string IntToString(int value) { |
346 | 0 | return IntToStringT<std::string, int, unsigned int, true>:: |
347 | 0 | IntToString(value); |
348 | 0 | } |
349 | | |
350 | 0 | string16 IntToString16(int value) { |
351 | 0 | return IntToStringT<string16, int, unsigned int, true>:: |
352 | 0 | IntToString(value); |
353 | 0 | } |
354 | | |
355 | 0 | std::string UintToString(unsigned int value) { |
356 | 0 | return IntToStringT<std::string, unsigned int, unsigned int, false>:: |
357 | 0 | IntToString(value); |
358 | 0 | } |
359 | | |
360 | 0 | string16 UintToString16(unsigned int value) { |
361 | 0 | return IntToStringT<string16, unsigned int, unsigned int, false>:: |
362 | 0 | IntToString(value); |
363 | 0 | } |
364 | | |
365 | 0 | std::string Int64ToString(int64_t value) { |
366 | 0 | return IntToStringT<std::string, int64_t, uint64_t, true>::IntToString(value); |
367 | 0 | } |
368 | | |
369 | 0 | string16 Int64ToString16(int64_t value) { |
370 | 0 | return IntToStringT<string16, int64_t, uint64_t, true>::IntToString(value); |
371 | 0 | } |
372 | | |
373 | 0 | std::string Uint64ToString(uint64_t value) { |
374 | 0 | return IntToStringT<std::string, uint64_t, uint64_t, false>::IntToString(value); |
375 | 0 | } |
376 | | |
377 | 0 | string16 Uint64ToString16(uint64_t value) { |
378 | 0 | return IntToStringT<string16, uint64_t, uint64_t, false>::IntToString(value); |
379 | 0 | } |
380 | | |
381 | 0 | std::string SizeTToString(size_t value) { |
382 | 0 | return IntToStringT<std::string, size_t, size_t, false>::IntToString(value); |
383 | 0 | } |
384 | | |
385 | 0 | string16 SizeTToString16(size_t value) { |
386 | 0 | return IntToStringT<string16, size_t, size_t, false>::IntToString(value); |
387 | 0 | } |
388 | | |
389 | 0 | std::string DoubleToString(double value) { |
390 | | // According to g_fmt.cc, it is sufficient to declare a buffer of size 32. |
391 | 0 | char buffer[32]; |
392 | 0 | dmg_fp::g_fmt(buffer, value); |
393 | 0 | return std::string(buffer); |
394 | 0 | } |
395 | | |
396 | 0 | bool StringToInt(const StringPiece& input, int* output) { |
397 | 0 | return StringToIntImpl(input, output); |
398 | 0 | } |
399 | | |
400 | 0 | bool StringToInt(const StringPiece16& input, int* output) { |
401 | 0 | return String16ToIntImpl(input, output); |
402 | 0 | } |
403 | | |
404 | 0 | bool StringToUint(const StringPiece& input, unsigned* output) { |
405 | 0 | return StringToIntImpl(input, output); |
406 | 0 | } |
407 | | |
408 | 0 | bool StringToUint(const StringPiece16& input, unsigned* output) { |
409 | 0 | return String16ToIntImpl(input, output); |
410 | 0 | } |
411 | | |
412 | 408 | bool StringToInt64(const StringPiece& input, int64_t* output) { |
413 | 408 | return StringToIntImpl(input, output); |
414 | 408 | } |
415 | | |
416 | 0 | bool StringToInt64(const StringPiece16& input, int64_t* output) { |
417 | 0 | return String16ToIntImpl(input, output); |
418 | 0 | } |
419 | | |
420 | 0 | bool StringToUint64(const StringPiece& input, uint64_t* output) { |
421 | 0 | return StringToIntImpl(input, output); |
422 | 0 | } |
423 | | |
424 | 0 | bool StringToUint64(const StringPiece16& input, uint64_t* output) { |
425 | 0 | return String16ToIntImpl(input, output); |
426 | 0 | } |
427 | | |
428 | 0 | bool StringToSizeT(const StringPiece& input, size_t* output) { |
429 | 0 | return StringToIntImpl(input, output); |
430 | 0 | } |
431 | | |
432 | 0 | bool StringToSizeT(const StringPiece16& input, size_t* output) { |
433 | 0 | return String16ToIntImpl(input, output); |
434 | 0 | } |
435 | | |
436 | 0 | bool StringToDouble(const std::string& input, double* output) { |
437 | | // Thread-safe? It is on at least Mac, Linux, and Windows. |
438 | 0 | ScopedClearErrno clear_errno; |
439 | |
|
440 | 0 | char* endptr = NULL; |
441 | 0 | *output = dmg_fp::strtod(input.c_str(), &endptr); |
442 | | |
443 | | // Cases to return false: |
444 | | // - If errno is ERANGE, there was an overflow or underflow. |
445 | | // - If the input string is empty, there was nothing to parse. |
446 | | // - If endptr does not point to the end of the string, there are either |
447 | | // characters remaining in the string after a parsed number, or the string |
448 | | // does not begin with a parseable number. endptr is compared to the |
449 | | // expected end given the string's stated length to correctly catch cases |
450 | | // where the string contains embedded NUL characters. |
451 | | // - If the first character is a space, there was leading whitespace |
452 | 0 | return errno == 0 && |
453 | 0 | !input.empty() && |
454 | 0 | input.c_str() + input.length() == endptr && |
455 | 0 | !isspace(input[0]); |
456 | 0 | } |
457 | | |
458 | | // Note: if you need to add String16ToDouble, first ask yourself if it's |
459 | | // really necessary. If it is, probably the best implementation here is to |
460 | | // convert to 8-bit and then use the 8-bit version. |
461 | | |
462 | | // Note: if you need to add an iterator range version of StringToDouble, first |
463 | | // ask yourself if it's really necessary. If it is, probably the best |
464 | | // implementation here is to instantiate a string and use the string version. |
465 | | |
466 | 0 | std::string HexEncode(const void* bytes, size_t size) { |
467 | 0 | static const char kHexChars[] = "0123456789ABCDEF"; |
468 | | |
469 | | // Each input byte creates two output hex characters. |
470 | 0 | std::string ret(size * 2, '\0'); |
471 | |
|
472 | 0 | for (size_t i = 0; i < size; ++i) { |
473 | 0 | char b = reinterpret_cast<const char*>(bytes)[i]; |
474 | 0 | ret[(i * 2)] = kHexChars[(b >> 4) & 0xf]; |
475 | 0 | ret[(i * 2) + 1] = kHexChars[b & 0xf]; |
476 | 0 | } |
477 | 0 | return ret; |
478 | 0 | } |
479 | | |
480 | 0 | bool HexStringToInt(const StringPiece& input, int* output) { |
481 | 0 | return IteratorRangeToNumber<HexIteratorRangeToIntTraits>::Invoke( |
482 | 0 | input.begin(), input.end(), output); |
483 | 0 | } |
484 | | |
485 | 0 | bool HexStringToUInt(const StringPiece& input, uint32_t* output) { |
486 | 0 | return IteratorRangeToNumber<HexIteratorRangeToUIntTraits>::Invoke( |
487 | 0 | input.begin(), input.end(), output); |
488 | 0 | } |
489 | | |
490 | 0 | bool HexStringToInt64(const StringPiece& input, int64_t* output) { |
491 | 0 | return IteratorRangeToNumber<HexIteratorRangeToInt64Traits>::Invoke( |
492 | 0 | input.begin(), input.end(), output); |
493 | 0 | } |
494 | | |
495 | 0 | bool HexStringToUInt64(const StringPiece& input, uint64_t* output) { |
496 | 0 | return IteratorRangeToNumber<HexIteratorRangeToUInt64Traits>::Invoke( |
497 | 0 | input.begin(), input.end(), output); |
498 | 0 | } |
499 | | |
500 | 0 | bool HexStringToBytes(const std::string& input, std::vector<uint8_t>* output) { |
501 | 0 | return HexStringToBytesT(input, output); |
502 | 0 | } |
503 | | |
504 | | } // namespace butil |