libcxx

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

const_optional_U.pass.cpp (6879B)


      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 // From LWG2451:
     14 // template<class U>
     15 //   optional<T>& operator=(const optional<U>& rhs);
     16 
     17 #include <optional>
     18 #include <type_traits>
     19 #include <cassert>
     20 
     21 #include "test_macros.h"
     22 #include "archetypes.hpp"
     23 
     24 using std::optional;
     25 
     26 struct X
     27 {
     28     static bool throw_now;
     29 
     30     X() = default;
     31     X(int)
     32     {
     33         if (throw_now)
     34             TEST_THROW(6);
     35     }
     36 };
     37 
     38 bool X::throw_now = false;
     39 
     40 struct Y1
     41 {
     42     Y1() = default;
     43     Y1(const int&) {}
     44     Y1& operator=(const Y1&) = delete;
     45 };
     46 
     47 struct Y2
     48 {
     49     Y2() = default;
     50     Y2(const int&) = delete;
     51     Y2& operator=(const int&) { return *this; }
     52 };
     53 
     54 template <class T>
     55 struct AssignableFrom {
     56   static int type_constructed;
     57   static int type_assigned;
     58 static int int_constructed;
     59   static int int_assigned;
     60 
     61   static void reset() {
     62       type_constructed = int_constructed = 0;
     63       type_assigned = int_assigned = 0;
     64   }
     65 
     66   AssignableFrom() = default;
     67 
     68   explicit AssignableFrom(T) { ++type_constructed; }
     69   AssignableFrom& operator=(T) { ++type_assigned; return *this; }
     70 
     71   AssignableFrom(int) { ++int_constructed; }
     72   AssignableFrom& operator=(int) { ++int_assigned; return *this; }
     73 private:
     74   AssignableFrom(AssignableFrom const&) = delete;
     75   AssignableFrom& operator=(AssignableFrom const&) = delete;
     76 };
     77 
     78 template <class T> int AssignableFrom<T>::type_constructed = 0;
     79 template <class T> int AssignableFrom<T>::type_assigned = 0;
     80 template <class T> int AssignableFrom<T>::int_constructed = 0;
     81 template <class T> int AssignableFrom<T>::int_assigned = 0;
     82 
     83 
     84 void test_with_test_type() {
     85     using T = TestTypes::TestType;
     86     T::reset();
     87     { // non-empty to empty
     88         T::reset_constructors();
     89         optional<T> opt;
     90         const optional<int> other(42);
     91         opt = other;
     92         assert(T::alive == 1);
     93         assert(T::constructed == 1);
     94         assert(T::value_constructed == 1);
     95         assert(T::assigned == 0);
     96         assert(T::destroyed == 0);
     97         assert(static_cast<bool>(other) == true);
     98         assert(*other == 42);
     99         assert(static_cast<bool>(opt) == true);
    100         assert(*opt == T(42));
    101     }
    102     assert(T::alive == 0);
    103     { // non-empty to non-empty
    104         optional<T> opt(101);
    105         const optional<int> other(42);
    106         T::reset_constructors();
    107         opt = other;
    108         assert(T::alive == 1);
    109         assert(T::constructed == 0);
    110         assert(T::assigned == 1);
    111         assert(T::value_assigned == 1);
    112         assert(T::destroyed == 0);
    113         assert(static_cast<bool>(other) == true);
    114         assert(*other == 42);
    115         assert(static_cast<bool>(opt) == true);
    116         assert(*opt == T(42));
    117     }
    118     assert(T::alive == 0);
    119     { // empty to non-empty
    120         optional<T> opt(101);
    121         const optional<int> other;
    122         T::reset_constructors();
    123         opt = other;
    124         assert(T::alive == 0);
    125         assert(T::constructed == 0);
    126         assert(T::assigned == 0);
    127         assert(T::destroyed == 1);
    128         assert(static_cast<bool>(other) == false);
    129         assert(static_cast<bool>(opt) == false);
    130     }
    131     assert(T::alive == 0);
    132     { // empty to empty
    133         optional<T> opt;
    134         const optional<int> other;
    135         T::reset_constructors();
    136         opt = other;
    137         assert(T::alive == 0);
    138         assert(T::constructed == 0);
    139         assert(T::assigned == 0);
    140         assert(T::destroyed == 0);
    141         assert(static_cast<bool>(other) == false);
    142         assert(static_cast<bool>(opt) == false);
    143     }
    144     assert(T::alive == 0);
    145 }
    146 
    147 void test_ambigious_assign() {
    148     using OptInt = std::optional<int>;
    149     {
    150         using T = AssignableFrom<OptInt const&>;
    151         const OptInt a(42);
    152         T::reset();
    153         {
    154             std::optional<T> t;
    155             t = a;
    156             assert(T::type_constructed == 1);
    157             assert(T::type_assigned == 0);
    158             assert(T::int_constructed == 0);
    159             assert(T::int_assigned == 0);
    160         }
    161         T::reset();
    162         {
    163             std::optional<T> t(42);
    164             t = a;
    165             assert(T::type_constructed == 0);
    166             assert(T::type_assigned == 1);
    167             assert(T::int_constructed == 1);
    168             assert(T::int_assigned == 0);
    169         }
    170         T::reset();
    171         {
    172             std::optional<T> t(42);
    173             t = std::move(a);
    174             assert(T::type_constructed == 0);
    175             assert(T::type_assigned == 1);
    176             assert(T::int_constructed == 1);
    177             assert(T::int_assigned == 0);
    178         }
    179     }
    180     {
    181         using T = AssignableFrom<OptInt&>;
    182         OptInt a(42);
    183         T::reset();
    184         {
    185             std::optional<T> t;
    186             t = a;
    187             assert(T::type_constructed == 1);
    188             assert(T::type_assigned == 0);
    189             assert(T::int_constructed == 0);
    190             assert(T::int_assigned == 0);
    191         }
    192         {
    193             using Opt = std::optional<T>;
    194             static_assert(!std::is_assignable_v<Opt&, OptInt const&>, "");
    195         }
    196     }
    197 }
    198 
    199 
    200 int main()
    201 {
    202     test_with_test_type();
    203     test_ambigious_assign();
    204     {
    205         optional<int> opt;
    206         constexpr optional<short> opt2;
    207         opt = opt2;
    208         static_assert(static_cast<bool>(opt2) == false, "");
    209         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
    210     }
    211     {
    212         optional<int> opt;
    213         constexpr optional<short> opt2(short{2});
    214         opt = opt2;
    215         static_assert(static_cast<bool>(opt2) == true, "");
    216         static_assert(*opt2 == 2, "");
    217         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
    218         assert(*opt == *opt2);
    219     }
    220     {
    221         optional<int> opt(3);
    222         constexpr optional<short> opt2;
    223         opt = opt2;
    224         static_assert(static_cast<bool>(opt2) == false, "");
    225         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
    226     }
    227     {
    228         optional<int> opt(3);
    229         constexpr optional<short> opt2(short{2});
    230         opt = opt2;
    231         static_assert(static_cast<bool>(opt2) == true, "");
    232         static_assert(*opt2 == 2, "");
    233         assert(static_cast<bool>(opt) == static_cast<bool>(opt2));
    234         assert(*opt == *opt2);
    235     }
    236 #ifndef TEST_HAS_NO_EXCEPTIONS
    237     {
    238         optional<X> opt;
    239         optional<int> opt2(42);
    240         assert(static_cast<bool>(opt2) == true);
    241         try
    242         {
    243             X::throw_now = true;
    244             opt = opt2;
    245             assert(false);
    246         }
    247         catch (int i)
    248         {
    249             assert(i == 6);
    250             assert(static_cast<bool>(opt) == false);
    251         }
    252     }
    253 #endif
    254 }