/*******************************************************************************
*
* TRIQS: a Toolbox for Research in Interacting Quantum Systems
*
* Copyright (C) 2013 by O. Parcollet
*
* TRIQS is free software: you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later
* version.
*
* TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* TRIQS. If not, see .
*
******************************************************************************/
#ifndef TRIQS_ARRAYS_INDEXMAP_CUBOID_GROUP_INDICES_H
#define TRIQS_ARRAYS_INDEXMAP_CUBOID_GROUP_INDICES_H
#include
namespace triqs { namespace arrays {
// a variadic push_back into a vector.
template void vector_push_back_v(V & v){}
template void vector_push_back_v(V & v, T0 && t0, T && ... t){ v.push_back(std::forward(t0)); vector_push_back_v(v,t...);}
// a list of compile time int...
template struct m_index{};
template struct m_index {static constexpr int head = I0; };
template std::vector m_index_to_vector( m_index) { std::vector v; vector_push_back_v(v,Is...); return v;}
// a trait to get the min, max of a m_index
template struct get_min_max;
template struct get_min_max> {
typedef get_min_max> r;
static constexpr int min = (I0 < r::min ? I0 : r::min); static constexpr int max = (I0 > r::max ? I0 : r::max);
};
template struct get_min_max> { static constexpr int min = I0; static constexpr int max = I0; };
// given a m_index of indices, a metafunction to map to their position into memory
template struct index_group_to_mem_pos_list;
template struct index_group_to_mem_pos_list> {
typedef m_index < indexmaps::mem_layout::index_to_memory_rank(ML,Is)...> type;
static_assert( get_min_max::max - get_min_max::min + 1 == sizeof...(Is), "Indices not contiguous in memory");
};
#ifndef TRIQS_WORKAROUND_INTEL_COMPILER_BUGS
// count the number of Is strictly smaller than C
constexpr int count_pos(int C){ return 0;}
template constexpr int count_pos(int C, int i, T... t){ return (i struct count_pos_list { typedef m_index< count_pos(Is, Is...)...> type; };
#else
template struct count_pos;
template struct count_pos> : std::integral_constant>::value + (I0 {};
template struct count_pos> : std::integral_constant{};
template struct count_pos_list { typedef m_index tmp; typedef m_index< count_pos::value...> type; };
#endif
// a simple foreach
template void for_each (Callee & C, T0 const & t0, T const & ... t ) { C(t0); for_each(C, t...);}
template void for_each (Callee & C){}
// make a permutation out of a m_index
template struct to_permu;
template struct to_permu> { static constexpr ull_t value = permutations::permutation(Is...);};
// the main class
template struct group_indices_impl {
static constexpr int new_dim = sizeof...(MIndex);
typedef typename count_pos_list< index_group_to_mem_pos_list::type::head ...>::type new_memory_pos;
static constexpr ull_t traversal_layout = to_permu::value;
typedef array_view type;
static type invoke(A const & a) {
if (a.indexmap().memory_indices_layout_ull() != a.indexmap().traversal_order)
TRIQS_RUNTIME_ERROR << "Grouping indices is only possible for arrays when the memory_layout is the same as the traversal order \n"
<< "But here your memory_layout is "<< a.indexmap().memory_indices_layout() << " while the traversal order is "<< a.indexmap().traversal_order_indices_layout();
std::vector< std::vector > Indices;
vector_push_back_v(Indices, m_index_to_vector(MIndex())...);
mini_vector l;
mini_vector s;
for (size_t u=0; u
typename group_indices_impl::type group_indices(A const & a, MIndex... ) { return group_indices_impl::invoke(a);}
}}//namespace triqs::arrays
#endif