#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) {
- std::memcpy(storage.buffer, reinterpret_cast<char const *>(&y), sizeof(T));
- }
- 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();