brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.5 KiB · 629e315 Raw
320 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// UNSUPPORTED: c++03, c++11, c++1410// <optional>11 12// template <class... Args> T& optional<T>::emplace(Args&&... args);13 14#include <optional>15#include <type_traits>16#include <cassert>17#include <memory>18 19#include "test_macros.h"20#include "archetypes.h"21 22using std::optional;23 24class X25{26    int i_;27    int j_ = 0;28public:29    constexpr X() : i_(0) {}30    constexpr X(int i) : i_(i) {}31    constexpr X(int i, int j) : i_(i), j_(j) {}32 33    friend constexpr bool operator==(const X& x, const X& y)34        {return x.i_ == y.i_ && x.j_ == y.j_;}35};36 37class Y38{39public:40    static bool dtor_called;41    Y() = default;42    Y(int) { TEST_THROW(6);}43    Y(const Y&) = default;44    Y& operator=(const Y&) = default;45    ~Y() {dtor_called = true;}46};47 48bool Y::dtor_called = false;49 50template <class T>51constexpr bool test_one_arg() {52    using Opt = std::optional<T>;53    {54        Opt opt;55        auto & v = opt.emplace();56        static_assert( std::is_same_v<T&, decltype(v)>, "" );57        assert(static_cast<bool>(opt) == true);58        assert(*opt == T(0));59        assert(&v == &*opt);60    }61    {62        Opt opt;63        auto & v = opt.emplace(1);64        static_assert( std::is_same_v<T&, decltype(v)>, "" );65        assert(static_cast<bool>(opt) == true);66        assert(*opt == T(1));67        assert(&v == &*opt);68    }69    {70        Opt opt(2);71        auto & v = opt.emplace();72        static_assert( std::is_same_v<T&, decltype(v)>, "" );73        assert(static_cast<bool>(opt) == true);74        assert(*opt == T(0));75        assert(&v == &*opt);76    }77    {78        Opt opt(2);79        auto & v = opt.emplace(1);80        static_assert( std::is_same_v<T&, decltype(v)>, "" );81        assert(static_cast<bool>(opt) == true);82        assert(*opt == T(1));83        assert(&v == &*opt);84    }85    return true;86}87 88 89template <class T>90constexpr bool test_multi_arg()91{92    test_one_arg<T>();93    using Opt = std::optional<T>;94    {95        Opt opt;96        auto &v = opt.emplace(101, 41);97        static_assert( std::is_same_v<T&, decltype(v)>, "" );98        assert(static_cast<bool>(opt) == true);99        assert(   v == T(101, 41));100        assert(*opt == T(101, 41));101    }102    {103        Opt opt;104        auto &v = opt.emplace({1, 2, 3, 4});105        static_assert( std::is_same_v<T&, decltype(v)>, "" );106        assert(static_cast<bool>(opt) == true);107        assert(  v == T(4)); // T sets its value to the size of the init list108        assert(*opt == T(4));109    }110    {111        Opt opt;112        auto &v = opt.emplace({1, 2, 3, 4, 5}, 6);113        static_assert( std::is_same_v<T&, decltype(v)>, "" );114        assert(static_cast<bool>(opt) == true);115        assert(  v == T(5)); // T sets its value to the size of the init list116        assert(*opt == T(5)); // T sets its value to the size of the init list117    }118    return true;119}120 121template <class T>122void test_on_test_type() {123 124    T::reset();125    optional<T> opt;126    assert(T::alive == 0);127    {128        T::reset_constructors();129        auto &v = opt.emplace();130        static_assert( std::is_same_v<T&, decltype(v)>, "" );131        assert(T::alive == 1);132        assert(T::constructed == 1);133        assert(T::default_constructed == 1);134        assert(T::destroyed == 0);135        assert(static_cast<bool>(opt) == true);136        assert(*opt == T());137        assert(&v == &*opt);138    }139    {140        T::reset_constructors();141        auto &v = opt.emplace();142        static_assert( std::is_same_v<T&, decltype(v)>, "" );143        assert(T::alive == 1);144        assert(T::constructed == 1);145        assert(T::default_constructed == 1);146        assert(T::destroyed == 1);147        assert(static_cast<bool>(opt) == true);148        assert(*opt == T());149        assert(&v == &*opt);150    }151    {152        T::reset_constructors();153        auto &v = opt.emplace(101);154        static_assert( std::is_same_v<T&, decltype(v)>, "" );155        assert(T::alive == 1);156        assert(T::constructed == 1);157        assert(T::value_constructed == 1);158        assert(T::destroyed == 1);159        assert(static_cast<bool>(opt) == true);160        assert(*opt == T(101));161        assert(&v == &*opt);162    }163    {164        T::reset_constructors();165        auto &v = opt.emplace(-10, 99);166        static_assert( std::is_same_v<T&, decltype(v)>, "" );167        assert(T::alive == 1);168        assert(T::constructed == 1);169        assert(T::value_constructed == 1);170        assert(T::destroyed == 1);171        assert(static_cast<bool>(opt) == true);172        assert(*opt == T(-10, 99));173        assert(&v == &*opt);174    }175    {176        T::reset_constructors();177        auto &v = opt.emplace(-10, 99);178        static_assert( std::is_same_v<T&, decltype(v)>, "" );179        assert(T::alive == 1);180        assert(T::constructed == 1);181        assert(T::value_constructed == 1);182        assert(T::destroyed == 1);183        assert(static_cast<bool>(opt) == true);184        assert(*opt == T(-10, 99));185        assert(&v == &*opt);186    }187    {188        T::reset_constructors();189        auto &v = opt.emplace({-10, 99, 42, 1});190        static_assert( std::is_same_v<T&, decltype(v)>, "" );191        assert(T::alive == 1);192        assert(T::constructed == 1);193        assert(T::value_constructed == 1);194        assert(T::destroyed == 1);195        assert(static_cast<bool>(opt) == true);196        assert(*opt == T(4)); // size of the initializer list197        assert(&v == &*opt);198    }199    {200        T::reset_constructors();201        auto &v = opt.emplace({-10, 99, 42, 1}, 42);202        static_assert( std::is_same_v<T&, decltype(v)>, "" );203        assert(T::alive == 1);204        assert(T::constructed == 1);205        assert(T::value_constructed == 1);206        assert(T::destroyed == 1);207        assert(static_cast<bool>(opt) == true);208        assert(*opt == T(4)); // size of the initializer list209        assert(&v == &*opt);210    }211}212 213TEST_CONSTEXPR_CXX20 bool test_empty_emplace() {214  optional<const int> opt;215  auto& v = opt.emplace(42);216  static_assert(std::is_same_v<const int&, decltype(v)>, "");217  assert(*opt == 42);218  assert(v == 42);219  opt.emplace();220  assert(*opt == 0);221  return true;222}223 224#if TEST_STD_VER >= 26225template <class T, std::remove_reference_t<T> _Val>226constexpr bool test_ref() {227  using Opt = std::optional<T&>;228  T t{_Val};229  {230    Opt opt;231    auto& v = opt.emplace(t);232    static_assert(std::is_same_v<T&, decltype(v)>);233    assert(static_cast<bool>(opt) == true);234    assert(*opt == t);235    assert(&v == &*opt);236    assert(&t == &*opt);237  }238  return true;239}240#endif241 242int main(int, char**)243{244    {245        test_on_test_type<TestTypes::TestType>();246        test_on_test_type<ExplicitTestTypes::TestType>();247    }248    {249        using T = int;250        test_one_arg<T>();251        test_one_arg<const T>();252#if TEST_STD_VER > 17253        static_assert(test_one_arg<T>());254        static_assert(test_one_arg<const T>());255#endif256    }257    {258        using T = ConstexprTestTypes::TestType;259        test_multi_arg<T>();260#if TEST_STD_VER > 17261        static_assert(test_multi_arg<T>());262#endif263    }264    {265        using T = ExplicitConstexprTestTypes::TestType;266        test_multi_arg<T>();267#if TEST_STD_VER > 17268        static_assert(test_multi_arg<T>());269#endif270    }271    {272        using T = TrivialTestTypes::TestType;273        test_multi_arg<T>();274#if TEST_STD_VER > 17275        static_assert(test_multi_arg<T>());276#endif277    }278    {279        using T = ExplicitTrivialTestTypes::TestType;280        test_multi_arg<T>();281#if TEST_STD_VER > 17282        static_assert(test_multi_arg<T>());283#endif284    }285    {286        test_empty_emplace();287#if TEST_STD_VER > 17288        static_assert(test_empty_emplace());289#endif290    }291#ifndef TEST_HAS_NO_EXCEPTIONS292    Y::dtor_called = false;293    {294        Y y;295        optional<Y> opt(y);296        try297        {298            assert(static_cast<bool>(opt) == true);299            assert(Y::dtor_called == false);300            auto &v = opt.emplace(1);301            static_assert( std::is_same_v<Y&, decltype(v)>, "" );302            assert(false);303        }304        catch (int i)305        {306            assert(i == 6);307            assert(static_cast<bool>(opt) == false);308            assert(Y::dtor_called == true);309        }310    }311#endif312#if TEST_STD_VER >= 26313    static_assert(test_ref<int, 1>());314    static_assert(test_ref<double, 15.0>());315    assert((test_ref<int, 1>()));316    assert((test_ref<double, 15.0>()));317#endif318    return 0;319}320