#include "llvm/Support/type_traits.h"
#include <algorithm>
#include <cassert>
+#include <cstring>
#include <new>
#include <utility>
}
};
+template <typename T> struct OptionalStorage<T, true> {
+ AlignedCharArrayUnion<T> storage;
+ bool hasVal = false;
+
+ OptionalStorage() = default;
+
+ OptionalStorage(const T &y) : hasVal(true) { new (storage.buffer) T(y); }
+ OptionalStorage(const OptionalStorage &O) = default;
+ OptionalStorage(T &&y) : hasVal(true) {
+ std::memcpy(storage.buffer, reinterpret_cast<char*>(&y), sizeof(T));
+ }
+
+ OptionalStorage(OptionalStorage &&O) = default;
+
+ OptionalStorage &operator=(T &&y) {
+ hasVal = true;
+ std::memcpy(storage.buffer, reinterpret_cast<char*>(&y), sizeof(T));
+ return *this;
+ }
+ OptionalStorage &operator=(OptionalStorage &&O) = default;
+
+ OptionalStorage &operator=(const T &y) {
+ hasVal = true;
+ std::memcpy(storage.buffer, reinterpret_cast<char const*>(&y), sizeof(T));
+ return *this;
+ }
+ OptionalStorage &operator=(const OptionalStorage &O) = default;
+
+ ~OptionalStorage() = default;
+
+ T *getPointer() {
+ assert(hasVal);
+ return reinterpret_cast<T *>(storage.buffer);
+ }
+ const T *getPointer() const {
+ assert(hasVal);
+ return reinterpret_cast<const T *>(storage.buffer);
+ }
+
+ void reset() { hasVal = false; }
+};
+
} // namespace optional_detail
template <typename T> class Optional {
namespace {
+static_assert(llvm::is_trivially_copyable<Optional<int>>::value,
+ "trivially copyable");
+
+static_assert(llvm::is_trivially_copyable<Optional<std::array<int, 3>>>::value,
+ "trivially copyable");
+
struct NonDefaultConstructible {
static unsigned CopyConstructions;
static unsigned Destructions;
unsigned NonDefaultConstructible::Destructions = 0;
unsigned NonDefaultConstructible::CopyAssignments = 0;
+static_assert(
+ !llvm::is_trivially_copyable<Optional<NonDefaultConstructible>>::value,
+ "not trivially copyable");
+
// Test fixture
class OptionalTest : public testing::Test {
};
};
unsigned MultiArgConstructor::Destructions = 0;
+static_assert(
+ !llvm::is_trivially_copyable<Optional<MultiArgConstructor>>::value,
+ "not trivially copyable");
+
TEST_F(OptionalTest, Emplace) {
MultiArgConstructor::ResetCounts();
Optional<MultiArgConstructor> A;
unsigned MoveOnly::Destructions = 0;
unsigned MoveOnly::MoveAssignments = 0;
+static_assert(!llvm::is_trivially_copyable<Optional<MoveOnly>>::value,
+ "not trivially copyable");
+
TEST_F(OptionalTest, MoveOnlyNull) {
MoveOnly::ResetCounts();
Optional<MoveOnly> O;
unsigned Immovable::Constructions = 0;
unsigned Immovable::Destructions = 0;
+static_assert(!llvm::is_trivially_copyable<Optional<Immovable>>::value,
+ "not trivially copyable");
+
TEST_F(OptionalTest, ImmovableEmplace) {
Optional<Immovable> A;
Immovable::ResetCounts();