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> T& 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         auto & v = opt.emplace();
     55         static_assert( std::is_same_v<T&, decltype(v)>, "" );
     56         assert(static_cast<bool>(opt) == true);
     57         assert(*opt == T(0));
     58         assert(&v == &*opt);
     59     }
     60     {
     61         Opt opt;
     62         auto & v = opt.emplace(1);
     63         static_assert( std::is_same_v<T&, decltype(v)>, "" );
     64         assert(static_cast<bool>(opt) == true);
     65         assert(*opt == T(1));
     66         assert(&v == &*opt);
     67     }
     68     {
     69         Opt opt(2);
     70         auto & v = opt.emplace();
     71         static_assert( std::is_same_v<T&, decltype(v)>, "" );
     72         assert(static_cast<bool>(opt) == true);
     73         assert(*opt == T(0));
     74         assert(&v == &*opt);
     75     }
     76     {
     77         Opt opt(2);
     78         auto & v = opt.emplace(1);
     79         static_assert( std::is_same_v<T&, decltype(v)>, "" );
     80         assert(static_cast<bool>(opt) == true);
     81         assert(*opt == T(1));
     82         assert(&v == &*opt);
     83     }
     84 }
     85 
     86 
     87 template <class T>
     88 void test_multi_arg()
     89 {
     90     test_one_arg<T>();
     91     using Opt = std::optional<T>;
     92     {
     93         Opt opt;
     94         auto &v = opt.emplace(101, 41);
     95         static_assert( std::is_same_v<T&, decltype(v)>, "" );
     96         assert(static_cast<bool>(opt) == true);
     97         assert(   v == T(101, 41));
     98         assert(*opt == T(101, 41));
     99     }
    100     {
    101         Opt opt;
    102         auto &v = opt.emplace({1, 2, 3, 4});
    103         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    104         assert(static_cast<bool>(opt) == true);
    105         assert(  v == T(4)); // T sets its value to the size of the init list
    106         assert(*opt == T(4));
    107     }
    108     {
    109         Opt opt;
    110         auto &v = opt.emplace({1, 2, 3, 4, 5}, 6);
    111         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    112         assert(static_cast<bool>(opt) == true);
    113         assert(  v == T(5)); // T sets its value to the size of the init list
    114         assert(*opt == T(5)); // T sets its value to the size of the init list
    115     }
    116 }
    117 
    118 template <class T>
    119 void test_on_test_type() {
    120 
    121     T::reset();
    122     optional<T> opt;
    123     assert(T::alive == 0);
    124     {
    125         T::reset_constructors();
    126         auto &v = opt.emplace();
    127         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    128         assert(T::alive == 1);
    129         assert(T::constructed == 1);
    130         assert(T::default_constructed == 1);
    131         assert(T::destroyed == 0);
    132         assert(static_cast<bool>(opt) == true);
    133         assert(*opt == T());
    134         assert(&v == &*opt);
    135     }
    136     {
    137         T::reset_constructors();
    138         auto &v = opt.emplace();
    139         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    140         assert(T::alive == 1);
    141         assert(T::constructed == 1);
    142         assert(T::default_constructed == 1);
    143         assert(T::destroyed == 1);
    144         assert(static_cast<bool>(opt) == true);
    145         assert(*opt == T());
    146         assert(&v == &*opt);
    147     }
    148     {
    149         T::reset_constructors();
    150         auto &v = opt.emplace(101);
    151         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    152         assert(T::alive == 1);
    153         assert(T::constructed == 1);
    154         assert(T::value_constructed == 1);
    155         assert(T::destroyed == 1);
    156         assert(static_cast<bool>(opt) == true);
    157         assert(*opt == T(101));
    158         assert(&v == &*opt);
    159     }
    160     {
    161         T::reset_constructors();
    162         auto &v = opt.emplace(-10, 99);
    163         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    164         assert(T::alive == 1);
    165         assert(T::constructed == 1);
    166         assert(T::value_constructed == 1);
    167         assert(T::destroyed == 1);
    168         assert(static_cast<bool>(opt) == true);
    169         assert(*opt == T(-10, 99));
    170         assert(&v == &*opt);
    171     }
    172     {
    173         T::reset_constructors();
    174         auto &v = opt.emplace(-10, 99);
    175         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    176         assert(T::alive == 1);
    177         assert(T::constructed == 1);
    178         assert(T::value_constructed == 1);
    179         assert(T::destroyed == 1);
    180         assert(static_cast<bool>(opt) == true);
    181         assert(*opt == T(-10, 99));
    182         assert(&v == &*opt);
    183     }
    184     {
    185         T::reset_constructors();
    186         auto &v = opt.emplace({-10, 99, 42, 1});
    187         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    188         assert(T::alive == 1);
    189         assert(T::constructed == 1);
    190         assert(T::value_constructed == 1);
    191         assert(T::destroyed == 1);
    192         assert(static_cast<bool>(opt) == true);
    193         assert(*opt == T(4)); // size of the initializer list
    194         assert(&v == &*opt);
    195     }
    196     {
    197         T::reset_constructors();
    198         auto &v = opt.emplace({-10, 99, 42, 1}, 42);
    199         static_assert( std::is_same_v<T&, decltype(v)>, "" );
    200         assert(T::alive == 1);
    201         assert(T::constructed == 1);
    202         assert(T::value_constructed == 1);
    203         assert(T::destroyed == 1);
    204         assert(static_cast<bool>(opt) == true);
    205         assert(*opt == T(4)); // size of the initializer list
    206         assert(&v == &*opt);
    207     }
    208 }
    209 
    210 
    211 
    212 int main()
    213 {
    214     {
    215         test_on_test_type<TestTypes::TestType>();
    216         test_on_test_type<ExplicitTestTypes::TestType>();
    217     }
    218     {
    219         using T = int;
    220         test_one_arg<T>();
    221         test_one_arg<const T>();
    222     }
    223     {
    224         using T = ConstexprTestTypes::TestType;
    225         test_multi_arg<T>();
    226     }
    227     {
    228         using T = ExplicitConstexprTestTypes::TestType;
    229         test_multi_arg<T>();
    230     }
    231     {
    232         using T = TrivialTestTypes::TestType;
    233         test_multi_arg<T>();
    234     }
    235     {
    236         using T = ExplicitTrivialTestTypes::TestType;
    237         test_multi_arg<T>();
    238     }
    239     {
    240         optional<const int> opt;
    241         auto &v = opt.emplace(42);
    242         static_assert( std::is_same_v<const int&, decltype(v)>, "" );
    243         assert(*opt == 42);
    244         assert(   v == 42);
    245         opt.emplace();
    246         assert(*opt == 0);
    247     }
    248 #ifndef TEST_HAS_NO_EXCEPTIONS
    249     Y::dtor_called = false;
    250     {
    251         Y y;
    252         optional<Y> opt(y);
    253         try
    254         {
    255             assert(static_cast<bool>(opt) == true);
    256             assert(Y::dtor_called == false);
    257             auto &v = opt.emplace(1);
    258             static_assert( std::is_same_v<Y&, decltype(v)>, "" );
    259             assert(false);
    260         }
    261         catch (int i)
    262         {
    263             assert(i == 6);
    264             assert(static_cast<bool>(opt) == false);
    265             assert(Y::dtor_called == true);
    266         }
    267     }
    268 #endif
    269 }
    270