brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.5 KiB · c757120 Raw
428 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 T> void swap(optional<T>& x, optional<T>& y)13//     noexcept(noexcept(x.swap(y)));14 15#include <cassert>16#include <memory>17#include <optional>18#include <type_traits>19 20#include "test_macros.h"21#include "archetypes.h"22 23using std::optional;24 25class X26{27    int i_;28public:29    static unsigned dtor_called;30    X(int i) : i_(i) {}31    X(X&& x) = default;32    X& operator=(X&&) = default;33    ~X() {++dtor_called;}34 35    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}36};37 38unsigned X::dtor_called = 0;39 40class Y41{42    int i_;43public:44    static unsigned dtor_called;45    Y(int i) : i_(i) {}46    Y(Y&&) = default;47    ~Y() {++dtor_called;}48 49    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}50    friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}51};52 53unsigned Y::dtor_called = 0;54 55class Z56{57    int i_;58public:59    Z(int i) : i_(i) {}60    Z(Z&&) { TEST_THROW(7);}61 62    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}63    friend void swap(Z&, Z&) { TEST_THROW(6);}64};65 66 67struct NonSwappable {68    NonSwappable(NonSwappable const&) = delete;69};70void swap(NonSwappable&, NonSwappable&) = delete;71 72void test_swap_sfinae() {73    using std::optional;74    {75        using T = TestTypes::TestType;76        static_assert(std::is_swappable_v<optional<T>>, "");77    }78    {79        using T = TestTypes::MoveOnly;80        static_assert(std::is_swappable_v<optional<T>>, "");81    }82    {83        using T = TestTypes::Copyable;84        static_assert(std::is_swappable_v<optional<T>>, "");85    }86    {87        using T = TestTypes::NoCtors;88        static_assert(!std::is_swappable_v<optional<T>>, "");89    }90    {91        using T = NonSwappable;92        static_assert(!std::is_swappable_v<optional<T>>, "");93    }94    {95        // Even though CopyOnly has deleted move operations, those operations96        // cause optional<CopyOnly> to have implicitly deleted move operations97        // that decay into copies.98        using T = TestTypes::CopyOnly;99        using Opt = optional<T>;100        T::reset();101        Opt L(101), R(42);102        T::reset_constructors();103        std::swap(L, R);104        assert(L->value == 42);105        assert(R->value == 101);106        assert(T::copy_constructed == 1);107        assert(T::constructed == T::copy_constructed);108        assert(T::assigned == 2);109        assert(T::assigned == T::copy_assigned);110    }111}112 113#if TEST_STD_VER >= 26114template <typename T>115constexpr bool test_swap_ref() {116  {117    optional<T&> opt1;118    optional<T&> opt2;119    static_assert(noexcept(swap(opt1, opt2)) == true);120    assert(static_cast<bool>(opt1) == false);121    assert(static_cast<bool>(opt2) == false);122    swap(opt1, opt2);123    assert(static_cast<bool>(opt1) == false);124    assert(static_cast<bool>(opt2) == false);125  }126  {127    T one{1};128    optional<T&> opt1(one);129    optional<T&> opt2;130    static_assert(noexcept(swap(opt1, opt2)) == true);131    assert(static_cast<bool>(opt1) == true);132    assert(*opt1 == 1);133    assert(std::addressof(*opt1) == std::addressof(one));134    assert(static_cast<bool>(opt2) == false);135    swap(opt1, opt2);136    assert(static_cast<bool>(opt1) == false);137    assert(static_cast<bool>(opt2) == true);138    assert(*opt2 == 1);139    assert(std::addressof(*opt2) == std::addressof(one));140  }141  {142    T two{2};143    optional<T&> opt1;144    optional<T&> opt2(two);145    static_assert(noexcept(swap(opt1, opt2)) == true);146    assert(static_cast<bool>(opt1) == false);147    assert(static_cast<bool>(opt2) == true);148    assert(*opt2 == 2);149    assert(std::addressof(*opt2) == std::addressof(two));150    swap(opt1, opt2);151    assert(static_cast<bool>(opt1) == true);152    assert(*opt1 == 2);153    assert(std::addressof(*opt1) == std::addressof(two));154    assert(static_cast<bool>(opt2) == false);155  }156  {157    T one{1};158    T two{2};159    optional<T&> opt1(one);160    optional<T&> opt2(two);161    static_assert(noexcept(swap(opt1, opt2)) == true);162    assert(static_cast<bool>(opt1) == true);163    assert(*opt1 == 1);164    assert(std::addressof(*opt1) == std::addressof(one));165    assert(static_cast<bool>(opt2) == true);166    assert(*opt2 == 2);167    assert(std::addressof(*opt2) == std::addressof(two));168    swap(opt1, opt2);169    assert(static_cast<bool>(opt1) == true);170    assert(*opt1 == 2);171    assert(std::addressof(*opt1) == std::addressof(two));172    assert(static_cast<bool>(opt2) == true);173    assert(*opt2 == 1);174    assert(std::addressof(*opt2) == std::addressof(one));175  }176  return true;177}178#endif179 180int main(int, char**)181{182    test_swap_sfinae();183#if TEST_STD_VER >= 26184    static_assert(test_swap_ref<int>());185    static_assert(test_swap_ref<double>());186    test_swap_ref<int>();187    test_swap_ref<double>();188#endif189    {190        optional<int> opt1;191        optional<int> opt2;192        static_assert(noexcept(swap(opt1, opt2)) == true, "");193        assert(static_cast<bool>(opt1) == false);194        assert(static_cast<bool>(opt2) == false);195        swap(opt1, opt2);196        assert(static_cast<bool>(opt1) == false);197        assert(static_cast<bool>(opt2) == false);198    }199    {200        optional<int> opt1(1);201        optional<int> opt2;202        static_assert(noexcept(swap(opt1, opt2)) == true, "");203        assert(static_cast<bool>(opt1) == true);204        assert(*opt1 == 1);205        assert(static_cast<bool>(opt2) == false);206        swap(opt1, opt2);207        assert(static_cast<bool>(opt1) == false);208        assert(static_cast<bool>(opt2) == true);209        assert(*opt2 == 1);210    }211    {212        optional<int> opt1;213        optional<int> opt2(2);214        static_assert(noexcept(swap(opt1, opt2)) == true, "");215        assert(static_cast<bool>(opt1) == false);216        assert(static_cast<bool>(opt2) == true);217        assert(*opt2 == 2);218        swap(opt1, opt2);219        assert(static_cast<bool>(opt1) == true);220        assert(*opt1 == 2);221        assert(static_cast<bool>(opt2) == false);222    }223    {224        optional<int> opt1(1);225        optional<int> opt2(2);226        static_assert(noexcept(swap(opt1, opt2)) == true, "");227        assert(static_cast<bool>(opt1) == true);228        assert(*opt1 == 1);229        assert(static_cast<bool>(opt2) == true);230        assert(*opt2 == 2);231        swap(opt1, opt2);232        assert(static_cast<bool>(opt1) == true);233        assert(*opt1 == 2);234        assert(static_cast<bool>(opt2) == true);235        assert(*opt2 == 1);236    }237    {238        optional<X> opt1;239        optional<X> opt2;240        static_assert(noexcept(swap(opt1, opt2)) == true, "");241        assert(static_cast<bool>(opt1) == false);242        assert(static_cast<bool>(opt2) == false);243        swap(opt1, opt2);244        assert(static_cast<bool>(opt1) == false);245        assert(static_cast<bool>(opt2) == false);246        assert(X::dtor_called == 0);247    }248    {249        optional<X> opt1(1);250        optional<X> opt2;251        static_assert(noexcept(swap(opt1, opt2)) == true, "");252        assert(static_cast<bool>(opt1) == true);253        assert(*opt1 == 1);254        assert(static_cast<bool>(opt2) == false);255        X::dtor_called = 0;256        swap(opt1, opt2);257        assert(X::dtor_called == 1);258        assert(static_cast<bool>(opt1) == false);259        assert(static_cast<bool>(opt2) == true);260        assert(*opt2 == 1);261    }262    {263        optional<X> opt1;264        optional<X> opt2(2);265        static_assert(noexcept(swap(opt1, opt2)) == true, "");266        assert(static_cast<bool>(opt1) == false);267        assert(static_cast<bool>(opt2) == true);268        assert(*opt2 == 2);269        X::dtor_called = 0;270        swap(opt1, opt2);271        assert(X::dtor_called == 1);272        assert(static_cast<bool>(opt1) == true);273        assert(*opt1 == 2);274        assert(static_cast<bool>(opt2) == false);275    }276    {277        optional<X> opt1(1);278        optional<X> opt2(2);279        static_assert(noexcept(swap(opt1, opt2)) == true, "");280        assert(static_cast<bool>(opt1) == true);281        assert(*opt1 == 1);282        assert(static_cast<bool>(opt2) == true);283        assert(*opt2 == 2);284        X::dtor_called = 0;285        swap(opt1, opt2);286        assert(X::dtor_called == 1);  // from inside std::swap287        assert(static_cast<bool>(opt1) == true);288        assert(*opt1 == 2);289        assert(static_cast<bool>(opt2) == true);290        assert(*opt2 == 1);291    }292    {293        optional<Y> opt1;294        optional<Y> opt2;295        static_assert(noexcept(swap(opt1, opt2)) == false, "");296        assert(static_cast<bool>(opt1) == false);297        assert(static_cast<bool>(opt2) == false);298        swap(opt1, opt2);299        assert(static_cast<bool>(opt1) == false);300        assert(static_cast<bool>(opt2) == false);301        assert(Y::dtor_called == 0);302    }303    {304        optional<Y> opt1(1);305        optional<Y> opt2;306        static_assert(noexcept(swap(opt1, opt2)) == false, "");307        assert(static_cast<bool>(opt1) == true);308        assert(*opt1 == 1);309        assert(static_cast<bool>(opt2) == false);310        Y::dtor_called = 0;311        swap(opt1, opt2);312        assert(Y::dtor_called == 1);313        assert(static_cast<bool>(opt1) == false);314        assert(static_cast<bool>(opt2) == true);315        assert(*opt2 == 1);316    }317    {318        optional<Y> opt1;319        optional<Y> opt2(2);320        static_assert(noexcept(swap(opt1, opt2)) == false, "");321        assert(static_cast<bool>(opt1) == false);322        assert(static_cast<bool>(opt2) == true);323        assert(*opt2 == 2);324        Y::dtor_called = 0;325        swap(opt1, opt2);326        assert(Y::dtor_called == 1);327        assert(static_cast<bool>(opt1) == true);328        assert(*opt1 == 2);329        assert(static_cast<bool>(opt2) == false);330    }331    {332        optional<Y> opt1(1);333        optional<Y> opt2(2);334        static_assert(noexcept(swap(opt1, opt2)) == false, "");335        assert(static_cast<bool>(opt1) == true);336        assert(*opt1 == 1);337        assert(static_cast<bool>(opt2) == true);338        assert(*opt2 == 2);339        Y::dtor_called = 0;340        swap(opt1, opt2);341        assert(Y::dtor_called == 0);342        assert(static_cast<bool>(opt1) == true);343        assert(*opt1 == 2);344        assert(static_cast<bool>(opt2) == true);345        assert(*opt2 == 1);346    }347    {348        optional<Z> opt1;349        optional<Z> opt2;350        static_assert(noexcept(swap(opt1, opt2)) == false, "");351        assert(static_cast<bool>(opt1) == false);352        assert(static_cast<bool>(opt2) == false);353        swap(opt1, opt2);354        assert(static_cast<bool>(opt1) == false);355        assert(static_cast<bool>(opt2) == false);356    }357#ifndef TEST_HAS_NO_EXCEPTIONS358    {359        optional<Z> opt1;360        opt1.emplace(1);361        optional<Z> opt2;362        static_assert(noexcept(swap(opt1, opt2)) == false, "");363        assert(static_cast<bool>(opt1) == true);364        assert(*opt1 == 1);365        assert(static_cast<bool>(opt2) == false);366        try367        {368            swap(opt1, opt2);369            assert(false);370        }371        catch (int i)372        {373            assert(i == 7);374        }375        assert(static_cast<bool>(opt1) == true);376        assert(*opt1 == 1);377        assert(static_cast<bool>(opt2) == false);378    }379    {380        optional<Z> opt1;381        optional<Z> opt2;382        opt2.emplace(2);383        static_assert(noexcept(swap(opt1, opt2)) == false, "");384        assert(static_cast<bool>(opt1) == false);385        assert(static_cast<bool>(opt2) == true);386        assert(*opt2 == 2);387        try388        {389            swap(opt1, opt2);390            assert(false);391        }392        catch (int i)393        {394            assert(i == 7);395        }396        assert(static_cast<bool>(opt1) == false);397        assert(static_cast<bool>(opt2) == true);398        assert(*opt2 == 2);399    }400    {401        optional<Z> opt1;402        opt1.emplace(1);403        optional<Z> opt2;404        opt2.emplace(2);405        static_assert(noexcept(swap(opt1, opt2)) == false, "");406        assert(static_cast<bool>(opt1) == true);407        assert(*opt1 == 1);408        assert(static_cast<bool>(opt2) == true);409        assert(*opt2 == 2);410        try411        {412            swap(opt1, opt2);413            assert(false);414        }415        catch (int i)416        {417            assert(i == 6);418        }419        assert(static_cast<bool>(opt1) == true);420        assert(*opt1 == 1);421        assert(static_cast<bool>(opt2) == true);422        assert(*opt2 == 2);423    }424#endif // TEST_HAS_NO_EXCEPTIONS425 426  return 0;427}428