9#ifndef FORTRAN_COMMON_TEMPLATE_H_
10#define FORTRAN_COMMON_TEMPLATE_H_
13#include "flang/Common/idioms.h"
29template <
int N,
template <
typename>
class PREDICATE,
typename TUPLE>
31 static constexpr int value() {
32 if constexpr (N >= std::tuple_size_v<TUPLE>) {
34 }
else if constexpr (PREDICATE<std::tuple_element_t<N, TUPLE>>::value()) {
42template <
template <
typename>
class PREDICATE,
typename... TYPES>
43constexpr int SearchTypeList{
49 template <
typename B>
struct Match {
50 static constexpr bool value() {
51 return std::is_same_v<std::decay_t<A>, std::decay_t<B>>;
56template <
typename A,
typename... TYPES>
57constexpr int TypeIndex{SearchTypeList<MatchType<A>::template Match, TYPES...>};
60template <
typename A,
typename... TYPES>
61constexpr bool IsTypeInList{TypeIndex<A, TYPES...> >= 0};
67template <
template <
typename...>
class T,
typename... Ts>
69 using type = T<Ts...>;
71template <
template <
typename...>
class T,
typename... Ts>
73 using type = T<Ts...>;
76template <
template <
typename...>
class T,
typename TUPLEorVARIANT>
86 template <
typename... Ts>
struct Scanner {
87 static constexpr int value() {
return SearchTypeList<PREDICATE, Ts...>; }
91template <
template <
typename>
class PREDICATE,
typename TUPLEorVARIANT>
92constexpr int SearchMembers{
93 OverMembers<SearchMembersHelper<PREDICATE>::template Scanner,
94 TUPLEorVARIANT>::value()};
96template <
typename A,
typename TUPLEorVARIANT>
97constexpr int FindMember{
98 SearchMembers<MatchType<A>::template Match, TUPLEorVARIANT>};
99template <
typename A,
typename TUPLEorVARIANT>
100constexpr bool HasMember{FindMember<A, TUPLEorVARIANT> >= 0};
104std::optional<A> JoinOptional(std::optional<std::optional<A>> &&x) {
106 return std::move(*x);
112template <
typename A>
const A *GetPtrFromOptional(
const std::optional<A> &x) {
122template <
typename TOV,
typename FROMV> TOV CopyVariant(
const FROMV &u) {
123 return common::visit([](
const auto &x) -> TOV {
return {x}; }, u);
128template <
typename TOV,
typename FROMV>
129common::IfNoLvalue<TOV, FROMV> MoveVariant(FROMV &&u) {
130 return common::visit(
131 [](
auto &&x) -> TOV {
return {std::move(x)}; }, std::move(u));
140 static decltype(
auto) f(TUPLES *...a) {
141 return std::tuple_cat(std::move(*a)...);
143 using type =
decltype(f(
static_cast<TUPLES *
>(
nullptr)...));
145template <
typename... TUPLES>
153 using type = std::tuple<Ts...>;
155template <
typename VARIANT>
159 static constexpr bool value() {
160 if constexpr (
sizeof...(REST) > 0) {
162 return ((... && !std::is_same_v<A, REST>)) &&
168template <
typename... Ts>
173 static constexpr bool value() {
174 if constexpr (
sizeof...(Ts) == 0) {
178 return std::is_same_v<type, typename Rest::type> && Rest::value();
183template <
typename... Ts>
188 static_assert(AreTypesDistinct<Ts...>,
189 "TupleToVariant: types are not pairwise distinct");
190 using type = std::variant<Ts...>;
192template <
typename TUPLE>
196 using type = TupleToVariant<CombineTuples<VariantToTuple<VARIANTS>...>>;
198template <
typename... VARIANTS>
203template <
typename VARIANT>
204using SquashVariantOfVariants = OverMembers<CombineVariants, VARIANT>;
209template <
template <
typename>
class,
template <
typename...>
class,
typename...>
211template <
template <
typename>
class F,
template <
typename...>
class PACKAGE,
214 using type = PACKAGE<F<Ts>...>;
216template <
template <
typename>
class F,
template <
typename...>
class PACKAGE,
219 using type = PACKAGE<F<Ts>...>;
221template <
template <
typename>
class F,
typename TUPLEorVARIANT,
222 template <
typename...>
class PACKAGE = std::variant>
229template <
typename... A, std::size_t... J>
230std::optional<std::tuple<A...>> AllElementsPresentHelper(
231 std::tuple<std::optional<A>...> &&t, std::index_sequence<J...>) {
232 bool present[]{std::get<J>(t).has_value()...};
233 for (std::size_t j{0}; j <
sizeof...(J); ++j) {
238 return {std::make_tuple(*std::get<J>(t)...)};
241template <
typename... A>
242std::optional<std::tuple<A...>> AllElementsPresent(
243 std::tuple<std::optional<A>...> &&t) {
244 return AllElementsPresentHelper(
245 std::move(t), std::index_sequence_for<A...>{});
252std::optional<std::vector<A>> AllElementsPresent(
253 std::vector<std::optional<A>> &&v) {
254 for (
const auto &maybeA : v) {
259 std::vector<A> result;
260 for (
auto &&maybeA : std::move(v)) {
261 result.emplace_back(std::move(*maybeA));
269template <
typename... A>
270std::optional<std::tuple<A...>> AllPresent(std::optional<A> &&...x) {
271 return AllElementsPresent(std::make_tuple(std::move(x)...));
279template <
typename R,
typename... A>
280std::optional<R> MapOptional(
281 std::function<R(A &&...)> &&f, std::optional<A> &&...x) {
282 if (
auto args{AllPresent(std::move(x)...)}) {
283 return std::make_optional(std::apply(std::move(f), std::move(*args)));
287template <
typename R,
typename... A>
288std::optional<R> MapOptional(R (*f)(A &&...), std::optional<A> &&...x) {
289 return MapOptional(std::function<R(A && ...)>{f}, std::move(x)...);
302template <std::
size_t J,
typename VISITOR>
303common::IfNoLvalue<typename VISITOR::Result, VISITOR> SearchTypesHelper(
304 VISITOR &&visitor,
typename VISITOR::Result &&defaultResult) {
305 using Tuple =
typename VISITOR::Types;
306 if constexpr (J < std::tuple_size_v<Tuple>) {
307 if (
auto result{visitor.template Test<std::tuple_element_t<J, Tuple>>()}) {
310 return SearchTypesHelper<J + 1, VISITOR>(
311 std::move(visitor), std::move(defaultResult));
313 return std::move(defaultResult);
317template <
typename VISITOR>
318common::IfNoLvalue<typename VISITOR::Result, VISITOR> SearchTypes(
320 typename VISITOR::Result defaultResult =
typename VISITOR::Result{}) {
321 return SearchTypesHelper<0, VISITOR>(
322 std::move(visitor), std::move(defaultResult));
Definition: bit-population-count.h:20
Definition: template.h:171
Definition: template.h:158
Definition: template.h:139
Definition: template.h:195
Definition: template.h:210
Definition: template.h:49
Definition: template.h:48
Definition: template.h:66
Definition: template.h:86
Definition: template.h:85
Definition: template.h:30
Definition: template.h:186
Definition: template.h:151