9#ifndef FORTRAN_COMMON_TEMPLATE_H_
10#define FORTRAN_COMMON_TEMPLATE_H_
30template <
int N,
template <
typename>
class PREDICATE,
typename TUPLE>
32 static constexpr int value() {
33 if constexpr (N >= std::tuple_size_v<TUPLE>) {
35 }
else if constexpr (PREDICATE<std::tuple_element_t<N, TUPLE>>::value()) {
38 return SearchTypeListHelper<N + 1, PREDICATE, TUPLE>::value();
43template <
template <
typename>
class PREDICATE,
typename... TYPES>
44constexpr int SearchTypeList{
50 template <
typename B>
struct Match {
51 static constexpr bool value() {
52 return std::is_same_v<std::decay_t<A>, std::decay_t<B>>;
57template <
typename A,
typename... TYPES>
58constexpr int TypeIndex{SearchTypeList<MatchType<A>::template Match, TYPES...>};
61template <
typename A,
typename... TYPES>
62constexpr bool IsTypeInList{TypeIndex<A, TYPES...> >= 0};
68template <
template <
typename...>
class T,
typename... Ts>
70 using type = T<Ts...>;
72template <
template <
typename...>
class T,
typename... Ts>
74 using type = T<Ts...>;
77template <
template <
typename...>
class T,
typename TUPLEorVARIANT>
87 template <
typename... Ts>
struct Scanner {
88 static constexpr int value() {
return SearchTypeList<PREDICATE, Ts...>; }
92template <
template <
typename>
class PREDICATE,
typename TUPLEorVARIANT>
93constexpr int SearchMembers{
94 OverMembers<SearchMembersHelper<PREDICATE>::template Scanner,
95 TUPLEorVARIANT>::value()};
97template <
typename A,
typename TUPLEorVARIANT>
98constexpr int FindMember{
99 SearchMembers<MatchType<A>::template Match, TUPLEorVARIANT>};
100template <
typename A,
typename TUPLEorVARIANT>
101constexpr bool HasMember{FindMember<A, TUPLEorVARIANT> >= 0};
105std::optional<A> JoinOptional(std::optional<std::optional<A>> &&x) {
107 return std::move(*x);
113template <
typename A>
const A *GetPtrFromOptional(
const std::optional<A> &x) {
123template <
typename TOV,
typename FROMV> TOV CopyVariant(
const FROMV &u) {
124 return common::visit([](
const auto &x) -> TOV {
return {x}; }, u);
129template <
typename TOV,
typename FROMV>
130common::IfNoLvalue<TOV, FROMV> MoveVariant(FROMV &&u) {
131 return common::visit(
132 [](
auto &&x) -> TOV {
return {std::move(x)}; }, std::move(u));
141 static decltype(
auto) f(TUPLES *...a) {
142 return std::tuple_cat(std::move(*a)...);
144 using type =
decltype(f(
static_cast<TUPLES *
>(
nullptr)...));
146template <
typename... TUPLES>
154 using type = std::tuple<Ts...>;
156template <
typename VARIANT>
160 static constexpr bool value() {
161 if constexpr (
sizeof...(REST) > 0) {
163 return ((... && !std::is_same_v<A, REST>)) &&
164 AreTypesDistinctHelper<REST...>::value();
169template <
typename... Ts>
170constexpr bool AreTypesDistinct{AreTypesDistinctHelper<Ts...>::value()};
174 static constexpr bool value() {
175 if constexpr (
sizeof...(Ts) == 0) {
179 return std::is_same_v<type, typename Rest::type> && Rest::value();
184template <
typename... Ts>
185constexpr bool AreSameType{AreSameTypeHelper<Ts...>::value()};
189 static_assert(AreTypesDistinct<Ts...>,
190 "TupleToVariant: types are not pairwise distinct");
191 using type = std::variant<Ts...>;
193template <
typename TUPLE>
197 using type = TupleToVariant<CombineTuples<VariantToTuple<VARIANTS>...>>;
199template <
typename... VARIANTS>
204template <
typename VARIANT>
205using SquashVariantOfVariants = OverMembers<CombineVariants, VARIANT>;
210template <
template <
typename>
class,
template <
typename...>
class,
typename...>
212template <
template <
typename>
class F,
template <
typename...>
class PACKAGE,
215 using type = PACKAGE<F<Ts>...>;
217template <
template <
typename>
class F,
template <
typename...>
class PACKAGE,
220 using type = PACKAGE<F<Ts>...>;
222template <
template <
typename>
class F,
typename TUPLEorVARIANT,
223 template <
typename...>
class PACKAGE = std::variant>
230template <
typename... A, std::size_t... J>
231std::optional<std::tuple<A...>> AllElementsPresentHelper(
232 std::tuple<std::optional<A>...> &&t, std::index_sequence<J...>) {
233 bool present[]{std::get<J>(t).has_value()...};
234 for (std::size_t j{0}; j <
sizeof...(J); ++j) {
239 return {std::make_tuple(*std::get<J>(t)...)};
242template <
typename... A>
243std::optional<std::tuple<A...>> AllElementsPresent(
244 std::tuple<std::optional<A>...> &&t) {
245 return AllElementsPresentHelper(
246 std::move(t), std::index_sequence_for<A...>{});
253std::optional<std::vector<A>> AllElementsPresent(
254 std::vector<std::optional<A>> &&v) {
255 for (
const auto &maybeA : v) {
260 std::vector<A> result;
261 for (
auto &&maybeA : std::move(v)) {
262 result.emplace_back(std::move(*maybeA));
270template <
typename... A>
271std::optional<std::tuple<A...>> AllPresent(std::optional<A> &&...x) {
272 return AllElementsPresent(std::make_tuple(std::move(x)...));
280template <
typename R,
typename... A>
281std::optional<R> MapOptional(
282 std::function<R(A &&...)> &&f, std::optional<A> &&...x) {
283 if (
auto args{AllPresent(std::move(x)...)}) {
284 return std::make_optional(std::apply(std::move(f), std::move(*args)));
288template <
typename R,
typename... A>
289std::optional<R> MapOptional(R (*f)(A &&...), std::optional<A> &&...x) {
290 return MapOptional(std::function<R(A && ...)>{f}, std::move(x)...);
295template <
typename Target,
template <
typename...>
class List,
typename... Ts>
298 template <
typename Current,
typename... Rest>
299 static constexpr std::size_t find_index(std::size_t current_idx) {
300 if constexpr (std::is_same_v<Target, Current>) {
302 }
else if constexpr (
sizeof...(Rest) > 0) {
303 return find_index<Rest...>(current_idx + 1);
305 static_assert(std::is_same_v<Target, Current>,
306 "Target type not found in type list!");
312 static constexpr std::size_t value = find_index<Ts...>(0);
317template <
typename Target,
typename List>
Definition bit-population-count.h:20
constexpr std::size_t type_index_v
Definition template.h:318
Definition template.h:172
Definition template.h:159
Definition template.h:140
Definition template.h:196
Definition template.h:211
Definition template.h:187
Definition template.h:152
Definition template.h:293