about summary refs log tree commit diff
path: root/absl/flags
diff options
context:
space:
mode:
Diffstat (limited to 'absl/flags')
-rw-r--r--absl/flags/config.h20
-rw-r--r--absl/flags/flag_test.cc4
-rw-r--r--absl/flags/internal/commandlineflag.h17
-rw-r--r--absl/flags/internal/flag.cc36
-rw-r--r--absl/flags/internal/flag.h37
-rw-r--r--absl/flags/parse.cc6
6 files changed, 43 insertions, 77 deletions
diff --git a/absl/flags/config.h b/absl/flags/config.h
index 001f8feaf637..813a9257000f 100644
--- a/absl/flags/config.h
+++ b/absl/flags/config.h
@@ -64,4 +64,24 @@
 #define ABSL_FLAGS_INTERNAL_HAS_RTTI 1
 #endif  // !defined(__GNUC__) || defined(__GXX_RTTI)
 
+// These macros represent the "source of truth" for the list of supported
+// built-in types.
+#define ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \
+  A(bool, bool)                              \
+  A(short, short)                            \
+  A(unsigned short, unsigned_short)          \
+  A(int, int)                                \
+  A(unsigned int, unsigned_int)              \
+  A(long, long)                              \
+  A(unsigned long, unsigned_long)            \
+  A(long long, long_long)                    \
+  A(unsigned long long, unsigned_long_long)  \
+  A(double, double)                          \
+  A(float, float)
+
+#define ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(A) \
+  ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A)         \
+  A(std::string, std_string)                   \
+  A(std::vector<std::string>, std_vector_of_string)
+
 #endif  // ABSL_FLAGS_CONFIG_H_
diff --git a/absl/flags/flag_test.cc b/absl/flags/flag_test.cc
index 015b1fc9dc5d..416a31e5232a 100644
--- a/absl/flags/flag_test.cc
+++ b/absl/flags/flag_test.cc
@@ -145,8 +145,8 @@ DEFINE_CONSTRUCTED_FLAG(int32_t, 3, kOneWord);
 DEFINE_CONSTRUCTED_FLAG(uint32_t, 4, kOneWord);
 DEFINE_CONSTRUCTED_FLAG(int64_t, 5, kOneWord);
 DEFINE_CONSTRUCTED_FLAG(uint64_t, 6, kOneWord);
-DEFINE_CONSTRUCTED_FLAG(float, 7.8, kFloat);
-DEFINE_CONSTRUCTED_FLAG(double, 9.10, kDouble);
+DEFINE_CONSTRUCTED_FLAG(float, 7.8, kOneWord);
+DEFINE_CONSTRUCTED_FLAG(double, 9.10, kOneWord);
 DEFINE_CONSTRUCTED_FLAG(String, &TestMakeDflt<String>, kGenFunc);
 DEFINE_CONSTRUCTED_FLAG(UDT, &TestMakeDflt<UDT>, kGenFunc);
 
diff --git a/absl/flags/internal/commandlineflag.h b/absl/flags/internal/commandlineflag.h
index 0a7197b7bd96..fa050209b0d7 100644
--- a/absl/flags/internal/commandlineflag.h
+++ b/absl/flags/internal/commandlineflag.h
@@ -178,23 +178,6 @@ class CommandLineFlag {
   virtual void CheckDefaultValueParsingRoundtrip() const = 0;
 };
 
-// This macro is the "source of truth" for the list of supported flag built-in
-// types.
-#define ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(A) \
-  A(bool)                                    \
-  A(short)                                   \
-  A(unsigned short)                          \
-  A(int)                                     \
-  A(unsigned int)                            \
-  A(long)                                    \
-  A(unsigned long)                           \
-  A(long long)                               \
-  A(unsigned long long)                      \
-  A(double)                                  \
-  A(float)                                   \
-  A(std::string)                             \
-  A(std::vector<std::string>)
-
 }  // namespace flags_internal
 ABSL_NAMESPACE_END
 }  // namespace absl
diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc
index 8f0777fa1dc1..96c026dcb5d2 100644
--- a/absl/flags/internal/flag.cc
+++ b/absl/flags/internal/flag.cc
@@ -49,9 +49,9 @@ namespace {
 
 // Currently we only validate flag values for user-defined flag types.
 bool ShouldValidateFlagValue(FlagFastTypeId flag_type_id) {
-#define DONT_VALIDATE(T) \
+#define DONT_VALIDATE(T, _) \
   if (flag_type_id == base_internal::FastTypeId<T>()) return false;
-  ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(DONT_VALIDATE)
+  ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(DONT_VALIDATE)
 #undef DONT_VALIDATE
 
   return true;
@@ -150,23 +150,11 @@ void FlagImpl::Init() {
       break;
     case FlagValueStorageKind::kOneWordAtomic: {
       alignas(int64_t) std::array<char, sizeof(int64_t)> buf{};
-      switch (def_kind) {
-        case FlagDefaultKind::kOneWord:
-          std::memcpy(buf.data(), &default_value_.one_word,
-                      sizeof(default_value_.one_word));
-          break;
-        case FlagDefaultKind::kFloat:
-          std::memcpy(buf.data(), &default_value_.float_value,
-                      sizeof(default_value_.float_value));
-          break;
-        case FlagDefaultKind::kDouble:
-          std::memcpy(buf.data(), &default_value_.double_value,
-                      sizeof(default_value_.double_value));
-          break;
-        default:
-          assert(def_kind == FlagDefaultKind::kGenFunc);
-          (*default_value_.gen_func)(buf.data());
-          break;
+      if (def_kind == FlagDefaultKind::kGenFunc) {
+        (*default_value_.gen_func)(buf.data());
+      } else {
+        assert(def_kind != FlagDefaultKind::kDynamicValue);
+        std::memcpy(buf.data(), &default_value_, Sizeof(op_));
       }
       OneWordValue().store(absl::bit_cast<int64_t>(buf),
                            std::memory_order_release);
@@ -228,14 +216,8 @@ std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const {
       res = flags_internal::Alloc(op_);
       (*default_value_.gen_func)(res);
       break;
-    case FlagDefaultKind::kOneWord:
-      res = flags_internal::Clone(op_, &default_value_.one_word);
-      break;
-    case FlagDefaultKind::kFloat:
-      res = flags_internal::Clone(op_, &default_value_.float_value);
-      break;
-    case FlagDefaultKind::kDouble:
-      res = flags_internal::Clone(op_, &default_value_.double_value);
+    default:
+      res = flags_internal::Clone(op_, &default_value_);
       break;
   }
   return {res, DynValueDeleter{op_}};
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index 146c3efc2af3..e374ecde3d95 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -231,25 +231,21 @@ using FlagDfltGenFunc = void (*)(void*);
 union FlagDefaultSrc {
   constexpr explicit FlagDefaultSrc(FlagDfltGenFunc gen_func_arg)
       : gen_func(gen_func_arg) {}
-  template <typename T>
-  constexpr explicit FlagDefaultSrc(T one_word_value)
-      : one_word(static_cast<int64_t>(one_word_value)) {}
-  constexpr explicit FlagDefaultSrc(float f) : float_value(f) {}
-  constexpr explicit FlagDefaultSrc(double d) : double_value(d) {}
+
+#define ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE(T, name) \
+  T name##_value;                                  \
+  constexpr explicit FlagDefaultSrc(T value) : name##_value(value) {}  // NOLINT
+  ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE)
+#undef ABSL_FLAGS_INTERNAL_DFLT_FOR_TYPE
 
   void* dynamic_value;
   FlagDfltGenFunc gen_func;
-  int64_t one_word;
-  float float_value;
-  double double_value;
 };
 
 enum class FlagDefaultKind : uint8_t {
   kDynamicValue = 0,
   kGenFunc = 1,
-  kOneWord = 2,
-  kFloat = 3,
-  kDouble = 4
+  kOneWord = 2  // for default values UP to one word in size
 };
 
 struct FlagDefaultArg {
@@ -279,20 +275,6 @@ constexpr FlagDefaultArg DefaultArg(int) {
   return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kOneWord};
 }
 
-template <typename ValueT, typename GenT,
-          typename std::enable_if<std::is_same<ValueT, float>::value,
-                                  int>::type = (GenT{}, 0)>
-constexpr FlagDefaultArg DefaultArg(int) {
-  return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kFloat};
-}
-
-template <typename ValueT, typename GenT,
-          typename std::enable_if<std::is_same<ValueT, double>::value,
-                                  int>::type = (GenT{}, 0)>
-constexpr FlagDefaultArg DefaultArg(int) {
-  return {FlagDefaultSrc(GenT{}.value), FlagDefaultKind::kDouble};
-}
-
 template <typename ValueT, typename GenT>
 constexpr FlagDefaultArg DefaultArg(char) {
   return {FlagDefaultSrc(&GenT::Gen), FlagDefaultKind::kGenFunc};
@@ -576,9 +558,8 @@ class FlagImpl final : public flags_internal::CommandLineFlag {
   // Mutable flag's state (guarded by `data_guard_`).
 
   // def_kind_ is not guard by DataGuard() since it is accessed in Init without
-  // locks. If necessary we can decrease number of bits used to 2 by folding
-  // one_word storage cases.
-  uint8_t def_kind_ : 3;
+  // locks.
+  uint8_t def_kind_ : 2;
   // Has this flag's value been modified?
   bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard());
   // Has this flag been specified on command line.
diff --git a/absl/flags/parse.cc b/absl/flags/parse.cc
index 2e8f03b4bb5d..fbf4267512b6 100644
--- a/absl/flags/parse.cc
+++ b/absl/flags/parse.cc
@@ -309,11 +309,11 @@ void CheckDefaultValuesParsingRoundtrip() {
   flags_internal::ForEachFlag([&](CommandLineFlag* flag) {
     if (flag->IsRetired()) return;
 
-#define IGNORE_TYPE(T) \
+#define ABSL_FLAGS_INTERNAL_IGNORE_TYPE(T, _) \
   if (flag->IsOfType<T>()) return;
 
-    ABSL_FLAGS_INTERNAL_BUILTIN_TYPES(IGNORE_TYPE)
-#undef IGNORE_TYPE
+    ABSL_FLAGS_INTERNAL_SUPPORTED_TYPES(ABSL_FLAGS_INTERNAL_IGNORE_TYPE)
+#undef ABSL_FLAGS_INTERNAL_IGNORE_TYPE
 
     flags_internal::PrivateHandleAccessor::CheckDefaultValueParsingRoundtrip(
         *flag);