marshalling.cc
Go to the documentation of this file.
1 //
2 // Copyright 2019 The Abseil Authors.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // https://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #include "absl/flags/marshalling.h"
17 
18 #include <limits>
19 
20 #include "absl/base/macros.h"
21 #include "absl/strings/match.h"
22 #include "absl/strings/numbers.h"
23 #include "absl/strings/str_cat.h"
25 #include "absl/strings/str_join.h"
26 #include "absl/strings/str_split.h"
27 
28 namespace absl {
29 namespace flags_internal {
30 
31 // --------------------------------------------------------------------
32 // AbslParseFlag specializations for boolean type.
33 
34 bool AbslParseFlag(absl::string_view text, bool* dst, std::string*) {
35  const char* kTrue[] = {"1", "t", "true", "y", "yes"};
36  const char* kFalse[] = {"0", "f", "false", "n", "no"};
37  static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal");
38 
39  text = absl::StripAsciiWhitespace(text);
40 
41  for (size_t i = 0; i < ABSL_ARRAYSIZE(kTrue); ++i) {
42  if (absl::EqualsIgnoreCase(text, kTrue[i])) {
43  *dst = true;
44  return true;
45  } else if (absl::EqualsIgnoreCase(text, kFalse[i])) {
46  *dst = false;
47  return true;
48  }
49  }
50  return false; // didn't match a legal input
51 }
52 
53 // --------------------------------------------------------------------
54 // AbslParseFlag for integral types.
55 
56 // Return the base to use for parsing text as an integer. Leading 0x
57 // puts us in base 16. But leading 0 does not put us in base 8. It
58 // caused too many bugs when we had that behavior.
59 static int NumericBase(absl::string_view text) {
60  const bool hex = (text.size() >= 2 && text[0] == '0' &&
61  (text[1] == 'x' || text[1] == 'X'));
62  return hex ? 16 : 10;
63 }
64 
65 template <typename IntType>
66 inline bool ParseFlagImpl(absl::string_view text, IntType* dst) {
67  text = absl::StripAsciiWhitespace(text);
68 
70 }
71 
72 bool AbslParseFlag(absl::string_view text, short* dst, std::string*) {
73  int val;
74  if (!ParseFlagImpl(text, &val)) return false;
75  if (static_cast<short>(val) != val) // worked, but number out of range
76  return false;
77  *dst = static_cast<short>(val);
78  return true;
79 }
80 
81 bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) {
82  unsigned int val;
83  if (!ParseFlagImpl(text, &val)) return false;
84  if (static_cast<unsigned short>(val) !=
85  val) // worked, but number out of range
86  return false;
87  *dst = static_cast<unsigned short>(val);
88  return true;
89 }
90 
91 bool AbslParseFlag(absl::string_view text, int* dst, std::string*) {
92  return ParseFlagImpl(text, dst);
93 }
94 
95 bool AbslParseFlag(absl::string_view text, unsigned int* dst, std::string*) {
96  return ParseFlagImpl(text, dst);
97 }
98 
99 bool AbslParseFlag(absl::string_view text, long* dst, std::string*) {
100  return ParseFlagImpl(text, dst);
101 }
102 
103 bool AbslParseFlag(absl::string_view text, unsigned long* dst, std::string*) {
104  return ParseFlagImpl(text, dst);
105 }
106 
107 bool AbslParseFlag(absl::string_view text, long long* dst, std::string*) {
108  return ParseFlagImpl(text, dst);
109 }
110 
111 bool AbslParseFlag(absl::string_view text, unsigned long long* dst,
112  std::string*) {
113  return ParseFlagImpl(text, dst);
114 }
115 
116 // --------------------------------------------------------------------
117 // AbslParseFlag for floating point types.
118 
119 bool AbslParseFlag(absl::string_view text, float* dst, std::string*) {
120  return absl::SimpleAtof(text, dst);
121 }
122 
123 bool AbslParseFlag(absl::string_view text, double* dst, std::string*) {
124  return absl::SimpleAtod(text, dst);
125 }
126 
127 // --------------------------------------------------------------------
128 // AbslParseFlag for strings.
129 
130 bool AbslParseFlag(absl::string_view text, std::string* dst, std::string*) {
131  dst->assign(text.data(), text.size());
132  return true;
133 }
134 
135 // --------------------------------------------------------------------
136 // AbslParseFlag for vector of strings.
137 
138 bool AbslParseFlag(absl::string_view text, std::vector<std::string>* dst,
139  std::string*) {
140  // An empty flag value corresponds to an empty vector, not a vector
141  // with a single, empty std::string.
142  if (text.empty()) {
143  dst->clear();
144  return true;
145  }
146  *dst = absl::StrSplit(text, ',', absl::AllowEmpty());
147  return true;
148 }
149 
150 // --------------------------------------------------------------------
151 // AbslUnparseFlag specializations for various builtin flag types.
152 
153 std::string Unparse(bool v) { return v ? "true" : "false"; }
154 std::string Unparse(short v) { return absl::StrCat(v); }
155 std::string Unparse(unsigned short v) { return absl::StrCat(v); }
156 std::string Unparse(int v) { return absl::StrCat(v); }
157 std::string Unparse(unsigned int v) { return absl::StrCat(v); }
158 std::string Unparse(long v) { return absl::StrCat(v); }
159 std::string Unparse(unsigned long v) { return absl::StrCat(v); }
160 std::string Unparse(long long v) { return absl::StrCat(v); }
161 std::string Unparse(unsigned long long v) { return absl::StrCat(v); }
162 template <typename T>
163 std::string UnparseFloatingPointVal(T v) {
164  // digits10 is guaranteed to roundtrip correctly in std::string -> value -> std::string
165  // conversions, but may not be enough to represent all the values correctly.
166  std::string digit10_str =
167  absl::StrFormat("%.*g", std::numeric_limits<T>::digits10, v);
168  if (std::isnan(v) || std::isinf(v)) return digit10_str;
169 
170  T roundtrip_val = 0;
171  std::string err;
172  if (absl::ParseFlag(digit10_str, &roundtrip_val, &err) &&
173  roundtrip_val == v) {
174  return digit10_str;
175  }
176 
177  // max_digits10 is the number of base-10 digits that are necessary to uniquely
178  // represent all distinct values.
179  return absl::StrFormat("%.*g", std::numeric_limits<T>::max_digits10, v);
180 }
181 std::string Unparse(float v) { return UnparseFloatingPointVal(v); }
182 std::string Unparse(double v) { return UnparseFloatingPointVal(v); }
183 std::string AbslUnparseFlag(absl::string_view v) { return std::string(v); }
184 std::string AbslUnparseFlag(const std::vector<std::string>& v) {
185  return absl::StrJoin(v, ",");
186 }
187 
188 } // namespace flags_internal
189 } // namespace absl
int v
Definition: variant_test.cc:81
std::string StrJoin(Iterator start, Iterator end, absl::string_view sep, Formatter &&fmt)
Definition: str_join.h:244
bool ParseFlagImpl(absl::string_view text, IntType *dst)
Definition: marshalling.cc:66
bool AbslParseFlag(absl::string_view text, bool *dst, std::string *)
Definition: marshalling.cc:34
std::string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: str_cat.cc:98
Definition: algorithm.h:29
constexpr size_type size() const noexcept
Definition: string_view.h:260
bool SimpleAtod(absl::string_view str, double *out)
Definition: numbers.cc:69
bool SimpleAtof(absl::string_view str, float *out)
Definition: numbers.cc:43
ABSL_MUST_USE_RESULT std::string StrFormat(const FormatSpec< Args... > &format, const Args &...args)
Definition: str_format.h:305
strings_internal::Splitter< typename strings_internal::SelectDelimiter< Delimiter >::type, AllowEmpty > StrSplit(strings_internal::ConvertibleToStringView text, Delimiter d)
Definition: str_split.h:491
static int NumericBase(absl::string_view text)
Definition: marshalling.cc:59
ABSL_MUST_USE_RESULT absl::string_view StripAsciiWhitespace(absl::string_view str)
Definition: ascii.h:223
std::string Unparse(FlagMarshallingOpFn op, const void *val)
constexpr bool empty() const noexcept
Definition: string_view.h:277
ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type *out, int base)
Definition: numbers.h:139
std::string AbslUnparseFlag(absl::string_view v)
Definition: marshalling.cc:183
std::string UnparseFloatingPointVal(T v)
Definition: marshalling.cc:163
#define ABSL_ARRAYSIZE(array)
Definition: macros.h:42
constexpr const_pointer data() const noexcept
Definition: string_view.h:302
bool ParseFlag(absl::string_view input, T *dst, std::string *error)
Definition: marshalling.h:240
bool EqualsIgnoreCase(absl::string_view piece1, absl::string_view piece2)
Definition: match.cc:21


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:19:57