brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · c47883a Raw
131 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// <memory>10 11// unique_ptr12 13// Test swap14 15#include <memory>16#include <cassert>17 18#include "test_macros.h"19#include "deleter_types.h"20 21struct A22{23    int state_;24    static int count;25    TEST_CONSTEXPR_CXX23 A() : state_(0) {26      if (!TEST_IS_CONSTANT_EVALUATED)27        ++count;28    }29    TEST_CONSTEXPR_CXX23 explicit A(int i) : state_(i) {30      if (!TEST_IS_CONSTANT_EVALUATED)31        ++count;32    }33    TEST_CONSTEXPR_CXX23 A(const A& a) : state_(a.state_) {34      if (!TEST_IS_CONSTANT_EVALUATED)35        ++count;36    }37    TEST_CONSTEXPR_CXX23 A& operator=(const A& a) {38      state_ = a.state_;39      return *this;40    }41    TEST_CONSTEXPR_CXX23 ~A() {42      if (!TEST_IS_CONSTANT_EVALUATED)43        --count;44    }45 46    friend TEST_CONSTEXPR_CXX23 bool operator==(const A& x, const A& y) { return x.state_ == y.state_; }47};48 49int A::count = 0;50 51template <class T>52struct NonSwappableDeleter {53  TEST_CONSTEXPR_CXX23 explicit NonSwappableDeleter(int) {}54  TEST_CONSTEXPR_CXX23 NonSwappableDeleter& operator=(NonSwappableDeleter const&) { return *this; }55  TEST_CONSTEXPR_CXX23 void operator()(T*) const {}56 57private:58  NonSwappableDeleter(NonSwappableDeleter const&);59 60};61 62TEST_CONSTEXPR_CXX23 bool test() {63  {64    A* p1 = new A(1);65    std::unique_ptr<A, Deleter<A> > s1(p1, Deleter<A>(1));66    A* p2 = new A(2);67    std::unique_ptr<A, Deleter<A> > s2(p2, Deleter<A>(2));68    assert(s1.get() == p1);69    assert(*s1 == A(1));70    assert(s1.get_deleter().state() == 1);71    assert(s2.get() == p2);72    assert(*s2 == A(2));73    assert(s2.get_deleter().state() == 2);74    swap(s1, s2);75    assert(s1.get() == p2);76    assert(*s1 == A(2));77    assert(s1.get_deleter().state() == 2);78    assert(s2.get() == p1);79    assert(*s2 == A(1));80    assert(s2.get_deleter().state() == 1);81    if (!TEST_IS_CONSTANT_EVALUATED)82      assert(A::count == 2);83  }84  if (!TEST_IS_CONSTANT_EVALUATED)85    assert(A::count == 0);86  {87    A* p1 = new A[3];88    std::unique_ptr<A[], Deleter<A[]> > s1(p1, Deleter<A[]>(1));89    A* p2 = new A[3];90    std::unique_ptr<A[], Deleter<A[]> > s2(p2, Deleter<A[]>(2));91    assert(s1.get() == p1);92    assert(s1.get_deleter().state() == 1);93    assert(s2.get() == p2);94    assert(s2.get_deleter().state() == 2);95    swap(s1, s2);96    assert(s1.get() == p2);97    assert(s1.get_deleter().state() == 2);98    assert(s2.get() == p1);99    assert(s2.get_deleter().state() == 1);100    if (!TEST_IS_CONSTANT_EVALUATED)101      assert(A::count == 6);102  }103  if (!TEST_IS_CONSTANT_EVALUATED)104    assert(A::count == 0);105#if TEST_STD_VER >= 11106    {107        // test that unique_ptr's specialized swap is disabled when the deleter108        // is non-swappable. Instead we should pick up the generic swap(T, T)109        // and perform 3 move constructions.110        typedef NonSwappableDeleter<int> D;111        D  d(42);112        int x = 42;113        int y = 43;114        std::unique_ptr<int, D&> p(&x, d);115        std::unique_ptr<int, D&> p2(&y, d);116        std::swap(p, p2);117    }118#endif119 120    return true;121}122 123int main(int, char**) {124  test();125#if TEST_STD_VER >= 23126  static_assert(test());127#endif128 129  return 0;130}131