mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 19:52:54 +01:00
[ADT] Factor out in_place_t and expose in Optional ctor
Differential Revision: https://reviews.llvm.org/D100671
This commit is contained in:
parent
6944a84c4d
commit
337d1f312b
@ -17,6 +17,7 @@
|
||||
|
||||
#include "llvm/ADT/Hashing.h"
|
||||
#include "llvm/ADT/None.h"
|
||||
#include "llvm/ADT/STLForwardCompat.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include "llvm/Support/type_traits.h"
|
||||
#include <cassert>
|
||||
@ -30,8 +31,6 @@ class raw_ostream;
|
||||
|
||||
namespace optional_detail {
|
||||
|
||||
struct in_place_t {};
|
||||
|
||||
/// Storage for any type.
|
||||
//
|
||||
// The specialization condition intentionally uses
|
||||
@ -245,13 +244,16 @@ public:
|
||||
constexpr Optional() {}
|
||||
constexpr Optional(NoneType) {}
|
||||
|
||||
constexpr Optional(const T &y) : Storage(optional_detail::in_place_t{}, y) {}
|
||||
constexpr Optional(const T &y) : Storage(in_place, y) {}
|
||||
constexpr Optional(const Optional &O) = default;
|
||||
|
||||
constexpr Optional(T &&y)
|
||||
: Storage(optional_detail::in_place_t{}, std::move(y)) {}
|
||||
constexpr Optional(T &&y) : Storage(in_place, std::move(y)) {}
|
||||
constexpr Optional(Optional &&O) = default;
|
||||
|
||||
template <typename... ArgTypes>
|
||||
constexpr Optional(in_place_t, ArgTypes &&...Args)
|
||||
: Storage(in_place, std::forward<ArgTypes>(Args)...) {}
|
||||
|
||||
Optional &operator=(T &&y) {
|
||||
Storage = std::move(y);
|
||||
return *this;
|
||||
|
@ -44,6 +44,25 @@ template <typename B1, typename... Bn>
|
||||
struct disjunction<B1, Bn...>
|
||||
: std::conditional<bool(B1::value), B1, disjunction<Bn...>>::type {};
|
||||
|
||||
struct in_place_t // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
explicit in_place_t() = default;
|
||||
};
|
||||
/// \warning This must not be odr-used, as it cannot be made \c inline in C++14.
|
||||
constexpr in_place_t in_place; // NOLINT(readability-identifier-naming)
|
||||
|
||||
template <typename T>
|
||||
struct in_place_type_t // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
explicit in_place_type_t() = default;
|
||||
};
|
||||
|
||||
template <std::size_t I>
|
||||
struct in_place_index_t // NOLINT(readability-identifier-naming)
|
||||
{
|
||||
explicit in_place_index_t() = default;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Features from C++20
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -195,6 +195,14 @@ TEST(OptionalTest, NullCopyConstructionTest) {
|
||||
EXPECT_EQ(0u, NonDefaultConstructible::Destructions);
|
||||
}
|
||||
|
||||
TEST(OptionalTest, InPlaceConstructionNonDefaultConstructibleTest) {
|
||||
NonDefaultConstructible::ResetCounts();
|
||||
{ Optional<NonDefaultConstructible> A{in_place, 1}; }
|
||||
EXPECT_EQ(0u, NonDefaultConstructible::CopyConstructions);
|
||||
EXPECT_EQ(0u, NonDefaultConstructible::CopyAssignments);
|
||||
EXPECT_EQ(1u, NonDefaultConstructible::Destructions);
|
||||
}
|
||||
|
||||
TEST(OptionalTest, GetValueOr) {
|
||||
Optional<int> A;
|
||||
EXPECT_EQ(42, A.getValueOr(42));
|
||||
@ -214,6 +222,11 @@ struct MultiArgConstructor {
|
||||
MultiArgConstructor &operator=(const MultiArgConstructor &) = delete;
|
||||
MultiArgConstructor &operator=(MultiArgConstructor &&) = delete;
|
||||
|
||||
friend bool operator==(const MultiArgConstructor &LHS,
|
||||
const MultiArgConstructor &RHS) {
|
||||
return LHS.x == RHS.x && LHS.y == RHS.y;
|
||||
}
|
||||
|
||||
static unsigned Destructions;
|
||||
~MultiArgConstructor() {
|
||||
++Destructions;
|
||||
@ -244,6 +257,34 @@ TEST(OptionalTest, Emplace) {
|
||||
EXPECT_EQ(1u, MultiArgConstructor::Destructions);
|
||||
}
|
||||
|
||||
TEST(OptionalTest, InPlaceConstructionMultiArgConstructorTest) {
|
||||
MultiArgConstructor::ResetCounts();
|
||||
{
|
||||
Optional<MultiArgConstructor> A{in_place, 1, 2};
|
||||
EXPECT_TRUE(A.hasValue());
|
||||
EXPECT_EQ(1, A->x);
|
||||
EXPECT_EQ(2, A->y);
|
||||
Optional<MultiArgConstructor> B{in_place, 5, false};
|
||||
EXPECT_TRUE(B.hasValue());
|
||||
EXPECT_EQ(5, B->x);
|
||||
EXPECT_EQ(-5, B->y);
|
||||
EXPECT_EQ(0u, MultiArgConstructor::Destructions);
|
||||
}
|
||||
EXPECT_EQ(2u, MultiArgConstructor::Destructions);
|
||||
}
|
||||
|
||||
TEST(OptionalTest, InPlaceConstructionAndEmplaceEquivalentTest) {
|
||||
MultiArgConstructor::ResetCounts();
|
||||
{
|
||||
Optional<MultiArgConstructor> A{in_place, 1, 2};
|
||||
Optional<MultiArgConstructor> B;
|
||||
B.emplace(1, 2);
|
||||
EXPECT_EQ(0u, MultiArgConstructor::Destructions);
|
||||
ASSERT_EQ(A, B);
|
||||
}
|
||||
EXPECT_EQ(2u, MultiArgConstructor::Destructions);
|
||||
}
|
||||
|
||||
struct MoveOnly {
|
||||
static unsigned MoveConstructions;
|
||||
static unsigned Destructions;
|
||||
@ -391,6 +432,15 @@ TEST(OptionalTest, ImmovableEmplace) {
|
||||
EXPECT_EQ(0u, Immovable::Destructions);
|
||||
}
|
||||
|
||||
TEST(OptionalTest, ImmovableInPlaceConstruction) {
|
||||
Immovable::ResetCounts();
|
||||
Optional<Immovable> A{in_place, 4};
|
||||
EXPECT_TRUE((bool)A);
|
||||
EXPECT_EQ(4, A->val);
|
||||
EXPECT_EQ(1u, Immovable::Constructions);
|
||||
EXPECT_EQ(0u, Immovable::Destructions);
|
||||
}
|
||||
|
||||
// Craft a class which is_trivially_copyable, but not
|
||||
// is_trivially_copy_constructible.
|
||||
struct NonTCopy {
|
||||
|
Loading…
Reference in New Issue
Block a user