The wrap class#

template<typename IFace, auto Cfg = default_config>
requires std::is_class_v<IFace> && std::same_as<IFace, std::remove_cv_t<IFace>> && valid_config<Cfg>
class wrap#
wrap()#

Default constructor.

The default constructor is enabled in the following circumstances:

  • the configuration option invalid_default_ctor in Cfg is set to true. In this case, the default constructor initialises into the invalid state. Otherwise,

  • a non-void default-initialisable DefaultValueType with a valid, default-initialisable interface implementation for IFace has been specified as first template argument in Cfg. In this case, the default constructor value-initialises an instance of DefaultValueType as the internal type-erased value. When employing value semantics, the copyability, movability and swappability of DefaultValueType must be consistent with the corresponding settings in Cfg in order for this constructor to be enabled.

In both cases, the reference interface must be default-initialisable in order for this constructor to be available.

Throws:

any exception thrown by the default constructor of the interface implementation or of the reference interface, by the value-initialisation of a non-void DefaultValueType or by memory allocation errors if the non-void DefaultValueType does not fit in static storage or if reference semantics is being used. If it can be determined at compile time that none of these conditions can occurr, then this constructor is marked noexcept.

explicit wrap(invalid_wrap_t)#

Explicit initialisation into the invalid state.

This constructor is enabled only if the reference interface is default-initialisable.

Throws:

any exception thrown by the default constructor of the reference interface. If the default constructor of the reference interface does not throw, then this constructor is marked noexcept.

template<typename T>
wrap(T &&x)#

Generic constructor.

This constructor will create a wrap from the input value x.

This constructor is enabled only if all the following conditions are satisfied:

  • the reference interface is default-initialisable;

  • after the removal of reference and cv-qualifiers, T is not

    • the same as wrap (so that this constructor does not interfere with the copy/move constructors),

    • an instance of std::in_place_type_t (so that this constructor does not interfere with the in-place constructor),

    • the same as invalid_wrap_t (so that this constructor does not interfere with the constructor into the invalid state);

  • the interface IFace has a valid, default-initialisable implementation for the value type T (see the iface_with_impl concept);

  • x can be perfectly-forwarded to construct an instance of the value type;

  • when employing value semantics, the copyability, movability and swappability of the value type are consistent with the corresponding settings in Cfg.

This constructor is marked explicit if either:

Otherwise, the constructor is implicit.

Parameters:

x – the input value.

Throws:

any exception thrown by the default constructor of the interface implementation or of the reference interface, by the construction of the value type or by memory allocation errors if the value type does not fit in static storage or if reference semantics is being used. If it can be determined at compile time that none of these conditions can occurr, then this constructor is marked noexcept.

template<typename T, typename ...U>
explicit wrap(std::in_place_type_t<T>, U&&... args)#

Generic in-place constructor.

This constructor will create a wrap containing a type-erased value of type T constructed from the input argument(s) args. If no input arguments are provided, the internal value will be value-initialised.

This constructor is enabled only if all the following conditions are satisfied:

  • T is an object type without cv qualifications;

  • the reference interface is default-initialisable;

  • the interface IFace has a valid, default-initialisable implementation for the value type T (see the iface_with_impl concept);

  • args can be perfectly-forwarded to construct an instance of the value type T;

  • when employing value semantics, the copyability, movability and swappability of the value type T are consistent with the corresponding settings in Cfg.

Parameters:

args – the input construction arguments.

Throws:

any exception thrown by the default constructor of the interface implementation or of the reference interface, by the construction of the value type or by memory allocation errors if the value type does not fit in static storage or if reference semantics is being used. If it can be determined at compile time that none of these conditions can occurr, then this constructor is marked noexcept.

wrap(const wrap &other)#

Copy constructor.

When employing value semantics, the copy constructor will copy-construct the type-erased value from other. Otherwise, a wrap sharing ownership of the type-erased value with other will be constructed.

This constructor is enabled only if the following conditions are satisfied:

Parameters:

other – the wrap to be copied.

Throws:

any exception thrown by the default constructor of the interface implementation or of the reference interface, or by the copy-construction of the value type or by memory allocation errors when value semantics is being used. This constructor is marked noexcept when using reference semantics and if the reference interface’s default constructor is marked noexcept.

[[nodiscard]] friend bool is_invalid(const wrap &w) noexcept#

This function will return true if w is in the invalid state, false otherwise.

Parameters:

w – the input argument.

Returns:

the validity status for w.

[[nodiscard]] friend const IFace *iface_ptr(const wrap &w) noexcept#
[[nodiscard]] friend const IFace *iface_ptr(const wrap &&w) noexcept#
[[nodiscard]] friend IFace *iface_ptr(wrap &w) noexcept#
[[nodiscard]] friend IFace *iface_ptr(wrap &&w) noexcept#

Fetch a pointer to the interface.

These functions will return a pointer to the instance of the interface IFace stored within a wrap. If w is in the invalid state, then nullptr will be returned.

Parameters:

w – the input argument.

Returns:

a pointer to the interface.

template<typename T, typename ...Args>
friend void emplace(wrap &w, Args&&... args)#

Emplace a value into a wrap.

This function will first destroy the value in w (if w is not already in the invalid state). It will then construct in w a value of type T using the construction arguments Args.

This function is enabled only if the following conditions are satisfied:

  • T is an object type without cv qualifications;

  • an instance of T can be constructed from Args;

  • the interface IFace has a valid, default-initialisable implementation for the value type T (see the iface_with_impl concept);

  • when employing value semantics, the copyability, movability and swappability of the value type T are consistent with the corresponding settings in Cfg.

Passing w as an argument in args (e.g., attempting to emplace w into itself) will lead to undefined behaviour.

This function is noexcept if all these conditions are satisfied:

  • w is using value semantics,

  • the static size and alignment of w are large enough to store an instance of T,

  • the invoked constructor of T does not throw.

If an exception is thrown, w may be left in the invalid state.

Parameters:
  • w – the target wrap.

  • args – the construction arguments.

Throws:

any exception thrown by memory allocation primitives or by the invoked constructor of T.

[[nodiscard]] friend bool has_static_storage(const wrap &w) noexcept#

Query the storage type of a wrap.

Parameters:

w – the input wrap.

Returns:

true if w is currently employing static storage, false otherwise.

[[nodiscard]] friend wrap copy(const wrap &w)#
requires (Cfg.semantics == wrap_semantics::reference)

Make a deep-copy of a wrap employing reference semantics.

This function will return a new wrap containing a copy of the value stored in w.

Parameters:

w – the input wrap.

Returns:

a deep copy of w.

Throws:

std::invalid_argument – if the value stored in w is not copy-constructible.

Throws:

any exception thrown by memory allocation primitives or by the copy constructor of the value stored in w.

[[nodiscard]] friend bool same_value(const wrap &w1, const wrap &w2) noexcept#
requires (Cfg.semantics == wrap_semantics::reference)

Check if two wrap objects employing reference semantics share ownership of the internal value.

Parameters:
  • w1 – the first wrap.

  • w2 – the second wrap.

Returns:

true if w1 and w2 share the internal value, false otherwise.

[[nodiscard]] bool is_valid(const wrap &w) noexcept#

This function will return false if w is in the invalid state, true otherwise.

Parameters:

w – the input argument.

Returns:

the validity status for w.

template<typename IFace, auto Cfg>
bool has_dynamic_storage(const wrap<IFace, Cfg> &w) noexcept#

Query the storage type of a wrap.

Parameters:

w – the input wrap.

Returns:

true if w is currently employing dynamic storage, false otherwise.

struct invalid_wrap_t#

A tag structure used to set a wrap to the invalid state. This is a trivial empty struct.

inline constexpr auto invalid_wrap = invalid_wrap_t{}#

A global instance of invalid_wrap_t.

template<typename T>
concept any_wrap#

This concept is satisfied if T is any instance of wrap.

template<typename T, typename IFace, wrap_semantics Sem>
struct holder#

Holder class for type-erased values.

Note

This class is to be regarded as an implementation detail, and as such it is left undocumented on purpose.

template<typename T>
concept any_holder#

This concept is satisfied if T is any instance of holder.