llvm.org GIT mirror llvm / 44499d7
[ADT] Add llvm::to_float Summary: The function matches the interface of llvm::to_integer, but as we are calling out to a C library function, I let it take a Twine argument, so we can avoid a string copy at least in some cases. I add a test and replace a couple of existing uses of strtod with this function. Reviewers: zturner Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D34518 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306096 91177308-0d34-0410-b5e6-96231b3b80d8 Pavel Labath 2 years ago
4 changed file(s) with 58 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
1414 #define LLVM_ADT_STRINGEXTRAS_H
1515
1616 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/SmallString.h"
1718 #include "llvm/ADT/StringRef.h"
1819 #include
1920 #include
2021 #include
22 #include
2123 #include
2224 #include
2325 #include
126128 /// Returns true if the number was successfully converted, false otherwise.
127129 template bool to_integer(StringRef S, N &Num, unsigned Base = 0) {
128130 return !S.getAsInteger(Base, Num);
131 }
132
133 namespace detail {
134 template
135 inline bool to_float(const Twine &T, N &Num, N (*StrTo)(const char *, char **)) {
136 SmallString<32> Storage;
137 StringRef S = T.toNullTerminatedStringRef(Storage);
138 char *End;
139 N Temp = StrTo(S.data(), &End);
140 if (*End != '\0')
141 return false;
142 Num = Temp;
143 return true;
144 }
145 }
146
147 inline bool to_float(const Twine &T, float &Num) {
148 return detail::to_float(T, Num, std::strtof);
149 }
150
151 inline bool to_float(const Twine &T, double &Num) {
152 return detail::to_float(T, Num, std::strtod);
153 }
154
155 inline bool to_float(const Twine &T, long double &Num) {
156 return detail::to_float(T, Num, std::strtold);
129157 }
130158
131159 static inline std::string utostr(uint64_t X, bool isNeg = false) {
2323 #include "llvm/ADT/STLExtras.h"
2424 #include "llvm/ADT/SmallPtrSet.h"
2525 #include "llvm/ADT/SmallString.h"
26 #include "llvm/ADT/StringExtras.h"
2627 #include "llvm/ADT/StringMap.h"
2728 #include "llvm/ADT/Twine.h"
2829 #include "llvm/Config/config.h"
15211522 // parser/parser implementation
15221523 //
15231524 static bool parseDouble(Option &O, StringRef Arg, double &Value) {
1524 SmallString<32> TmpStr(Arg.begin(), Arg.end());
1525 const char *ArgStart = TmpStr.c_str();
1526 char *End;
1527 Value = strtod(ArgStart, &End);
1528 if (*End != 0)
1529 return O.error("'" + Arg + "' value invalid for floating point argument!");
1530 return false;
1525 if (to_float(Arg, Value))
1526 return false;
1527 return O.error("'" + Arg + "' value invalid for floating point argument!");
15311528 }
15321529
15331530 bool parser::parse(Option &O, StringRef ArgName, StringRef Arg,
99 #include "llvm/Support/YAMLTraits.h"
1010 #include "llvm/ADT/STLExtras.h"
1111 #include "llvm/ADT/SmallString.h"
12 #include "llvm/ADT/StringExtras.h"
1213 #include "llvm/ADT/StringRef.h"
1314 #include "llvm/ADT/Twine.h"
1415 #include "llvm/Support/Casting.h"
911912 }
912913
913914 StringRef ScalarTraits::input(StringRef Scalar, void *, double &Val) {
914 SmallString<32> buff(Scalar.begin(), Scalar.end());
915 char *end;
916 Val = strtod(buff.c_str(), &end);
917 if (*end != '\0')
918 return "invalid floating point number";
919 return StringRef();
915 if (to_float(Scalar, Val))
916 return StringRef();
917 return "invalid floating point number";
920918 }
921919
922920 void ScalarTraits::output(const float &Val, void *, raw_ostream &Out) {
924922 }
925923
926924 StringRef ScalarTraits::input(StringRef Scalar, void *, float &Val) {
927 SmallString<32> buff(Scalar.begin(), Scalar.end());
928 char *end;
929 Val = strtod(buff.c_str(), &end);
930 if (*end != '\0')
931 return "invalid floating point number";
932 return StringRef();
925 if (to_float(Scalar, Val))
926 return StringRef();
927 return "invalid floating point number";
933928 }
934929
935930 void ScalarTraits::output(const Hex8 &Val, void *, raw_ostream &Out) {
6464 EvenBytes.size());
6565 EXPECT_EQ(EvenStr, toHex(EvenData));
6666 EXPECT_EQ(EvenData, fromHex(EvenStr));
67 }
67 }
68
69 TEST(StringExtrasTest, to_float) {
70 float F;
71 EXPECT_TRUE(to_float("4.7", F));
72 EXPECT_FLOAT_EQ(4.7, F);
73
74 double D;
75 EXPECT_TRUE(to_float("4.7", D));
76 EXPECT_DOUBLE_EQ(4.7, D);
77
78 long double LD;
79 EXPECT_TRUE(to_float("4.7", LD));
80 EXPECT_DOUBLE_EQ(4.7, LD);
81
82 EXPECT_FALSE(to_float("foo", F));
83 EXPECT_FALSE(to_float("7.4 foo", F));
84 EXPECT_FLOAT_EQ(4.7, F); // F should be unchanged
85 }