move.pass.cpp revision 01afa5c6e407e985d9643707d7b7ab1384bd9317
1//===----------------------------------------------------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10// <optional>
11
12// optional<T>& operator=(optional<T>&& rhs)
13//     noexcept(is_nothrow_move_assignable<T>::value &&
14//              is_nothrow_move_constructible<T>::value);
15
16#include <optional>
17#include <type_traits>
18#include <cassert>
19
20#if _LIBCPP_STD_VER > 11
21
22struct X
23{
24    static bool throw_now;
25
26    X() = default;
27    X(X&&)
28    {
29        if (throw_now)
30            throw 6;
31    }
32    X& operator=(X&&) noexcept
33    {
34        return *this;
35    }
36};
37
38struct Y {};
39
40bool X::throw_now = false;
41
42#endif  // _LIBCPP_STD_VER > 11
43
44int main()
45{
46#if _LIBCPP_STD_VER > 11
47    {
48        static_assert(std::is_nothrow_move_assignable<std::optional<int>>::value, "");
49        std::optional<int> opt;
50        constexpr std::optional<int> opt2;
51        opt = std::move(opt2);
52        static_assert(static_cast<bool>(opt2) == false, "");
53        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
54    }
55    {
56        std::optional<int> opt;
57        constexpr std::optional<int> opt2(2);
58        opt = std::move(opt2);
59        static_assert(static_cast<bool>(opt2) == true, "");
60        static_assert(*opt2 == 2, "");
61        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
62        assert(*opt == *opt2);
63    }
64    {
65        std::optional<int> opt(3);
66        constexpr std::optional<int> opt2;
67        opt = std::move(opt2);
68        static_assert(static_cast<bool>(opt2) == false, "");
69        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
70    }
71    {
72        std::optional<int> opt(3);
73        constexpr std::optional<int> opt2(2);
74        opt = std::move(opt2);
75        static_assert(static_cast<bool>(opt2) == true, "");
76        static_assert(*opt2 == 2, "");
77        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
78        assert(*opt == *opt2);
79    }
80    {
81        static_assert(!std::is_nothrow_move_assignable<std::optional<X>>::value, "");
82        std::optional<X> opt;
83        std::optional<X> opt2(X{});
84        assert(static_cast<bool>(opt2) == true);
85        try
86        {
87            X::throw_now = true;
88            opt = std::move(opt2);
89            assert(false);
90        }
91        catch (int i)
92        {
93            assert(i == 6);
94            assert(static_cast<bool>(opt) == false);
95        }
96    }
97    {
98        static_assert(std::is_nothrow_move_assignable<std::optional<Y>>::value, "");
99    }
100#endif  // _LIBCPP_STD_VER > 11
101}
102