Skip to content

Commit 14d4aed

Browse files
Abseil Teamcopybara-github
authored andcommitted
Add std::variant specializations for IsOwner and IsView
Fixes: #1960 PiperOrigin-RevId: 951017341 Change-Id: If8de7073695152947aa93e0d5a3800dac6e353b6
1 parent 3d9e676 commit 14d4aed

2 files changed

Lines changed: 40 additions & 0 deletions

File tree

absl/meta/type_traits.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <string_view>
4242
#include <type_traits>
4343
#include <utility>
44+
#include <variant>
4445
#include <vector>
4546

4647
#include "absl/base/attributes.h"
@@ -583,6 +584,14 @@ struct IsOwner<std::basic_string<T, Traits, Alloc>> : std::true_type {};
583584
template <typename T, typename Alloc>
584585
struct IsOwner<std::vector<T, Alloc>> : std::true_type {};
585586

587+
template <typename... T>
588+
struct IsOwner<std::variant<T...>>
589+
: std::bool_constant<(sizeof...(T) > 0) &&
590+
// Uses a C++17 fold expression where '...' unpacks the
591+
// parameter pack T, and 'true &&' provides the base
592+
// case for the logical AND operation across all types.
593+
(true && ... && IsOwner<T>::value)> {};
594+
586595
// Detects if a class's definition has declared itself to be a view by declaring
587596
// using absl_internal_is_view = std::true_type;
588597
// as a member.
@@ -620,6 +629,14 @@ struct IsView<std::pair<T1, T2>>
620629
template <typename Char, typename Traits>
621630
struct IsView<std::basic_string_view<Char, Traits>> : std::true_type {};
622631

632+
template <typename... T>
633+
struct IsView<std::variant<T...>>
634+
: std::bool_constant<(sizeof...(T) > 0) &&
635+
// Uses a C++17 fold expression where '...' unpacks the
636+
// parameter pack T, and 'true &&' provides the base
637+
// case for the logical AND operation across all types.
638+
(true && ... && IsView<T>::value)> {};
639+
623640
#ifdef __cpp_lib_span
624641
template <typename T>
625642
struct IsView<std::span<T>> : std::true_type {};

absl/meta/type_traits_test.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <string_view>
2020
#include <type_traits>
2121
#include <utility>
22+
#include <variant>
2223
#include <vector>
2324

2425
#include "gtest/gtest.h"
@@ -31,6 +32,11 @@ namespace {
3132

3233
using ::testing::StaticAssertTypeEq;
3334

35+
template <typename T>
36+
using IsViewAndNotOwner =
37+
std::conjunction<absl::type_traits_internal::IsView<T>,
38+
std::negation<absl::type_traits_internal::IsOwner<T>>>;
39+
3440
template <typename T>
3541
using IsOwnerAndNotView =
3642
std::conjunction<absl::type_traits_internal::IsOwner<T>,
@@ -50,6 +56,23 @@ static_assert(!IsOwnerAndNotView<std::string_view>::value,
5056
static_assert(!IsOwnerAndNotView<std::wstring_view>::value,
5157
"wstring_view is a view, not an owner");
5258

59+
static_assert(!IsOwnerAndNotView<std::variant<>>::value,
60+
"empty variant is not an owner");
61+
static_assert(!IsViewAndNotOwner<std::variant<>>::value,
62+
"empty variant is not a view");
63+
64+
static_assert(IsOwnerAndNotView<std::variant<std::string, std::vector<char>,
65+
std::vector<int>>>::value,
66+
"aggregate of owners is an owner");
67+
static_assert(
68+
IsViewAndNotOwner<std::variant<std::wstring_view, std::string_view>>::value,
69+
"aggregate of views is an view");
70+
71+
static_assert(!IsOwnerAndNotView<std::variant<const char*, std::string>>::value,
72+
"variant of mixed-ownership types is not considered an owner");
73+
static_assert(!IsViewAndNotOwner<std::variant<const char*, std::string>>::value,
74+
"variant of mixed-ownership types is not considered a view");
75+
5376
template <class T, class U>
5477
struct simple_pair {
5578
T first;

0 commit comments

Comments
 (0)