39 template <
typename... T>
struct _triqs_zipped_tuple {
41 template <
typename... U> _triqs_zipped_tuple(U &&...u) : _tu(std::forward<U>(u)...) {}
44 template <
size_t I,
size_t... Is>
auto _get(std::index_sequence<Is...>) {
return std::tie(std::get<I>(std::get<Is>(_tu))...); }
45 template <
size_t I,
size_t... Is> [[nodiscard]]
auto _get(std::index_sequence<Is...>)
const {
46 return std::tie(std::get<I>(std::get<Is>(_tu))...);
51 template <
typename... T> _triqs_zipped_tuple<T...> zip_tuples(T &&...x) {
return {std::forward<T>(x)...}; }
59 template <
typename T0,
typename... T>
class tuple_size<triqs::_triqs_zipped_tuple<T0, T...>> :
public std::tuple_size<std::decay_t<T0>> {};
62 template <
size_t I,
typename... T>
decltype(
auto) get(triqs::_triqs_zipped_tuple<T...>
const &tu) {
63 return tu.template _get<I>(std::make_index_sequence<
sizeof...(T)>());
67 template <
typename TU>
struct _triqs_reversed_tuple {
72 template <
typename... T> _triqs_reversed_tuple<std::tuple<T...>> reverse(std::tuple<T...> &&x) {
return {std::move(x)}; }
73 template <
typename... T> _triqs_reversed_tuple<std::tuple<T...> &> reverse(std::tuple<T...> &x) {
return {x}; }
74 template <
typename... T> _triqs_reversed_tuple<std::tuple<T...>
const &> reverse(std::tuple<T...>
const &x) {
return {x}; }
77 template <
int pos,
typename TU>
decltype(
auto) get(_triqs_reversed_tuple<TU>
const &t) {
78 return std::get<std::tuple_size_v<std::decay_t<TU>> - 1 - pos>(t._x);
81 template <
int pos,
typename TU>
decltype(
auto) get(_triqs_reversed_tuple<TU> &t) {
82 return std::get<std::tuple_size_v<std::decay_t<TU>> - 1 - pos>(t._x);
85 template <
int pos,
typename TU>
decltype(
auto) get(_triqs_reversed_tuple<TU> &&t) {
86 return std::get<std::tuple_size_v<std::decay_t<TU>> - 1 - pos>(std::move(t._x));
90 template <
typename TU>
class tuple_size<_triqs_reversed_tuple<TU>> :
public tuple_size<std::decay_t<TU>> {};
94namespace triqs::tuple {
102 template <
typename T> std::make_index_sequence<std::tuple_size_v<std::decay_t<T>>> _get_seq() {
return {}; }
105 template <
typename Tu>
constexpr int _get_seq_len() {
return std::tuple_size_v<std::decay_t<Tu>>; }
108 template <
int N>
struct _int {};
111 template <
int... Is>
struct all_indices : _int<Is>... {};
114 template <
int N,
typename hole_seq,
int... Is>
struct complement_sequence_impl {
115 static complement_sequence_impl<N - 1, hole_seq, Is...> get(_int<N>) {}
116 static complement_sequence_impl<N - 1, hole_seq, N, Is...> get(...) {}
117 using type =
typename decltype(get(hole_seq()))::type;
121 template <
typename hole_seq,
int... Is>
struct complement_sequence_impl<-1, hole_seq, Is...> {
122 using type = std::index_sequence<Is...>;
126 template <
int N,
int... Is>
using complement_sequence =
typename complement_sequence_impl<N, all_indices<Is...>>::type;
129 template <
typename T, std::size_t... Is>
auto make_tuple_repeat_impl(T
const &x, std::index_sequence<Is...>) {
130 return std::make_tuple(((
void)Is, x)...);
141 template <
int N,
typename X>
auto make_tuple_repeat(X
const &x) {
return make_tuple_repeat_impl(x, std::make_index_sequence<N>()); }
144 template <
typename F,
typename T,
size_t... Is>
decltype(
auto) apply_impl(F &&f, T &&t, std::index_sequence<Is...>) {
145 return std::forward<F>(f)(std::get<Is>(std::forward<T>(t))...);
159 template <
typename F,
typename T>
decltype(
auto)
apply(F &&f, T &&t) {
return apply_impl(std::forward<F>(f), std::forward<T>(t), _get_seq<T>()); }
162 template <
typename C,
typename T,
size_t... Is>
decltype(
auto) apply_construct_impl(T &&t, std::index_sequence<Is...>) {
163 return C{std::get<Is>(std::forward<T>(t))...};
174 template <
typename C,
typename T>
decltype(
auto)
apply_construct(T &&t) {
return apply_construct_impl<C>(std::forward<T>(t), _get_seq<T>()); }
177 template <
typename C,
typename T,
size_t... Is>
decltype(
auto) apply_construct_parenthesis_impl(T &&t, std::index_sequence<Is...>) {
178 return C(std::get<Is>(std::forward<T>(t))...);
190 return apply_construct_parenthesis_impl<C>(std::forward<T>(t), _get_seq<T>());
194 template <
typename F>
struct _called_on_tuple {
196 template <
typename Tu>
decltype(
auto)
operator()(Tu &&tu) {
return triqs::tuple::apply(_f, std::forward<Tu>(tu)); }
206 template <
typename F>
auto called_on_tuple(F &&f) {
return _called_on_tuple<F>{std::forward<F>(f)}; }
209 template <
typename F>
void _for_each_impl(F &&) {}
212 template <
typename F,
typename T0,
typename... T>
void _for_each_impl(F &&f, T0 &&x0, T &&...x) {
213 f(std::forward<T0>(x0));
214 _for_each_impl(f, std::forward<T>(x)...);
218 template <
typename F>
void _for_each_apply_impl(F &&) {}
221 template <
typename F,
typename T0,
typename... T>
void _for_each_apply_impl(F &&f, T0 &&t0, T &&...t) {
223 _for_each_apply_impl(f, std::forward<T>(t)...);
227 template <
typename F,
typename T,
size_t... Is>
void for_each_impl(F &&f, T &&t, std::index_sequence<Is...>) {
228 _for_each_impl(f, std::get<Is>(t)...);
239 template <
typename T,
typename F>
void for_each(T &&t, F &&f) { for_each_impl(std::forward<F>(f), std::forward<T>(t), _get_seq<T>()); }
242 template <
typename F,
typename T,
size_t... Is>
void _for_each_enum_impl(F &&f, T &&t, std::index_sequence<Is...>) {
243 _for_each_apply_impl(f, std::tuple<
int,
decltype(std::get<Is>(t))>(Is, std::get<Is>(t))...);
257 _for_each_enum_impl(std::forward<F>(f), std::forward<T>(t), _get_seq<T>());
270 template <
typename F,
typename... Ts>
void for_each_zip(F &&f, Ts &&...ts) {
275 template <
typename F,
typename T,
size_t... Is>
decltype(
auto) _map_impl(F &&f, T &&t, std::index_sequence<Is...>) {
276 return std::make_tuple(std::forward<F>(f)(std::get<Is>(std::forward<T>(t)))...);
288 template <
typename F,
typename T>
decltype(
auto)
map(F &&f, T &&t) {
return _map_impl(std::forward<F>(f), std::forward<T>(t), _get_seq<T>()); }
299 template <
typename... Ts,
typename F>
auto map_on_zip(F &&f, Ts &&...ts) {
304 template <
int pos,
typename F,
typename T,
typename R>
decltype(
auto) fold_impl(_int<pos>, F &&f, T &&t, R &&r) {
305 return fold_impl(_int<pos - 1>(), std::forward<F>(f), std::forward<T>(t), f(std::get<_get_seq_len<T>() - 1 - pos>(t), std::forward<R>(r)));
309 template <
typename F,
typename T,
typename R> R fold_impl(_int<-1>, F &&, T &&, R &&r) {
return std::forward<R>(r); }
324 template <
typename F,
typename T,
typename R>
decltype(
auto)
fold(F &&f, T &&t, R &&r) {
325 return fold_impl(_int<_get_seq_len<T>() - 1>(), std::forward<F>(f), std::forward<T>(t), std::forward<R>(r));
329 template <
int pos,
typename F,
typename T0,
typename T1,
typename R>
decltype(
auto) fold_impl(_int<pos>, F &&f, T0 &&t0, T1 &&t1, R &&r) {
330 constexpr int n = _get_seq_len<T0>() - 1 - pos;
331 return fold_impl(_int<pos - 1>(), std::forward<F>(f), std::forward<T0>(t0), std::forward<T1>(t1),
332 f(std::get<n>(t0), std::get<n>(t1), std::forward<R>(r)));
336 template <
typename F,
typename T0,
typename T1,
typename R> R fold_impl(_int<-1>, F &&, T0 &&, T1 &&, R &&r) {
return std::forward<R>(r); }
354 template <
typename F,
typename T0,
typename T1,
typename R>
decltype(
auto)
fold(F &&f, T0 &&t1, T1 &&t2, R &&r) {
355 return fold_impl(_int<_get_seq_len<T0>() - 1>(), std::forward<F>(f), std::forward<T0>(t1), std::forward<T1>(t2), std::forward<R>(r));
359 template <
int I,
typename T,
typename R> R _get_rpl(T &&, R &&r, _int<I>) {
return std::forward<R>(r); }
363 template <
int I,
typename T,
typename R> T _get_rpl(T &&x, R &&, ...) {
return std::forward<T>(x); }
366 template <
size_t... Is,
typename Tu,
typename R,
typename AllIndices>
367 auto _replace_impl(Tu &&tu, R &&r, AllIndices _,
368 std::index_sequence<Is...>) {
369 return std::make_tuple(_get_rpl<Is>(std::get<Is>(tu), r, _)...);
382 template <
int... Is,
typename T,
typename R>
auto replace(T &&t, R &&r) {
383 return _replace_impl(std::forward<T>(t), std::forward<R>(r), all_indices<Is...>(), _get_seq<T>());
392 template <
typename T,
size_t... Is>
using filter_t = std::tuple<std::tuple_element_t<Is, std::decay_t<T>>...>;
402 template <
size_t... Is,
typename T>
filter_t<T, Is...>
filter(T &&t) {
return filter_t<T, Is...>(std::get<Is>(std::forward<T>(t))...); }
412 template <
size_t... Is,
typename T>
filter_t<T, Is...>
filter(T &&t, std::index_sequence<Is...>) {
413 return filter_t<T, Is...>(std::get<Is>(std::forward<T>(t))...);
424 template <
int... Is,
typename T>
decltype(
auto)
filter_out(T &&t) {
445 template <
typename T,
typename X>
auto push_back(T &&t, X &&x) {
return std::tuple_cat(std::forward<T>(t), std::make_tuple(std::forward<X>(x))); }
456 template <
typename T,
typename X>
auto push_front(T &&t, X &&x) {
return std::tuple_cat(std::make_tuple(std::forward<X>(x)), std::forward<T>(t)); }
486 template <
typename... T> std::ostream &
operator<<(std::ostream &os, std::tuple<T...>
const &t) {
504 template <
typename T1,
typename T2> std::ostream &
operator<<(std::ostream &os, std::pair<T1, T2>
const &x) {
505 return os <<
'(' << x.first <<
", " << x.second <<
')';
std::ostream & operator<<(std::ostream &os, std::tuple< T... > const &t)
Write a std::tuple to an output stream.
void for_each(T &&t, F &&f)
Apply a callable to every element of a tuple, in order.
void for_each_zip(F &&f, Ts &&...ts)
Apply an N-ary callable across tuples zipped together.
typename complement_sequence_impl< N, all_indices< Is... > >::type complement_sequence
Index sequence containing all integers of that are not in Is....
auto make_tuple_repeat(X const &x)
Build a tuple with copies of a value.
std::decay_t< decltype(filter_out< Is... >(std::declval< T >()))> filter_out_t
Result type of filter_out() for tuple type T dropping positions Is....
decltype(auto) apply_construct_parenthesis(T &&t)
Parenthesis-construct an object from the elements of a tuple.
filter_t< T, Is... > filter(T &&t)
Keep only the elements of a tuple at the given positions.
std::tuple< std::tuple_element_t< Is, std::decay_t< T > >... > filter_t
Tuple type made of the elements at the given positions of given tuple type T.
decltype(auto) apply_construct(T &&t)
Brace-construct an object from the elements of a tuple.
auto called_on_tuple(F &&f)
Wrap a callable so that it can be invoked with a single tuple argument.
decltype(auto) filter_out(T &&t)
Drop the elements of a tuple at the given positions.
auto push_front(T &&t, X &&x)
Prepend an element to the front of a tuple.
decltype(auto) fold(F &&f, T &&t, R &&r)
Left-fold a callable over the elements of a tuple.
decltype(auto) map(F &&f, T &&t)
Map a callable over the elements of a tuple.
decltype(auto) apply(F &&f, T &&t)
Call a function with the elements of a tuple as its arguments.
auto replace(T &&t, R &&r)
Return a copy of a tuple with the elements at the given positions replaced by a given value.
auto map_on_zip(F &&f, Ts &&...ts)
Map an N-ary callable across N tuples zipped together.
auto push_back(T &&t, X &&x)
Append an element to the end of a tuple.
auto pop_front(T &&t)
Remove the first element of a tuple.
void for_each_enumerate(T &&t, F &&f)
Apply a callable to every (index, element) pair of a tuple.
Common macros used in TRIQS.