libcxx

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

move.pass.cpp (6208B)


      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 
     12 // XFAIL: availability=macosx10.13
     13 // XFAIL: availability=macosx10.12
     14 // XFAIL: availability=macosx10.11
     15 // XFAIL: availability=macosx10.10
     16 // XFAIL: availability=macosx10.9
     17 // XFAIL: availability=macosx10.8
     18 // XFAIL: availability=macosx10.7
     19 
     20 // <optional>
     21 
     22 // constexpr optional(optional<T>&& rhs);
     23 
     24 #include <optional>
     25 #include <type_traits>
     26 #include <cassert>
     27 
     28 #include "test_macros.h"
     29 #include "archetypes.hpp"
     30 
     31 using std::optional;
     32 
     33 template <class T, class ...InitArgs>
     34 void test(InitArgs&&... args)
     35 {
     36     const optional<T> orig(std::forward<InitArgs>(args)...);
     37     optional<T> rhs(orig);
     38     bool rhs_engaged = static_cast<bool>(rhs);
     39     optional<T> lhs = std::move(rhs);
     40     assert(static_cast<bool>(lhs) == rhs_engaged);
     41     if (rhs_engaged)
     42         assert(*lhs == *orig);
     43 }
     44 
     45 template <class T, class ...InitArgs>
     46 constexpr bool constexpr_test(InitArgs&&... args)
     47 {
     48     static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
     49     const optional<T> orig(std::forward<InitArgs>(args)...);
     50     optional<T> rhs(orig);
     51     optional<T> lhs = std::move(rhs);
     52     return (lhs.has_value() == orig.has_value()) &&
     53            (lhs.has_value() ? *lhs == *orig : true);
     54 }
     55 
     56 void test_throwing_ctor() {
     57 #ifndef TEST_HAS_NO_EXCEPTIONS
     58     struct Z {
     59         Z() : count(0) {}
     60         Z(Z&& o) : count(o.count + 1)
     61         { if (count == 2) throw 6; }
     62         int count;
     63     };
     64     Z z;
     65     optional<Z> rhs(std::move(z));
     66     try
     67     {
     68         optional<Z> lhs(std::move(rhs));
     69         assert(false);
     70     }
     71     catch (int i)
     72     {
     73         assert(i == 6);
     74     }
     75 #endif
     76 }
     77 
     78 
     79 template <class T, class ...InitArgs>
     80 void test_ref(InitArgs&&... args)
     81 {
     82     optional<T> rhs(std::forward<InitArgs>(args)...);
     83     bool rhs_engaged = static_cast<bool>(rhs);
     84     optional<T> lhs = std::move(rhs);
     85     assert(static_cast<bool>(lhs) == rhs_engaged);
     86     if (rhs_engaged)
     87         assert(&(*lhs) == &(*rhs));
     88 }
     89 
     90 void test_reference_extension()
     91 {
     92 #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
     93     using T = TestTypes::TestType;
     94     T::reset();
     95     {
     96         T t;
     97         T::reset_constructors();
     98         test_ref<T&>();
     99         test_ref<T&>(t);
    100         assert(T::alive == 1);
    101         assert(T::constructed == 0);
    102         assert(T::assigned == 0);
    103         assert(T::destroyed == 0);
    104     }
    105     assert(T::destroyed == 1);
    106     assert(T::alive == 0);
    107     {
    108         T t;
    109         const T& ct = t;
    110         T::reset_constructors();
    111         test_ref<T const&>();
    112         test_ref<T const&>(t);
    113         test_ref<T const&>(ct);
    114         assert(T::alive == 1);
    115         assert(T::constructed == 0);
    116         assert(T::assigned == 0);
    117         assert(T::destroyed == 0);
    118     }
    119     assert(T::alive == 0);
    120     assert(T::destroyed == 1);
    121     {
    122         T t;
    123         T::reset_constructors();
    124         test_ref<T&&>();
    125         test_ref<T&&>(std::move(t));
    126         assert(T::alive == 1);
    127         assert(T::constructed == 0);
    128         assert(T::assigned == 0);
    129         assert(T::destroyed == 0);
    130     }
    131     assert(T::alive == 0);
    132     assert(T::destroyed == 1);
    133     {
    134         T t;
    135         const T& ct = t;
    136         T::reset_constructors();
    137         test_ref<T const&&>();
    138         test_ref<T const&&>(std::move(t));
    139         test_ref<T const&&>(std::move(ct));
    140         assert(T::alive == 1);
    141         assert(T::constructed == 0);
    142         assert(T::assigned == 0);
    143         assert(T::destroyed == 0);
    144     }
    145     assert(T::alive == 0);
    146     assert(T::destroyed == 1);
    147     {
    148         static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
    149         static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
    150     }
    151 #endif
    152 }
    153 
    154 
    155 int main()
    156 {
    157     test<int>();
    158     test<int>(3);
    159     static_assert(constexpr_test<int>(), "" );
    160     static_assert(constexpr_test<int>(3), "" );
    161 
    162     {
    163         optional<const int> o(42);
    164         optional<const int> o2(std::move(o));
    165         assert(*o2 == 42);
    166     }
    167     {
    168         using T = TestTypes::TestType;
    169         T::reset();
    170         optional<T> rhs;
    171         assert(T::alive == 0);
    172         const optional<T> lhs(std::move(rhs));
    173         assert(lhs.has_value() == false);
    174         assert(rhs.has_value() == false);
    175         assert(T::alive == 0);
    176     }
    177     TestTypes::TestType::reset();
    178     {
    179         using T = TestTypes::TestType;
    180         T::reset();
    181         optional<T> rhs(42);
    182         assert(T::alive == 1);
    183         assert(T::value_constructed == 1);
    184         assert(T::move_constructed == 0);
    185         const optional<T> lhs(std::move(rhs));
    186         assert(lhs.has_value());
    187         assert(rhs.has_value());
    188         assert(lhs.value().value == 42);
    189         assert(rhs.value().value == -1);
    190         assert(T::move_constructed == 1);
    191         assert(T::alive == 2);
    192     }
    193     TestTypes::TestType::reset();
    194     {
    195         using namespace ConstexprTestTypes;
    196         test<TestType>();
    197         test<TestType>(42);
    198     }
    199     {
    200         using namespace TrivialTestTypes;
    201         test<TestType>();
    202         test<TestType>(42);
    203     }
    204     {
    205         test_throwing_ctor();
    206     }
    207     {
    208         struct ThrowsMove {
    209           ThrowsMove() noexcept(false) {}
    210           ThrowsMove(ThrowsMove const&) noexcept(false) {}
    211           ThrowsMove(ThrowsMove &&) noexcept(false) {}
    212         };
    213         static_assert(!std::is_nothrow_move_constructible<optional<ThrowsMove>>::value, "");
    214         struct NoThrowMove {
    215           NoThrowMove() noexcept(false) {}
    216           NoThrowMove(NoThrowMove const&) noexcept(false) {}
    217           NoThrowMove(NoThrowMove &&) noexcept(true) {}
    218         };
    219         static_assert(std::is_nothrow_move_constructible<optional<NoThrowMove>>::value, "");
    220     }
    221     {
    222         test_reference_extension();
    223     }
    224     {
    225     constexpr std::optional<int> o1{4};
    226     constexpr std::optional<int> o2 = std::move(o1);
    227     static_assert( *o2 == 4, "" );
    228     }
    229 }