Home | History | Annotate | Download | only in optional.object.assign
      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 <experimental/optional>
     17 #include <type_traits>
     18 #include <cassert>
     19 
     20 #if _LIBCPP_STD_VER > 11
     21 
     22 using std::experimental::optional;
     23 
     24 struct X
     25 {
     26     static bool throw_now;
     27 
     28     X() = default;
     29     X(X&&)
     30     {
     31         if (throw_now)
     32             throw 6;
     33     }
     34     X& operator=(X&&) noexcept
     35     {
     36         return *this;
     37     }
     38 };
     39 
     40 struct Y {};
     41 
     42 bool X::throw_now = false;
     43 
     44 #endif  // _LIBCPP_STD_VER > 11
     45 
     46 int main()
     47 {
     48 #if _LIBCPP_STD_VER > 11
     49     {
     50         static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
     51         optional<int> opt;
     52         constexpr optional<int> opt2;
     53         opt = std::move(opt2);
     54         static_assert(static_cast<bool>(opt2) == false, "");
     55         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
     56     }
     57     {
     58         optional<int> opt;
     59         constexpr optional<int> opt2(2);
     60         opt = std::move(opt2);
     61         static_assert(static_cast<bool>(opt2) == true, "");
     62         static_assert(*opt2 == 2, "");
     63         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
     64         assert(*opt == *opt2);
     65     }
     66     {
     67         optional<int> opt(3);
     68         constexpr optional<int> opt2;
     69         opt = std::move(opt2);
     70         static_assert(static_cast<bool>(opt2) == false, "");
     71         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
     72     }
     73     {
     74         optional<int> opt(3);
     75         constexpr optional<int> opt2(2);
     76         opt = std::move(opt2);
     77         static_assert(static_cast<bool>(opt2) == true, "");
     78         static_assert(*opt2 == 2, "");
     79         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
     80         assert(*opt == *opt2);
     81     }
     82     {
     83         static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
     84         optional<X> opt;
     85         optional<X> opt2(X{});
     86         assert(static_cast<bool>(opt2) == true);
     87         try
     88         {
     89             X::throw_now = true;
     90             opt = std::move(opt2);
     91             assert(false);
     92         }
     93         catch (int i)
     94         {
     95             assert(i == 6);
     96             assert(static_cast<bool>(opt) == false);
     97         }
     98     }
     99     {
    100         static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
    101     }
    102 #endif  // _LIBCPP_STD_VER > 11
    103 }
    104