4.6.0
Freundlich's C++ toolkit
|
A class that can hold any object from a fixed set of types.
A variant is a type that can hold objects of a fixed set of types, which is sometimes also called a sum type. The closest language feature in C++ are unions, which are very low-level and dangerous to use:
fcppt::variant
fixes the aforementioned problems in the following way:
Consider a variant of an int and a string, for which we provide a print function:
Notice that we do not query which type the variant holds. Instead, we make use of fcppt::variant::match and write out all cases explicitly.
A more general way to access variants is called visitation, which is similar to pattern matching. A visitor is a struct or class that uses an overloaded operator()
to distinguish between the possible types of a variant.
Suppose we want to define a visitor that does something different for all integral types. The easiest way this can be done is by using std::enable_if
.
The following code shows how such a visitor is called:
Here is a small example for defining a binary visitor:
Non-const visitation, which means that the visited variant can be modified, is also supported.
Visitation and matching are the most common ways to access a variant. The other ways are:
static_cast
to a derived class. While the design of fcppt::variant
is similar to std::variant
, there are some key differences:
std::variant
default constructs the first type of all possible types instead, which does not make any sense. Header file | Description |
---|---|
object_fwd.hpp | Contains fcppt::variant::object variants's declaration. |
object_decl.hpp | Contains fcppt::variant::object variant's definition. |
object_impl.hpp | Contains the definition of fcppt::variant::object variants's member functions. |
object.hpp | The same as object_impl.hpp . |
apply.hpp | Contains fcppt::variant::apply . |
compare.hpp | Contains fcppt::variant::compare . |
comparison.hpp | Contains operator< , operator== and operator!= . |
from_list_fwd.hpp | Contains fcppt::variant::from_list. |
from_list.hpp | Includes fcppt/variant/object_fwd.hpp and defines fcppt::variant::object. |
get_unsafe.hpp | Contains fcppt::variant::get_unsafe which does the same thing as the fcppt::variant::object::get_unsafe member function. |
holds_type.hpp | Contains the fcppt::variant::holds_type function to check if a type is held by the variant. |
match.hpp | Contains fcppt::variant::match. |
output.hpp | Contains operator<< for output. |
to_optional.hpp | Contains fcppt::variant::to_optional. |
to_optional_ref.hpp | Contains fcppt::variant::to_optional_ref. |
type_info.hpp | Contains fcppt::variant::type_info. |
Classes | |
class | fcppt::variant::object< Types > |
A class that can hold any object from a fixed set of types. More... | |
Typedefs | |
template<fcppt::mpl::list::object_concept Types> | |
using | fcppt::variant::dynamic_cast_types = fcppt::mpl::list::map<Types, fcppt::mpl::lambda<fcppt::reference>> |
The variant element types used for fcppt::variant::dynamic_cast_. | |
template<fcppt::mpl::list::object_concept Types> | |
using | fcppt::variant::from_list = fcppt::mpl::list::as<fcppt::variant::object, Types> |
Declares a variant using an mpl::list. | |
template<fcppt::variant::object_concept Variant, typename Element > | |
using | fcppt::variant::has_type = fcppt::mpl::list::contains<fcppt::variant::types_of<Variant>, Element> |
Checks if a variant has a specific type. | |
template<typename Container > | |
using | fcppt::variant::partition_result |
The result of fcppt::variant::partition. | |
using | fcppt::variant::size_type = std::size_t |
An integer type used to describe a type index. | |
template<fcppt::variant::object_concept Variant> | |
using | fcppt::variant::types_of = typename fcppt::variant::detail::types_of<std::remove_cvref_t<Variant>>::type |
The types of a variant. | |
Functions | |
template<typename Function , fcppt::variant::object_concept... Variants> | |
decltype(auto) | fcppt::variant::apply (Function const &_function, Variants &&..._variants) |
Applies a function to the elements of several variants. | |
template<typename... Types, typename Compare > | |
bool | fcppt::variant::compare (fcppt::variant::object< Types... > const &_left, fcppt::variant::object< Types... > const &_right, Compare const &_compare) |
Compares two variants using a Compare function. | |
template<typename... Types> | |
bool | fcppt::variant::operator== (fcppt::variant::object< Types... > const &_left, fcppt::variant::object< Types... > const &_right) |
Compares two variants for equality. | |
template<typename... Types> | |
bool | fcppt::variant::operator!= (fcppt::variant::object< Types... > const &_a, fcppt::variant::object< Types... > const &_b) |
Compares two variants for inequality. | |
template<typename... Elements> | |
std::string | fcppt::variant::current_type_name (fcppt::variant::object< Elements... > const &_variant) |
Returns the type name of the current type. | |
template<fcppt::mpl::list::object_concept Types, fcppt::cast::dynamic_fun_concept Cast, typename Base > | |
fcppt::optional::object< fcppt::variant::from_list< fcppt::variant::dynamic_cast_types< Types > > > | fcppt::variant::dynamic_cast_ (Base &_base) |
Tries several dynamic casts, returning a variant of their types. | |
template<typename Type , typename... Elements> requires fcppt::variant::has_type_v<fcppt::variant::object<Elements...>,Type> | |
Type & | fcppt::variant::get_unsafe (fcppt::variant::object< Elements... > &_object) |
Free get_unsafe function. | |
template<typename Type , typename... Elements> requires fcppt::variant::has_type_v<fcppt::variant::object<Elements...>,Type> | |
Type const & | fcppt::variant::get_unsafe (fcppt::variant::object< Elements... > const &_object) |
Free get_unsafe function. | |
template<typename Type , typename... Elements> requires fcppt::variant::has_type_v<fcppt::variant::object<Elements...>, Type> | |
bool | fcppt::variant::holds_type (fcppt::variant::object< Elements... > const &_variant) |
Checks if a type is held by a variant. | |
template<fcppt::variant::object_concept Variant, typename... Functions> | |
decltype(auto) | fcppt::variant::match (Variant &&_variant, Functions const &..._functions) |
Matches a variant with a function for each element type. | |
template<typename... Types, typename Ch , typename Traits > | |
std::basic_ostream< Ch, Traits > & | fcppt::variant::operator<< (std::basic_ostream< Ch, Traits > &_stream, fcppt::variant::object< Types... > const &_object) |
Outputs the value held by the variant to a basic_ostream. | |
template<typename Container > | |
fcppt::variant::partition_result< Container > | fcppt::variant::partition (Container &&_container) |
Partitions a container of variants into multiple containers. | |
template<typename Type , fcppt::variant::object_concept Variant> requires fcppt::variant::has_type_v<Variant,Type> | |
fcppt::optional::object< Type > | fcppt::variant::to_optional (Variant &&_variant) |
Converts a variant and a type to an optional. | |
template<typename Type , fcppt::variant::object_concept Variant> requires fcppt::variant::has_type_v<Variant,std::remove_const_t<Type>> | |
fcppt::optional::reference< Type > | fcppt::variant::to_optional_ref (Variant &_variant) |
Converts a variant and a type to an optional reference. | |
template<typename... Types> | |
std::type_info const & | fcppt::variant::type_info (fcppt::variant::object< Types... > const &_variant) |
Returns an std::type_info of the held type. | |
Variables | |
template<fcppt::variant::object_concept Variant, typename Element > | |
constexpr bool | fcppt::variant::has_type_v = fcppt::variant::has_type<Variant,Element>::value |
Checks if a variant has a specific type. | |
template<typename T > | |
constexpr bool | fcppt::variant::is_object_v = fcppt::variant::is_object<T>::value |
Checks if a given type is an fcppt::variant::object. | |
using fcppt::variant::dynamic_cast_types = fcppt::mpl::list::map<Types, fcppt::mpl::lambda<fcppt::reference>> |
The variant element types used for fcppt::variant::dynamic_cast_.
using fcppt::variant::from_list = fcppt::mpl::list::as<fcppt::variant::object, Types> |
Declares a variant using an mpl::list.
using fcppt::variant::has_type = fcppt::mpl::list::contains<fcppt::variant::types_of<Variant>, Element> |
Checks if a variant has a specific type.
using fcppt::variant::partition_result |
The result of fcppt::variant::partition.
Partitioning a Container<fcppt::variant::object<T_1,...,T_n>>
yields fcppt::tuple::object<std::vector<T_1>,...,std::vector<T_n>>
.
using fcppt::variant::size_type = std::size_t |
An integer type used to describe a type index.
using fcppt::variant::types_of = typename fcppt::variant::detail::types_of<std::remove_cvref_t<Variant>>::type |
The types of a variant.
|
inlinenodiscard |
Applies a function to the elements of several variants.
TODO(concepts)
|
inlinenodiscard |
Compares two variants using a Compare function.
Compares _left and _right using _compare. The two variants are equal if they hold the same type T
and _compare(_left.get<T>(), _right.get<T>())
holds.
_left | The first variant |
_right | The second variant |
_compare | The function to use for comparison |
|
nodiscard |
Returns the type name of the current type.
|
nodiscard |
Tries several dynamic casts, returning a variant of their types.
Let Types=(T_1,...,T_n)
. The function tries to cast _base to T_1
first. If this fails, it tries to cast _base to T_2
, and so on. The result of the first cast that succeeds is returned.
fcppt::reference<T_1>,...,fcppt::reference<T_n>
.Base | The base class type to cast from. |
TODO(concepts)
|
inline |
|
inline |
|
inlinenodiscard |
Checks if a type is held by a variant.
The currently held type of a variant is the type passed to its constructor or assignment operator. A type T can be held by a variant<Set>
if T is a member of Set.
This function checks if Type is held by _variant.
Type | The type to check for which must be a possible type for the variant. |
|
inline |
Matches a variant with a function for each element type.
Matches _variant with _functions. The functions must be listed in the order the types appear in the variant.
TODO(concepts)
|
nodiscard |
Compares two variants for inequality.
Compares _a and _b for inequality. Equal to !(_a == _b)
. This function requires all possible types of the variant to be equality comparable.
TODO(concepts)
|
inline |
Outputs the value held by the variant to a basic_ostream.
Outputs the value held by _object to _stream. This function requires all possibles types to be printable.
TODO(concepts)
|
nodiscard |
Compares two variants for equality.
Compares _left and _right for equality. The two variants are equal if they hold the same type and the values compare equal. This function requires all possible types of the variant to be equality comparable.
TODO(concepts)
|
nodiscard |
Partitions a container of variants into multiple containers.
Container | A container of fcppt::variant::object. |
|
nodiscard |
Converts a variant and a type to an optional.
|
nodiscard |
Converts a variant and a type to an optional reference.
std::type_info const & fcppt::variant::type_info | ( | fcppt::variant::object< Types... > const & | _variant | ) |
Returns an std::type_info
of the held type.
|
inlineconstexpr |
Checks if a variant has a specific type.
|
inlineconstexpr |
Checks if a given type is an fcppt::variant::object.