Class Subspace :: sus :: choice_type :: Choice
A tagged union, or sum type.
A Choice is always set to one of its Tags values, and each tag has zero
or more types attached to it as data values.
Choice can be thought of as a combination of an enum and a
std::variant, and
typically the Tags are specified to be values in an enum.
A Choice always has an active member, as the tag must be specified at
construction, and the asociated values for the tag are always set as they
must be set when the tag is specified. This means a Choice is always in a
fully specified state, or it is moved-from. Once it is moved from it may not
be used except to be re-initialized.
Use the sus_choice_types() macro to specify the types in a Choice type.
To access the values in Choice, the current tag must be specified as a
template parameter, and it will be checked for correctness. When it does not
match, the Choice method will panic.
as<Tag>()gives const access to all the values attached to the tag.as_mut<Tag>()gives mutable access to all the values attached to the tag. It is only callable on mutableChoice.into_inner<Tag>()moves all values attached to the tag out of theChoiceand marks theChoiceas moved-from. It is only callable on an rvalueChoice.get<Tag>()returns a const reference to the values attached to the tag if its currently active, and returnsNoneif the tag is not active.get_mut<Tag>()returns a mutable reference to the values attached to the tag if its currently active, and returnsNoneif the tag is not active.
Examples
This Choice holds either a u64 with
the First tag or a u32 with the Second tag.
enum class Order { First, Second };
using EitherOr = Choice<sus_choice_types(
(Order::First, u64),
(Order::Second, u32)
)>;
A Choice tag may be associated with no values by making its type void or
may be associated with more than one type in which case all access will be
done with a Tuple.
enum class Order { First, Second };
using EitherOr = Choice<sus_choice_types(
(Order::First, void),
(Order::Second, std::string, i32)
)>;
auto e1 = EitherOr::with<Order::First>();
auto e2 = EitherOr::with<Order::Second>("text", 123);
The Choice type can be used in a switch, with each case being one of its
possible tag values. Within each tag case block, the values can be pulled
out of the Choice with as in a
type-safe and memory-safe way.
enum class Order { First, Second };
using EitherOr = Choice<sus_choice_types(
(Order::First, u64),
(Order::Second, std::string, i32)
)>;
auto e = EitherOr::with<Order::Second>("hello worl", 0xd);
switch (e) {
case Order::First: {
const auto& i = e.as<Order::First>();
// We don't get here.
fmt::println("First has u64 {}", i);
break;
}
case Order::Second: {
const auto& [s, i] = e.as<Order::Second>();
// Prints "Second has hello world".
fmt::println("Second has {}{:x}", s, i);
break;
}
}
Choice will re-export the tag value type as a nested Tag subtype. This
allows access to the Choice's values though MyChoiceType::Tag::Name.
enum class Order { First, Second };
using EitherOr = Choice<sus_choice_types(
(Order::First, u64),
(Order::Second, u32)
)>;
auto x = EitherOr::with<EitherOr::Tag::First>(987u);
Static Methods
__private::StorageCount<StorageTypeOfTag<V>> == 1u
sus::construct::SafelyConstructibleFromReference<StorageTypeOfTag<V>, U &&>
std::convertible_to<U &&, StorageTypeOfTag<V>>
__private::StorageCount<StorageTypeOfTag<V>> > 1u
sizeof...(Us) ==
__private::StorageCount<StorageTypeOfTag<V>>
sus::choice_type::__private::StorageIsSafelyConstructibleFromReference<StorageTypeOfTag<V>, Us &&...>
std::constructible_from<StorageTypeOfTag<V>, Us &&...>
Constructs a Choice with the V tag indicating its active member, and
with the parameters used to set the associated values.
If the associated type of the tag is void then with() takes no
parameters.
Methods
Returns a const reference to the value(s) inside the Choice.
The function has a template parameter specifying the tag of the active
member in the Choice.
If the active member's associated type is void then this method is
deleted and can't be called.
If the active member has a single value, a reference to it is returned
directly, otherwise a Tuple of references is returned to all values in the
active member.
Panics
The function will panic if the active member does not match the tag value passed as the template parameter.
Returns a mutable reference to the value(s) inside the Choice.
The function has a template parameter specifying the tag of the active
member in the Choice.
If the active member's associated type is void then this method is
deleted and can't be called.
If the active member has a single value, a reference to it is returned
directly, otherwise a Tuple of references is returned to all values in the
active member.
Panics
The function will panic if the active member does not match the tag value passed as the template parameter.
Returns a const reference to the value(s) inside the Choice.
If the template parameter does not match the active member in the
Choice, the function returns None.
If the active member's associated type is void then this method is
deleted and can't be called.
If the active member has a single value, a reference to it is returned
directly, otherwise a Tuple of references is
returned to all values in the active member.
Returns a mutable reference to the value(s) inside the Choice.
If the template parameter does not match the active member in the
Choice, the function returns None.
If the active member's associated type is void then this method is
deleted and can't be called.
If the active member has a single value, a reference to it is returned
directly, otherwise a Tuple of references is
returned to all values in the active member.
__private::StorageCount<StorageTypeOfTag<V>> > 0u
!std::is_reference_v<StorageTypeOfTag<V>>
Returns a const reference to the value(s) inside the Choice.
The function has a template parameter specifying the tag of the active
member in the Choice.
If the active member's associated type is void then this method is
deleted and can't be called.
If the active member has a single value, a reference to it is returned
directly, otherwise a Tuple of references is
returned to all values in the active member.
Safety
If the active member does not match the tag value passed as the template parameter, Undefined Behaviour results.
__private::StorageCount<StorageTypeOfTag<V>> > 0u
Returns a mutable reference to the value(s) inside the Choice.
The function has a template parameter specifying the tag of the active
member in the Choice.
If the active member's associated type is void then this method is
deleted and can't be called.
If the active member has a single value, a reference to it is returned
directly, otherwise a Tuple of references is
returned to all values in the active member.
Safety
If the active member does not match the tag value passed as the template parameter, Undefined Behaviour results.
__private::StorageCount<StorageTypeOfTag<V>> > 0u
Unwraps the Choice to move out the current value(s) inside the Choice.
The function has a template parameter specifying the tag of the active
member in the Choice.
If the active member's associated type is void then this method is
deleted and can't be called.
If the active member has a single value, an rvalue reference to it is
returned directly, otherwise a Tuple of
rvalue references is returned to all values in the active member.
Panics
The function will panic if the active member does not match the tag value passed as the template parameter.
__private::StorageCount<StorageTypeOfTag<V>> > 1u
sizeof...(Us) ==
__private::StorageCount<StorageTypeOfTag<V>>
sus::choice_type::__private::StorageIsSafelyConstructibleFromReference<StorageTypeOfTag<V>, Us &&...>
std::constructible_from<StorageTypeOfTag<V>, Us &&...>
Changes the Choice to make the tag V active, and sets the associated
values of V from the paramters.
If the associated type of the tag is void then set() takes no
parameters.
Returns which is the active member of the Choice.
Typically to access the data in the Choice, a switch statement would
be used, so as to call the getter or setter methods with the right value
specified as a template parameter. When used in a switch statement, the
which method can be omitted.
Example
switch (my_choice) {
case Value1: return my_choice.as<Value1>().stuff;
case Value2: return my_choice.as<Value2>().andmore;
case Value3: return my_choice.as<Value3>().stufftoo;
}
Inspiration
████████
████▓▓░░▓▓██
██▓▓▓▓▓▓▓▓██
██▓▓▓▓░░▓▓██
██░░▓▓▓▓▓▓██
██▓▓▓▓▓▓▓▓▓▓██
██▓▓▓▓░░▓▓▓▓██
████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████
██▓▓░░▓▓▓▓▓▓░░▓▓▓▓▓▓▓▓▓▓░░▓▓▓▓▓▓██
██████████████████▓▓██████████████
██ ██ ██
██ ██ ██ ██
██ ██ ████ ██
██ ██ ██
██▒▒ ██ ██
██▒▒ ██ ██
████████████████████
██ ██
██ ██▓▓██
▓▓ ██▓▓▓▓██
██ ████░░▓▓▓▓██ ▓▓▓▓▓▓▓▓▓▓▓▓
██ ██ ██▓▓▓▓░░▓▓██ ▓▓░░░░░░░░░░░░
██ ██ ████▓▓▓▓▓▓██ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓
▓▓▓▓ ██ ██ ██▓▓▓▓▓▓░░▓▓██ ▓▓▓▓░░░░░░░░░░░░
▓▓▓▓▓▓▓▓▓▓██████▓▓▓▓██▓▓░░▓▓▓▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
██████████ ▓▓▓▓░░░░░░░░░░░░
██ ██ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓
██ ██ ▓▓░░░░░░░░░░░░
██ ██ ▓▓▓▓▓▓▓▓▓▓▒▒
████
Conversions
Support for using Choice in a switch() statment.
See the type's top level documentation for an example.