You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
3.5 KiB
69 lines
3.5 KiB
#pragma once
|
|
|
|
#include <type_traits>
|
|
|
|
template <class _Tp, size_t _Disambiguator = 0, class _Enable = void, class _Is_Fundamental = void>
|
|
struct no_unique_address_emulation {
|
|
using stored_type = _Tp;
|
|
using _Tp::_Tp;
|
|
|
|
_Tp v;
|
|
|
|
inline constexpr _Tp const& ref() const noexcept { return v; }
|
|
|
|
inline constexpr _Tp& ref() noexcept { return v; }
|
|
};
|
|
|
|
template <class _Tp, size_t _Disambiguator>
|
|
struct no_unique_address_emulation<_Tp, _Disambiguator, void, std::enable_if_t<std::is_fundamental_v<_Tp>>> {
|
|
using stored_type = _Tp;
|
|
|
|
_Tp v;
|
|
|
|
inline constexpr _Tp const& ref() const noexcept { return v; }
|
|
|
|
inline constexpr _Tp& ref() noexcept { return v; }
|
|
|
|
inline constexpr no_unique_address_emulation() noexcept = default;
|
|
inline constexpr no_unique_address_emulation(no_unique_address_emulation const&) noexcept = default;
|
|
inline constexpr no_unique_address_emulation(no_unique_address_emulation&&) noexcept = default;
|
|
inline constexpr no_unique_address_emulation& operator=(no_unique_address_emulation const&) noexcept = default;
|
|
inline constexpr no_unique_address_emulation& operator=(no_unique_address_emulation&&) noexcept = default;
|
|
inline ~no_unique_address_emulation() noexcept = default;
|
|
|
|
inline explicit constexpr no_unique_address_emulation(_Tp const& v) noexcept : _Tp(v) {}
|
|
|
|
inline explicit constexpr no_unique_address_emulation(_Tp&& v) noexcept : _Tp(std::move(v)) {}
|
|
};
|
|
|
|
// Empty case
|
|
// This doesn't work if _Tp is final, of course, but we're not using anything
|
|
// like that currently. That kind of thing could be added pretty easily though
|
|
template <class _Tp, size_t _Disambiguator>
|
|
struct no_unique_address_emulation<_Tp,
|
|
_Disambiguator,
|
|
std::enable_if_t<std::is_empty_v<_Tp> &&
|
|
// If the type isn't trivially destructible, its destructor
|
|
// won't be called at the right time, so don't use this
|
|
// specialization
|
|
std::is_trivially_destructible_v<_Tp>>> : protected _Tp {
|
|
using stored_type = _Tp;
|
|
using _Tp::_Tp;
|
|
|
|
constexpr _Tp const& ref() const noexcept { return *static_cast<_Tp const*>(this); }
|
|
|
|
constexpr _Tp& ref() noexcept { return *static_cast<_Tp*>(this); }
|
|
|
|
inline constexpr no_unique_address_emulation() noexcept = default;
|
|
inline constexpr no_unique_address_emulation(no_unique_address_emulation const&) noexcept = default;
|
|
inline constexpr no_unique_address_emulation(no_unique_address_emulation&&) noexcept = default;
|
|
inline constexpr no_unique_address_emulation& operator=(no_unique_address_emulation const&) noexcept = default;
|
|
inline constexpr no_unique_address_emulation& operator=(no_unique_address_emulation&&) noexcept = default;
|
|
inline ~no_unique_address_emulation() noexcept = default;
|
|
|
|
// Explicitly make this not a reference so that the copy or move
|
|
// constructor still gets called.
|
|
inline explicit constexpr no_unique_address_emulation(_Tp const& v) noexcept : _Tp(v) {}
|
|
|
|
inline explicit constexpr no_unique_address_emulation(_Tp&& v) noexcept : _Tp(std::move(v)) {}
|
|
};
|