Home | History | Annotate | Download | only in optional.object.swap
      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 // void swap(optional&)
     13 //     noexcept(is_nothrow_move_constructible<T>::value &&
     14 //              noexcept(swap(declval<T&>(), declval<T&>())));
     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 class X
     25 {
     26     int i_;
     27 public:
     28     static unsigned dtor_called;
     29     X(int i) : i_(i) {}
     30     X(X&& x) = default;
     31     X& operator=(X&&) = default;
     32     ~X() {++dtor_called;}
     33 
     34     friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}
     35 };
     36 
     37 unsigned X::dtor_called = 0;
     38 
     39 class Y
     40 {
     41     int i_;
     42 public:
     43     static unsigned dtor_called;
     44     Y(int i) : i_(i) {}
     45     Y(Y&&) = default;
     46     ~Y() {++dtor_called;}
     47 
     48     friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}
     49     friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}
     50 };
     51 
     52 unsigned Y::dtor_called = 0;
     53 
     54 class Z
     55 {
     56     int i_;
     57 public:
     58     Z(int i) : i_(i) {}
     59     Z(Z&&) {throw 7;}
     60 
     61     friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}
     62     friend void swap(Z& x, Z& y) {throw 6;}
     63 };
     64 
     65 
     66 #endif  // _LIBCPP_STD_VER > 11
     67 
     68 int main()
     69 {
     70 #if _LIBCPP_STD_VER > 11
     71     {
     72         optional<int> opt1;
     73         optional<int> opt2;
     74         static_assert(noexcept(opt1.swap(opt2)) == true, "");
     75         assert(static_cast<bool>(opt1) == false);
     76         assert(static_cast<bool>(opt2) == false);
     77         opt1.swap(opt2);
     78         assert(static_cast<bool>(opt1) == false);
     79         assert(static_cast<bool>(opt2) == false);
     80     }
     81     {
     82         optional<int> opt1(1);
     83         optional<int> opt2;
     84         static_assert(noexcept(opt1.swap(opt2)) == true, "");
     85         assert(static_cast<bool>(opt1) == true);
     86         assert(*opt1 == 1);
     87         assert(static_cast<bool>(opt2) == false);
     88         opt1.swap(opt2);
     89         assert(static_cast<bool>(opt1) == false);
     90         assert(static_cast<bool>(opt2) == true);
     91         assert(*opt2 == 1);
     92     }
     93     {
     94         optional<int> opt1;
     95         optional<int> opt2(2);
     96         static_assert(noexcept(opt1.swap(opt2)) == true, "");
     97         assert(static_cast<bool>(opt1) == false);
     98         assert(static_cast<bool>(opt2) == true);
     99         assert(*opt2 == 2);
    100         opt1.swap(opt2);
    101         assert(static_cast<bool>(opt1) == true);
    102         assert(*opt1 == 2);
    103         assert(static_cast<bool>(opt2) == false);
    104     }
    105     {
    106         optional<int> opt1(1);
    107         optional<int> opt2(2);
    108         static_assert(noexcept(opt1.swap(opt2)) == true, "");
    109         assert(static_cast<bool>(opt1) == true);
    110         assert(*opt1 == 1);
    111         assert(static_cast<bool>(opt2) == true);
    112         assert(*opt2 == 2);
    113         opt1.swap(opt2);
    114         assert(static_cast<bool>(opt1) == true);
    115         assert(*opt1 == 2);
    116         assert(static_cast<bool>(opt2) == true);
    117         assert(*opt2 == 1);
    118     }
    119     {
    120         optional<X> opt1;
    121         optional<X> opt2;
    122         static_assert(noexcept(opt1.swap(opt2)) == true, "");
    123         assert(static_cast<bool>(opt1) == false);
    124         assert(static_cast<bool>(opt2) == false);
    125         opt1.swap(opt2);
    126         assert(static_cast<bool>(opt1) == false);
    127         assert(static_cast<bool>(opt2) == false);
    128         assert(X::dtor_called == 0);
    129     }
    130     {
    131         optional<X> opt1(1);
    132         optional<X> opt2;
    133         static_assert(noexcept(opt1.swap(opt2)) == true, "");
    134         assert(static_cast<bool>(opt1) == true);
    135         assert(*opt1 == 1);
    136         assert(static_cast<bool>(opt2) == false);
    137         X::dtor_called = 0;
    138         opt1.swap(opt2);
    139         assert(X::dtor_called == 1);
    140         assert(static_cast<bool>(opt1) == false);
    141         assert(static_cast<bool>(opt2) == true);
    142         assert(*opt2 == 1);
    143     }
    144     {
    145         optional<X> opt1;
    146         optional<X> opt2(2);
    147         static_assert(noexcept(opt1.swap(opt2)) == true, "");
    148         assert(static_cast<bool>(opt1) == false);
    149         assert(static_cast<bool>(opt2) == true);
    150         assert(*opt2 == 2);
    151         X::dtor_called = 0;
    152         opt1.swap(opt2);
    153         assert(X::dtor_called == 1);
    154         assert(static_cast<bool>(opt1) == true);
    155         assert(*opt1 == 2);
    156         assert(static_cast<bool>(opt2) == false);
    157     }
    158     {
    159         optional<X> opt1(1);
    160         optional<X> opt2(2);
    161         static_assert(noexcept(opt1.swap(opt2)) == true, "");
    162         assert(static_cast<bool>(opt1) == true);
    163         assert(*opt1 == 1);
    164         assert(static_cast<bool>(opt2) == true);
    165         assert(*opt2 == 2);
    166         X::dtor_called = 0;
    167         opt1.swap(opt2);
    168         assert(X::dtor_called == 1);  // from inside std::swap
    169         assert(static_cast<bool>(opt1) == true);
    170         assert(*opt1 == 2);
    171         assert(static_cast<bool>(opt2) == true);
    172         assert(*opt2 == 1);
    173     }
    174     {
    175         optional<Y> opt1;
    176         optional<Y> opt2;
    177         static_assert(noexcept(opt1.swap(opt2)) == false, "");
    178         assert(static_cast<bool>(opt1) == false);
    179         assert(static_cast<bool>(opt2) == false);
    180         opt1.swap(opt2);
    181         assert(static_cast<bool>(opt1) == false);
    182         assert(static_cast<bool>(opt2) == false);
    183         assert(Y::dtor_called == 0);
    184     }
    185     {
    186         optional<Y> opt1(1);
    187         optional<Y> opt2;
    188         static_assert(noexcept(opt1.swap(opt2)) == false, "");
    189         assert(static_cast<bool>(opt1) == true);
    190         assert(*opt1 == 1);
    191         assert(static_cast<bool>(opt2) == false);
    192         Y::dtor_called = 0;
    193         opt1.swap(opt2);
    194         assert(Y::dtor_called == 1);
    195         assert(static_cast<bool>(opt1) == false);
    196         assert(static_cast<bool>(opt2) == true);
    197         assert(*opt2 == 1);
    198     }
    199     {
    200         optional<Y> opt1;
    201         optional<Y> opt2(2);
    202         static_assert(noexcept(opt1.swap(opt2)) == false, "");
    203         assert(static_cast<bool>(opt1) == false);
    204         assert(static_cast<bool>(opt2) == true);
    205         assert(*opt2 == 2);
    206         Y::dtor_called = 0;
    207         opt1.swap(opt2);
    208         assert(Y::dtor_called == 1);
    209         assert(static_cast<bool>(opt1) == true);
    210         assert(*opt1 == 2);
    211         assert(static_cast<bool>(opt2) == false);
    212     }
    213     {
    214         optional<Y> opt1(1);
    215         optional<Y> opt2(2);
    216         static_assert(noexcept(opt1.swap(opt2)) == false, "");
    217         assert(static_cast<bool>(opt1) == true);
    218         assert(*opt1 == 1);
    219         assert(static_cast<bool>(opt2) == true);
    220         assert(*opt2 == 2);
    221         Y::dtor_called = 0;
    222         opt1.swap(opt2);
    223         assert(Y::dtor_called == 0);
    224         assert(static_cast<bool>(opt1) == true);
    225         assert(*opt1 == 2);
    226         assert(static_cast<bool>(opt2) == true);
    227         assert(*opt2 == 1);
    228     }
    229     {
    230         optional<Z> opt1;
    231         optional<Z> opt2;
    232         static_assert(noexcept(opt1.swap(opt2)) == false, "");
    233         assert(static_cast<bool>(opt1) == false);
    234         assert(static_cast<bool>(opt2) == false);
    235         opt1.swap(opt2);
    236         assert(static_cast<bool>(opt1) == false);
    237         assert(static_cast<bool>(opt2) == false);
    238     }
    239     {
    240         optional<Z> opt1;
    241         opt1.emplace(1);
    242         optional<Z> opt2;
    243         static_assert(noexcept(opt1.swap(opt2)) == false, "");
    244         assert(static_cast<bool>(opt1) == true);
    245         assert(*opt1 == 1);
    246         assert(static_cast<bool>(opt2) == false);
    247         try
    248         {
    249             opt1.swap(opt2);
    250             assert(false);
    251         }
    252         catch (int i)
    253         {
    254             assert(i == 7);
    255         }
    256         assert(static_cast<bool>(opt1) == true);
    257         assert(*opt1 == 1);
    258         assert(static_cast<bool>(opt2) == false);
    259     }
    260     {
    261         optional<Z> opt1;
    262         optional<Z> opt2;
    263         opt2.emplace(2);
    264         static_assert(noexcept(opt1.swap(opt2)) == false, "");
    265         assert(static_cast<bool>(opt1) == false);
    266         assert(static_cast<bool>(opt2) == true);
    267         assert(*opt2 == 2);
    268         try
    269         {
    270             opt1.swap(opt2);
    271             assert(false);
    272         }
    273         catch (int i)
    274         {
    275             assert(i == 7);
    276         }
    277         assert(static_cast<bool>(opt1) == false);
    278         assert(static_cast<bool>(opt2) == true);
    279         assert(*opt2 == 2);
    280     }
    281     {
    282         optional<Z> opt1;
    283         opt1.emplace(1);
    284         optional<Z> opt2;
    285         opt2.emplace(2);
    286         static_assert(noexcept(opt1.swap(opt2)) == false, "");
    287         assert(static_cast<bool>(opt1) == true);
    288         assert(*opt1 == 1);
    289         assert(static_cast<bool>(opt2) == true);
    290         assert(*opt2 == 2);
    291         try
    292         {
    293             opt1.swap(opt2);
    294             assert(false);
    295         }
    296         catch (int i)
    297         {
    298             assert(i == 6);
    299         }
    300         assert(static_cast<bool>(opt1) == true);
    301         assert(*opt1 == 1);
    302         assert(static_cast<bool>(opt2) == true);
    303         assert(*opt2 == 2);
    304     }
    305 #endif  // _LIBCPP_STD_VER > 11
    306 }
    307