about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--absl/flags/internal/flag.cc12
-rw-r--r--absl/flags/internal/flag.h48
-rw-r--r--absl/strings/internal/str_format/bind.cc3
-rw-r--r--absl/strings/internal/str_format/bind_test.cc24
-rw-r--r--absl/strings/internal/str_format/extension.cc24
-rw-r--r--absl/strings/internal/str_format/extension.h51
-rw-r--r--absl/strings/internal/str_format/parser.cc37
-rw-r--r--absl/strings/internal/str_format/parser.h13
-rw-r--r--absl/strings/internal/str_format/parser_test.cc32
9 files changed, 116 insertions, 128 deletions
diff --git a/absl/flags/internal/flag.cc b/absl/flags/internal/flag.cc
index 3df8d82cfede..6ce7def2d3d2 100644
--- a/absl/flags/internal/flag.cc
+++ b/absl/flags/internal/flag.cc
@@ -120,7 +120,7 @@ void FlagImpl::Destroy() {
     if (value_.dynamic) Delete(op_, value_.dynamic);
 
     // Release the dynamically allocated default value if any.
-    if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) {
+    if (DefaultKind() == FlagDefaultKind::kDynamicValue) {
       Delete(op_, default_src_.dynamic_value);
     }
 
@@ -135,7 +135,7 @@ void FlagImpl::Destroy() {
 
 std::unique_ptr<void, DynValueDeleter> FlagImpl::MakeInitValue() const {
   void* res = nullptr;
-  if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) {
+  if (DefaultKind() == FlagDefaultKind::kDynamicValue) {
     res = Clone(op_, default_src_.dynamic_value);
   } else {
     res = (*default_src_.gen_func)();
@@ -150,8 +150,8 @@ std::string FlagImpl::Filename() const {
 }
 
 std::string FlagImpl::Help() const {
-  return help_source_kind_ == FlagHelpKind::kLiteral ? help_.literal
-                                                     : help_.gen_func();
+  return HelpSourceKind() == FlagHelpKind::kLiteral ? help_.literal
+                                                    : help_.gen_func();
 }
 
 bool FlagImpl::IsModified() const {
@@ -364,7 +364,7 @@ bool FlagImpl::SetFromString(absl::string_view value, FlagSettingMode set_mode,
       break;
     }
     case SET_FLAGS_DEFAULT: {
-      if (def_kind_ == FlagDefaultSrcKind::kDynamicValue) {
+      if (DefaultKind() == FlagDefaultKind::kDynamicValue) {
         if (!TryParse(&default_src_.dynamic_value, value, err)) {
           return false;
         }
@@ -375,7 +375,7 @@ bool FlagImpl::SetFromString(absl::string_view value, FlagSettingMode set_mode,
         }
 
         default_src_.dynamic_value = new_default_val;
-        def_kind_ = FlagDefaultSrcKind::kDynamicValue;
+        def_kind_ = static_cast<uint8_t>(FlagDefaultKind::kDynamicValue);
       }
 
       if (!modified_) {
diff --git a/absl/flags/internal/flag.h b/absl/flags/internal/flag.h
index cc07dce1829b..b5471fa8a734 100644
--- a/absl/flags/internal/flag.h
+++ b/absl/flags/internal/flag.h
@@ -87,7 +87,7 @@ union FlagHelpMsg {
   HelpGenFunc gen_func;
 };
 
-enum class FlagHelpKind : int8_t { kLiteral, kGenFunc };
+enum class FlagHelpKind : uint8_t { kLiteral = 0, kGenFunc = 1 };
 
 struct FlagHelpArg {
   FlagHelpMsg source;
@@ -147,7 +147,7 @@ union FlagDefaultSrc {
   FlagDfltGenFunc gen_func;
 };
 
-enum class FlagDefaultSrcKind : int8_t { kDynamicValue, kGenFunc };
+enum class FlagDefaultKind : uint8_t { kDynamicValue = 0, kGenFunc = 1 };
 
 ///////////////////////////////////////////////////////////////////////////////
 // Flag current value auxiliary structs.
@@ -279,8 +279,14 @@ class FlagImpl {
         op_(op),
         marshalling_op_(marshalling_op),
         help_(help.source),
-        help_source_kind_(help.kind),
-        def_kind_(FlagDefaultSrcKind::kGenFunc),
+        help_source_kind_(static_cast<uint8_t>(help.kind)),
+        def_kind_(static_cast<uint8_t>(FlagDefaultKind::kGenFunc)),
+        is_data_guard_inited_(false),
+        modified_(false),
+        on_command_line_(false),
+        inited_(false),
+        counter_(0),
+        callback_(nullptr),
         default_src_(default_value_gen),
         data_guard_{} {}
 
@@ -370,6 +376,14 @@ class FlagImpl {
   // Lazy initialization of the Flag's data.
   void Init();
 
+  FlagHelpKind HelpSourceKind() const {
+    return static_cast<FlagHelpKind>(help_source_kind_);
+  }
+  FlagDefaultKind DefaultKind() const
+      ABSL_EXCLUSIVE_LOCKS_REQUIRED(*DataGuard()) {
+    return static_cast<FlagDefaultKind>(def_kind_);
+  }
+
   // Immutable flag's state.
 
   // Flags name passed to ABSL_FLAG as second arg.
@@ -383,35 +397,31 @@ class FlagImpl {
   // Help message literal or function to generate it.
   const FlagHelpMsg help_;
   // Indicates if help message was supplied as literal or generator func.
-  const FlagHelpKind help_source_kind_;
-
-  // Indicates that the Flag state is initialized.
-  std::atomic<bool> inited_{false};
+  const uint8_t help_source_kind_ : 1;
 
   // Mutable flag's state (guarded by `data_guard_`).
 
+  // If def_kind_ == kDynamicValue, default_src_ holds a dynamically allocated
+  // value.
+  uint8_t def_kind_ : 1 ABSL_GUARDED_BY(*DataGuard());
   // Protects against multiple concurrent constructions of `data_guard_`.
-  bool is_data_guard_inited_ = false;
+  bool is_data_guard_inited_ : 1;
   // Has this flag's value been modified?
-  bool modified_ ABSL_GUARDED_BY(*DataGuard()) = false;
+  bool modified_ : 1 ABSL_GUARDED_BY(*DataGuard());
   // Has this flag been specified on command line.
-  bool on_command_line_ ABSL_GUARDED_BY(*DataGuard()) = false;
+  bool on_command_line_ : 1 ABSL_GUARDED_BY(*DataGuard());
 
+  // Indicates that the flag state is initialized.
+  std::atomic<bool> inited_;
   // Mutation counter
-  int64_t counter_ ABSL_GUARDED_BY(*DataGuard()) = 0;
-
+  int64_t counter_ ABSL_GUARDED_BY(*DataGuard());
   // Optional flag's callback and absl::Mutex to guard the invocations.
-  FlagCallback* callback_ ABSL_GUARDED_BY(*DataGuard()) = nullptr;
-
-  // If def_kind_ == kDynamicValue, default_src_ holds a dynamically allocated
-  // value.
-  FlagDefaultSrcKind def_kind_ ABSL_GUARDED_BY(*DataGuard());
+  FlagCallback* callback_ ABSL_GUARDED_BY(*DataGuard());
   // Either a pointer to the function generating the default value based on the
   // value specified in ABSL_FLAG or pointer to the dynamically set default
   // value via SetCommandLineOptionWithMode. def_kind_ is used to distinguish
   // these two cases.
   FlagDefaultSrc default_src_ ABSL_GUARDED_BY(*DataGuard());
-
   // Current Flag Value
   FlagValue value_;
 
diff --git a/absl/strings/internal/str_format/bind.cc b/absl/strings/internal/str_format/bind.cc
index 1ee281af9c16..2d19b613e43d 100644
--- a/absl/strings/internal/str_format/bind.cc
+++ b/absl/strings/internal/str_format/bind.cc
@@ -77,7 +77,6 @@ inline bool ArgContext::Bind(const UnboundConversion* unbound,
     bound->set_precision(-1);
   }
 
-  bound->set_length_mod(unbound->length_mod);
   bound->set_conv(unbound->conv);
   bound->set_arg(arg);
   return true;
@@ -143,7 +142,7 @@ class SummarizingConverter {
     ss << "{" << Streamable(spec, {*bound.arg()}) << ":" << bound.flags();
     if (bound.width() >= 0) ss << bound.width();
     if (bound.precision() >= 0) ss << "." << bound.precision();
-    ss << bound.length_mod() << bound.conv() << "}";
+    ss << bound.conv() << "}";
     Append(ss.str());
     return true;
   }
diff --git a/absl/strings/internal/str_format/bind_test.cc b/absl/strings/internal/str_format/bind_test.cc
index f6817419feb4..64790a85fd23 100644
--- a/absl/strings/internal/str_format/bind_test.cc
+++ b/absl/strings/internal/str_format/bind_test.cc
@@ -113,18 +113,18 @@ TEST_F(FormatBindTest, FormatPack) {
                                 FormatArgImpl(ia[2]), FormatArgImpl(ia[3]),
                                 FormatArgImpl(ia[4])};
   const Expectation kExpect[] = {
-    {__LINE__, "a%4db%dc", "a{10:4d}b{20:d}c"},
-    {__LINE__, "a%.4db%dc", "a{10:.4d}b{20:d}c"},
-    {__LINE__, "a%4.5db%dc", "a{10:4.5d}b{20:d}c"},
-    {__LINE__, "a%db%4.5dc", "a{10:d}b{20:4.5d}c"},
-    {__LINE__, "a%db%*.*dc", "a{10:d}b{40:20.30d}c"},
-    {__LINE__, "a%.*fb", "a{20:.10f}b"},
-    {__LINE__, "a%1$db%2$*3$.*4$dc", "a{10:d}b{20:30.40d}c"},
-    {__LINE__, "a%4$db%3$*2$.*1$dc", "a{40:d}b{30:20.10d}c"},
-    {__LINE__, "a%04ldb", "a{10:04ld}b"},
-    {__LINE__, "a%-#04lldb", "a{10:-#04lld}b"},
-    {__LINE__, "a%1$*5$db", "a{10:-10d}b"},
-    {__LINE__, "a%1$.*5$db", "a{10:d}b"},
+      {__LINE__, "a%4db%dc", "a{10:4d}b{20:d}c"},
+      {__LINE__, "a%.4db%dc", "a{10:.4d}b{20:d}c"},
+      {__LINE__, "a%4.5db%dc", "a{10:4.5d}b{20:d}c"},
+      {__LINE__, "a%db%4.5dc", "a{10:d}b{20:4.5d}c"},
+      {__LINE__, "a%db%*.*dc", "a{10:d}b{40:20.30d}c"},
+      {__LINE__, "a%.*fb", "a{20:.10f}b"},
+      {__LINE__, "a%1$db%2$*3$.*4$dc", "a{10:d}b{20:30.40d}c"},
+      {__LINE__, "a%4$db%3$*2$.*1$dc", "a{40:d}b{30:20.10d}c"},
+      {__LINE__, "a%04ldb", "a{10:04d}b"},
+      {__LINE__, "a%-#04lldb", "a{10:-#04d}b"},
+      {__LINE__, "a%1$*5$db", "a{10:-10d}b"},
+      {__LINE__, "a%1$.*5$db", "a{10:d}b"},
   };
   for (const Expectation &e : kExpect) {
     absl::string_view fmt = e.fmt;
diff --git a/absl/strings/internal/str_format/extension.cc b/absl/strings/internal/str_format/extension.cc
index 559011bf4a97..21688e873f2c 100644
--- a/absl/strings/internal/str_format/extension.cc
+++ b/absl/strings/internal/str_format/extension.cc
@@ -22,28 +22,6 @@
 namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace str_format_internal {
-namespace {
-// clang-format off
-#define ABSL_LENGTH_MODS_EXPAND_ \
-  X_VAL(h) X_SEP \
-  X_VAL(hh) X_SEP \
-  X_VAL(l) X_SEP \
-  X_VAL(ll) X_SEP \
-  X_VAL(L) X_SEP \
-  X_VAL(j) X_SEP \
-  X_VAL(z) X_SEP \
-  X_VAL(t) X_SEP \
-  X_VAL(q)
-// clang-format on
-}  // namespace
-
-const LengthMod::Spec LengthMod::kSpecs[] = {
-#define X_VAL(id) { LengthMod::id, #id, strlen(#id) }
-#define X_SEP ,
-    ABSL_LENGTH_MODS_EXPAND_, {LengthMod::none, "", 0}
-#undef X_VAL
-#undef X_SEP
-};
 
 const ConversionChar::Spec ConversionChar::kSpecs[] = {
 #define X_VAL(id) { ConversionChar::id, #id[0] }
@@ -64,8 +42,6 @@ std::string Flags::ToString() const {
   return s;
 }
 
-const size_t LengthMod::kNumValues;
-
 const size_t ConversionChar::kNumValues;
 
 bool FormatSinkImpl::PutPaddedString(string_view v, int w, int p, bool l) {
diff --git a/absl/strings/internal/str_format/extension.h b/absl/strings/internal/str_format/extension.h
index 0a7640354fd4..4868eac3e8b4 100644
--- a/absl/strings/internal/str_format/extension.h
+++ b/absl/strings/internal/str_format/extension.h
@@ -136,54 +136,6 @@ struct Flags {
   }
 };
 
-struct ABSL_DLL LengthMod {
- public:
-  enum Id : uint8_t {
-    h, hh, l, ll, L, j, z, t, q, none
-  };
-  static const size_t kNumValues = none + 1;
-
-  LengthMod() : id_(none) {}
-
-  // Index into the opaque array of LengthMod enums.
-  // Requires: i < kNumValues
-  static LengthMod FromIndex(size_t i) {
-    return LengthMod(kSpecs[i].value);
-  }
-
-  static LengthMod FromId(Id id) { return LengthMod(id); }
-
-  // The length modifier std::string associated with a specified LengthMod.
-  string_view name() const {
-    const Spec& spec = kSpecs[id_];
-    return {spec.name, spec.name_length};
-  }
-
-  Id id() const { return id_; }
-
-  friend bool operator==(const LengthMod& a, const LengthMod& b) {
-    return a.id() == b.id();
-  }
-  friend bool operator!=(const LengthMod& a, const LengthMod& b) {
-    return !(a == b);
-  }
-  friend std::ostream& operator<<(std::ostream& os, const LengthMod& v) {
-    return os << v.name();
-  }
-
- private:
-  struct Spec {
-    Id value;
-    const char *name;
-    size_t name_length;
-  };
-  static const Spec kSpecs[];
-
-  explicit LengthMod(Id id) : id_(id) {}
-
-  Id id_;
-};
-
 // clang-format off
 #define ABSL_CONVERSION_CHARS_EXPAND_(X_VAL, X_SEP) \
   /* text */ \
@@ -306,7 +258,6 @@ struct ABSL_DLL ConversionChar {
 class ConversionSpec {
  public:
   Flags flags() const { return flags_; }
-  LengthMod length_mod() const { return length_mod_; }
   ConversionChar conv() const {
     // Keep this field first in the struct . It generates better code when
     // accessing it when ConversionSpec is passed by value in registers.
@@ -322,7 +273,6 @@ class ConversionSpec {
   int precision() const { return precision_; }
 
   void set_flags(Flags f) { flags_ = f; }
-  void set_length_mod(LengthMod lm) { length_mod_ = lm; }
   void set_conv(ConversionChar c) { conv_ = c; }
   void set_width(int w) { width_ = w; }
   void set_precision(int p) { precision_ = p; }
@@ -331,7 +281,6 @@ class ConversionSpec {
  private:
   ConversionChar conv_;
   Flags flags_;
-  LengthMod length_mod_;
   int width_;
   int precision_;
 };
diff --git a/absl/strings/internal/str_format/parser.cc b/absl/strings/internal/str_format/parser.cc
index eff68f35c032..c4b527bc48aa 100644
--- a/absl/strings/internal/str_format/parser.cc
+++ b/absl/strings/internal/str_format/parser.cc
@@ -18,7 +18,8 @@ ABSL_NAMESPACE_BEGIN
 namespace str_format_internal {
 
 using CC = ConversionChar::Id;
-using LM = LengthMod::Id;
+using LM = LengthMod;
+
 ABSL_CONST_INIT const ConvTag kTags[256] = {
     {},    {},    {},    {},    {},    {},    {},    {},     // 00-07
     {},    {},    {},    {},    {},    {},    {},    {},     // 08-0f
@@ -205,11 +206,11 @@ flags_done:
     using str_format_internal::LengthMod;
     LengthMod length_mod = tag.as_length();
     ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
-    if (c == 'h' && length_mod.id() == LengthMod::h) {
-      conv->length_mod = LengthMod::FromId(LengthMod::hh);
+    if (c == 'h' && length_mod == LengthMod::h) {
+      conv->length_mod = LengthMod::hh;
       ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
-    } else if (c == 'l' && length_mod.id() == LengthMod::l) {
-      conv->length_mod = LengthMod::FromId(LengthMod::ll);
+    } else if (c == 'l' && length_mod == LengthMod::l) {
+      conv->length_mod = LengthMod::ll;
       ABSL_FORMAT_PARSER_INTERNAL_GET_CHAR();
     } else {
       conv->length_mod = length_mod;
@@ -228,6 +229,32 @@ flags_done:
 
 }  // namespace
 
+std::string LengthModToString(LengthMod v) {
+  switch (v) {
+    case LengthMod::h:
+      return "h";
+    case LengthMod::hh:
+      return "hh";
+    case LengthMod::l:
+      return "l";
+    case LengthMod::ll:
+      return "ll";
+    case LengthMod::L:
+      return "L";
+    case LengthMod::j:
+      return "j";
+    case LengthMod::z:
+      return "z";
+    case LengthMod::t:
+      return "t";
+    case LengthMod::q:
+      return "q";
+    case LengthMod::none:
+      return "";
+  }
+  return "";
+}
+
 const char *ConsumeUnboundConversion(const char *p, const char *end,
                                      UnboundConversion *conv, int *next_arg) {
   if (*next_arg < 0) return ConsumeConversion<true>(p, end, conv, next_arg);
diff --git a/absl/strings/internal/str_format/parser.h b/absl/strings/internal/str_format/parser.h
index 116dda06d4e2..6cbe257697e4 100644
--- a/absl/strings/internal/str_format/parser.h
+++ b/absl/strings/internal/str_format/parser.h
@@ -6,10 +6,12 @@
 #include <stdlib.h>
 
 #include <cassert>
+#include <cstdint>
 #include <initializer_list>
 #include <iosfwd>
 #include <iterator>
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "absl/strings/internal/str_format/checker.h"
@@ -19,6 +21,10 @@ namespace absl {
 ABSL_NAMESPACE_BEGIN
 namespace str_format_internal {
 
+enum class LengthMod : std::uint8_t { h, hh, l, ll, L, j, z, t, q, none };
+
+std::string LengthModToString(LengthMod v);
+
 // The analyzed properties of a single specified conversion.
 struct UnboundConversion {
   UnboundConversion()
@@ -60,7 +66,7 @@ struct UnboundConversion {
   InputValue precision;
 
   Flags flags;
-  LengthMod length_mod;
+  LengthMod length_mod = LengthMod::none;
   ConversionChar conv;
 };
 
@@ -79,7 +85,8 @@ class ConvTag {
   constexpr ConvTag(ConversionChar::Id id) : tag_(id) {}  // NOLINT
   // We invert the length modifiers to make them negative so that we can easily
   // test for them.
-  constexpr ConvTag(LengthMod::Id id) : tag_(~id) {}  // NOLINT
+  constexpr ConvTag(LengthMod length_mod)  // NOLINT
+      : tag_(~static_cast<std::int8_t>(length_mod)) {}
   // Everything else is -128, which is negative to make is_conv() simpler.
   constexpr ConvTag() : tag_(-128) {}
 
@@ -91,7 +98,7 @@ class ConvTag {
   }
   LengthMod as_length() const {
     assert(is_length());
-    return LengthMod::FromId(static_cast<LengthMod::Id>(~tag_));
+    return static_cast<LengthMod>(~tag_);
   }
 
  private:
diff --git a/absl/strings/internal/str_format/parser_test.cc b/absl/strings/internal/str_format/parser_test.cc
index 33ed8f094436..4a8efd0805aa 100644
--- a/absl/strings/internal/str_format/parser_test.cc
+++ b/absl/strings/internal/str_format/parser_test.cc
@@ -17,7 +17,7 @@ using testing::Pair;
 TEST(LengthModTest, Names) {
   struct Expectation {
     int line;
-    LengthMod::Id id;
+    LengthMod mod;
     const char *name;
   };
   const Expectation kExpect[] = {
@@ -32,12 +32,10 @@ TEST(LengthModTest, Names) {
     {__LINE__, LengthMod::t,    "t" },
     {__LINE__, LengthMod::q,    "q" },
   };
-  EXPECT_EQ(ABSL_ARRAYSIZE(kExpect), LengthMod::kNumValues);
+  EXPECT_EQ(ABSL_ARRAYSIZE(kExpect), 10);
   for (auto e : kExpect) {
     SCOPED_TRACE(e.line);
-    LengthMod mod = LengthMod::FromId(e.id);
-    EXPECT_EQ(e.id, mod.id());
-    EXPECT_EQ(e.name, mod.name());
+    EXPECT_EQ(e.name, LengthModToString(e.mod));
   }
 }
 
@@ -127,7 +125,6 @@ TEST_F(ConsumeUnboundConversionTest, BasicConversion) {
   EXPECT_FALSE(o.precision.is_from_arg());
   EXPECT_LT(o.precision.value(), 0);
   EXPECT_EQ(1, o.arg_position);
-  EXPECT_EQ(LengthMod::none, o.length_mod.id());
 }
 
 TEST_F(ConsumeUnboundConversionTest, ArgPosition) {
@@ -290,6 +287,29 @@ TEST_F(ConsumeUnboundConversionTest, BasicFlag) {
   }
 }
 
+TEST_F(ConsumeUnboundConversionTest, LengthMod) {
+  EXPECT_TRUE(Run("d"));
+  EXPECT_EQ(LengthMod::none, o.length_mod);
+  EXPECT_TRUE(Run("hd"));
+  EXPECT_EQ(LengthMod::h, o.length_mod);
+  EXPECT_TRUE(Run("hhd"));
+  EXPECT_EQ(LengthMod::hh, o.length_mod);
+  EXPECT_TRUE(Run("ld"));
+  EXPECT_EQ(LengthMod::l, o.length_mod);
+  EXPECT_TRUE(Run("lld"));
+  EXPECT_EQ(LengthMod::ll, o.length_mod);
+  EXPECT_TRUE(Run("Lf"));
+  EXPECT_EQ(LengthMod::L, o.length_mod);
+  EXPECT_TRUE(Run("qf"));
+  EXPECT_EQ(LengthMod::q, o.length_mod);
+  EXPECT_TRUE(Run("jd"));
+  EXPECT_EQ(LengthMod::j, o.length_mod);
+  EXPECT_TRUE(Run("zd"));
+  EXPECT_EQ(LengthMod::z, o.length_mod);
+  EXPECT_TRUE(Run("td"));
+  EXPECT_EQ(LengthMod::t, o.length_mod);
+}
+
 struct SummarizeConsumer {
   std::string* out;
   explicit SummarizeConsumer(std::string* out) : out(out) {}