libcxx

libcxx mirror with random patches
git clone https://git.neptards.moe/neptards/libcxx.git
Log | Files | Refs

move.pass.cpp (6277B)


      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 // UNSUPPORTED: c++98, c++03, c++11, c++14
     11 // <optional>
     12 
     13 // optional<T>& operator=(optional<T>&& rhs)
     14 //     noexcept(is_nothrow_move_assignable<T>::value &&
     15 //              is_nothrow_move_constructible<T>::value); // constexpr in C++20
     16 
     17 #include <optional>
     18 #include <cassert>
     19 #include <type_traits>
     20 #include <utility>
     21 
     22 #include "test_macros.h"
     23 #include "archetypes.hpp"
     24 
     25 using std::optional;
     26 
     27 struct X
     28 {
     29     static bool throw_now;
     30     static int alive;
     31 
     32     X() { ++alive; }
     33     X(X&&)
     34     {
     35         if (throw_now)
     36             TEST_THROW(6);
     37         ++alive;
     38     }
     39 
     40     X& operator=(X&&)
     41     {
     42         if (throw_now)
     43             TEST_THROW(42);
     44         return *this;
     45     }
     46 
     47     ~X() { assert(alive > 0); --alive; }
     48 };
     49 
     50 struct Y {};
     51 
     52 bool X::throw_now = false;
     53 int X::alive = 0;
     54 
     55 
     56 template <class Tp>
     57 constexpr bool assign_empty(optional<Tp>&& lhs) {
     58     optional<Tp> rhs;
     59     lhs = std::move(rhs);
     60     return !lhs.has_value() && !rhs.has_value();
     61 }
     62 
     63 template <class Tp>
     64 constexpr bool assign_value(optional<Tp>&& lhs) {
     65     optional<Tp> rhs(101);
     66     lhs = std::move(rhs);
     67     return lhs.has_value() && rhs.has_value() && *lhs == Tp{101};
     68 }
     69 
     70 int main()
     71 {
     72     {
     73         static_assert(std::is_nothrow_move_assignable<optional<int>>::value, "");
     74         optional<int> opt;
     75         constexpr optional<int> opt2;
     76         opt = std::move(opt2);
     77         static_assert(static_cast<bool>(opt2) == false, "");
     78         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
     79     }
     80     {
     81         optional<int> opt;
     82         constexpr optional<int> opt2(2);
     83         opt = std::move(opt2);
     84         static_assert(static_cast<bool>(opt2) == true, "");
     85         static_assert(*opt2 == 2, "");
     86         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
     87         assert(*opt == *opt2);
     88     }
     89     {
     90         optional<int> opt(3);
     91         constexpr optional<int> opt2;
     92         opt = std::move(opt2);
     93         static_assert(static_cast<bool>(opt2) == false, "");
     94         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
     95     }
     96     {
     97         using T = TestTypes::TestType;
     98         T::reset();
     99         optional<T> opt(3);
    100         optional<T> opt2;
    101         assert(T::alive == 1);
    102         opt = std::move(opt2);
    103         assert(T::alive == 0);
    104         assert(static_cast<bool>(opt2) == false);
    105         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
    106     }
    107     {
    108         optional<int> opt(3);
    109         constexpr optional<int> opt2(2);
    110         opt = std::move(opt2);
    111         static_assert(static_cast<bool>(opt2) == true, "");
    112         static_assert(*opt2 == 2, "");
    113         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
    114         assert(*opt == *opt2);
    115     }
    116     {
    117         using O = optional<int>;
    118 #if TEST_STD_VER > 17
    119         LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
    120         LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
    121 #endif
    122         assert(assign_empty(O{42}));
    123         assert(assign_value(O{42}));
    124     }
    125     {
    126         using O = optional<TrivialTestTypes::TestType>;
    127 #if TEST_STD_VER > 17
    128         LIBCPP_STATIC_ASSERT(assign_empty(O{42}), "");
    129         LIBCPP_STATIC_ASSERT(assign_value(O{42}), "");
    130 #endif
    131         assert(assign_empty(O{42}));
    132         assert(assign_value(O{42}));
    133     }
    134 #ifndef TEST_HAS_NO_EXCEPTIONS
    135     {
    136         static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
    137         X::alive = 0;
    138         X::throw_now = false;
    139         optional<X> opt;
    140         optional<X> opt2(X{});
    141         assert(X::alive == 1);
    142         assert(static_cast<bool>(opt2) == true);
    143         try
    144         {
    145             X::throw_now = true;
    146             opt = std::move(opt2);
    147             assert(false);
    148         }
    149         catch (int i)
    150         {
    151             assert(i == 6);
    152             assert(static_cast<bool>(opt) == false);
    153         }
    154         assert(X::alive == 1);
    155     }
    156     assert(X::alive == 0);
    157     {
    158         static_assert(!std::is_nothrow_move_assignable<optional<X>>::value, "");
    159         X::throw_now = false;
    160         optional<X> opt(X{});
    161         optional<X> opt2(X{});
    162         assert(X::alive == 2);
    163         assert(static_cast<bool>(opt2) == true);
    164         try
    165         {
    166             X::throw_now = true;
    167             opt = std::move(opt2);
    168             assert(false);
    169         }
    170         catch (int i)
    171         {
    172             assert(i == 42);
    173             assert(static_cast<bool>(opt) == true);
    174         }
    175         assert(X::alive == 2);
    176     }
    177     assert(X::alive == 0);
    178 #endif // TEST_HAS_NO_EXCEPTIONS
    179     {
    180         static_assert(std::is_nothrow_move_assignable<optional<Y>>::value, "");
    181     }
    182     {
    183         struct ThrowsMove {
    184             ThrowsMove() noexcept {}
    185             ThrowsMove(ThrowsMove const&) noexcept {}
    186             ThrowsMove(ThrowsMove &&) noexcept(false) {}
    187             ThrowsMove& operator=(ThrowsMove const&) noexcept { return *this; }
    188             ThrowsMove& operator=(ThrowsMove &&) noexcept { return *this; }
    189         };
    190         static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMove>>::value, "");
    191         struct ThrowsMoveAssign {
    192             ThrowsMoveAssign() noexcept {}
    193             ThrowsMoveAssign(ThrowsMoveAssign const&) noexcept {}
    194             ThrowsMoveAssign(ThrowsMoveAssign &&) noexcept {}
    195             ThrowsMoveAssign& operator=(ThrowsMoveAssign const&) noexcept { return *this; }
    196             ThrowsMoveAssign& operator=(ThrowsMoveAssign &&) noexcept(false) { return *this; }
    197         };
    198         static_assert(!std::is_nothrow_move_assignable<optional<ThrowsMoveAssign>>::value, "");
    199         struct NoThrowMove {
    200             NoThrowMove() noexcept(false) {}
    201             NoThrowMove(NoThrowMove const&) noexcept(false) {}
    202             NoThrowMove(NoThrowMove &&) noexcept {}
    203             NoThrowMove& operator=(NoThrowMove const&) noexcept { return *this; }
    204             NoThrowMove& operator=(NoThrowMove&&) noexcept { return *this; }
    205         };
    206         static_assert(std::is_nothrow_move_assignable<optional<NoThrowMove>>::value, "");
    207     }
    208 }