-
-
Save XRay3D/196a5054e3a2fcbee3f052724bc74453 to your computer and use it in GitHub Desktop.
FastPimpl after Yandex.Taxi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <type_traits> | |
#include <utility> | |
namespace Fast | |
{ | |
template <typename Type, size_t Size, size_t Alignment> | |
class FastPimpl | |
{ | |
public: | |
template <typename... Args> | |
explicit FastPimpl(Args &&... args) | |
{ | |
new (Ptr()) Type(std::forward<Args>(args)...); | |
} | |
~FastPimpl() noexcept | |
{ | |
static_assert(sizeof(Type) > 0, "Type is incomplete"); | |
validate<sizeof(Type), alignof(Type)>(); | |
Ptr()->~Type(); | |
} | |
FastPimpl &operator=(FastPimpl &&other) noexcept | |
{ | |
*Ptr() = std::move(*other); | |
return *this; | |
} | |
Type *operator->() noexcept | |
{ | |
return Ptr(); | |
} | |
Type const *operator->() const noexcept | |
{ | |
return Ptr(); | |
} | |
Type &operator*() noexcept | |
{ | |
return *Ptr(); | |
} | |
Type const &operator*() const noexcept | |
{ | |
return *Ptr(); | |
} | |
private: | |
Type *Ptr() | |
{ | |
return reinterpret_cast<Type *>(&data); | |
} | |
Type const *Ptr() const | |
{ | |
return reinterpret_cast<Type const *>(&data); | |
} | |
template <size_t ActualSize, size_t ActualAlignment> | |
static void validate() noexcept | |
{ | |
static_assert(ActualSize == Size, "Size and sizeof(Type) mismatch"); | |
static_assert(ActualAlignment == Alignment, "Alignment and alignof(Type) mismatch"); | |
} | |
std::aligned_storage_t<Size, Alignment> data; | |
}; | |
}; // namespace Fast |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment