brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.7 KiB · 4751f8e Raw
256 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// From LWG2451:13// template<class U>14//   optional<T>& operator=(const optional<U>& rhs);15 16#include <optional>17#include <type_traits>18#include <cassert>19 20#include "test_macros.h"21#include "archetypes.h"22 23using std::optional;24 25struct X26{27    static bool throw_now;28 29    X() = default;30    X(int)31    {32        if (throw_now)33            TEST_THROW(6);34    }35};36 37bool X::throw_now = false;38 39struct Y140{41    Y1() = default;42    Y1(const int&) {}43    Y1& operator=(const Y1&) = delete;44};45 46struct Y247{48    Y2() = default;49    Y2(const int&) = delete;50    Y2& operator=(const int&) { return *this; }51};52 53template <class T>54struct AssignableFrom {55  static int type_constructed;56  static int type_assigned;57static int int_constructed;58  static int int_assigned;59 60  static void reset() {61      type_constructed = int_constructed = 0;62      type_assigned = int_assigned = 0;63  }64 65  AssignableFrom() = default;66 67  explicit AssignableFrom(T) { ++type_constructed; }68  AssignableFrom& operator=(T) { ++type_assigned; return *this; }69 70  AssignableFrom(int) { ++int_constructed; }71  AssignableFrom& operator=(int) { ++int_assigned; return *this; }72private:73  AssignableFrom(AssignableFrom const&) = delete;74  AssignableFrom& operator=(AssignableFrom const&) = delete;75};76 77template <class T> int AssignableFrom<T>::type_constructed = 0;78template <class T> int AssignableFrom<T>::type_assigned = 0;79template <class T> int AssignableFrom<T>::int_constructed = 0;80template <class T> int AssignableFrom<T>::int_assigned = 0;81 82 83void test_with_test_type() {84    using T = TestTypes::TestType;85    T::reset();86    { // non-empty to empty87        T::reset_constructors();88        optional<T> opt;89        const optional<int> other(42);90        opt = other;91        assert(T::alive == 1);92        assert(T::constructed == 1);93        assert(T::value_constructed == 1);94        assert(T::assigned == 0);95        assert(T::destroyed == 0);96        assert(static_cast<bool>(other) == true);97        assert(*other == 42);98        assert(static_cast<bool>(opt) == true);99        assert(*opt == T(42));100    }101    assert(T::alive == 0);102    { // non-empty to non-empty103        optional<T> opt(101);104        const optional<int> other(42);105        T::reset_constructors();106        opt = other;107        assert(T::alive == 1);108        assert(T::constructed == 0);109        assert(T::assigned == 1);110        assert(T::value_assigned == 1);111        assert(T::destroyed == 0);112        assert(static_cast<bool>(other) == true);113        assert(*other == 42);114        assert(static_cast<bool>(opt) == true);115        assert(*opt == T(42));116    }117    assert(T::alive == 0);118    { // empty to non-empty119        optional<T> opt(101);120        const optional<int> other;121        T::reset_constructors();122        opt = other;123        assert(T::alive == 0);124        assert(T::constructed == 0);125        assert(T::assigned == 0);126        assert(T::destroyed == 1);127        assert(static_cast<bool>(other) == false);128        assert(static_cast<bool>(opt) == false);129    }130    assert(T::alive == 0);131    { // empty to empty132        optional<T> opt;133        const optional<int> other;134        T::reset_constructors();135        opt = other;136        assert(T::alive == 0);137        assert(T::constructed == 0);138        assert(T::assigned == 0);139        assert(T::destroyed == 0);140        assert(static_cast<bool>(other) == false);141        assert(static_cast<bool>(opt) == false);142    }143    assert(T::alive == 0);144}145 146void test_ambiguous_assign() {147    using OptInt = std::optional<int>;148    {149        using T = AssignableFrom<OptInt const&>;150        const OptInt a(42);151        T::reset();152        {153            std::optional<T> t;154            t = a;155            assert(T::type_constructed == 1);156            assert(T::type_assigned == 0);157            assert(T::int_constructed == 0);158            assert(T::int_assigned == 0);159        }160        T::reset();161        {162            std::optional<T> t(42);163            t = a;164            assert(T::type_constructed == 0);165            assert(T::type_assigned == 1);166            assert(T::int_constructed == 1);167            assert(T::int_assigned == 0);168        }169        T::reset();170        {171            std::optional<T> t(42);172            t = std::move(a);173            assert(T::type_constructed == 0);174            assert(T::type_assigned == 1);175            assert(T::int_constructed == 1);176            assert(T::int_assigned == 0);177        }178    }179    {180        using T = AssignableFrom<OptInt&>;181        OptInt a(42);182        T::reset();183        {184            std::optional<T> t;185            t = a;186            assert(T::type_constructed == 1);187            assert(T::type_assigned == 0);188            assert(T::int_constructed == 0);189            assert(T::int_assigned == 0);190        }191        {192            using Opt = std::optional<T>;193            static_assert(!std::is_assignable_v<Opt&, OptInt const&>, "");194        }195    }196}197 198 199int main(int, char**)200{201    test_with_test_type();202    test_ambiguous_assign();203    {204        optional<int> opt;205        constexpr optional<short> opt2;206        opt = opt2;207        static_assert(static_cast<bool>(opt2) == false, "");208        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));209    }210    {211        optional<int> opt;212        constexpr optional<short> opt2(short{2});213        opt = opt2;214        static_assert(static_cast<bool>(opt2) == true, "");215        static_assert(*opt2 == 2, "");216        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));217        assert(*opt == *opt2);218    }219    {220        optional<int> opt(3);221        constexpr optional<short> opt2;222        opt = opt2;223        static_assert(static_cast<bool>(opt2) == false, "");224        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));225    }226    {227        optional<int> opt(3);228        constexpr optional<short> opt2(short{2});229        opt = opt2;230        static_assert(static_cast<bool>(opt2) == true, "");231        static_assert(*opt2 == 2, "");232        assert(static_cast<bool>(opt) == static_cast<bool>(opt2));233        assert(*opt == *opt2);234    }235#ifndef TEST_HAS_NO_EXCEPTIONS236    {237        optional<X> opt;238        optional<int> opt2(42);239        assert(static_cast<bool>(opt2) == true);240        try241        {242            X::throw_now = true;243            opt = opt2;244            assert(false);245        }246        catch (int i)247        {248            assert(i == 6);249            assert(static_cast<bool>(opt) == false);250        }251    }252#endif253 254  return 0;255}256