Line data Source code
1 : //
2 : // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
3 : // Use of this source code is governed by a BSD-style license that can be
4 : // found in the LICENSE file.
5 : //
6 :
7 : // numeric_lex.h: Functions to extract numeric values from string.
8 :
9 : #ifndef COMPILER_PREPROCESSOR_NUMERICLEX_H_
10 : #define COMPILER_PREPROCESSOR_NUMERICLEX_H_
11 :
12 : #include <cmath>
13 : #include <sstream>
14 :
15 : namespace pp {
16 :
17 0 : inline std::ios::fmtflags numeric_base_int(const std::string &str)
18 : {
19 0 : if ((str.size() >= 2) &&
20 0 : (str[0] == '0') &&
21 0 : (str[1] == 'x' || str[1] == 'X'))
22 : {
23 0 : return std::ios::hex;
24 : }
25 0 : if ((str.size() >= 1) && (str[0] == '0'))
26 : {
27 0 : return std::ios::oct;
28 : }
29 0 : return std::ios::dec;
30 : }
31 :
32 : // The following functions parse the given string to extract a numerical
33 : // value of the given type. These functions assume that the string is
34 : // of the correct form. They can only fail if the parsed value is too big,
35 : // in which case false is returned.
36 :
37 : template<typename IntType>
38 0 : bool numeric_lex_int(const std::string &str, IntType *value)
39 : {
40 0 : std::istringstream stream(str);
41 : // This should not be necessary, but MSVS has a buggy implementation.
42 : // It returns incorrect results if the base is not specified.
43 0 : stream.setf(numeric_base_int(str), std::ios::basefield);
44 :
45 0 : stream >> (*value);
46 0 : return !stream.fail();
47 : }
48 :
49 : template<typename FloatType>
50 0 : bool numeric_lex_float(const std::string &str, FloatType *value)
51 : {
52 : // On 64-bit Intel Android, istringstream is broken. Until this is fixed in
53 : // a newer NDK, don't use it. Android doesn't have locale support, so this
54 : // doesn't have to force the C locale.
55 : // TODO(thakis): Remove this once this bug has been fixed in the NDK and
56 : // that NDK has been rolled into chromium.
57 : #if defined(ANGLE_PLATFORM_ANDROID) && __x86_64__
58 : *value = strtod(str.c_str(), nullptr);
59 : return errno != ERANGE;
60 : #else
61 0 : std::istringstream stream(str);
62 : // Force "C" locale so that decimal character is always '.', and
63 : // not dependent on the current locale.
64 0 : stream.imbue(std::locale::classic());
65 :
66 0 : stream >> (*value);
67 0 : return !stream.fail() && std::isfinite(*value);
68 : #endif
69 : }
70 :
71 : } // namespace pp.
72 :
73 : #endif // COMPILER_PREPROCESSOR_NUMERICLEX_H_
|