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