11USERVER_NAMESPACE_BEGIN
45template <
class T, std::size_t Size, std::size_t Alignment,
bool Strict =
false>
46class FastPimpl final {
49 FastPimpl(FastPimpl&& v)
noexcept(
noexcept(T(std::declval<T>())))
50 : FastPimpl(std::move(*v)) {}
53 FastPimpl(
const FastPimpl& v)
noexcept(
noexcept(T(std::declval<
const T&>())))
57 FastPimpl& operator=(
const FastPimpl& rhs)
noexcept(
58 noexcept(std::declval<T&>() = std::declval<
const T&>())) {
63 FastPimpl& operator=(FastPimpl&& rhs)
noexcept(
65 noexcept(std::declval<T&>() = std::declval<T>())) {
66 *AsHeld() = std::move(*rhs);
70 template <
typename... Args>
72 explicit FastPimpl(Args&&... args)
noexcept(
73 noexcept(T(std::declval<Args>()...))) {
74 ::
new (AsHeld()) T(std::forward<Args>(args)...);
77 T* operator->()
noexcept {
return AsHeld(); }
79 const T* operator->()
const noexcept {
return AsHeld(); }
81 T& operator*()
noexcept {
return *AsHeld(); }
83 const T& operator*()
const noexcept {
return *AsHeld(); }
85 ~FastPimpl()
noexcept {
86 Validate<
sizeof(T),
alignof(T)>();
92 template <std::size_t ActualSize, std::size_t ActualAlignment>
93 static void Validate()
noexcept {
94 static_assert(Size >= ActualSize,
"invalid Size: Size >= sizeof(T) failed");
95 static_assert(!Strict || Size == ActualSize,
96 "invalid Size: Size == sizeof(T) failed");
98 static_assert(Alignment % ActualAlignment == 0,
99 "invalid Alignment: Alignment % alignof(T) == 0 failed");
100 static_assert(!Strict || Alignment == ActualAlignment,
101 "invalid Alignment: Alignment == alignof(T) failed");
104 alignas(Alignment) std::byte storage_[Size];
106 T* AsHeld()
noexcept {
return reinterpret_cast<T*>(&storage_); }
108 const T* AsHeld()
const noexcept {
109 return reinterpret_cast<
const T*>(&storage_);