101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//===----------------------------------------------------------------------===//
201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//
301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//                     The LLVM Compiler Infrastructure
401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//
501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant// This file is dual licensed under the MIT and the University of Illinois Open
601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant// Source Licenses. See LICENSE.TXT for details.
701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//
801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//===----------------------------------------------------------------------===//
901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
1001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant// <optional>
1101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
1201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant// void swap(optional&)
1301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//     noexcept(is_nothrow_move_constructible<T>::value &&
1401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//              noexcept(swap(declval<T&>(), declval<T&>())));
1501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
160cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow#include <experimental/optional>
1701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#include <type_traits>
1801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#include <cassert>
1901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
2001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#if _LIBCPP_STD_VER > 11
2101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
220cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clowusing std::experimental::optional;
230cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow
2401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantclass X
2501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant{
2601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    int i_;
2701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantpublic:
2801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    static unsigned dtor_called;
2901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    X(int i) : i_(i) {}
3001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    X(X&& x) = default;
3101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    X& operator=(X&&) = default;
3201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    ~X() {++dtor_called;}
3301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
3401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
3501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant};
3601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
3701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantunsigned X::dtor_called = 0;
3801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
3901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantclass Y
4001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant{
4101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    int i_;
4201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantpublic:
4301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    static unsigned dtor_called;
4401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    Y(int i) : i_(i) {}
4501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    Y(Y&&) = default;
4601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    ~Y() {++dtor_called;}
4701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
4801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
4901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
5001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant};
5101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
5201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantunsigned Y::dtor_called = 0;
5301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
5401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantclass Z
5501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant{
5601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    int i_;
5701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantpublic:
5801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    Z(int i) : i_(i) {}
5901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    Z(Z&&) {throw 7;}
6001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
6101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
6201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    friend void swap(Z& x, Z& y) {throw 6;}
6301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant};
6401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
6501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
6601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#endif  // _LIBCPP_STD_VER > 11
6701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
6801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantint main()
6901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant{
7001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#if _LIBCPP_STD_VER > 11
7101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
720cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt1;
730cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt2;
7401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == true, "");
7501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
7601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
7701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
7801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
7901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
8001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
8101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
820cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt1(1);
830cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt2;
8401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == true, "");
8501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
8601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
8701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
8801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
8901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
9001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
9101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 1);
9201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
9301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
940cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt1;
950cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt2(2);
9601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == true, "");
9701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
9801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
9901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
10001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
10101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
10201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 2);
10301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
10401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
10501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
1060cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt1(1);
1070cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt2(2);
10801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == true, "");
10901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
11001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
11101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
11201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
11301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
11401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
11501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 2);
11601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
11701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 1);
11801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
11901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
1200cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt1;
1210cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt2;
12201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == true, "");
12301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
12401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
12501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
12601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
12701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
12801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(X::dtor_called == 0);
12901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
13001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
1310cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt1(1);
1320cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt2;
13301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == true, "");
13401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
13501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
13601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
13701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        X::dtor_called = 0;
13801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
13901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(X::dtor_called == 1);
14001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
14101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
14201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 1);
14301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
14401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
1450cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt1;
1460cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt2(2);
14701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == true, "");
14801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
14901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
15001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
15101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        X::dtor_called = 0;
15201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
15301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(X::dtor_called == 1);
15401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
15501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 2);
15601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
15701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
15801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
1590cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt1(1);
1600cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt2(2);
16101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == true, "");
16201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
16301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
16401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
16501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
16601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        X::dtor_called = 0;
16701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
16801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(X::dtor_called == 1);  // from inside std::swap
16901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
17001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 2);
17101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
17201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 1);
17301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
17401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
1750cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Y> opt1;
1760cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Y> opt2;
17701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == false, "");
17801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
17901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
18001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
18101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
18201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
18301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(Y::dtor_called == 0);
18401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
18501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
1860cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Y> opt1(1);
1870cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Y> opt2;
18801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == false, "");
18901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
19001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
19101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
19201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        Y::dtor_called = 0;
19301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
19401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(Y::dtor_called == 1);
19501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
19601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
19701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 1);
19801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
19901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
2000cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Y> opt1;
2010cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Y> opt2(2);
20201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == false, "");
20301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
20401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
20501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
20601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        Y::dtor_called = 0;
20701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
20801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(Y::dtor_called == 1);
20901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
21001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 2);
21101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
21201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
21301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
2140cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Y> opt1(1);
2150cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Y> opt2(2);
21601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == false, "");
21701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
21801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
21901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
22001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
22101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        Y::dtor_called = 0;
22201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
22301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(Y::dtor_called == 0);
22401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
22501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 2);
22601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
22701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 1);
22801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
22901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
2300cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Z> opt1;
2310cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Z> opt2;
23201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == false, "");
23301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
23401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
23501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.swap(opt2);
23601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
23701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
23801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
23901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
2400cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Z> opt1;
24101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.emplace(1);
2420cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Z> opt2;
24301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == false, "");
24401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
24501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
24601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
24701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        try
24801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        {
24901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            opt1.swap(opt2);
25001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(false);
25101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        }
25201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        catch (int i)
25301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        {
25401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(i == 7);
25501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        }
25601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
25701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
25801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == false);
25901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
26001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
2610cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Z> opt1;
2620cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Z> opt2;
26301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt2.emplace(2);
26401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == false, "");
26501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
26601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
26701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
26801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        try
26901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        {
27001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            opt1.swap(opt2);
27101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(false);
27201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        }
27301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        catch (int i)
27401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        {
27501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(i == 7);
27601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        }
27701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == false);
27801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
27901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
28001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
28101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
2820cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Z> opt1;
28301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt1.emplace(1);
2840cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<Z> opt2;
28501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt2.emplace(2);
28601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(noexcept(opt1.swap(opt2)) == false, "");
28701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
28801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
28901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
29001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
29101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        try
29201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        {
29301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            opt1.swap(opt2);
29401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(false);
29501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        }
29601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        catch (int i)
29701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        {
29801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(i == 6);
29901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        }
30001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt1) == true);
30101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt1 == 1);
30201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
30301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt2 == 2);
30401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
30501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#endif  // _LIBCPP_STD_VER > 11
30601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant}
307