|
| 1 | +// Copyright 2025 Google LLC |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +// you may not use this file except in compliance with the License. |
| 5 | +// You may obtain a copy of the License at |
| 6 | +// |
| 7 | +// https://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +// |
| 9 | +// Unless required by applicable law or agreed to in writing, software |
| 10 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +// See the License for the specific language governing permissions and |
| 13 | +// limitations under the License. |
| 14 | + |
| 15 | +// IWYU pragma: private, include "sus/choice/choice.h" |
| 16 | +// IWYU pragma: friend "sus/.*" |
| 17 | +#pragma once |
| 18 | + |
| 19 | +#include "sus/macros/for_each.h" |
| 20 | +#include "sus/macros/remove_parens.h" |
| 21 | + |
| 22 | +/// A macro used to declare the value-type pairings in a [`Choice`]( |
| 23 | +/// $sus::choice_type::Choice). See the [`Choice`]( |
| 24 | +/// $sus::choice_type::Choice) type for examples of its use. |
| 25 | +/// |
| 26 | +/// Constructs a set of associated value and types pairings. The type of the |
| 27 | +/// values need have no relationship to the specified types. |
| 28 | +/// |
| 29 | +/// # Details |
| 30 | +/// The input takes the format: `(Value1, Type1A, Type1B), (Value2, Type2), ...` |
| 31 | +/// The output is the sequence `TypeList<Tuple<Type1A, Type1B>, Tuple<Type2>, |
| 32 | +/// ...>, Value1, Value2, ...`. |
| 33 | +/// Use `sus::macros::value_types::TypeAt<I, Types<...>>` to extract each tuple |
| 34 | +/// type from the returned set of types. |
| 35 | +/// |
| 36 | +/// The number of values that follow will always be the same as the number of |
| 37 | +/// types in the set. This is the primary value of the `sus_choice_types()` |
| 38 | +/// construct. |
| 39 | +/// |
| 40 | +/// # Example |
| 41 | +/// ``` |
| 42 | +/// template <class Types, auto FirstValue, auto... Values> |
| 43 | +/// class Example { |
| 44 | +/// using first_type = v<0, Types>; |
| 45 | +/// static constexpr auto first_value = FirstValue; |
| 46 | +/// }; |
| 47 | +/// |
| 48 | +/// using E = Example<sus_choice_types(('h', i32), ('w', f32))>; |
| 49 | +/// // `E::first_value` will be `'h'` of type `char`. |
| 50 | +/// // `E::first_type` will be `Tuple<i32>`. |
| 51 | +/// ``` |
| 52 | +// |
| 53 | +// clang-format off |
| 54 | +#define sus_choice_types(...) \ |
| 55 | + sus::choice_type::__private::TypeList< \ |
| 56 | + _sus_for_each(_sus__make_union_storage_type, _sus_for_each_sep_comma, \ |
| 57 | + _sus_for_each(_sus__value_types_types, _sus_for_each_sep_comma, \ |
| 58 | + __VA_ARGS__))>, \ |
| 59 | + _sus_for_each(_sus__value_types_value, _sus_for_each_sep_comma, \ |
| 60 | + __VA_ARGS__) |
| 61 | + |
| 62 | +// clang-format on |
| 63 | + |
| 64 | +#define _sus__make_union_storage_type(types) \ |
| 65 | + ::sus::choice_type::__private::MakeStorageType<_sus_remove_parens(types)>::type |
| 66 | + |
| 67 | +#define _sus__first(a, ...) a |
| 68 | +#define _sus__second_plus(a, ...) __VA_ARGS__ |
| 69 | + |
| 70 | +#define _sus__value_types_types(x) \ |
| 71 | + (_sus_remove_parens_and_eval(_sus__second_plus, x)) |
| 72 | +#define _sus__value_types_value(x) _sus_remove_parens_and_eval(_sus__first, x) |
0 commit comments