brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.4 KiB · a82ca61 Raw
404 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// void swap(optional&)13//     noexcept(is_nothrow_move_constructible<T>::value &&14//              is_nothrow_swappable<T>::value)15 16#include <cassert>17#include <memory>18#include <optional>19#include <type_traits>20 21#include "test_macros.h"22#include "archetypes.h"23 24using std::optional;25 26class X27{28    int i_;29public:30    static unsigned dtor_called;31    X(int i) : i_(i) {}32    X(X&& x) = default;33    X& operator=(X&&) = default;34    ~X() {++dtor_called;}35 36    friend bool operator==(const X& x, const X& y) {return x.i_ == y.i_;}37};38 39unsigned X::dtor_called = 0;40 41class Y42{43    int i_;44public:45    static unsigned dtor_called;46    Y(int i) : i_(i) {}47    Y(Y&&) = default;48    ~Y() {++dtor_called;}49 50    friend constexpr bool operator==(const Y& x, const Y& y) {return x.i_ == y.i_;}51    friend void swap(Y& x, Y& y) {std::swap(x.i_, y.i_);}52};53 54unsigned Y::dtor_called = 0;55 56class Z57{58    int i_;59public:60    Z(int i) : i_(i) {}61    Z(Z&&) {TEST_THROW(7);}62 63    friend constexpr bool operator==(const Z& x, const Z& y) {return x.i_ == y.i_;}64    friend void swap(Z&, Z&) {TEST_THROW(6);}65};66 67class W68{69    int i_;70public:71    constexpr W(int i) : i_(i) {}72 73    friend constexpr bool operator==(const W& x, const W& y) {return x.i_ == y.i_;}74    friend TEST_CONSTEXPR_CXX20 void swap(W& x, W& y) noexcept {std::swap(x.i_, y.i_);}75};76 77template<class T>78TEST_CONSTEXPR_CXX20 bool check_swap()79{80    {81        optional<T> opt1;82        optional<T> opt2;83        static_assert(noexcept(opt1.swap(opt2)) == true);84        assert(static_cast<bool>(opt1) == false);85        assert(static_cast<bool>(opt2) == false);86        opt1.swap(opt2);87        assert(static_cast<bool>(opt1) == false);88        assert(static_cast<bool>(opt2) == false);89    }90    {91        optional<T> opt1(1);92        optional<T> opt2;93        static_assert(noexcept(opt1.swap(opt2)) == true);94        assert(static_cast<bool>(opt1) == true);95        assert(*opt1 == 1);96        assert(static_cast<bool>(opt2) == false);97        opt1.swap(opt2);98        assert(static_cast<bool>(opt1) == false);99        assert(static_cast<bool>(opt2) == true);100        assert(*opt2 == 1);101    }102    {103        optional<T> opt1;104        optional<T> opt2(2);105        static_assert(noexcept(opt1.swap(opt2)) == true, "");106        assert(static_cast<bool>(opt1) == false);107        assert(static_cast<bool>(opt2) == true);108        assert(*opt2 == 2);109        opt1.swap(opt2);110        assert(static_cast<bool>(opt1) == true);111        assert(*opt1 == 2);112        assert(static_cast<bool>(opt2) == false);113    }114    {115        optional<T> opt1(1);116        optional<T> opt2(2);117        static_assert(noexcept(opt1.swap(opt2)) == true, "");118        assert(static_cast<bool>(opt1) == true);119        assert(*opt1 == 1);120        assert(static_cast<bool>(opt2) == true);121        assert(*opt2 == 2);122        opt1.swap(opt2);123        assert(static_cast<bool>(opt1) == true);124        assert(*opt1 == 2);125        assert(static_cast<bool>(opt2) == true);126        assert(*opt2 == 1);127    }128    return true;129}130 131#if TEST_STD_VER >= 26132template <typename T>133constexpr bool check_swap_ref() {134  {135    optional<T&> opt1;136    optional<T&> opt2;137    static_assert(noexcept(opt1.swap(opt2)) == true);138    assert(static_cast<bool>(opt1) == false);139    assert(static_cast<bool>(opt2) == false);140    opt1.swap(opt2);141    assert(static_cast<bool>(opt1) == false);142    assert(static_cast<bool>(opt2) == false);143  }144 145  {146    T one{1};147    optional<T&> opt1(one);148    optional<T&> opt2;149    static_assert(noexcept(opt1.swap(opt2)) == true);150    assert(static_cast<bool>(opt1) == true);151    assert(std::addressof(*opt1) == std::addressof(one));152    assert(static_cast<bool>(opt2) == false);153    opt1.swap(opt2);154    assert(static_cast<bool>(opt1) == false);155    assert(static_cast<bool>(opt2) == true);156    assert(std::addressof(*opt2) == std::addressof(one));157  }158 159  {160    T two{2};161    optional<T&> opt1;162    optional<T&> opt2(two);163    static_assert(noexcept(opt1.swap(opt2)) == true);164    assert(static_cast<bool>(opt1) == false);165    assert(static_cast<bool>(opt2) == true);166    assert(std::addressof(*opt2) == std::addressof(two));167    opt1.swap(opt2);168    assert(static_cast<bool>(opt1) == true);169    assert(std::addressof(*opt1) == std::addressof(two));170    assert(static_cast<bool>(opt2) == false);171  }172 173  {174    T one{1};175    T two{2};176 177    optional<T&> opt1(one);178    optional<T&> opt2(two);179    static_assert(noexcept(opt1.swap(opt2)) == true);180    assert(static_cast<bool>(opt1) == true);181    assert(*opt1 == 1);182    assert(std::addressof(*opt1) == std::addressof(one));183    assert(static_cast<bool>(opt2) == true);184    assert(*opt2 == 2);185    assert(std::addressof(*opt2) == std::addressof(two));186    opt1.swap(opt2);187    assert(static_cast<bool>(opt1) == true);188    assert(*opt1 == 2);189    assert(std::addressof(*opt1) == std::addressof(two));190    assert(static_cast<bool>(opt2) == true);191    assert(*opt2 == 1);192    assert(std::addressof(*opt2) == std::addressof(one));193  }194 195  return true;196}197#endif198 199int main(int, char**)200{201    check_swap<int>();202    check_swap<W>();203#if TEST_STD_VER > 17204    static_assert(check_swap<int>());205    static_assert(check_swap<W>());206#endif207#if TEST_STD_VER >= 26208    static_assert(check_swap_ref<int>());209    static_assert(check_swap_ref<W>());210    check_swap_ref<int>();211    check_swap_ref<W>();212#endif213    {214        optional<X> opt1;215        optional<X> opt2;216        static_assert(noexcept(opt1.swap(opt2)) == true, "");217        assert(static_cast<bool>(opt1) == false);218        assert(static_cast<bool>(opt2) == false);219        opt1.swap(opt2);220        assert(static_cast<bool>(opt1) == false);221        assert(static_cast<bool>(opt2) == false);222        assert(X::dtor_called == 0);223    }224    {225        optional<X> opt1(1);226        optional<X> opt2;227        static_assert(noexcept(opt1.swap(opt2)) == true, "");228        assert(static_cast<bool>(opt1) == true);229        assert(*opt1 == 1);230        assert(static_cast<bool>(opt2) == false);231        X::dtor_called = 0;232        opt1.swap(opt2);233        assert(X::dtor_called == 1);234        assert(static_cast<bool>(opt1) == false);235        assert(static_cast<bool>(opt2) == true);236        assert(*opt2 == 1);237    }238    {239        optional<X> opt1;240        optional<X> opt2(2);241        static_assert(noexcept(opt1.swap(opt2)) == true, "");242        assert(static_cast<bool>(opt1) == false);243        assert(static_cast<bool>(opt2) == true);244        assert(*opt2 == 2);245        X::dtor_called = 0;246        opt1.swap(opt2);247        assert(X::dtor_called == 1);248        assert(static_cast<bool>(opt1) == true);249        assert(*opt1 == 2);250        assert(static_cast<bool>(opt2) == false);251    }252    {253        optional<X> opt1(1);254        optional<X> opt2(2);255        static_assert(noexcept(opt1.swap(opt2)) == true, "");256        assert(static_cast<bool>(opt1) == true);257        assert(*opt1 == 1);258        assert(static_cast<bool>(opt2) == true);259        assert(*opt2 == 2);260        X::dtor_called = 0;261        opt1.swap(opt2);262        assert(X::dtor_called == 1);  // from inside std::swap263        assert(static_cast<bool>(opt1) == true);264        assert(*opt1 == 2);265        assert(static_cast<bool>(opt2) == true);266        assert(*opt2 == 1);267    }268    {269        optional<Y> opt1;270        optional<Y> opt2;271        static_assert(noexcept(opt1.swap(opt2)) == false, "");272        assert(static_cast<bool>(opt1) == false);273        assert(static_cast<bool>(opt2) == false);274        opt1.swap(opt2);275        assert(static_cast<bool>(opt1) == false);276        assert(static_cast<bool>(opt2) == false);277        assert(Y::dtor_called == 0);278    }279    {280        optional<Y> opt1(1);281        optional<Y> opt2;282        static_assert(noexcept(opt1.swap(opt2)) == false, "");283        assert(static_cast<bool>(opt1) == true);284        assert(*opt1 == 1);285        assert(static_cast<bool>(opt2) == false);286        Y::dtor_called = 0;287        opt1.swap(opt2);288        assert(Y::dtor_called == 1);289        assert(static_cast<bool>(opt1) == false);290        assert(static_cast<bool>(opt2) == true);291        assert(*opt2 == 1);292    }293    {294        optional<Y> opt1;295        optional<Y> opt2(2);296        static_assert(noexcept(opt1.swap(opt2)) == false, "");297        assert(static_cast<bool>(opt1) == false);298        assert(static_cast<bool>(opt2) == true);299        assert(*opt2 == 2);300        Y::dtor_called = 0;301        opt1.swap(opt2);302        assert(Y::dtor_called == 1);303        assert(static_cast<bool>(opt1) == true);304        assert(*opt1 == 2);305        assert(static_cast<bool>(opt2) == false);306    }307    {308        optional<Y> opt1(1);309        optional<Y> opt2(2);310        static_assert(noexcept(opt1.swap(opt2)) == false, "");311        assert(static_cast<bool>(opt1) == true);312        assert(*opt1 == 1);313        assert(static_cast<bool>(opt2) == true);314        assert(*opt2 == 2);315        Y::dtor_called = 0;316        opt1.swap(opt2);317        assert(Y::dtor_called == 0);318        assert(static_cast<bool>(opt1) == true);319        assert(*opt1 == 2);320        assert(static_cast<bool>(opt2) == true);321        assert(*opt2 == 1);322    }323    {324        optional<Z> opt1;325        optional<Z> opt2;326        static_assert(noexcept(opt1.swap(opt2)) == false, "");327        assert(static_cast<bool>(opt1) == false);328        assert(static_cast<bool>(opt2) == false);329        opt1.swap(opt2);330        assert(static_cast<bool>(opt1) == false);331        assert(static_cast<bool>(opt2) == false);332    }333#ifndef TEST_HAS_NO_EXCEPTIONS334    {335        optional<Z> opt1;336        opt1.emplace(1);337        optional<Z> opt2;338        static_assert(noexcept(opt1.swap(opt2)) == false, "");339        assert(static_cast<bool>(opt1) == true);340        assert(*opt1 == 1);341        assert(static_cast<bool>(opt2) == false);342        try343        {344            opt1.swap(opt2);345            assert(false);346        }347        catch (int i)348        {349            assert(i == 7);350        }351        assert(static_cast<bool>(opt1) == true);352        assert(*opt1 == 1);353        assert(static_cast<bool>(opt2) == false);354    }355    {356        optional<Z> opt1;357        optional<Z> opt2;358        opt2.emplace(2);359        static_assert(noexcept(opt1.swap(opt2)) == false, "");360        assert(static_cast<bool>(opt1) == false);361        assert(static_cast<bool>(opt2) == true);362        assert(*opt2 == 2);363        try364        {365            opt1.swap(opt2);366            assert(false);367        }368        catch (int i)369        {370            assert(i == 7);371        }372        assert(static_cast<bool>(opt1) == false);373        assert(static_cast<bool>(opt2) == true);374        assert(*opt2 == 2);375    }376    {377        optional<Z> opt1;378        opt1.emplace(1);379        optional<Z> opt2;380        opt2.emplace(2);381        static_assert(noexcept(opt1.swap(opt2)) == false, "");382        assert(static_cast<bool>(opt1) == true);383        assert(*opt1 == 1);384        assert(static_cast<bool>(opt2) == true);385        assert(*opt2 == 2);386        try387        {388            opt1.swap(opt2);389            assert(false);390        }391        catch (int i)392        {393            assert(i == 6);394        }395        assert(static_cast<bool>(opt1) == true);396        assert(*opt1 == 1);397        assert(static_cast<bool>(opt2) == true);398        assert(*opt2 == 2);399    }400#endif401 402  return 0;403}404