Home | History | Annotate | Download | only in optional.object.ctor
      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 // constexpr optional(const optional<T>& rhs);
     14 
     15 #include <optional>
     16 #include <type_traits>
     17 #include <cassert>
     18 
     19 #include "test_macros.h"
     20 #include "archetypes.hpp"
     21 
     22 using std::optional;
     23 
     24 template <class T, class ...InitArgs>
     25 void test(InitArgs&&... args)
     26 {
     27     const optional<T> rhs(std::forward<InitArgs>(args)...);
     28     bool rhs_engaged = static_cast<bool>(rhs);
     29     optional<T> lhs = rhs;
     30     assert(static_cast<bool>(lhs) == rhs_engaged);
     31     if (rhs_engaged)
     32         assert(*lhs == *rhs);
     33 }
     34 
     35 template <class T, class ...InitArgs>
     36 constexpr bool constexpr_test(InitArgs&&... args)
     37 {
     38     static_assert( std::is_trivially_copy_constructible_v<T>, ""); // requirement
     39     const optional<T> rhs(std::forward<InitArgs>(args)...);
     40     optional<T> lhs = rhs;
     41     return (lhs.has_value() == rhs.has_value()) &&
     42            (lhs.has_value() ? *lhs == *rhs : true);
     43 }
     44 
     45 void test_throwing_ctor() {
     46 #ifndef TEST_HAS_NO_EXCEPTIONS
     47     struct Z {
     48         Z() : count(0) {}
     49         Z(Z const& o) : count(o.count + 1)
     50         { if (count == 2) throw 6; }
     51         int count;
     52     };
     53     const Z z;
     54     const optional<Z> rhs(z);
     55     try
     56     {
     57         optional<Z> lhs(rhs);
     58         assert(false);
     59     }
     60     catch (int i)
     61     {
     62         assert(i == 6);
     63     }
     64 #endif
     65 }
     66 
     67 template <class T, class ...InitArgs>
     68 void test_ref(InitArgs&&... args)
     69 {
     70     const optional<T> rhs(std::forward<InitArgs>(args)...);
     71     bool rhs_engaged = static_cast<bool>(rhs);
     72     optional<T> lhs = rhs;
     73     assert(static_cast<bool>(lhs) == rhs_engaged);
     74     if (rhs_engaged)
     75         assert(&(*lhs) == &(*rhs));
     76 }
     77 
     78 
     79 void test_reference_extension()
     80 {
     81 #if defined(_LIBCPP_VERSION) && 0 // FIXME these extensions are currently disabled.
     82     using T = TestTypes::TestType;
     83     T::reset();
     84     {
     85         T t;
     86         T::reset_constructors();
     87         test_ref<T&>();
     88         test_ref<T&>(t);
     89         assert(T::alive == 1);
     90         assert(T::constructed == 0);
     91         assert(T::assigned == 0);
     92         assert(T::destroyed == 0);
     93     }
     94     assert(T::destroyed == 1);
     95     assert(T::alive == 0);
     96     {
     97         T t;
     98         const T& ct = t;
     99         T::reset_constructors();
    100         test_ref<T const&>();
    101         test_ref<T const&>(t);
    102         test_ref<T const&>(ct);
    103         assert(T::alive == 1);
    104         assert(T::constructed == 0);
    105         assert(T::assigned == 0);
    106         assert(T::destroyed == 0);
    107     }
    108     assert(T::alive == 0);
    109     assert(T::destroyed == 1);
    110     {
    111         static_assert(!std::is_copy_constructible<std::optional<T&&>>::value, "");
    112         static_assert(!std::is_copy_constructible<std::optional<T const&&>>::value, "");
    113     }
    114 #endif
    115 }
    116 
    117 int main()
    118 {
    119     test<int>();
    120     test<int>(3);
    121     static_assert(constexpr_test<int>(), "" );
    122     static_assert(constexpr_test<int>(3), "" );
    123 
    124     {
    125         const optional<const int> o(42);
    126         optional<const int> o2(o);
    127         assert(*o2 == 42);
    128     }
    129     {
    130         using T = TestTypes::TestType;
    131         T::reset();
    132         const optional<T> rhs;
    133         assert(T::alive == 0);
    134         const optional<T> lhs(rhs);
    135         assert(lhs.has_value() == false);
    136         assert(T::alive == 0);
    137     }
    138     TestTypes::TestType::reset();
    139     {
    140         using T = TestTypes::TestType;
    141         T::reset();
    142         const optional<T> rhs(42);
    143         assert(T::alive == 1);
    144         assert(T::value_constructed == 1);
    145         assert(T::copy_constructed == 0);
    146         const optional<T> lhs(rhs);
    147         assert(lhs.has_value());
    148         assert(T::copy_constructed == 1);
    149         assert(T::alive == 2);
    150     }
    151     TestTypes::TestType::reset();
    152     {
    153         using namespace ConstexprTestTypes;
    154         test<TestType>();
    155         test<TestType>(42);
    156     }
    157     {
    158         using namespace TrivialTestTypes;
    159         test<TestType>();
    160         test<TestType>(42);
    161     }
    162     {
    163         test_throwing_ctor();
    164     }
    165     {
    166         test_reference_extension();
    167     }
    168     {
    169     constexpr std::optional<int> o1{4};
    170     constexpr std::optional<int> o2 = o1;
    171     static_assert( *o2 == 4, "" );
    172     }
    173 }
    174