From c8010e3a51474b9258bb6424ac4aafa81243be58 Mon Sep 17 00:00:00 2001 From: mutouyun Date: Sun, 3 Sep 2023 11:43:06 +0800 Subject: [PATCH] Place holder-base into small-storage. --- include/libpmr/allocator.h | 8 ++- include/libpmr/holder_base.h | 122 --------------------------------- include/libpmr/small_storage.h | 110 ++++++++++++++++++++++++++++- 3 files changed, 114 insertions(+), 126 deletions(-) delete mode 100644 include/libpmr/holder_base.h diff --git a/include/libpmr/allocator.h b/include/libpmr/allocator.h index d24bab2..9acaeae 100644 --- a/include/libpmr/allocator.h +++ b/include/libpmr/allocator.h @@ -62,16 +62,18 @@ class LIBIMP_EXPORT allocator { */ template class holder_mr> : public holder_mr { + using base_t = holder_mr; + public: holder_mr(MR *p_mr) noexcept - : holder_mr{p_mr} {} + : base_t{p_mr} {} void *alloc(std::size_t s, std::size_t a) const override { - return res_->allocate(s, a); + return base_t::res_->allocate(s, a); } void dealloc(void *p, std::size_t s, std::size_t a) const override { - res_->deallocate(p, s, a); + base_t::res_->deallocate(p, s, a); } }; diff --git a/include/libpmr/holder_base.h b/include/libpmr/holder_base.h deleted file mode 100644 index fc52c6d..0000000 --- a/include/libpmr/holder_base.h +++ /dev/null @@ -1,122 +0,0 @@ -/** - * \file libpmr/small_storage.h - * \author mutouyun (orz@orzz.org) - * \brief Unified SSO (Small Size Optimization) holder base. - * \date 2023-09-02 - */ -#pragma once - -#include -#include -#include -#include -#include - -#include "libimp/export.h" -#include "libimp/construct.h" -#include "libimp/byte.h" -#include "libimp/generic.h" - -#include "libpmr/def.h" - -LIBPMR_NAMESPACE_BEG_ - -class LIBIMP_EXPORT allocator; - -/** - * \class holder_base - * \brief Data holder base class. -*/ -class holder_base { -public: - virtual ~holder_base() noexcept = default; - virtual bool valid() const noexcept = 0; - virtual std::type_info const &type() const noexcept = 0; - virtual std::size_t sizeof_type() const noexcept = 0; - virtual std::size_t count() const noexcept = 0; - virtual std::size_t size () const noexcept = 0; - virtual void *get() noexcept = 0; - virtual void const *get() const noexcept = 0; - virtual void move_to(allocator const &, void *) noexcept = 0; - virtual void copy_to(allocator const &, void *) const noexcept(false) = 0; -}; - -/** - * \class holder_null - * \brief A holder implementation that does not hold any data objects. -*/ -class holder_null : public holder_base { -public: - bool valid() const noexcept override { return false; } - std::type_info const &type() const noexcept override { return typeid(nullptr);} - std::size_t sizeof_type() const noexcept override { return 0; } - std::size_t count() const noexcept override { return 0; } - std::size_t size () const noexcept override { return 0; } - void *get() noexcept override { return nullptr; } - void const *get() const noexcept override { return nullptr; } - - /// \brief The passed destination pointer is never null, - /// and the memory to which it points is uninitialized. - void move_to(allocator const &, void *) noexcept override {} - void copy_to(allocator const &, void *) const noexcept(false) override {} -}; - -template -class holder; - -/** - * \class template holder - * \brief A holder implementation that holds a data object if type `Value` on stack memory. - * \tparam Value The storage type of the holder. - */ -template -class holder : public holder_base { - - alignas(alignof(Value)) std::array<::LIBIMP::byte, sizeof(Value)> value_storage_; - -public: - holder() = default; // uninitialized - - template - holder(::LIBIMP::in_place_t, A &&...args) { - ::LIBIMP::construct(value_storage_.data(), std::forward(args)...); - } - - bool valid() const noexcept override { - return true; - } - - std::type_info const &type() const noexcept override { - return typeid(Value); - } - - std::size_t sizeof_type() const noexcept override { - return sizeof(Value); - } - - std::size_t count() const noexcept override { - return 1; - } - - std::size_t size() const noexcept override { - return value_storage_.size(); - } - - void *get() noexcept override { - return value_storage_.data(); - } - - void const *get() const noexcept override { - return value_storage_.data(); - } - - void move_to(allocator const &, void *p) noexcept override { - ::LIBIMP::construct(p, ::LIBIMP::in_place, std::move(*static_cast(get()))); - } - - void copy_to(allocator const &, void *p) const noexcept(false) override { - ::LIBIMP::construct(p, ::LIBIMP::in_place, *static_cast(get())); - } -}; - -LIBPMR_NAMESPACE_END_ diff --git a/include/libpmr/small_storage.h b/include/libpmr/small_storage.h index 918dc93..eb830ec 100644 --- a/include/libpmr/small_storage.h +++ b/include/libpmr/small_storage.h @@ -19,10 +19,113 @@ #include "libimp/generic.h" #include "libpmr/def.h" -#include "libpmr/holder_base.h" LIBPMR_NAMESPACE_BEG_ +class LIBIMP_EXPORT allocator; + +/** + * \class holder_base + * \brief Data holder base class. +*/ +class holder_base { +public: + virtual ~holder_base() noexcept = default; + virtual bool valid() const noexcept = 0; + virtual std::type_info const &type() const noexcept = 0; + virtual std::size_t sizeof_type() const noexcept = 0; + virtual std::size_t count() const noexcept = 0; + virtual std::size_t size () const noexcept = 0; + virtual void *get() noexcept = 0; + virtual void const *get() const noexcept = 0; + + /// \brief The passed destination pointer is never null, + /// and the memory to which it points is uninitialized. + virtual void move_to(allocator const &, void *) noexcept = 0; + virtual void copy_to(allocator const &, void *) const noexcept(false) = 0; + virtual void destroy(allocator const &) noexcept = 0; +}; + +/** + * \class holder_null + * \brief A holder implementation that does not hold any data objects. +*/ +class holder_null : public holder_base { +public: + bool valid() const noexcept override { return false; } + std::type_info const &type() const noexcept override { return typeid(nullptr);} + std::size_t sizeof_type() const noexcept override { return 0; } + std::size_t count() const noexcept override { return 0; } + std::size_t size () const noexcept override { return 0; } + void *get() noexcept override { return nullptr; } + void const *get() const noexcept override { return nullptr; } + void move_to(allocator const &, void *) noexcept override {} + void copy_to(allocator const &, void *) const noexcept(false) override {} + void destroy(allocator const &) noexcept override {} +}; + +template +class holder; + +/** + * \class template holder + * \brief A holder implementation that holds a data object if type `Value` on stack memory. + * \tparam Value The storage type of the holder. + */ +template +class holder : public holder_base { + + alignas(alignof(Value)) std::array<::LIBIMP::byte, sizeof(Value)> value_storage_; + +public: + holder() = default; // uninitialized + + template + holder(::LIBIMP::in_place_t, A &&...args) { + ::LIBIMP::construct(value_storage_.data(), std::forward(args)...); + } + + bool valid() const noexcept override { + return true; + } + + std::type_info const &type() const noexcept override { + return typeid(Value); + } + + std::size_t sizeof_type() const noexcept override { + return sizeof(Value); + } + + std::size_t count() const noexcept override { + return 1; + } + + std::size_t size() const noexcept override { + return value_storage_.size(); + } + + void *get() noexcept override { + return value_storage_.data(); + } + + void const *get() const noexcept override { + return value_storage_.data(); + } + + void move_to(allocator const &, void *p) noexcept override { + ::LIBIMP::construct(p, ::LIBIMP::in_place, std::move(*static_cast(get()))); + } + + void copy_to(allocator const &, void *p) const noexcept(false) override { + ::LIBIMP::construct(p, ::LIBIMP::in_place, *static_cast(get())); + } + + void destroy(allocator const &) noexcept override { + ::LIBIMP::destroy(value_storage_.data()); + } +}; + /** * \class template holder * \brief A holder implementation that holds a data object if type `Value` on heap memory. @@ -30,6 +133,11 @@ LIBPMR_NAMESPACE_BEG_ */ template class holder : public holder_base { + + Value *value_ptr_ = nullptr; + +public: + holder() = default; // uninitialized }; LIBPMR_NAMESPACE_END_