mirror of
https://github.com/mutouyun/cpp-ipc.git
synced 2025-12-06 16:56:45 +08:00
Place holder-base into small-storage.
This commit is contained in:
parent
cd545653c4
commit
c8010e3a51
@ -62,16 +62,18 @@ class LIBIMP_EXPORT allocator {
|
|||||||
*/
|
*/
|
||||||
template <typename MR>
|
template <typename MR>
|
||||||
class holder_mr<MR, verify_memory_resource<MR>> : public holder_mr<MR, void> {
|
class holder_mr<MR, verify_memory_resource<MR>> : public holder_mr<MR, void> {
|
||||||
|
using base_t = holder_mr<MR, void>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
holder_mr(MR *p_mr) noexcept
|
holder_mr(MR *p_mr) noexcept
|
||||||
: holder_mr<MR, void>{p_mr} {}
|
: base_t{p_mr} {}
|
||||||
|
|
||||||
void *alloc(std::size_t s, std::size_t a) const override {
|
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 {
|
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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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 <type_traits>
|
|
||||||
#include <array>
|
|
||||||
#include <typeinfo>
|
|
||||||
#include <utility>
|
|
||||||
#include <cstddef>
|
|
||||||
|
|
||||||
#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 <typename Value, bool/*is on stack*/>
|
|
||||||
class holder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \class template <typename Value> holder<Value, true>
|
|
||||||
* \brief A holder implementation that holds a data object if type `Value` on stack memory.
|
|
||||||
* \tparam Value The storage type of the holder.
|
|
||||||
*/
|
|
||||||
template <typename Value>
|
|
||||||
class holder<Value, true> : public holder_base {
|
|
||||||
|
|
||||||
alignas(alignof(Value)) std::array<::LIBIMP::byte, sizeof(Value)> value_storage_;
|
|
||||||
|
|
||||||
public:
|
|
||||||
holder() = default; // uninitialized
|
|
||||||
|
|
||||||
template <typename... A>
|
|
||||||
holder(::LIBIMP::in_place_t, A &&...args) {
|
|
||||||
::LIBIMP::construct<Value>(value_storage_.data(), std::forward<A>(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<holder>(p, ::LIBIMP::in_place, std::move(*static_cast<Value *>(get())));
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_to(allocator const &, void *p) const noexcept(false) override {
|
|
||||||
::LIBIMP::construct<holder>(p, ::LIBIMP::in_place, *static_cast<Value *>(get()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
LIBPMR_NAMESPACE_END_
|
|
||||||
@ -19,10 +19,113 @@
|
|||||||
#include "libimp/generic.h"
|
#include "libimp/generic.h"
|
||||||
|
|
||||||
#include "libpmr/def.h"
|
#include "libpmr/def.h"
|
||||||
#include "libpmr/holder_base.h"
|
|
||||||
|
|
||||||
LIBPMR_NAMESPACE_BEG_
|
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 <typename Value, bool/*is on stack*/>
|
||||||
|
class holder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \class template <typename Value> holder<Value, true>
|
||||||
|
* \brief A holder implementation that holds a data object if type `Value` on stack memory.
|
||||||
|
* \tparam Value The storage type of the holder.
|
||||||
|
*/
|
||||||
|
template <typename Value>
|
||||||
|
class holder<Value, true> : public holder_base {
|
||||||
|
|
||||||
|
alignas(alignof(Value)) std::array<::LIBIMP::byte, sizeof(Value)> value_storage_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
holder() = default; // uninitialized
|
||||||
|
|
||||||
|
template <typename... A>
|
||||||
|
holder(::LIBIMP::in_place_t, A &&...args) {
|
||||||
|
::LIBIMP::construct<Value>(value_storage_.data(), std::forward<A>(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<holder>(p, ::LIBIMP::in_place, std::move(*static_cast<Value *>(get())));
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy_to(allocator const &, void *p) const noexcept(false) override {
|
||||||
|
::LIBIMP::construct<holder>(p, ::LIBIMP::in_place, *static_cast<Value *>(get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy(allocator const &) noexcept override {
|
||||||
|
::LIBIMP::destroy<Value>(value_storage_.data());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \class template <typename Value> holder<Value, false>
|
* \class template <typename Value> holder<Value, false>
|
||||||
* \brief A holder implementation that holds a data object if type `Value` on heap memory.
|
* \brief A holder implementation that holds a data object if type `Value` on heap memory.
|
||||||
@ -30,6 +133,11 @@ LIBPMR_NAMESPACE_BEG_
|
|||||||
*/
|
*/
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
class holder<Value, false> : public holder_base {
|
class holder<Value, false> : public holder_base {
|
||||||
|
|
||||||
|
Value *value_ptr_ = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
holder() = default; // uninitialized
|
||||||
};
|
};
|
||||||
|
|
||||||
LIBPMR_NAMESPACE_END_
|
LIBPMR_NAMESPACE_END_
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user