Commit f36d3331 by Abseil Team Committed by Copybara-Service

Make mutable CompressedTuple::get() constexpr.

This change makes the mutable overloads of CompressedTuple::get() constexpr.
This is consistent with std::get(std::tuple), which is constexpr since C++14.

PiperOrigin-RevId: 648603141
Change-Id: Icbd61809f7a06723cf581dbed5488b7bae998cc9
parent 1278ee9b
......@@ -89,9 +89,9 @@ struct Storage {
explicit constexpr Storage(absl::in_place_t, V&& v)
: value(std::forward<V>(v)) {}
constexpr const T& get() const& { return value; }
T& get() & { return value; }
constexpr T& get() & { return value; }
constexpr const T&& get() const&& { return std::move(*this).value; }
T&& get() && { return std::move(*this).value; }
constexpr T&& get() && { return std::move(*this).value; }
};
template <typename T, size_t I>
......@@ -102,9 +102,9 @@ struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage<T, I, true> : T {
explicit constexpr Storage(absl::in_place_t, V&& v) : T(std::forward<V>(v)) {}
constexpr const T& get() const& { return *this; }
T& get() & { return *this; }
constexpr T& get() & { return *this; }
constexpr const T&& get() const&& { return std::move(*this); }
T&& get() && { return std::move(*this); }
constexpr T&& get() && { return std::move(*this); }
};
template <typename D, typename I, bool ShouldAnyUseBase>
......@@ -237,7 +237,7 @@ class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple
std::forward<Vs>(base)...) {}
template <int I>
ElemT<I>& get() & {
constexpr ElemT<I>& get() & {
return StorageT<I>::get();
}
......@@ -247,7 +247,7 @@ class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple
}
template <int I>
ElemT<I>&& get() && {
constexpr ElemT<I>&& get() && {
return std::move(*this).StorageT<I>::get();
}
......
......@@ -31,14 +31,22 @@
// These are declared at global scope purely so that error messages
// are smaller and easier to understand.
enum class CallType { kConstRef, kConstMove };
enum class CallType { kMutableRef, kConstRef, kMutableMove, kConstMove };
template <int>
struct Empty {
constexpr CallType value() & { return CallType::kMutableRef; }
constexpr CallType value() const& { return CallType::kConstRef; }
constexpr CallType value() && { return CallType::kMutableMove; }
constexpr CallType value() const&& { return CallType::kConstMove; }
};
// Unconditionally return an lvalue reference to `t`.
template <typename T>
constexpr T& AsLValue(T&& t) {
return t;
}
template <typename T>
struct NotEmpty {
T value;
......@@ -375,8 +383,24 @@ TEST(CompressedTupleTest, Constexpr) {
constexpr int value() const { return v; }
int v;
};
constexpr CompressedTuple<int, double, CompressedTuple<int>, Empty<0>> x(
7, 1.25, CompressedTuple<int>(5), {});
using Tuple = CompressedTuple<int, double, CompressedTuple<int>, Empty<0>>;
constexpr int r0 =
AsLValue(Tuple(1, 0.75, CompressedTuple<int>(9), {})).get<0>();
constexpr double r1 =
AsLValue(Tuple(1, 0.75, CompressedTuple<int>(9), {})).get<1>();
constexpr int r2 =
AsLValue(Tuple(1, 0.75, CompressedTuple<int>(9), {})).get<2>().get<0>();
constexpr CallType r3 =
AsLValue(Tuple(1, 0.75, CompressedTuple<int>(9), {})).get<3>().value();
EXPECT_EQ(r0, 1);
EXPECT_EQ(r1, 0.75);
EXPECT_EQ(r2, 9);
EXPECT_EQ(r3, CallType::kMutableRef);
constexpr Tuple x(7, 1.25, CompressedTuple<int>(5), {});
constexpr int x0 = x.get<0>();
constexpr double x1 = x.get<1>();
constexpr int x2 = x.get<2>().get<0>();
......@@ -387,6 +411,18 @@ TEST(CompressedTupleTest, Constexpr) {
EXPECT_EQ(x2, 5);
EXPECT_EQ(x3, CallType::kConstRef);
constexpr int m0 = Tuple(5, 0.25, CompressedTuple<int>(3), {}).get<0>();
constexpr double m1 = Tuple(5, 0.25, CompressedTuple<int>(3), {}).get<1>();
constexpr int m2 =
Tuple(5, 0.25, CompressedTuple<int>(3), {}).get<2>().get<0>();
constexpr CallType m3 =
Tuple(5, 0.25, CompressedTuple<int>(3), {}).get<3>().value();
EXPECT_EQ(m0, 5);
EXPECT_EQ(m1, 0.25);
EXPECT_EQ(m2, 3);
EXPECT_EQ(m3, CallType::kMutableMove);
constexpr CompressedTuple<Empty<0>, TrivialStruct, int> trivial = {};
constexpr CallType trivial0 = trivial.get<0>().value();
constexpr int trivial1 = trivial.get<1>().value();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment