diff --git a/sus/choice/choice.h b/sus/choice/choice.h index 273f74d69..cb45dbda6 100644 --- a/sus/choice/choice.h +++ b/sus/choice/choice.h @@ -174,6 +174,16 @@ struct CanConvertToStorage, U> { /// } /// } /// ``` +/// `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; +/// auto x = EitherOr::with(987u); +/// ``` template class Choice<__private::TypeList, Tags...> final { static_assert(sizeof...(Ts) > 0, diff --git a/sus/choice/choice_types.h b/sus/choice/choice_types.h index b089db1c1..677762ff8 100644 --- a/sus/choice/choice_types.h +++ b/sus/choice/choice_types.h @@ -22,9 +22,14 @@ #include "sus/macros/remove_parens.h" #include "sus/tuple/tuple.h" -/// Construct a set of associated value and types pairings. The type of the +/// A macro used to declare the value-type pairings in a [`Choice`]( +/// $sus::choice_type::Choice). See the [`Choice`]( +/// $sus::choice_type::Choice) type for examples of its use. +/// +/// Constructs a set of associated value and types pairings. The type of the /// values need have no relationship to the specified types. /// +/// # Details /// The input takes the format: `(Value1, Type1A, Type1B), (Value2, Type2), ...` /// The output is the sequence `TypeList, Tuple, /// ...>, Value1, Value2, ...`. @@ -60,11 +65,11 @@ // clang-format on #define _sus__make_union_storage_type(types) \ - ::sus::choice_type::__private::MakeStorageType::type + ::sus::choice_type::__private::MakeStorageType<_sus_remove_parens(types)>::type #define _sus__first(a, ...) a #define _sus__second_plus(a, ...) __VA_ARGS__ #define _sus__value_types_types(x) \ - (sus_remove_parens_and_eval(_sus__second_plus, x)) -#define _sus__value_types_value(x) sus_remove_parens_and_eval(_sus__first, x) + (_sus_remove_parens_and_eval(_sus__second_plus, x)) +#define _sus__value_types_value(x) _sus_remove_parens_and_eval(_sus__first, x) diff --git a/sus/choice/choice_unittest.cc b/sus/choice/choice_unittest.cc index dd85a7a36..9b37418ba 100644 --- a/sus/choice/choice_unittest.cc +++ b/sus/choice/choice_unittest.cc @@ -1026,6 +1026,12 @@ TEST(Choice, Example_Construct) { } } } + { + enum class Order { First, Second }; + using EitherOr = + Choice; + auto x = EitherOr::with(987u); + } } } // namespace diff --git a/sus/macros/eval_macro.h b/sus/macros/eval_macro.h index c58cdf1ec..b6a548d30 100644 --- a/sus/macros/eval_macro.h +++ b/sus/macros/eval_macro.h @@ -22,7 +22,7 @@ /// # Example /// ``` /// #define f(s) hello(s) -/// sus_eval_macro(f, "world") +/// _sus_eval_macro(f, "world") /// // Evaluates to: `hello("world")` /// ``` -#define sus_eval_macro(x, ...) x(__VA_ARGS__) +#define _sus_eval_macro(x, ...) x(__VA_ARGS__) diff --git a/sus/macros/remove_parens.h b/sus/macros/remove_parens.h index ddf93c503..fe72e1530 100644 --- a/sus/macros/remove_parens.h +++ b/sus/macros/remove_parens.h @@ -25,12 +25,12 @@ /// * `(x, y)` => `x, y` /// /// Based on: https://stackoverflow.com/a/62984543 -#define sus_remove_parens(x) _sus__remove_inner_rename(_sus__remove_inner x) +#define _sus_remove_parens(x) _sus__remove_inner_rename(_sus__remove_inner x) -#define sus_remove_parens_and_eval(e, x) \ - sus_eval_macro(e, sus_remove_parens(x)) +#define _sus_remove_parens_and_eval(e, x) \ + _sus_eval_macro(e, _sus_remove_parens(x)) -// Implementation of sus_remove_parens(x). +// Implementation of _sus_remove_parens(x). // Step 1: If the input had brackets, now it no longer does. The result will // always be `_sus__remove_inner x` at the end.