135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier//===----------------------------------------------------------------------===//
235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier//
335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier//                     The LLVM Compiler Infrastructure
435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier//
535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier// This file is dual licensed under the MIT and the University of Illinois Open
635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier// Source Licenses. See LICENSE.TXT for details.
735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier//
835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier//===----------------------------------------------------------------------===//
935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
1035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier// UNSUPPORTED: c++98, c++03, c++11, c++14
1135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier// <optional>
1235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
1335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
1435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include <optional>
1535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include <type_traits>
1635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include <cassert>
1735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
1835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include "archetypes.hpp"
1935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
2035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliertemplate <class T>
2135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselierstruct SpecialMemberTest {
2235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    using O = std::optional<T>;
2335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
2435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    template <template <class> class TestMF>
2535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    static constexpr bool check_same() {
2635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        return TestMF<O>::value == TestMF<T>::value;
2735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
2835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
2935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    // Test that optional inherits the correct trivial/non-trivial members
3035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    static_assert(check_same<std::is_trivially_destructible>(), "");
3135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    static_assert(check_same<std::is_trivially_copyable>(), "");
3235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier};
3335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
3435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliertemplate <class ...Args> static void sink(Args&&...) {}
3535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
3635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliertemplate <class ...TestTypes>
3735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselierstruct DoTestsMetafunction {
3835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    DoTestsMetafunction() { sink(SpecialMemberTest<TestTypes>{}...); }
3935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier};
4035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
4135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselierstruct TrivialMoveNonTrivialCopy {
4235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialMoveNonTrivialCopy() = default;
4335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialMoveNonTrivialCopy(const TrivialMoveNonTrivialCopy&) {}
4435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialMoveNonTrivialCopy(TrivialMoveNonTrivialCopy&&) = default;
4535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialMoveNonTrivialCopy& operator=(const TrivialMoveNonTrivialCopy&) { return *this; }
4635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialMoveNonTrivialCopy& operator=(TrivialMoveNonTrivialCopy&&) = default;
4735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier};
4835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
4935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselierstruct TrivialCopyNonTrivialMove {
5035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialCopyNonTrivialMove() = default;
5135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialCopyNonTrivialMove(const TrivialCopyNonTrivialMove&) = default;
5235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialCopyNonTrivialMove(TrivialCopyNonTrivialMove&&) {}
5335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialCopyNonTrivialMove& operator=(const TrivialCopyNonTrivialMove&) = default;
5435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TrivialCopyNonTrivialMove& operator=(TrivialCopyNonTrivialMove&&) { return *this; }
5535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier};
5635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
5735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselierint main()
5835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier{
5935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    sink(
6035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        ImplicitTypes::ApplyTypes<DoTestsMetafunction>{},
6135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        ExplicitTypes::ApplyTypes<DoTestsMetafunction>{},
6235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        NonLiteralTypes::ApplyTypes<DoTestsMetafunction>{},
6335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        NonTrivialTypes::ApplyTypes<DoTestsMetafunction>{},
6435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        DoTestsMetafunction<TrivialMoveNonTrivialCopy, TrivialCopyNonTrivialMove>{}
6535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    );
6635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier}
67