OLD | NEW |
1 // Copyright 2014 The Crashpad Authors. All rights reserved. | 1 // Copyright 2014 The Crashpad Authors. All rights reserved. |
2 // | 2 // |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | 3 // Licensed under the Apache License, Version 2.0 (the "License"); |
4 // you may not use this file except in compliance with the License. | 4 // you may not use this file except in compliance with the License. |
5 // You may obtain a copy of the License at | 5 // You may obtain a copy of the License at |
6 // | 6 // |
7 // http://www.apache.org/licenses/LICENSE-2.0 | 7 // http://www.apache.org/licenses/LICENSE-2.0 |
8 // | 8 // |
9 // Unless required by applicable law or agreed to in writing, software | 9 // Unless required by applicable law or agreed to in writing, software |
10 // distributed under the License is distributed on an "AS IS" BASIS, | 10 // distributed under the License is distributed on an "AS IS" BASIS, |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 // See the License for the specific language governing permissions and | 12 // See the License for the specific language governing permissions and |
13 // limitations under the License. | 13 // limitations under the License. |
14 | 14 |
15 #include "util/stdlib/string_number_conversion.h" | 15 #include "util/stdlib/string_number_conversion.h" |
16 | 16 |
17 #include <ctype.h> | 17 #include <ctype.h> |
18 #include <errno.h> | 18 #include <errno.h> |
19 #include <stdlib.h> | 19 #include <stdlib.h> |
20 #include <string.h> | 20 #include <string.h> |
21 | 21 |
22 #include <limits> | 22 #include <limits> |
23 | 23 |
24 #include "base/basictypes.h" | |
25 #include "base/logging.h" | 24 #include "base/logging.h" |
26 #include "util/stdlib/cxx.h" | 25 #include "util/stdlib/cxx.h" |
27 | 26 |
28 // CONSTEXPR_COMPILE_ASSERT will be a normal COMPILE_ASSERT if the C++ library | 27 // CONSTEXPR_STATIC_ASSERT will be a normal static_assert if the C++ library is |
29 // is the C++11 library. If using an older C++ library when compiling C++11 | 28 // the C++11 library. If using an older C++ library when compiling C++11 code, |
30 // code, the std::numeric_limits<>::min() and max() functions will not be | 29 // the std::numeric_limits<>::min() and max() functions will not be marked as |
31 // marked as constexpr, and thus won’t be usable with C++11’s static_assert(). | 30 // constexpr, and thus won’t be usable with C++11’s static_assert(). In that |
32 // In that case, a run-time CHECK() will have to do. | 31 // case, a run-time CHECK() will have to do. |
33 #if CXX_LIBRARY_VERSION >= 2011 | 32 #if CXX_LIBRARY_VERSION >= 2011 |
34 #define CONSTEXPR_COMPILE_ASSERT(condition, message) \ | 33 #define CONSTEXPR_STATIC_ASSERT(condition, message) \ |
35 COMPILE_ASSERT(condition, message) | 34 static_assert(condition, message) |
36 #else | 35 #else |
37 #define CONSTEXPR_COMPILE_ASSERT(condition, message) CHECK(condition) | 36 #define CONSTEXPR_STATIC_ASSERT(condition, message) CHECK(condition) << message |
38 #endif | 37 #endif |
39 | 38 |
40 namespace { | 39 namespace { |
41 | 40 |
42 template <typename TIntType, typename TLongType> | 41 template <typename TIntType, typename TLongType> |
43 struct StringToIntegerTraits { | 42 struct StringToIntegerTraits { |
44 typedef TIntType IntType; | 43 typedef TIntType IntType; |
45 typedef TLongType LongType; | 44 typedef TLongType LongType; |
46 static void TypeCheck() { | 45 static void TypeCheck() { |
47 COMPILE_ASSERT(std::numeric_limits<TIntType>::is_integer && | 46 static_assert(std::numeric_limits<TIntType>::is_integer && |
48 std::numeric_limits<TLongType>::is_integer, | 47 std::numeric_limits<TLongType>::is_integer, |
49 IntType_and_LongType_must_be_integer); | 48 "IntType and LongType must be integer"); |
50 COMPILE_ASSERT(std::numeric_limits<TIntType>::is_signed == | 49 static_assert(std::numeric_limits<TIntType>::is_signed == |
51 std::numeric_limits<TLongType>::is_signed, | 50 std::numeric_limits<TLongType>::is_signed, |
52 IntType_and_LongType_signedness_must_agree); | 51 "IntType and LongType signedness must agree"); |
53 CONSTEXPR_COMPILE_ASSERT(std::numeric_limits<TIntType>::min() >= | 52 CONSTEXPR_STATIC_ASSERT(std::numeric_limits<TIntType>::min() >= |
54 std::numeric_limits<TLongType>::min() && | 53 std::numeric_limits<TLongType>::min() && |
55 std::numeric_limits<TIntType>::min() < | 54 std::numeric_limits<TIntType>::min() < |
56 std::numeric_limits<TLongType>::max(), | 55 std::numeric_limits<TLongType>::max(), |
57 IntType_min_must_be_in_LongType_range); | 56 "IntType min must be in LongType range"); |
58 CONSTEXPR_COMPILE_ASSERT(std::numeric_limits<TIntType>::max() > | 57 CONSTEXPR_STATIC_ASSERT(std::numeric_limits<TIntType>::max() > |
59 std::numeric_limits<TLongType>::min() && | 58 std::numeric_limits<TLongType>::min() && |
60 std::numeric_limits<TIntType>::max() <= | 59 std::numeric_limits<TIntType>::max() <= |
61 std::numeric_limits<TLongType>::max(), | 60 std::numeric_limits<TLongType>::max(), |
62 IntType_max_must_be_in_LongType_range); | 61 "IntType max must be in LongType range"); |
63 } | 62 } |
64 }; | 63 }; |
65 | 64 |
66 template <typename TIntType, typename TLongType> | 65 template <typename TIntType, typename TLongType> |
67 struct StringToSignedIntegerTraits | 66 struct StringToSignedIntegerTraits |
68 : public StringToIntegerTraits<TIntType, TLongType> { | 67 : public StringToIntegerTraits<TIntType, TLongType> { |
69 static void TypeCheck() { | 68 static void TypeCheck() { |
70 COMPILE_ASSERT(std::numeric_limits<TIntType>::is_signed, | 69 static_assert(std::numeric_limits<TIntType>::is_signed, |
71 StringToSignedTraits_IntType_must_be_signed); | 70 "StringToSignedTraits IntType must be signed"); |
72 return super::TypeCheck(); | 71 return super::TypeCheck(); |
73 } | 72 } |
74 static bool IsNegativeOverflow(TLongType value) { | 73 static bool IsNegativeOverflow(TLongType value) { |
75 return value < std::numeric_limits<TIntType>::min(); | 74 return value < std::numeric_limits<TIntType>::min(); |
76 } | 75 } |
77 | 76 |
78 private: | 77 private: |
79 typedef StringToIntegerTraits<TIntType, TLongType> super; | 78 typedef StringToIntegerTraits<TIntType, TLongType> super; |
80 }; | 79 }; |
81 | 80 |
82 template <typename TIntType, typename TLongType> | 81 template <typename TIntType, typename TLongType> |
83 struct StringToUnsignedIntegerTraits | 82 struct StringToUnsignedIntegerTraits |
84 : public StringToIntegerTraits<TIntType, TLongType> { | 83 : public StringToIntegerTraits<TIntType, TLongType> { |
85 static void TypeCheck() { | 84 static void TypeCheck() { |
86 COMPILE_ASSERT(!std::numeric_limits<TIntType>::is_signed, | 85 static_assert(!std::numeric_limits<TIntType>::is_signed, |
87 StringToUnsignedTraits_IntType_must_be_unsigned); | 86 "StringToUnsignedTraits IntType must be unsigned"); |
88 return super::TypeCheck(); | 87 return super::TypeCheck(); |
89 } | 88 } |
90 static bool IsNegativeOverflow(TLongType value) { return false; } | 89 static bool IsNegativeOverflow(TLongType value) { return false; } |
91 | 90 |
92 private: | 91 private: |
93 typedef StringToIntegerTraits<TIntType, TLongType> super; | 92 typedef StringToIntegerTraits<TIntType, TLongType> super; |
94 }; | 93 }; |
95 | 94 |
96 struct StringToIntTraits : public StringToSignedIntegerTraits<int, long> { | 95 struct StringToIntTraits : public StringToSignedIntegerTraits<int, long> { |
97 static LongType Convert(const char* str, char** end, int base) { | 96 static LongType Convert(const char* str, char** end, int base) { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
148 | 147 |
149 bool StringToNumber(const base::StringPiece& string, int* number) { | 148 bool StringToNumber(const base::StringPiece& string, int* number) { |
150 return StringToIntegerInternal<StringToIntTraits>(string, number); | 149 return StringToIntegerInternal<StringToIntTraits>(string, number); |
151 } | 150 } |
152 | 151 |
153 bool StringToNumber(const base::StringPiece& string, unsigned int* number) { | 152 bool StringToNumber(const base::StringPiece& string, unsigned int* number) { |
154 return StringToIntegerInternal<StringToUnsignedIntTraits>(string, number); | 153 return StringToIntegerInternal<StringToUnsignedIntTraits>(string, number); |
155 } | 154 } |
156 | 155 |
157 } // namespace crashpad | 156 } // namespace crashpad |
OLD | NEW |