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// optional<T>& operator=(optional<T>&& rhs)
1301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//     noexcept(is_nothrow_move_assignable<T>::value &&
1401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant//              is_nothrow_move_constructible<T>::value);
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 Hinnantstruct X
2501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant{
2601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    static bool throw_now;
2701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
2801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    X() = default;
2901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    X(X&&)
3001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
3101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        if (throw_now)
3201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            throw 6;
3301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
3401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    X& operator=(X&&) noexcept
3501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
3601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        return *this;
3701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
3801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant};
3901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
4001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantstruct Y {};
4101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
4201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantbool X::throw_now = false;
4301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
4401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#endif  // _LIBCPP_STD_VER > 11
4501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant
4601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnantint main()
4701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant{
4801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#if _LIBCPP_STD_VER > 11
4901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
500cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
510cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt;
520cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        constexpr optional<int> opt2;
5301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt = std::move(opt2);
5401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(static_cast<bool>(opt2) == false, "");
5501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
5601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
5701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
580cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt;
590cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        constexpr optional<int> opt2(2);
6001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt = std::move(opt2);
6101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(static_cast<bool>(opt2) == true, "");
6201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(*opt2 == 2, "");
6301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
6401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt == *opt2);
6501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
6601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
670cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt(3);
680cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        constexpr optional<int> opt2;
6901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt = std::move(opt2);
7001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(static_cast<bool>(opt2) == false, "");
7101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
7201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
7301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
740cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<int> opt(3);
750cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        constexpr optional<int> opt2(2);
7601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        opt = std::move(opt2);
7701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(static_cast<bool>(opt2) == true, "");
7801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        static_assert(*opt2 == 2, "");
7901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
8001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(*opt == *opt2);
8101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
8201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
830cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
840cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt;
850cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        optional<X> opt2(X{});
8601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        assert(static_cast<bool>(opt2) == true);
8701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        try
8801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        {
8901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            X::throw_now = true;
9001afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            opt = std::move(opt2);
9101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(false);
9201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        }
9301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        catch (int i)
9401afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        {
9501afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(i == 6);
9601afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant            assert(static_cast<bool>(opt) == false);
9701afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant        }
9801afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
9901afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    {
1000cdbe6048173c1f05628dbc85430acf191a3e173Marshall Clow        static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
10101afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant    }
10201afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant#endif  // _LIBCPP_STD_VER > 11
10301afa5c6e407e985d9643707d7b7ab1384bd9317Howard Hinnant}
104