about summary refs log tree commit diff
path: root/absl/types/internal
diff options
context:
space:
mode:
Diffstat (limited to 'absl/types/internal')
-rw-r--r--absl/types/internal/variant.h15
1 files changed, 11 insertions, 4 deletions
diff --git a/absl/types/internal/variant.h b/absl/types/internal/variant.h
index 3414c9142daf..7db5e0535f68 100644
--- a/absl/types/internal/variant.h
+++ b/absl/types/internal/variant.h
@@ -579,12 +579,9 @@ struct VariantCoreAccess {
     self.index_ = other.index();
   }
 
+  // Access a variant alternative, assuming the index is correct.
   template <std::size_t I, class Variant>
   static VariantAccessResult<I, Variant> Access(Variant&& self) {
-    if (ABSL_PREDICT_FALSE(self.index_ != I)) {
-      TypedThrowBadVariantAccess<VariantAccessResult<I, Variant>>();
-    }
-
     // This cast instead of invocation of AccessUnion with an rvalue is a
     // workaround for msvc. Without this there is a runtime failure when dealing
     // with rvalues.
@@ -593,6 +590,16 @@ struct VariantCoreAccess {
         variant_internal::AccessUnion(self.state_, SizeT<I>()));
   }
 
+  // Access a variant alternative, throwing if the index is incorrect.
+  template <std::size_t I, class Variant>
+  static VariantAccessResult<I, Variant> CheckedAccess(Variant&& self) {
+    if (ABSL_PREDICT_FALSE(self.index_ != I)) {
+      TypedThrowBadVariantAccess<VariantAccessResult<I, Variant>>();
+    }
+
+    return Access<I>(absl::forward<Variant>(self));
+  }
+
   // The implementation of the move-assignment operation for a variant.
   template <class VType>
   struct MoveAssignVisitor {