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