#pragma once #include #include #include "concept.h" #include "pool_alloc.h" namespace ipc { // pimpl small object optimization helpers template using IsImplComfortable = ipc::require<(sizeof(T) <= sizeof(T*)), R>; template using IsImplUncomfortable = ipc::require<(sizeof(T) > sizeof(T*)), R>; template constexpr auto make_impl(P&&... params) -> IsImplComfortable { T* buf {}; ::new (&buf) T { std::forward

(params)... }; return buf; } template constexpr auto impl(T* const (& p)) -> IsImplComfortable { return reinterpret_cast(&const_cast(reinterpret_cast(p))); } template constexpr auto clear_impl(T* p) -> IsImplComfortable { if (p != nullptr) impl(p)->~T(); } template constexpr auto make_impl(P&&... params) -> IsImplUncomfortable { return mem::alloc(std::forward

(params)...); } template constexpr auto clear_impl(T* p) -> IsImplUncomfortable { mem::free(p); } template constexpr auto impl(T* const (& p)) -> IsImplUncomfortable { return p; } template struct pimpl { template constexpr static T* make(P&&... params) { return make_impl(std::forward

(params)...); } #if __cplusplus >= 201703L constexpr void clear() { #else /*__cplusplus < 201703L*/ void clear() { #endif/*__cplusplus < 201703L*/ clear_impl(static_cast(const_cast(this))); } }; } // namespace ipc