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// optional(const optional<T>& rhs);
1435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
1535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include <optional>
1635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include <type_traits>
1735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include <cassert>
1835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
1935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include "test_macros.h"
2035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#include "archetypes.hpp"
2135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
2235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselierusing std::optional;
2335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
2435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliertemplate <class T, class ...InitArgs>
2535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliervoid test(InitArgs&&... args)
2635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier{
2735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    const optional<T> rhs(std::forward<InitArgs>(args)...);
2835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    bool rhs_engaged = static_cast<bool>(rhs);
2935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    optional<T> lhs = rhs;
3035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    assert(static_cast<bool>(lhs) == rhs_engaged);
3135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    if (rhs_engaged)
3235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(*lhs == *rhs);
3335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier}
3435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
3535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliervoid test_throwing_ctor() {
3635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#ifndef TEST_HAS_NO_EXCEPTIONS
3735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    struct Z {
3835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier      Z() : count(0) {}
3935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier      Z(Z const& o) : count(o.count + 1)
4035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier      { if (count == 2) throw 6; }
4135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier      int count;
4235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    };
4335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    const Z z;
4435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    const optional<Z> rhs(z);
4535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    try
4635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
4735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        optional<Z> lhs(rhs);
4835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(false);
4935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
5035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    catch (int i)
5135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
5235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(i == 6);
5335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
5435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#endif
5535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier}
5635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
5735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliertemplate <class T, class ...InitArgs>
5835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliervoid test_ref(InitArgs&&... args)
5935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier{
6035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    const optional<T> rhs(std::forward<InitArgs>(args)...);
6135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    bool rhs_engaged = static_cast<bool>(rhs);
6235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    optional<T> lhs = rhs;
6335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    assert(static_cast<bool>(lhs) == rhs_engaged);
6435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    if (rhs_engaged)
6535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(&(*lhs) == &(*rhs));
6635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier}
6735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
6835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
6935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiseliervoid test_reference_extension()
7035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier{
7135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
7235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    using T = TestTypes::TestType;
7335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    T::reset();
7435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
7535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        T t;
7635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        T::reset_constructors();
7735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test_ref<T&>();
7835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test_ref<T&>(t);
7935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::alive == 1);
8035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::constructed == 0);
8135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::assigned == 0);
8235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::destroyed == 0);
8335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
8435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    assert(T::destroyed == 1);
8535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    assert(T::alive == 0);
8635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
8735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        T t;
8835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        const T& ct = t;
8935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        T::reset_constructors();
9035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test_ref<T const&>();
9135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test_ref<T const&>(t);
9235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test_ref<T const&>(ct);
9335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::alive == 1);
9435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::constructed == 0);
9535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::assigned == 0);
9635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::destroyed == 0);
9735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
9835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    assert(T::alive == 0);
9935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    assert(T::destroyed == 1);
10035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
10135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
10235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
10335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
10435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier#endif
10535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier}
10635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier
10735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselierint main()
10835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier{
10935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    test<int>();
11035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    test<int>(3);
11135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
112a0b4d55133a01e6c863095624a6d2bb30a46e8efEric Fiselier        const optional<const int> o(42);
113a0b4d55133a01e6c863095624a6d2bb30a46e8efEric Fiselier        optional<const int> o2(o);
114a0b4d55133a01e6c863095624a6d2bb30a46e8efEric Fiselier        assert(*o2 == 42);
115a0b4d55133a01e6c863095624a6d2bb30a46e8efEric Fiselier    }
116a0b4d55133a01e6c863095624a6d2bb30a46e8efEric Fiselier    {
11735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        using T = TestTypes::TestType;
11835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        T::reset();
11935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        const optional<T> rhs;
12035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::alive == 0);
12135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        const optional<T> lhs(rhs);
12235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(lhs.has_value() == false);
12335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::alive == 0);
12435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
12535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TestTypes::TestType::reset();
12635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
12735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        using T = TestTypes::TestType;
12835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        T::reset();
12935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        const optional<T> rhs(42);
13035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::alive == 1);
13135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::value_constructed == 1);
13235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::copy_constructed == 0);
13335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        const optional<T> lhs(rhs);
13435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(lhs.has_value());
13535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::copy_constructed == 1);
13635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        assert(T::alive == 2);
13735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
13835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    TestTypes::TestType::reset();
13935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
14035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        using namespace ConstexprTestTypes;
14135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test<TestType>();
14235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test<TestType>(42);
14335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
14435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
14535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        using namespace TrivialTestTypes;
14635ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test<TestType>();
14735ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test<TestType>(42);
14835ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
14935ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
15035ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test_throwing_ctor();
15135ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
15235ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    {
15335ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier        test_reference_extension();
15435ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier    }
15535ce4859dd7cc2b7ed280cecc0fe0d9cabe6461bEric Fiselier}
156