marshalling.cc
Go to the documentation of this file.
00001 //
00002 //  Copyright 2019 The Abseil Authors.
00003 //
00004 // Licensed under the Apache License, Version 2.0 (the "License");
00005 // you may not use this file except in compliance with the License.
00006 // You may obtain a copy of the License at
00007 //
00008 //      https://www.apache.org/licenses/LICENSE-2.0
00009 //
00010 // Unless required by applicable law or agreed to in writing, software
00011 // distributed under the License is distributed on an "AS IS" BASIS,
00012 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013 // See the License for the specific language governing permissions and
00014 // limitations under the License.
00015 
00016 #include "absl/flags/marshalling.h"
00017 
00018 #include <limits>
00019 
00020 #include "absl/base/macros.h"
00021 #include "absl/strings/match.h"
00022 #include "absl/strings/numbers.h"
00023 #include "absl/strings/str_cat.h"
00024 #include "absl/strings/str_format.h"
00025 #include "absl/strings/str_join.h"
00026 #include "absl/strings/str_split.h"
00027 
00028 namespace absl {
00029 namespace flags_internal {
00030 
00031 // --------------------------------------------------------------------
00032 // AbslParseFlag specializations for boolean type.
00033 
00034 bool AbslParseFlag(absl::string_view text, bool* dst, std::string*) {
00035   const char* kTrue[] = {"1", "t", "true", "y", "yes"};
00036   const char* kFalse[] = {"0", "f", "false", "n", "no"};
00037   static_assert(sizeof(kTrue) == sizeof(kFalse), "true_false_equal");
00038 
00039   text = absl::StripAsciiWhitespace(text);
00040 
00041   for (size_t i = 0; i < ABSL_ARRAYSIZE(kTrue); ++i) {
00042     if (absl::EqualsIgnoreCase(text, kTrue[i])) {
00043       *dst = true;
00044       return true;
00045     } else if (absl::EqualsIgnoreCase(text, kFalse[i])) {
00046       *dst = false;
00047       return true;
00048     }
00049   }
00050   return false;  // didn't match a legal input
00051 }
00052 
00053 // --------------------------------------------------------------------
00054 // AbslParseFlag for integral types.
00055 
00056 // Return the base to use for parsing text as an integer.  Leading 0x
00057 // puts us in base 16.  But leading 0 does not put us in base 8. It
00058 // caused too many bugs when we had that behavior.
00059 static int NumericBase(absl::string_view text) {
00060   const bool hex = (text.size() >= 2 && text[0] == '0' &&
00061                     (text[1] == 'x' || text[1] == 'X'));
00062   return hex ? 16 : 10;
00063 }
00064 
00065 template <typename IntType>
00066 inline bool ParseFlagImpl(absl::string_view text, IntType* dst) {
00067   text = absl::StripAsciiWhitespace(text);
00068 
00069   return absl::numbers_internal::safe_strtoi_base(text, dst, NumericBase(text));
00070 }
00071 
00072 bool AbslParseFlag(absl::string_view text, short* dst, std::string*) {
00073   int val;
00074   if (!ParseFlagImpl(text, &val)) return false;
00075   if (static_cast<short>(val) != val)  // worked, but number out of range
00076     return false;
00077   *dst = static_cast<short>(val);
00078   return true;
00079 }
00080 
00081 bool AbslParseFlag(absl::string_view text, unsigned short* dst, std::string*) {
00082   unsigned int val;
00083   if (!ParseFlagImpl(text, &val)) return false;
00084   if (static_cast<unsigned short>(val) !=
00085       val)  // worked, but number out of range
00086     return false;
00087   *dst = static_cast<unsigned short>(val);
00088   return true;
00089 }
00090 
00091 bool AbslParseFlag(absl::string_view text, int* dst, std::string*) {
00092   return ParseFlagImpl(text, dst);
00093 }
00094 
00095 bool AbslParseFlag(absl::string_view text, unsigned int* dst, std::string*) {
00096   return ParseFlagImpl(text, dst);
00097 }
00098 
00099 bool AbslParseFlag(absl::string_view text, long* dst, std::string*) {
00100   return ParseFlagImpl(text, dst);
00101 }
00102 
00103 bool AbslParseFlag(absl::string_view text, unsigned long* dst, std::string*) {
00104   return ParseFlagImpl(text, dst);
00105 }
00106 
00107 bool AbslParseFlag(absl::string_view text, long long* dst, std::string*) {
00108   return ParseFlagImpl(text, dst);
00109 }
00110 
00111 bool AbslParseFlag(absl::string_view text, unsigned long long* dst,
00112                    std::string*) {
00113   return ParseFlagImpl(text, dst);
00114 }
00115 
00116 // --------------------------------------------------------------------
00117 // AbslParseFlag for floating point types.
00118 
00119 bool AbslParseFlag(absl::string_view text, float* dst, std::string*) {
00120   return absl::SimpleAtof(text, dst);
00121 }
00122 
00123 bool AbslParseFlag(absl::string_view text, double* dst, std::string*) {
00124   return absl::SimpleAtod(text, dst);
00125 }
00126 
00127 // --------------------------------------------------------------------
00128 // AbslParseFlag for strings.
00129 
00130 bool AbslParseFlag(absl::string_view text, std::string* dst, std::string*) {
00131   dst->assign(text.data(), text.size());
00132   return true;
00133 }
00134 
00135 // --------------------------------------------------------------------
00136 // AbslParseFlag for vector of strings.
00137 
00138 bool AbslParseFlag(absl::string_view text, std::vector<std::string>* dst,
00139                    std::string*) {
00140   // An empty flag value corresponds to an empty vector, not a vector
00141   // with a single, empty std::string.
00142   if (text.empty()) {
00143     dst->clear();
00144     return true;
00145   }
00146   *dst = absl::StrSplit(text, ',', absl::AllowEmpty());
00147   return true;
00148 }
00149 
00150 // --------------------------------------------------------------------
00151 // AbslUnparseFlag specializations for various builtin flag types.
00152 
00153 std::string Unparse(bool v) { return v ? "true" : "false"; }
00154 std::string Unparse(short v) { return absl::StrCat(v); }
00155 std::string Unparse(unsigned short v) { return absl::StrCat(v); }
00156 std::string Unparse(int v) { return absl::StrCat(v); }
00157 std::string Unparse(unsigned int v) { return absl::StrCat(v); }
00158 std::string Unparse(long v) { return absl::StrCat(v); }
00159 std::string Unparse(unsigned long v) { return absl::StrCat(v); }
00160 std::string Unparse(long long v) { return absl::StrCat(v); }
00161 std::string Unparse(unsigned long long v) { return absl::StrCat(v); }
00162 template <typename T>
00163 std::string UnparseFloatingPointVal(T v) {
00164   // digits10 is guaranteed to roundtrip correctly in std::string -> value -> std::string
00165   // conversions, but may not be enough to represent all the values correctly.
00166   std::string digit10_str =
00167       absl::StrFormat("%.*g", std::numeric_limits<T>::digits10, v);
00168   if (std::isnan(v) || std::isinf(v)) return digit10_str;
00169 
00170   T roundtrip_val = 0;
00171   std::string err;
00172   if (absl::ParseFlag(digit10_str, &roundtrip_val, &err) &&
00173       roundtrip_val == v) {
00174     return digit10_str;
00175   }
00176 
00177   // max_digits10 is the number of base-10 digits that are necessary to uniquely
00178   // represent all distinct values.
00179   return absl::StrFormat("%.*g", std::numeric_limits<T>::max_digits10, v);
00180 }
00181 std::string Unparse(float v) { return UnparseFloatingPointVal(v); }
00182 std::string Unparse(double v) { return UnparseFloatingPointVal(v); }
00183 std::string AbslUnparseFlag(absl::string_view v) { return std::string(v); }
00184 std::string AbslUnparseFlag(const std::vector<std::string>& v) {
00185   return absl::StrJoin(v, ",");
00186 }
00187 
00188 }  // namespace flags_internal
00189 }  // namespace absl


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