xentara-utils v2.0.4
The Xentara Utility Library
Loading...
Searching...
No Matches
xentara::utils::tools::PolymorphicVariant< Base, ValueHints > Class Template Reference

An aligned union for polymorphic types derived from a base class. More...

#include <xentara/utils/tools/PolymorphicVariant.hpp>

Classes

class  AbstractSupervisor
 A supervisor object that deals with the actual types. More...
 
class  ValuelessByExceptionSupervisor
 A dummy supervisor for variants that are valueleass by exception. More...
 

Public Member Functions

template<std::derived_from< Base > Derived, typename... Arguments>
 PolymorphicVariant (std::in_place_type_t< Derived >, Arguments &&...arguments) noexcept(std::is_nothrow_constructible_v< Derived, Arguments &&... >)
 Creates a variant containing an object of a specific type.
 
template<typename Derived >
requires std::derived_from<std::remove_cvref_t<Derived>, Base>
 PolymorphicVariant (Derived &&value) noexcept(std::is_nothrow_constructible_v< Derived, Derived && >)
 Creates a variant containing a specific value.
 
 PolymorphicVariant (const PolymorphicVariant &other)
 Copy constructor.
 
 PolymorphicVariant (PolymorphicVariant &&other) noexcept(polymorphicNothrowMoveConstructible(std::in_place_type< Base >))
 Move constructor.
 
 ~PolymorphicVariant () noexcept(polymorphicNothrowDestructible(std::in_place_type< Base >))
 Destructor.
 
auto operator= (const PolymorphicVariant &rhs) -> PolymorphicVariant &requires(polymorphicCopyAssignable(std::in_place_type< Base >) &&polymorphicDestructible(std::in_place_type< Base >) &&polymorphicCopyConstructible(std::in_place_type< Base >))
 Copy assignment operator.
 
auto operator= (PolymorphicVariant &&rhs) noexcept(polymorphicNothrowMoveAssignable(std::in_place_type< Base >) &&polymorphicNothrowDestructible(std::in_place_type< Base >) &&polymorphicNothrowMoveConstructible(std::in_place_type< Base >)) -> PolymorphicVariant &requires(polymorphicMoveAssignable(std::in_place_type< Base >) &&polymorphicDestructible(std::in_place_type< Base >) &&polymorphicMoveConstructible(std::in_place_type< Base >))
 Move assignment operator.
 
template<typename Derived >
requires std::derived_from<std::remove_cvref_t<Derived>, Base>
auto operator= (Derived &&value) -> PolymorphicVariant &requires(polymorphicCopyAssignable(std::in_place_type< Base >) &&polymorphicDestructible(std::in_place_type< Base >) &&polymorphicCopyConstructible(std::in_place_type< Base >))
 Assignment operator for a derived value.
 
constexpr auto operator* () const &noexcept -> const Base &
 Gets the object.
 
constexpr auto operator* () &noexcept -> Base &
 Gets the object.
 
constexpr auto operator* () const &&noexcept -> const Base &&
 Gets the object.
 
constexpr auto operator* () &&noexcept -> Base &&
 Gets the object.
 
constexpr auto operator-> () const noexcept -> const Base *
 Member access for the object.
 
constexpr auto operator-> () noexcept -> Base *
 Member access for the object.
 
template<std::derived_from< Base > Derived, typename... Arguments>
auto emplace (Arguments &&...arguments) noexcept -> PolymorphicVariant &
 Replaces the current value of the variant with an object of a certain type.
 
auto valueless_by_exception () const noexcept -> bool
 Checks whether the variant has been left in a valueless state because of an exception.
 
auto value () &noexcept -> Base &
 Checked access to the object.
 
auto value () const &noexcept -> const Base &
 Checked access to the object.
 
auto value () &&noexcept -> Base &&
 Checked access to the object.
 
auto value () const &&noexcept -> const Base &&
 Checked access to the object.
 
auto swap (PolymorphicVariant &other) noexcept(polymorphicNothrowSwappable(std::in_place_type< Base >)) -> void requires(polymorphicSwappable(std::in_place_type< Base >))
 Swaps the value with another unowned pointer.
 

Related Symbols

(Note that these are not member symbols.)

template<typename Base >
consteval auto polymorphicDestructible (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be destructible.
 
template<typename Base >
consteval auto polymorphicNothrowDestructible (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be nothrow destructible.
 
template<typename Base >
consteval auto polymorphicCopyConstructible (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be copy constructible.
 
template<typename Base >
consteval auto polymorphicMoveConstructible (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be move constructible.
 
template<typename Base >
consteval auto polymorphicNothrowMoveConstructible (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be nothrow move constructible.
 
template<typename Base >
consteval auto polymorphicCopyAssignable (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be copy assignable.
 
template<typename Base >
consteval auto polymorphicMoveAssignable (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be move assignable.
 
template<typename Base >
consteval auto polymorphicNothrowMoveAssignable (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be nothrow move assignable.
 
template<typename Base >
consteval auto polymorphicSwappable (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be swappable.
 
template<typename Base >
consteval auto polymorphicNothrowSwappable (std::in_place_type_t< Base >) noexcept -> bool
 Determines whether a specialization of PolymorphicVariant should be nothrow swappable.
 
template<typename Base , typename... ValueHints>
auto swap (PolymorphicVariant< Base, ValueHints... > &lhs, PolymorphicVariant< Base, ValueHints... > &rhs) noexcept(polymorphicNothrowSwappable(std::in_place_type< Base >)) -> void
 Swaps two variants.
 

Detailed Description

template<typename Base, typename... ValueHints>
class xentara::utils::tools::PolymorphicVariant< Base, ValueHints >

An aligned union for polymorphic types derived from a base class.

This class is a utility class that allows you to implement variant-like behaviour without restricting the variant content to a specific type. Instead, any type derived from the specified base class, and not exceeding the specified size and alignment requirements, can be stored in the variant.

Template Parameters
BaseThe base class
ValueHints

These are hints used to determine the size and alignment of the storage used for the variant. The variant can contain any type that is no larger that the largest ValueHint type, and whose alignment requirement is no greater than that of the strictest ValueHints type.

ValueHints does not need to contain the actual classes you want to store. They only need to represent the size and alignment requrements for the values. The value hints do not have to be derived from Base, nor do they have to be real constructible objects. The only requirement is that sizeof(ValueHints) and alignof(ValueHints) are valid.

Constructor & Destructor Documentation

◆ PolymorphicVariant() [1/4]

template<typename Base , typename... ValueHints>
template<std::derived_from< Base > Derived, typename... Arguments>
xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::PolymorphicVariant ( std::in_place_type_t< Derived >  ,
Arguments &&...  arguments 
)
noexcept

Creates a variant containing an object of a specific type.

Parameters
argumentsThe arguments for the constructor of the object.
Template Parameters
Derived

The actual type of the object to create. The size and alignment requirements of the type must be no greater than those specified using ValueHints.

Additionally, the class must meet the following requirements:

◆ PolymorphicVariant() [2/4]

template<typename Base , typename... ValueHints>
template<typename Derived >
requires std::derived_from<std::remove_cvref_t<Derived>, Base>
xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::PolymorphicVariant ( Derived &&  value)
noexcept

Creates a variant containing a specific value.

Parameters
valueThe value. The value must be of a type derived from Base, and must fit into the variant. See the PolymorphicVariant(std::in_place_type_t<Derived>, Arguments &&...arguments) noexcept(std::is_nothrow_constructible_v<Derived, Arguments &&...>) "in-place constructor" for details on the exact type requirements.

◆ PolymorphicVariant() [3/4]

template<typename Base , typename... ValueHints>
requires (polymorphicCopyConstructible(std::in_place_type<Base>))
xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::PolymorphicVariant ( const PolymorphicVariant< Base, ValueHints > &  other)

Copy constructor.

◆ PolymorphicVariant() [4/4]

template<typename Base , typename... ValueHints>
requires (polymorphicMoveConstructible(std::in_place_type<Base>))
xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::PolymorphicVariant ( PolymorphicVariant< Base, ValueHints > &&  other)
noexcept

Move constructor.

◆ ~PolymorphicVariant()

template<typename Base , typename... ValueHints>
requires (polymorphicDestructible(std::in_place_type<Base>))
xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::~PolymorphicVariant ( )
noexcept

Destructor.

Member Function Documentation

◆ emplace()

template<typename Base , typename... ValueHints>
template<std::derived_from< Base > Derived, typename... Arguments>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::emplace ( Arguments &&...  arguments) -> PolymorphicVariant &
noexcept

Replaces the current value of the variant with an object of a certain type.

Parameters
argumentsThe arguments for the constructor of the object.
Template Parameters
DerivedThe actual type of the object to create. The value must be of a type derived from Base, and must fit into the variant. See the PolymorphicVariant(std::in_place_type_t<Derived>, Arguments &&...arguments) noexcept(std::is_nothrow_constructible_v<Derived, Arguments &&...>) "in-place constructor" for details on the exact type requirements.

◆ operator*() [1/4]

template<typename Base , typename... ValueHints>
constexpr auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator* ( ) && -> Base &&
constexprnoexcept

Gets the object.

◆ operator*() [2/4]

template<typename Base , typename... ValueHints>
constexpr auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator* ( ) & -> Base &
constexprnoexcept

Gets the object.

◆ operator*() [3/4]

template<typename Base , typename... ValueHints>
constexpr auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator* ( ) const && -> const Base &&
constexprnoexcept

Gets the object.

◆ operator*() [4/4]

template<typename Base , typename... ValueHints>
constexpr auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator* ( ) const & -> const Base &
constexprnoexcept

Gets the object.

◆ operator->() [1/2]

template<typename Base , typename... ValueHints>
constexpr auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator-> ( ) const -> const Base *
constexprnoexcept

Member access for the object.

◆ operator->() [2/2]

template<typename Base , typename... ValueHints>
constexpr auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator-> ( ) -> Base *
constexprnoexcept

Member access for the object.

◆ operator=() [1/3]

template<typename Base , typename... ValueHints>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator= ( const PolymorphicVariant< Base, ValueHints > &  rhs) -> PolymorphicVariant & requires(polymorphicCopyAssignable(std::in_place_type<Base>) &&polymorphicDestructible(std::in_place_type<Base>) &&polymorphicCopyConstructible(std::in_place_type<Base>))

Copy assignment operator.

◆ operator=() [2/3]

template<typename Base , typename... ValueHints>
requires std::derived_from<std::remove_cvref_t<Derived>, Base>
template<typename Derived >
requires std::derived_from<std::remove_cvref_t<Derived>, Base>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator= ( Derived &&  value) -> PolymorphicVariant & requires(polymorphicCopyAssignable(std::in_place_type<Base>) &&polymorphicDestructible(std::in_place_type<Base>) &&polymorphicCopyConstructible(std::in_place_type<Base>))

Assignment operator for a derived value.

Parameters
valueThe value. The value must be of a type derived from Base, and must fit into the variant. See the PolymorphicVariant(std::in_place_type_t<Derived>, Arguments &&...arguments) noexcept(std::is_nothrow_constructible_v<Derived, Arguments &&...>) "in-place constructor" for details on the exact type requirements.

◆ operator=() [3/3]

template<typename Base , typename... ValueHints>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::operator= ( PolymorphicVariant< Base, ValueHints > &&  rhs) -> PolymorphicVariant & requires(polymorphicMoveAssignable(std::in_place_type<Base>) &&polymorphicDestructible(std::in_place_type<Base>) &&polymorphicMoveConstructible(std::in_place_type<Base>))
noexcept

Move assignment operator.

◆ swap()

template<typename Base , typename... ValueHints>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::swap ( PolymorphicVariant< Base, ValueHints > &  other) -> void requires(polymorphicSwappable(std::in_place_type<Base>))
noexcept

Swaps the value with another unowned pointer.

◆ value() [1/4]

template<typename Base , typename... ValueHints>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::value ( ) && -> Base &&
noexcept

Checked access to the object.

◆ value() [2/4]

template<typename Base , typename... ValueHints>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::value ( ) & -> Base &
noexcept

Checked access to the object.

Exceptions
std::bad_variant_accessThe variant is valueleass by exception.

◆ value() [3/4]

template<typename Base , typename... ValueHints>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::value ( ) const && -> const Base &&
noexcept

Checked access to the object.

◆ value() [4/4]

template<typename Base , typename... ValueHints>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::value ( ) const & -> const Base &
noexcept

Checked access to the object.

◆ valueless_by_exception()

template<typename Base , typename... ValueHints>
auto xentara::utils::tools::PolymorphicVariant< Base, ValueHints >::valueless_by_exception ( ) const -> bool
noexcept

Checks whether the variant has been left in a valueless state because of an exception.

Returns
Return true if the variant does not contain a value because an exception was thrown during move or copy assignment, or during a type-changing assignment or emplace().
See also
std::variant::valueless_by_exception()

Friends And Related Symbol Documentation

◆ polymorphicCopyAssignable()

template<typename Base >
consteval auto polymorphicCopyAssignable ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be copy assignable.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be copy assignable by defining your own function polymorphicCopyAssignable(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_copy_assignable_v<Base>.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be copy assignable.

◆ polymorphicCopyConstructible()

template<typename Base >
consteval auto polymorphicCopyConstructible ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be copy constructible.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be copy constructible by defining your own function polymorphicCopyConstructible(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_copy_constructible_v<Base> if Base is not an abstract class. Due to the limitations of std::is_copy_constructible_v, which is always false for abstract classes, the default implementation instead returns std::is_copy_assignable_v<Base> for abstract classes.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be copy constructible.

◆ polymorphicDestructible()

template<typename Base >
consteval auto polymorphicDestructible ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be destructible.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be destructible by defining your own function polymorphicDestructible(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_destructible_v<Base>.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be destructible.

◆ polymorphicMoveAssignable()

template<typename Base >
consteval auto polymorphicMoveAssignable ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be move assignable.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be move assignable by defining your own function polymorphicMoveAssignable(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_move_assignable_v<Base>.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be move assignable.

◆ polymorphicMoveConstructible()

template<typename Base >
consteval auto polymorphicMoveConstructible ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be move constructible.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be move constructible by defining your own function polymorphicMoveConstructible(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_move_constructible_v<Base> if Base is not an abstract class. Due to the limitations of std::is_move_constructible_v, which is always false for abstract classes, the default implementation instead returns std::is_move_assignable_v<Base> for abstract classes.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be move constructible.

◆ polymorphicNothrowDestructible()

template<typename Base >
consteval auto polymorphicNothrowDestructible ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be nothrow destructible.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be nothrow destructible by defining your own function polymorphicNothrowDestructible(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_nothrow_destructible_v<Base>.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be nothrow destructible.

◆ polymorphicNothrowMoveAssignable()

template<typename Base >
consteval auto polymorphicNothrowMoveAssignable ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be nothrow move assignable.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be move nothrow assignable by defining your own function polymorphicNothrowMoveAssignable(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_nothrow_move_assignable_v<Base>.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be nothrow move assignable.

◆ polymorphicNothrowMoveConstructible()

template<typename Base >
consteval auto polymorphicNothrowMoveConstructible ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be nothrow move constructible.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be nothrow move constructible by defining your own function polymorphicNothrowMoveConstructible(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_nothrow_move_constructible_v<Base> if Base is not an abstract class. Due to the limitations of std::is_nothrow_move_constructible_v, which is always false for abstract classes, the default implementation instead returns polymorphicMoveConstructible(std::in_place_type<Base>) && std::is_nothrow_move_assignable_v<Base> for abstract classes.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be nothrow move constructible.

◆ polymorphicNothrowSwappable()

template<typename Base >
consteval auto polymorphicNothrowSwappable ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be nothrow swappable.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be nothrow swappable by defining your own function polymorphicNothrowSwappable(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_nothrow_swappable_v<Base> if Base is not an abstract class. Due to the limitations of std::is_nothrow_swappable_v, which is always false for abstract classes, the default implementation instead returns polymorphicSwappable(std::in_place_type<Base>) && polymorphicNothrowMoveConstructible(std::in_place_type<Base>) && polymorphicNothrowMoveAssignable(std::in_place_type<Base>) for abstract classes.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be nothrow swappable.

◆ polymorphicSwappable()

template<typename Base >
consteval auto polymorphicSwappable ( std::in_place_type_t< Base >  ) -> bool
related

Determines whether a specialization of PolymorphicVariant should be swappable.

This function is a customization point. You can specify whether PolymorphicVariant<MyType> should be swappable by defining your own function polymorphicSwappable(std::in_place_type_t<MyType>) that will be found by ADL lookup. Basically that means that it should either be a friend of MyType, or reside in the same namespace.

The default implementation returns std::is_swappable_v<Base> if Base is not an abstract class. Due to the limitations of std::is_swappable_v, which is always false for abstract classes, the default implementation instead returns polymorphicMoveConstructible(std::in_place_type<Base>) && polymorphicMoveAssignable(std::in_place_type<Base>) for abstract classes.

Template Parameters
BaseThe Base parameter of the PolymorphicVariant
Returns
Whether PolymorphicVariant<Base> should be swappable.

◆ swap()

template<typename Base , typename... ValueHints>
auto swap ( PolymorphicVariant< Base, ValueHints... > &  lhs,
PolymorphicVariant< Base, ValueHints... > &  rhs 
) -> void
related

Swaps two variants.