Add GetIf* methods to Item for each type

This allows code to avoid redundant is_foo / GetFoo calls, and will
make it easier to remove the combined GetString/TakeString methods.

PiperOrigin-RevId: 956472466
diff --git a/quiche/common/structured_headers.cc b/quiche/common/structured_headers.cc
index 4a6337a..6e002f5 100644
--- a/quiche/common/structured_headers.cc
+++ b/quiche/common/structured_headers.cc
@@ -802,7 +802,7 @@
   return true;
 }
 
-Item::Item() {}
+Item::Item() = default;
 Item::Item(std::string value, Item::ItemType type) {
   switch (type) {
     case kStringType:
@@ -825,6 +825,44 @@
 Item::Item(double value) : value_(value) {}
 Item::Item(bool value) : value_(value) {}
 
+const int64_t* Item::GetIfInteger() const {
+  return std::get_if<kIntegerType>(&value_);
+}
+
+int64_t* Item::GetIfInteger() { return std::get_if<kIntegerType>(&value_); }
+
+const double* Item::GetIfDecimal() const {
+  return std::get_if<kDecimalType>(&value_);
+}
+
+double* Item::GetIfDecimal() { return std::get_if<kDecimalType>(&value_); }
+
+const std::string* Item::GetIfString() const {
+  return std::get_if<kStringType>(&value_);
+}
+
+std::string* Item::GetIfString() { return std::get_if<kStringType>(&value_); }
+
+const std::string* Item::GetIfToken() const {
+  return std::get_if<kTokenType>(&value_);
+}
+
+std::string* Item::GetIfToken() { return std::get_if<kTokenType>(&value_); }
+
+const std::string* Item::GetIfByteSequence() const {
+  return std::get_if<kByteSequenceType>(&value_);
+}
+
+std::string* Item::GetIfByteSequence() {
+  return std::get_if<kByteSequenceType>(&value_);
+}
+
+const bool* Item::GetIfBoolean() const {
+  return std::get_if<kBooleanType>(&value_);
+}
+
+bool* Item::GetIfBoolean() { return std::get_if<kBooleanType>(&value_); }
+
 bool operator==(const Item&, const Item&) = default;
 
 ParameterizedItem::ParameterizedItem() = default;
diff --git a/quiche/common/structured_headers.h b/quiche/common/structured_headers.h
index 57f8944..0d516d0 100644
--- a/quiche/common/structured_headers.h
+++ b/quiche/common/structured_headers.h
@@ -15,6 +15,7 @@
 #include <variant>
 #include <vector>
 
+#include "absl/base/attributes.h"
 #include "absl/strings/string_view.h"
 #include "quiche/common/platform/api/quiche_export.h"
 #include "quiche/common/platform/api/quiche_logging.h"
@@ -89,21 +90,43 @@
   bool is_boolean() const { return Type() == kBooleanType; }
 
   int64_t GetInteger() const {
-    const auto* value = std::get_if<int64_t>(&value_);
+    const auto* value = GetIfInteger();
     QUICHE_CHECK(value);
     return *value;
   }
   double GetDecimal() const {
-    const auto* value = std::get_if<double>(&value_);
+    const auto* value = GetIfDecimal();
     QUICHE_CHECK(value);
     return *value;
   }
   bool GetBoolean() const {
-    const auto* value = std::get_if<bool>(&value_);
+    const auto* value = GetIfBoolean();
     QUICHE_CHECK(value);
     return *value;
   }
-  // TODO(iclelland): Split up accessors for String, Token and Byte Sequence.
+
+  const int64_t* GetIfInteger() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
+  int64_t* GetIfInteger() ABSL_ATTRIBUTE_LIFETIME_BOUND;
+
+  const double* GetIfDecimal() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
+  double* GetIfDecimal() ABSL_ATTRIBUTE_LIFETIME_BOUND;
+
+  const std::string* GetIfToken() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
+  std::string* GetIfToken() ABSL_ATTRIBUTE_LIFETIME_BOUND;
+
+  // Note: This only returns a non-nullptr if `Type() == kString`, unlike the
+  // deprecated `GetString()` and `TakeString()` methods.
+  const std::string* GetIfString() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
+  std::string* GetIfString() ABSL_ATTRIBUTE_LIFETIME_BOUND;
+
+  const std::string* GetIfByteSequence() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
+  std::string* GetIfByteSequence() ABSL_ATTRIBUTE_LIFETIME_BOUND;
+
+  const bool* GetIfBoolean() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
+  bool* GetIfBoolean() ABSL_ATTRIBUTE_LIFETIME_BOUND;
+
+  // Deprecated: Prefer `GetIfString()`, `GetIfToken()`, or
+  // `GetIfByteSequence()`.
   const std::string& GetString() const {
     struct Visitor {
       const std::string* operator()(const std::monostate&) { return nullptr; }
@@ -117,7 +140,8 @@
     return *value;
   }
 
-  // Transfers ownership of the underlying String, Token, or Byte Sequence.
+  // Deprecated: Prefer `GetIfString()`, `GetIfToken()`, or
+  // `GetIfByteSequence()`.
   std::string TakeString() && {
     struct Visitor {
       std::string* operator()(std::monostate&) { return nullptr; }