Skip to content

Instantly share code, notes, and snippets.

@nikkon-dev
Created January 15, 2020 22:53
Show Gist options
  • Save nikkon-dev/d580d6284d98e110e3b3fddea4ac6055 to your computer and use it in GitHub Desktop.
Save nikkon-dev/d580d6284d98e110e3b3fddea4ac6055 to your computer and use it in GitHub Desktop.
FastPimpl after Yandex.Taxi
#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