Home | History | Annotate | Download | only in optional.object.assign
      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 // template <class... Args> void optional<T>::emplace(Args&&... args);
     14 
     15 #include <optional>
     16 #include <type_traits>
     17 #include <cassert>
     18 #include <memory>
     19 
     20 #include "test_macros.h"
     21 #include "archetypes.hpp"
     22 
     23 using std::optional;
     24 
     25 class X
     26 {
     27     int i_;
     28     int j_ = 0;
     29 public:
     30     X() : i_(0) {}
     31     X(int i) : i_(i) {}
     32     X(int i, int j) : i_(i), j_(j) {}
     33 
     34     friend bool operator==(const X& x, const X& y)
     35         {return x.i_ == y.i_ && x.j_ == y.j_;}
     36 };
     37 
     38 class Y
     39 {
     40 public:
     41     static bool dtor_called;
     42     Y() = default;
     43     Y(int) { TEST_THROW(6);}
     44     ~Y() {dtor_called = true;}
     45 };
     46 
     47 bool Y::dtor_called = false;
     48 
     49 template <class T>
     50 void test_one_arg() {
     51     using Opt = std::optional<T>;
     52     {
     53         Opt opt;
     54         opt.emplace();
     55         assert(static_cast<bool>(opt) == true);
     56         assert(*opt == T(0));
     57     }
     58     {
     59         Opt opt;
     60         opt.emplace(1);
     61         assert(static_cast<bool>(opt) == true);
     62         assert(*opt == T(1));
     63     }
     64     {
     65         Opt opt(2);
     66         opt.emplace();
     67         assert(static_cast<bool>(opt) == true);
     68         assert(*opt == T(0));
     69     }
     70     {
     71         Opt opt(2);
     72         opt.emplace(1);
     73         assert(static_cast<bool>(opt) == true);
     74         assert(*opt == T(1));
     75     }
     76 }
     77 
     78 
     79 template <class T>
     80 void test_multi_arg()
     81 {
     82     test_one_arg<T>();
     83     using Opt = std::optional<T>;
     84     {
     85         Opt opt;
     86         opt.emplace(101, 41);
     87         assert(static_cast<bool>(opt) == true);
     88         assert(*opt == T(101, 41));
     89     }
     90     {
     91         Opt opt;
     92         opt.emplace({1, 2, 3, 4});
     93         assert(static_cast<bool>(opt) == true);
     94         assert(*opt == T(4)); // T sets its value to the size of the init list
     95     }
     96     {
     97         Opt opt;
     98         opt.emplace({1, 2, 3, 4, 5}, 6);
     99         assert(static_cast<bool>(opt) == true);
    100         assert(*opt == T(5)); // T sets its value to the size of the init list
    101     }
    102 }
    103 
    104 template <class T>
    105 void test_on_test_type() {
    106 
    107     T::reset();
    108     optional<T> opt;
    109     assert(T::alive == 0);
    110     {
    111         T::reset_constructors();
    112         opt.emplace();
    113         assert(T::alive == 1);
    114         assert(T::constructed == 1);
    115         assert(T::default_constructed == 1);
    116         assert(T::destroyed == 0);
    117         assert(static_cast<bool>(opt) == true);
    118         assert(*opt == T());
    119     }
    120     {
    121         T::reset_constructors();
    122         opt.emplace();
    123         assert(T::alive == 1);
    124         assert(T::constructed == 1);
    125         assert(T::default_constructed == 1);
    126         assert(T::destroyed == 1);
    127         assert(static_cast<bool>(opt) == true);
    128         assert(*opt == T());
    129     }
    130     {
    131         T::reset_constructors();
    132         opt.emplace(101);
    133         assert(T::alive == 1);
    134         assert(T::constructed == 1);
    135         assert(T::value_constructed == 1);
    136         assert(T::destroyed == 1);
    137         assert(static_cast<bool>(opt) == true);
    138         assert(*opt == T(101));
    139     }
    140     {
    141         T::reset_constructors();
    142         opt.emplace(-10, 99);
    143         assert(T::alive == 1);
    144         assert(T::constructed == 1);
    145         assert(T::value_constructed == 1);
    146         assert(T::destroyed == 1);
    147         assert(static_cast<bool>(opt) == true);
    148         assert(*opt == T(-10, 99));
    149     }
    150     {
    151         T::reset_constructors();
    152         opt.emplace(-10, 99);
    153         assert(T::alive == 1);
    154         assert(T::constructed == 1);
    155         assert(T::value_constructed == 1);
    156         assert(T::destroyed == 1);
    157         assert(static_cast<bool>(opt) == true);
    158         assert(*opt == T(-10, 99));
    159     }
    160     {
    161         T::reset_constructors();
    162         opt.emplace({-10, 99, 42, 1});
    163         assert(T::alive == 1);
    164         assert(T::constructed == 1);
    165         assert(T::value_constructed == 1);
    166         assert(T::destroyed == 1);
    167         assert(static_cast<bool>(opt) == true);
    168         assert(*opt == T(4)); // size of the initializer list
    169     }
    170     {
    171         T::reset_constructors();
    172         opt.emplace({-10, 99, 42, 1}, 42);
    173         assert(T::alive == 1);
    174         assert(T::constructed == 1);
    175         assert(T::value_constructed == 1);
    176         assert(T::destroyed == 1);
    177         assert(static_cast<bool>(opt) == true);
    178         assert(*opt == T(4)); // size of the initializer list
    179     }
    180 }
    181 
    182 
    183 
    184 int main()
    185 {
    186     {
    187         test_on_test_type<TestTypes::TestType>();
    188         test_on_test_type<ExplicitTestTypes::TestType>();
    189     }
    190     {
    191         using T = int;
    192         test_one_arg<T>();
    193         test_one_arg<const T>();
    194     }
    195     {
    196         using T = ConstexprTestTypes::TestType;
    197         test_multi_arg<T>();
    198     }
    199     {
    200         using T = ExplicitConstexprTestTypes::TestType;
    201         test_multi_arg<T>();
    202     }
    203     {
    204         using T = TrivialTestTypes::TestType;
    205         test_multi_arg<T>();
    206     }
    207     {
    208         using T = ExplicitTrivialTestTypes::TestType;
    209         test_multi_arg<T>();
    210     }
    211     {
    212         optional<const int> opt;
    213         opt.emplace(42);
    214         assert(*opt == 42);
    215         opt.emplace();
    216         assert(*opt == 0);
    217     }
    218 #ifndef TEST_HAS_NO_EXCEPTIONS
    219     Y::dtor_called = false;
    220     {
    221         Y y;
    222         optional<Y> opt(y);
    223         try
    224         {
    225             assert(static_cast<bool>(opt) == true);
    226             assert(Y::dtor_called == false);
    227             opt.emplace(1);
    228         }
    229         catch (int i)
    230         {
    231             assert(i == 6);
    232             assert(static_cast<bool>(opt) == false);
    233             assert(Y::dtor_called == true);
    234         }
    235     }
    236 #endif
    237 }
    238