mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-07 01:06:45 +08:00
Continue to update holders.
This commit is contained in:
parent
5fec1f80ff
commit
6b22006897
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/codecvt.h
|
* \file libimp/codecvt.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Character set conversion interface
|
* \brief Character set conversion interface.
|
||||||
* \date 2022-08-07
|
* \date 2022-08-07
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/countof.h
|
* \file libimp/countof.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Returns the size of the given range
|
* \brief Returns the size of the given range.
|
||||||
* \date 2022-03-01
|
* \date 2022-03-01
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/dataof.h
|
* \file libimp/dataof.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Returns the data pointer of the given range
|
* \brief Returns the data pointer of the given range.
|
||||||
* \date 2023-05-27
|
* \date 2023-05-27
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/export.h
|
* \file libimp/export.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Define the symbol export interfaces
|
* \brief Define the symbol export interfaces.
|
||||||
* \date 2022-02-27
|
* \date 2022-02-27
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/pimpl.h
|
* \file libimp/pimpl.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Pointer To Implementation (pImpl) idiom
|
* \brief Pointer To Implementation (pImpl) idiom.
|
||||||
* \date 2022-02-27
|
* \date 2022-02-27
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/result.h
|
* \file libimp/result.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Define the return value type with a status code
|
* \brief Define the return value type with a status code.
|
||||||
* \date 2022-04-17
|
* \date 2022-04-17
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
78
include/libimp/scope_exit.h
Normal file
78
include/libimp/scope_exit.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* \file libimp/scope_exit.h
|
||||||
|
* \author mutouyun (orz@orzz.org)
|
||||||
|
* \brief Execute guard function when the enclosing scope exits.
|
||||||
|
* \date 2022-03-01
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <utility> // std::forward, std::move
|
||||||
|
#include <functional> // std::function
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "libimp/def.h"
|
||||||
|
|
||||||
|
LIBIMP_NAMESPACE_BEG_
|
||||||
|
|
||||||
|
template <typename F = std::function<void()>>
|
||||||
|
class scope_exit {
|
||||||
|
F destructor_;
|
||||||
|
mutable bool released_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template <typename G>
|
||||||
|
explicit scope_exit(G &&destructor) noexcept
|
||||||
|
: destructor_(std::forward<G>(destructor))
|
||||||
|
, released_ (false) {}
|
||||||
|
|
||||||
|
scope_exit(scope_exit &&other) noexcept
|
||||||
|
: destructor_(std::move(other.destructor_))
|
||||||
|
, released_ (std::exchange(other.released_, true)) /*release rhs*/ {}
|
||||||
|
|
||||||
|
scope_exit &operator=(scope_exit &&other) noexcept {
|
||||||
|
destructor_ = std::move(other.destructor_);
|
||||||
|
released_ = std::exchange(other.released_, true);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~scope_exit() noexcept {
|
||||||
|
if (!released_) destructor_();
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() const noexcept {
|
||||||
|
released_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_exit() noexcept {
|
||||||
|
if (released_) return;
|
||||||
|
destructor_();
|
||||||
|
released_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(scope_exit &other) noexcept {
|
||||||
|
std::swap(destructor_, other.destructor_);
|
||||||
|
std::swap(released_ , other.released_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// \brief Creates a scope_exit object.
|
||||||
|
template <typename F>
|
||||||
|
auto make_scope_exit(F &&destructor) noexcept {
|
||||||
|
return scope_exit<std::decay_t<F>>(std::forward<F>(destructor));
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
struct scope_exit_helper {
|
||||||
|
template <typename F>
|
||||||
|
auto operator=(F &&f) const noexcept {
|
||||||
|
return make_scope_exit(std::forward<F>(f));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
#define LIBIMP_SCOPE_EXIT($val) \
|
||||||
|
auto $val = ::LIBIMP::detail::scope_exit_helper{}
|
||||||
|
|
||||||
|
LIBIMP_NAMESPACE_END_
|
||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/span.h
|
* \file libimp/span.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Describes an object that can refer to a contiguous sequence of objects
|
* \brief Describes an object that can refer to a contiguous sequence of objects.
|
||||||
* \date 2022-10-16
|
* \date 2022-10-16
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/system.h
|
* \file libimp/system.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Isolation and encapsulation of system APIs
|
* \brief Isolation and encapsulation of system APIs.
|
||||||
* \date 2022-08-07
|
* \date 2022-08-07
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* \file libimp/underlyof.h
|
* \file libimp/underlyof.h
|
||||||
* \author mutouyun (orz@orzz.org)
|
* \author mutouyun (orz@orzz.org)
|
||||||
* \brief Returns the underlying type of the given enum
|
* \brief Returns the underlying type of the given enum.
|
||||||
* \date 2022-03-01
|
* \date 2022-03-01
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|||||||
@ -223,6 +223,39 @@ void *holder_construct(allocator const &alloc, std::size_t n, Construct &&c) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class holder_info_ptr {
|
||||||
|
allocator const &alloc_;
|
||||||
|
holder_info **pptr_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
holder_info_ptr(allocator const &alloc, holder_info *(&ptr)) noexcept
|
||||||
|
: alloc_(alloc), pptr_(&ptr) {
|
||||||
|
*pptr_ = static_cast<holder_info *>(alloc_.allocate(sizeof(holder_info), alignof(holder_info)));
|
||||||
|
}
|
||||||
|
|
||||||
|
~holder_info_ptr() noexcept {
|
||||||
|
if (pptr_ == nullptr) return;
|
||||||
|
alloc_.deallocate(*pptr_, sizeof(holder_info), alignof(holder_info));
|
||||||
|
*pptr_ = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool() const noexcept {
|
||||||
|
return (pptr_ != nullptr) && (*pptr_ != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
holder_info *operator->() const noexcept {
|
||||||
|
return *pptr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
holder_info &operator*() noexcept {
|
||||||
|
return **pptr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void release() noexcept {
|
||||||
|
pptr_ = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -246,7 +279,7 @@ public:
|
|||||||
std::enable_if_t<alignof(Value) <= alignof(std::max_align_t), bool> = true>
|
std::enable_if_t<alignof(Value) <= alignof(std::max_align_t), bool> = true>
|
||||||
holder(allocator const &alloc, ::LIBIMP::types<Value>, std::size_t n) : holder() {
|
holder(allocator const &alloc, ::LIBIMP::types<Value>, std::size_t n) : holder() {
|
||||||
value_ptr_ = detail::holder_construct<Value>(alloc, n,
|
value_ptr_ = detail::holder_construct<Value>(alloc, n,
|
||||||
::LIBIMP::uninitialized_default_construct_n<Value *, std::size_t>);
|
::LIBIMP::uninitialized_default_construct_n<Value *, std::size_t>);
|
||||||
if (value_ptr_ == nullptr) return;
|
if (value_ptr_ == nullptr) return;
|
||||||
info_.type = &typeid(Value);
|
info_.type = &typeid(Value);
|
||||||
info_.sizeof_type = sizeof(Value);
|
info_.sizeof_type = sizeof(Value);
|
||||||
@ -271,6 +304,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::type_info const &type() const noexcept override {
|
std::type_info const &type() const noexcept override {
|
||||||
|
if (!valid()) return typeid(nullptr);
|
||||||
return *info_.type;
|
return *info_.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,4 +348,104 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class template <> holder<void, false>
|
||||||
|
* \brief A holder implementation of some data objects that stores type information on heap memory.
|
||||||
|
*/
|
||||||
|
template <>
|
||||||
|
class holder<void, false> : public holder_base {
|
||||||
|
|
||||||
|
detail::holder_info *info_ptr_;
|
||||||
|
void *value_ptr_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
holder() noexcept
|
||||||
|
: info_ptr_ (nullptr)
|
||||||
|
, value_ptr_(nullptr) {}
|
||||||
|
|
||||||
|
/// \brief Constructs a holder with type of `Value`.
|
||||||
|
/// alignof(Value) must be less than or equal to alignof(std::max_align_t).
|
||||||
|
template <typename Value,
|
||||||
|
std::enable_if_t<alignof(Value) <= alignof(std::max_align_t), bool> = true>
|
||||||
|
holder(allocator const &alloc, ::LIBIMP::types<Value>, std::size_t n) : holder() {
|
||||||
|
detail::holder_info_ptr info_p{alloc, info_ptr_};
|
||||||
|
if (!info_p) return;
|
||||||
|
value_ptr_ = detail::holder_construct<Value>(alloc, n,
|
||||||
|
::LIBIMP::uninitialized_default_construct_n<Value *, std::size_t>);
|
||||||
|
if (value_ptr_ == nullptr) return;
|
||||||
|
info_p->type = &typeid(Value);
|
||||||
|
info_p->sizeof_type = sizeof(Value);
|
||||||
|
info_p->count = n;
|
||||||
|
info_p->copy = [](allocator const &alloc, void const *s, void *d) {
|
||||||
|
auto const &src = *static_cast<holder const *>(s);
|
||||||
|
auto & dst = *::LIBIMP::construct<holder>(d);
|
||||||
|
if (!src.valid()) return;
|
||||||
|
detail::holder_info_ptr info_p{alloc, dst.info_ptr_};
|
||||||
|
if (!info_p) return;
|
||||||
|
dst.value_ptr_ = detail::holder_construct<Value>(alloc, src.count(), [s = src.get()](Value *d, std::size_t n) {
|
||||||
|
std::uninitialized_copy_n(static_cast<Value const *>(s), n, d);
|
||||||
|
});
|
||||||
|
if (dst.value_ptr_ == nullptr) return;
|
||||||
|
*info_p = *src.info_ptr_;
|
||||||
|
info_p.release();
|
||||||
|
};
|
||||||
|
info_p->dest = [](void *p, std::size_t n) noexcept {
|
||||||
|
::LIBIMP::destroy_n(static_cast<Value *>(p), n);
|
||||||
|
};
|
||||||
|
info_p.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid() const noexcept override {
|
||||||
|
return (value_ptr_ != nullptr) && (info_ptr_ != nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::type_info const &type() const noexcept override {
|
||||||
|
if (!valid()) return typeid(nullptr);
|
||||||
|
return *info_ptr_->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t sizeof_type() const noexcept override {
|
||||||
|
if (!valid()) return 0;
|
||||||
|
return info_ptr_->sizeof_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t sizeof_heap() const noexcept override {
|
||||||
|
if (!valid()) return 0;
|
||||||
|
return info_ptr_->sizeof_type * info_ptr_->count + sizeof(detail::holder_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t count() const noexcept override {
|
||||||
|
if (!valid()) return 0;
|
||||||
|
return info_ptr_->count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *get() noexcept override {
|
||||||
|
return value_ptr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void const *get() const noexcept override {
|
||||||
|
return value_ptr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void move_to(allocator const &, void *p) noexcept override {
|
||||||
|
auto *des = ::LIBIMP::construct<holder>(p);
|
||||||
|
if (!valid()) return;
|
||||||
|
std::swap(value_ptr_, des->value_ptr_);
|
||||||
|
std::swap(info_ptr_ , des->info_ptr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_to(allocator const &alloc, void *p) const noexcept(false) override {
|
||||||
|
auto *des = ::LIBIMP::construct<holder>(p);
|
||||||
|
if (!valid()) return;
|
||||||
|
info_ptr_->copy(alloc, this, des);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(allocator const &alloc) noexcept override {
|
||||||
|
if (!valid()) return;
|
||||||
|
info_ptr_->dest (value_ptr_, count());
|
||||||
|
alloc.deallocate(value_ptr_, sizeof_heap());
|
||||||
|
alloc.deallocate(info_ptr_ , sizeof(detail::holder_info), alignof(detail::holder_info));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
LIBPMR_NAMESPACE_END_
|
LIBPMR_NAMESPACE_END_
|
||||||
|
|||||||
@ -11,6 +11,7 @@ TEST(small_storage, holder_construct) {
|
|||||||
pmr::holder<int, true>();
|
pmr::holder<int, true>();
|
||||||
pmr::holder<int, false>();
|
pmr::holder<int, false>();
|
||||||
pmr::holder<void, true>();
|
pmr::holder<void, true>();
|
||||||
|
pmr::holder<void, false>();
|
||||||
SUCCEED();
|
SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -19,21 +20,25 @@ TEST(small_storage, holder_copy_move_construct) {
|
|||||||
EXPECT_FALSE((std::is_copy_constructible<pmr::holder<int, true>>::value));
|
EXPECT_FALSE((std::is_copy_constructible<pmr::holder<int, true>>::value));
|
||||||
EXPECT_FALSE((std::is_copy_constructible<pmr::holder<int, false>>::value));
|
EXPECT_FALSE((std::is_copy_constructible<pmr::holder<int, false>>::value));
|
||||||
EXPECT_FALSE((std::is_copy_constructible<pmr::holder<void, true>>::value));
|
EXPECT_FALSE((std::is_copy_constructible<pmr::holder<void, true>>::value));
|
||||||
|
EXPECT_FALSE((std::is_copy_constructible<pmr::holder<void, false>>::value));
|
||||||
|
|
||||||
EXPECT_FALSE(std::is_copy_assignable<pmr::holder_null>::value);
|
EXPECT_FALSE(std::is_copy_assignable<pmr::holder_null>::value);
|
||||||
EXPECT_FALSE((std::is_copy_assignable<pmr::holder<int, true>>::value));
|
EXPECT_FALSE((std::is_copy_assignable<pmr::holder<int, true>>::value));
|
||||||
EXPECT_FALSE((std::is_copy_assignable<pmr::holder<int, false>>::value));
|
EXPECT_FALSE((std::is_copy_assignable<pmr::holder<int, false>>::value));
|
||||||
EXPECT_FALSE((std::is_copy_assignable<pmr::holder<void, true>>::value));
|
EXPECT_FALSE((std::is_copy_assignable<pmr::holder<void, true>>::value));
|
||||||
|
EXPECT_FALSE((std::is_copy_assignable<pmr::holder<void, false>>::value));
|
||||||
|
|
||||||
EXPECT_FALSE(std::is_move_constructible<pmr::holder_null>::value);
|
EXPECT_FALSE(std::is_move_constructible<pmr::holder_null>::value);
|
||||||
EXPECT_FALSE((std::is_move_constructible<pmr::holder<int, true>>::value));
|
EXPECT_FALSE((std::is_move_constructible<pmr::holder<int, true>>::value));
|
||||||
EXPECT_FALSE((std::is_move_constructible<pmr::holder<int, false>>::value));
|
EXPECT_FALSE((std::is_move_constructible<pmr::holder<int, false>>::value));
|
||||||
EXPECT_FALSE((std::is_move_constructible<pmr::holder<void, true>>::value));
|
EXPECT_FALSE((std::is_move_constructible<pmr::holder<void, true>>::value));
|
||||||
|
EXPECT_FALSE((std::is_move_constructible<pmr::holder<void, false>>::value));
|
||||||
|
|
||||||
EXPECT_FALSE(std::is_move_assignable<pmr::holder_null>::value);
|
EXPECT_FALSE(std::is_move_assignable<pmr::holder_null>::value);
|
||||||
EXPECT_FALSE((std::is_move_assignable<pmr::holder<int, true>>::value));
|
EXPECT_FALSE((std::is_move_assignable<pmr::holder<int, true>>::value));
|
||||||
EXPECT_FALSE((std::is_move_assignable<pmr::holder<int, false>>::value));
|
EXPECT_FALSE((std::is_move_assignable<pmr::holder<int, false>>::value));
|
||||||
EXPECT_FALSE((std::is_move_assignable<pmr::holder<void, true>>::value));
|
EXPECT_FALSE((std::is_move_assignable<pmr::holder<void, true>>::value));
|
||||||
|
EXPECT_FALSE((std::is_move_assignable<pmr::holder<void, false>>::value));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(small_storage, holder_copy_move) {
|
TEST(small_storage, holder_copy_move) {
|
||||||
@ -46,7 +51,7 @@ TEST(small_storage, holder_copy_move) {
|
|||||||
|
|
||||||
pmr::allocator alc;
|
pmr::allocator alc;
|
||||||
pmr::holder<foo, true> h1(alc, 1);
|
pmr::holder<foo, true> h1(alc, 1);
|
||||||
pmr::holder<foo, true> h2, h3; // uninitialized
|
pmr::holder<foo, true> h2, h3;
|
||||||
h1.copy_to(alc, &h2);
|
h1.copy_to(alc, &h2);
|
||||||
EXPECT_EQ(static_cast<foo *>(h1.get())->i, 1);
|
EXPECT_EQ(static_cast<foo *>(h1.get())->i, 1);
|
||||||
EXPECT_EQ(static_cast<foo *>(h2.get())->i, 1);
|
EXPECT_EQ(static_cast<foo *>(h2.get())->i, 1);
|
||||||
@ -58,7 +63,7 @@ TEST(small_storage, holder_copy_move) {
|
|||||||
h3.destroy(alc);
|
h3.destroy(alc);
|
||||||
|
|
||||||
pmr::holder<foo, false> h4(alc, 1);
|
pmr::holder<foo, false> h4(alc, 1);
|
||||||
pmr::holder<foo, false> h5, h6; // uninitialized
|
pmr::holder<foo, false> h5, h6;
|
||||||
h4.copy_to(alc, &h5);
|
h4.copy_to(alc, &h5);
|
||||||
EXPECT_EQ(static_cast<foo *>(h4.get())->i, 1);
|
EXPECT_EQ(static_cast<foo *>(h4.get())->i, 1);
|
||||||
EXPECT_EQ(static_cast<foo *>(h5.get())->i, 1);
|
EXPECT_EQ(static_cast<foo *>(h5.get())->i, 1);
|
||||||
@ -70,7 +75,7 @@ TEST(small_storage, holder_copy_move) {
|
|||||||
h6.destroy(alc);
|
h6.destroy(alc);
|
||||||
|
|
||||||
pmr::holder<void, true> h7(alc, ::LIBIMP::types<int>{}, 10);
|
pmr::holder<void, true> h7(alc, ::LIBIMP::types<int>{}, 10);
|
||||||
pmr::holder<void, true> h8, h9; // uninitialized
|
pmr::holder<void, true> h8, h9;
|
||||||
h7.copy_to(alc, &h8);
|
h7.copy_to(alc, &h8);
|
||||||
EXPECT_EQ(h7.count(), 10);
|
EXPECT_EQ(h7.count(), 10);
|
||||||
EXPECT_EQ(h8.count(), 10);
|
EXPECT_EQ(h8.count(), 10);
|
||||||
@ -80,6 +85,18 @@ TEST(small_storage, holder_copy_move) {
|
|||||||
h7.destroy(alc);
|
h7.destroy(alc);
|
||||||
h8.destroy(alc);
|
h8.destroy(alc);
|
||||||
h9.destroy(alc);
|
h9.destroy(alc);
|
||||||
|
|
||||||
|
pmr::holder<void, false> h10(alc, ::LIBIMP::types<int>{}, 10);
|
||||||
|
pmr::holder<void, false> h11, h12;
|
||||||
|
h10.copy_to(alc, &h11);
|
||||||
|
EXPECT_EQ(h10.count(), 10);
|
||||||
|
EXPECT_EQ(h11.count(), 10);
|
||||||
|
h10.move_to(alc, &h12);
|
||||||
|
EXPECT_EQ(h10.count(), 0);
|
||||||
|
EXPECT_EQ(h12.count(), 10);
|
||||||
|
h10.destroy(alc);
|
||||||
|
h11.destroy(alc);
|
||||||
|
h12.destroy(alc);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(small_storage, construct) {
|
TEST(small_storage, construct) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user