mirror of
https://github.com/triqs/dft_tools
synced 2024-10-31 19:23:45 +01:00
implement array_const_view
This commit is contained in:
parent
6a140d2950
commit
9002c1e456
@ -1,47 +0,0 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "./common.hpp"
|
||||
#include "./src/array.hpp"
|
||||
#include <iostream>
|
||||
|
||||
//using std::cout; using std::endl;
|
||||
using namespace triqs::arrays;
|
||||
#include <type_traits>
|
||||
|
||||
|
||||
template<typename U, ull_t opt, ull_t to, bool B>
|
||||
void f (array_const_view<U,2,opt,to,B> const & a) {
|
||||
std::cout << a << std::endl ;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
array<long,2 > A (2,3);
|
||||
A() =3;
|
||||
|
||||
f(A());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
using namespace triqs::arrays;
|
||||
|
||||
void f( array_view<long,2> & A, long u) {
|
||||
void f( array_view<long,2> A, long u) {
|
||||
A(0,0) = u;
|
||||
}
|
||||
|
||||
|
@ -24,18 +24,37 @@
|
||||
|
||||
using namespace triqs::arrays;
|
||||
|
||||
|
||||
template <typename U, ull_t opt, ull_t to, bool B> void f(array_view<U, 2, opt, to, B, true> const &a) {
|
||||
std::cout << a << std::endl;
|
||||
}
|
||||
|
||||
void f2(array_const_view<long, 2> const &a) { std::cout << a << std::endl; }
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
const array<long,1> A = {1,2,3,4};
|
||||
{
|
||||
array<long, 2> A(2, 3);
|
||||
A() = 3;
|
||||
auto const &AA = A;
|
||||
f2(A());
|
||||
|
||||
std::cerr << A.opt_flags<<std::endl;
|
||||
std::cerr << A().opt_flags<<std::endl;
|
||||
|
||||
// None of this should compile
|
||||
//A(0) = 2;
|
||||
//A()(0) = 2;
|
||||
//A(range(0,2))(0) = 10;
|
||||
array_const_view<long,2> Vc = A();
|
||||
//array_view<long,2> V = Vc;
|
||||
}
|
||||
|
||||
//#define SHOULD_NOT_COMPILE
|
||||
#ifdef SHOULD_NOT_COMPILE
|
||||
{
|
||||
const array<long, 1> A = {1, 2, 3, 4};
|
||||
|
||||
// None of this should compile
|
||||
A(0) = 2;
|
||||
A()(0) = 2;
|
||||
A(range(0,2))(0) = 10;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ auto bad (array<long,1> const & a) DECL_AND_RETURN (a(range(0,3)));
|
||||
|
||||
auto bad2 (array<long,1> const & a) DECL_AND_RETURN (a(0));
|
||||
|
||||
array_view<long,1> good(array<long,1> const & a) {return a(range(0,3));}
|
||||
array_const_view<long,1> good(array<long,1> const & a) {return a(range(0,3));}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -15,7 +15,7 @@ int main() {
|
||||
// test hdf5
|
||||
H5::H5File file("gf_scalar.h5", H5F_ACC_TRUNC);
|
||||
h5_write(file, "g", G);
|
||||
h5_write(file, "gm", reinterpret_scalar_valued_gf_as_matrix_valued(G));
|
||||
h5_write(file, "gm", reinterpret_scalar_valued_gf_as_matrix_valued(G()));
|
||||
|
||||
}
|
||||
TRIQS_CATCH_AND_ABORT;
|
||||
|
@ -29,7 +29,7 @@ int main() {
|
||||
TEST( G( 0) ) ;
|
||||
Gv.on_mesh(0) = 0;
|
||||
|
||||
auto Gv2 = slice_target(G,range(0,1),range(0,1));
|
||||
auto Gv2 = slice_target(G(),range(0,1),range(0,1));
|
||||
TEST( Gv2( 0) ) ;
|
||||
Gv2.on_mesh(0) = 10;
|
||||
TEST( Gv2( 0) ) ;
|
||||
|
@ -28,32 +28,36 @@
|
||||
#include "impl/flags.hpp"
|
||||
namespace triqs { namespace arrays {
|
||||
|
||||
template <typename ValueType, int Rank, ull_t Opt=0, ull_t TraversalOrder= 0, bool Borrowed=false > class array_view;
|
||||
template <typename ValueType, int Rank, ull_t Opt=0, ull_t TraversalOrder= 0, bool Borrowed=false, bool IsConst=false > class array_view;
|
||||
template <typename ValueType, int Rank, ull_t Opt=0, ull_t TraversalOrder= 0> class array;
|
||||
|
||||
// ---------------------- array_view --------------------------------
|
||||
|
||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<Rank,Opt,TraversalOrder>, \
|
||||
storages::shared_block<ValueType, Borrowed>, Opt, TraversalOrder, Tag::array_view >
|
||||
storages::shared_block<ValueType, Borrowed>, Opt, TraversalOrder, IsConst, Tag::array_view >
|
||||
|
||||
template <typename ValueType, int Rank, ull_t Opt, ull_t TraversalOrder, bool Borrowed>
|
||||
class array_view : Tag::array_view, TRIQS_CONCEPT_TAG_NAME(MutableArray), public IMPL_TYPE {
|
||||
template <typename ValueType, int Rank, ull_t Opt, ull_t TraversalOrder, bool Borrowed, bool IsConst>
|
||||
class array_view: Tag::array_view, TRIQS_CONCEPT_TAG_NAME(MutableArray), public IMPL_TYPE {
|
||||
static_assert( Rank>0, " Rank must be >0");
|
||||
public:
|
||||
typedef typename IMPL_TYPE::indexmap_type indexmap_type;
|
||||
typedef typename IMPL_TYPE::storage_type storage_type;
|
||||
typedef array <ValueType,Rank,Opt,TraversalOrder> regular_type;
|
||||
typedef array_view<ValueType,Rank,Opt,TraversalOrder> view_type;
|
||||
typedef array_view<ValueType, Rank, Opt, TraversalOrder, false, true> const_view_type;
|
||||
typedef array_view<ValueType,Rank,Opt,TraversalOrder,true> weak_view_type;
|
||||
|
||||
/// Build from an IndexMap and a storage
|
||||
template<typename S> array_view (indexmap_type const & Ind,S const & Mem): IMPL_TYPE(Ind, Mem) {}
|
||||
template <typename S> array_view(indexmap_type const& Ind, S const& Mem) : IMPL_TYPE(Ind, Mem) {}
|
||||
|
||||
/// Copy constructor
|
||||
array_view(array_view const & X): IMPL_TYPE(X.indexmap(),X.storage()) {}
|
||||
|
||||
/// Build from anything that has an indexmap and a storage compatible with this class
|
||||
template<typename ISP> array_view(const ISP & X): IMPL_TYPE(X.indexmap(),X.storage()) {}
|
||||
template<typename ISP> array_view(const ISP & X): IMPL_TYPE(X.indexmap(),X.storage()) {
|
||||
// to be activated
|
||||
static_assert(IsConst || (!ISP::is_const), "Can not construct a non const view from a const one !");
|
||||
}
|
||||
|
||||
#ifdef TRIQS_WITH_PYTHON_SUPPORT
|
||||
/// Build from a numpy.array (X is a borrowed reference) : throws if X is not a numpy.array
|
||||
@ -88,12 +92,12 @@ namespace triqs { namespace arrays {
|
||||
#undef IMPL_TYPE
|
||||
|
||||
template <typename ValueType, int Rank, ull_t Opt=0, ull_t TraversalOrder=0, bool Borrowed=false>
|
||||
using array_const_view = array_view<ValueType, Rank, Opt, TraversalOrder, Borrowed>;
|
||||
using array_const_view = array_view<ValueType, Rank, Opt, TraversalOrder, Borrowed, true>;
|
||||
|
||||
//------------------------------- array ---------------------------------------------------
|
||||
|
||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<Rank,Opt,TraversalOrder>, \
|
||||
storages::shared_block<ValueType>, Opt, TraversalOrder, Tag::array_view >
|
||||
storages::shared_block<ValueType>, Opt, TraversalOrder, false, Tag::array_view >
|
||||
|
||||
template <typename ValueType, int Rank, ull_t Opt, ull_t TraversalOrder>
|
||||
class array: Tag::array, TRIQS_CONCEPT_TAG_NAME(MutableArray), public IMPL_TYPE {
|
||||
@ -101,9 +105,10 @@ namespace triqs { namespace arrays {
|
||||
typedef typename IMPL_TYPE::value_type value_type;
|
||||
typedef typename IMPL_TYPE::storage_type storage_type;
|
||||
typedef typename IMPL_TYPE::indexmap_type indexmap_type;
|
||||
typedef array <ValueType,Rank,Opt,TraversalOrder> regular_type;
|
||||
typedef array_view<ValueType,Rank,Opt,TraversalOrder> view_type;
|
||||
typedef array_view<ValueType,Rank,Opt,TraversalOrder,true> weak_view_type;
|
||||
typedef array<ValueType, Rank, Opt, TraversalOrder> regular_type;
|
||||
typedef array_view<ValueType, Rank, Opt, TraversalOrder> view_type;
|
||||
typedef array_view<ValueType, Rank, Opt, TraversalOrder, false, true> const_view_type;
|
||||
typedef array_view<ValueType, Rank, Opt, TraversalOrder, true> weak_view_type;
|
||||
|
||||
/// Empty array.
|
||||
explicit array(memory_layout<Rank> ml = memory_layout<Rank>(IMPL_TYPE::indexmap_type::traversal_order)) :IMPL_TYPE(ml){}
|
||||
@ -206,16 +211,16 @@ namespace triqs { namespace arrays {
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// how to build the view type ....
|
||||
template < class V, int R, ull_t Opt, ull_t TraversalOrder, bool Borrowed >
|
||||
struct ISPViewType< V, R, Opt, TraversalOrder,Tag::array_view, Borrowed> { typedef array_view<V,R,Opt,TraversalOrder, Borrowed> type; };
|
||||
template < class V, int R, ull_t Opt, ull_t TraversalOrder, bool Borrowed, bool IsConst >
|
||||
struct ISPViewType< V, R, Opt, TraversalOrder,Tag::array_view, Borrowed,IsConst> { typedef array_view<V,R,Opt,TraversalOrder, Borrowed,IsConst> type; };
|
||||
|
||||
}}//namespace triqs::arrays
|
||||
|
||||
// The std::swap is WRONG for a view because of the copy/move semantics of view.
|
||||
// Use swap instead (the correct one, found by ADL).
|
||||
namespace std {
|
||||
template <typename V, int R, triqs::ull_t Opt, triqs::ull_t To, bool B1, bool B2>
|
||||
void swap( triqs::arrays::array_view<V,R,Opt,To,B1> & a , triqs::arrays::array_view<V,R,Opt,To,B2> & b)= delete;
|
||||
template <typename V, int R, triqs::ull_t Opt, triqs::ull_t To, bool B1, bool B2, bool C1, bool C2>
|
||||
void swap( triqs::arrays::array_view<V,R,Opt,To,B1,C1> & a , triqs::arrays::array_view<V,R,Opt,To,B2,C2> & b)= delete;
|
||||
}
|
||||
|
||||
#include "./expression_template/array_algebra.hpp"
|
||||
|
@ -45,20 +45,19 @@ namespace triqs { namespace arrays {
|
||||
template<typename A1, typename A2, typename Enable =void > struct need_copy_ct : mpl::true_{};
|
||||
template<typename A1, typename A2> struct need_copy_ct<A1,A2, ENABLE_IF(is_amv_value_or_view_class<A1>)> :
|
||||
mpl::not_<std::is_same< typename A1::value_type, typename A2::value_type> > {};
|
||||
//mpl::not_<indexmaps::IndexOrder::same_order<typename A1::indexmap_type::index_order_type, typename A2::indexmap_type::index_order_type> >{};
|
||||
|
||||
template<typename DataType, typename CacheType> class const_cache {
|
||||
template<typename DataType, typename CacheType, bool IsConst> class cache_impl {
|
||||
protected:
|
||||
typedef memory_layout< DataType::domain_type::rank> ml_t;
|
||||
const ml_t ml;
|
||||
typename view_type_if_exists_else_type<DataType>::type keeper;
|
||||
typename std::conditional<IsConst, typename const_view_type_if_exists_else_type<DataType>::type, typename view_type_if_exists_else_type<DataType>::type>::type keeper;
|
||||
static const bool CT_need_copy = need_copy_ct<DataType,CacheType>::value;
|
||||
const bool need_copy;
|
||||
typedef typename CacheType::view_type exposed_view_type;
|
||||
typedef typename std::conditional<IsConst, typename CacheType::const_view_type, typename CacheType::view_type>::type exposed_view_type;
|
||||
struct internal_data {
|
||||
CacheType copy;
|
||||
exposed_view_type view;
|
||||
internal_data(const_cache const & P,ml_t ml) : copy(CacheType(P.keeper,ml)), view(copy) {
|
||||
internal_data(cache_impl const & P,ml_t ml) : copy(CacheType(P.keeper,ml)), view(copy) {
|
||||
#ifdef TRIQS_ARRAYS_CACHE_COPY_VERBOSE
|
||||
std::cerr<< " Cache : copy made "<< std::endl<< " -- TRACE = --" << std::endl << triqs::utility::stack_trace() << std::endl;
|
||||
#endif
|
||||
@ -68,18 +67,10 @@ namespace triqs { namespace arrays {
|
||||
mutable std::shared_ptr<internal_data> _id;
|
||||
internal_data & id() const { if (!_id) _id= std::make_shared<internal_data>(*this,ml); return *_id;}
|
||||
|
||||
//exposed_view_type & view2 () { if (need_copy) return id().view; else return keeper;}
|
||||
//exposed_view_type const & view2 () const { if (need_copy) return id().view; else return keeper;}
|
||||
|
||||
// avoid compiling the transformation keeper-> exposed_view_type when it does not make sense
|
||||
exposed_view_type & view1 (mpl::false_) { if (need_copy) return id().view; else return keeper; }
|
||||
exposed_view_type const & view1 (mpl::false_) const { if (need_copy) return id().view; else return keeper;}
|
||||
|
||||
exposed_view_type & view1 (mpl::true_) { return id().view; }
|
||||
exposed_view_type const & view1 (mpl::true_) const { return id().view; }
|
||||
|
||||
exposed_view_type & view2 () { return view1(mpl::bool_<CT_need_copy>());}
|
||||
exposed_view_type const & view2 () const { return view1(mpl::bool_<CT_need_copy>());}
|
||||
exposed_view_type view1 (mpl::false_) const { if (need_copy) return id().view; else return keeper;}
|
||||
exposed_view_type view1 (mpl::true_) const { return id().view; }
|
||||
exposed_view_type view2 () const { return view1(mpl::bool_<CT_need_copy>());}
|
||||
|
||||
template<typename D>
|
||||
typename std::enable_if< ! is_amv_value_or_view_class<D>::value, bool>::type
|
||||
@ -90,27 +81,31 @@ namespace triqs { namespace arrays {
|
||||
need_copy_dynamic ( D const & x) const { return (x.indexmap().memory_indices_layout() != ml );}
|
||||
|
||||
public :
|
||||
const_cache (DataType const & x, ml_t ml_ = ml_t()):
|
||||
cache_impl (DataType const & x, ml_t ml_ = ml_t()):
|
||||
ml(ml_),keeper (x),
|
||||
need_copy ( CT_need_copy || need_copy_dynamic(x) || (!has_contiguous_data(x)) ) {}
|
||||
void update() { if (need_copy && _id) id().view = keeper;}
|
||||
exposed_view_type const & view () const { return view2();}
|
||||
operator exposed_view_type const & () const { return view2();}
|
||||
exposed_view_type view () const { return view2();}
|
||||
operator exposed_view_type () const { return view2();}
|
||||
};
|
||||
|
||||
// Const case : just add the back copy in the destructor
|
||||
template<typename DataType, typename CacheType> class const_cache : public cache_impl<DataType,CacheType,true> {
|
||||
typedef cache_impl<DataType,CacheType,true> B;
|
||||
typedef typename B::ml_t ml_t;
|
||||
public :
|
||||
const_cache (DataType const & x, ml_t ml = ml_t() ): B(x,ml) {}
|
||||
};
|
||||
|
||||
// Non const case : just add the back copy in the destructor
|
||||
template<typename DataType, typename CacheType> class cache : const_cache<DataType,CacheType> {
|
||||
template<typename DataType, typename CacheType> class cache : public cache_impl<DataType,CacheType,false> {
|
||||
static_assert( is_amv_value_or_view_class<DataType>::value, "non const cache only for regular classes and views, not expressions");
|
||||
typedef const_cache<DataType,CacheType> B;
|
||||
typedef cache_impl<DataType,CacheType,false> B;
|
||||
typedef typename B::ml_t ml_t;
|
||||
public :
|
||||
cache (DataType const & x, ml_t ml = ml_t() ): B(x,ml) {}
|
||||
~cache() { back_update(); }
|
||||
void back_update() { if (this->need_copy) this->keeper = this->id().view;}
|
||||
typename B::exposed_view_type & view () {return B::view2();}
|
||||
typename B::exposed_view_type const & view () const {return B::view2();}
|
||||
operator typename B::exposed_view_type & () {return B::view2();}
|
||||
operator typename B::exposed_view_type const & () const {return B::view2();}
|
||||
};
|
||||
}}//namespace triqs::arrays
|
||||
#endif
|
||||
|
@ -28,6 +28,7 @@
|
||||
namespace triqs { namespace arrays {
|
||||
namespace h5_impl {
|
||||
|
||||
template <typename T, int R> const void * get_array_data_cptr ( array_const_view<T,R> const & A) { return h5::get_data_ptr(&(A.storage()[0]));}
|
||||
template <typename T, int R> const void * get_array_data_cptr ( array_view<T,R> const & A) { return h5::get_data_ptr(&(A.storage()[0]));}
|
||||
template <typename T, int R> const void * get_array_data_cptr ( array<T,R> const & A) { return h5::get_data_ptr(&(A.storage()[0]));}
|
||||
//template <typename T, int R> void * get_array_data_ptr ( array_view<T,R> & A) { return h5::get_data_ptr(&(A.storage()[0]));}
|
||||
@ -76,7 +77,7 @@ namespace triqs { namespace arrays {
|
||||
* \exception The HDF5 exceptions will be caught and rethrown as TRIQS_RUNTIME_ERROR (with a full stackstrace, cf triqs doc).
|
||||
*/
|
||||
template <typename T, int R>
|
||||
void write_array (h5::group g, std::string const & name, array_view <T,R> const & A, bool C_reorder = true) {
|
||||
void write_array (h5::group g, std::string const & name, array_const_view <T,R> const & A, bool C_reorder = true) {
|
||||
static_assert( !std::is_base_of<std::string, T>::value, " Not implemented");// 1d is below
|
||||
if (C_reorder) { write_array(g,name, make_const_cache(A).view(),false); return; }
|
||||
try {
|
||||
@ -90,6 +91,8 @@ namespace triqs { namespace arrays {
|
||||
|
||||
template <typename T, int R>
|
||||
void write_array (h5::group g, std::string const & name, array <T,R> const & A, bool C_reorder = true) { write_array(g,name,A(),C_reorder);}
|
||||
template <typename T, int R>
|
||||
void write_array (h5::group g, std::string const & name, array_view <T,R> const & A, bool C_reorder = true) { write_array(g,name,A(),C_reorder);}
|
||||
|
||||
/*********************************** READ array ****************************************************************/
|
||||
/**
|
||||
@ -102,8 +105,9 @@ namespace triqs { namespace arrays {
|
||||
* cache of the data to reorder them in memory. If false, the array is stored as it [if you know what you are doing]
|
||||
* \exception The HDF5 exceptions will be caught and rethrown as TRIQS_RUNTIME_ERROR (with a full stackstrace, cf triqs doc).
|
||||
*/
|
||||
template <typename ArrayType>
|
||||
void read_array (h5::group g, std::string const & name, ArrayType & A, bool C_reorder = true) {
|
||||
template <typename ArrayType1>
|
||||
void read_array (h5::group g, std::string const & name, ArrayType1 && A, bool C_reorder = true) {
|
||||
typedef typename std::remove_reference<ArrayType1>::type ArrayType;
|
||||
static_assert( !std::is_base_of<std::string, typename ArrayType::value_type>::value, " Not implemented");// 1d is below
|
||||
typedef typename ArrayType::value_type V;
|
||||
try {
|
||||
@ -127,12 +131,12 @@ namespace triqs { namespace arrays {
|
||||
}
|
||||
|
||||
// overload : special treatment for arrays of strings (one dimension only).
|
||||
inline void write_array (h5::group f, std::string const & name, vector_view<std::string> const & V) {
|
||||
inline void write_array (h5::group f, std::string const & name, vector_const_view<std::string> V) {
|
||||
h5::detail::write_1darray_vector_of_string_impl(f,name,V);
|
||||
}
|
||||
|
||||
inline void write_array (h5::group f, std::string const & name, array_view<std::string,1> const & V) {
|
||||
write_array(f,name,vector_view<std::string>(V));
|
||||
inline void write_array (h5::group f, std::string const & name, array_const_view<std::string,1> V) {
|
||||
write_array(f,name,vector_const_view<std::string>(V));
|
||||
}
|
||||
|
||||
inline void read_array (h5::group f, std::string const & name, arrays::vector<std::string> & V) {
|
||||
@ -187,7 +191,7 @@ namespace triqs { namespace arrays {
|
||||
template <typename ArrayType>
|
||||
//ENABLE_IF(is_amv_value_or_view_class<ArrayType>)
|
||||
ENABLE_IFC(is_amv_value_or_view_class<ArrayType>::value && has_scalar_or_string_value_type<ArrayType>::value)
|
||||
h5_write (h5::group fg, std::string const & name, ArrayType const & A) { h5_impl::write_array(fg,name, array_view<typename ArrayType::value_type, ArrayType::rank>(A));}
|
||||
h5_write (h5::group fg, std::string const & name, ArrayType const & A) { h5_impl::write_array(fg,name, array_const_view<typename ArrayType::value_type, ArrayType::rank>(A));}
|
||||
|
||||
}}
|
||||
#endif
|
||||
|
@ -36,7 +36,6 @@ namespace triqs { namespace arrays {
|
||||
// 3 -> Init the array
|
||||
// 5 -> Boundcheck
|
||||
|
||||
constexpr ull_t ConstView = 1ull << 0;
|
||||
constexpr ull_t TraversalOrderC = 1ull << 1;
|
||||
constexpr ull_t TraversalOrderFortran = 1ull << 2;
|
||||
constexpr ull_t DefaultInit = 1ull << 3;
|
||||
@ -55,8 +54,6 @@ namespace triqs { namespace arrays {
|
||||
constexpr ull_t get(ull_t f, ull_t a) { return ((f & (1ull<<a)) >> a);}
|
||||
constexpr ull_t get2(ull_t f, ull_t a) { return ((f & ((1ull<<a) + (1ull<< (a+1ull)))) >> a);}
|
||||
|
||||
constexpr bool is_const (ull_t f) { return get (f,0) !=0;}
|
||||
|
||||
#ifdef TRIQS_ARRAYS_ENFORCE_BOUNDCHECK
|
||||
constexpr bool bound_check (ull_t f) { return true;}
|
||||
#else
|
||||
|
@ -50,10 +50,10 @@ namespace triqs { namespace arrays {
|
||||
|
||||
template <bool Const, typename IndexMapIterator, typename StorageType > class iterator_adapter;
|
||||
|
||||
template <class V, int R, ull_t OptionFlags, ull_t TraversalOrder, class ViewTag, bool Borrowed > struct ISPViewType;
|
||||
template <class V, int R, ull_t OptionFlags, ull_t TraversalOrder, class ViewTag, bool Borrowed, bool IsConst> struct ISPViewType;
|
||||
|
||||
template <typename IndexMapType, typename StorageType, ull_t OptionFlags, ull_t TraversalOrder, typename ViewTag >
|
||||
class indexmap_storage_pair : Tag::indexmap_storage_pair, TRIQS_CONCEPT_TAG_NAME(MutableCuboidArray) {
|
||||
template <typename IndexMapType, typename StorageType, ull_t OptionFlags, ull_t TraversalOrder, bool IsConst, typename ViewTag>
|
||||
class indexmap_storage_pair : Tag::indexmap_storage_pair, TRIQS_CONCEPT_TAG_NAME(MutableCuboidArray) {
|
||||
|
||||
public :
|
||||
typedef typename StorageType::value_type value_type;
|
||||
@ -64,6 +64,7 @@ namespace triqs { namespace arrays {
|
||||
static constexpr unsigned int rank = IndexMapType::domain_type::rank;
|
||||
static constexpr ull_t opt_flags = OptionFlags;
|
||||
static constexpr ull_t traversal_order = TraversalOrder;
|
||||
static constexpr bool is_const = IsConst;
|
||||
|
||||
protected:
|
||||
|
||||
@ -170,13 +171,13 @@ namespace triqs { namespace arrays {
|
||||
|
||||
// ------------------------------- operator () --------------------------------------------
|
||||
|
||||
typedef typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag,false >::type view_type;
|
||||
typedef typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag,true >::type weak_view_type;
|
||||
typedef typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag,false, IsConst >::type view_type;
|
||||
typedef typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag,true , IsConst>::type weak_view_type;
|
||||
|
||||
// Evaluation and slices
|
||||
template<typename... Args>
|
||||
typename std::enable_if<
|
||||
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0) && !flags::is_const(OptionFlags)
|
||||
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0) && (!IsConst)
|
||||
, value_type &>::type
|
||||
operator()(Args const & ... args) { return storage_[indexmap_(args...)]; }
|
||||
|
||||
@ -191,17 +192,18 @@ namespace triqs { namespace arrays {
|
||||
//typedef typename std::conditional<is_const, typename std::add_const<value_type>::type, value_type>::type V2;
|
||||
typedef value_type V2;
|
||||
static_assert(IM2::domain_type::rank !=0, "Internal error");
|
||||
static constexpr ull_t optmodif = (is_const ? ConstView : 0ull);
|
||||
typedef typename ISPViewType<V2,IM2::domain_type::rank, OptionFlags|optmodif, IM2::traversal_order_in_template, ViewTag, ForceBorrowed || StorageType::is_weak >::type type;
|
||||
typedef typename ISPViewType<V2,IM2::domain_type::rank, OptionFlags, IM2::traversal_order_in_template, ViewTag, ForceBorrowed || StorageType::is_weak, is_const >::type type;
|
||||
};
|
||||
|
||||
// simplify this ?
|
||||
#ifndef TRIQS_ARRAYS_SLICE_DEFAUT_IS_SHARED
|
||||
template<typename... Args> // non const version
|
||||
typename boost::lazy_enable_if_c<
|
||||
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank!=0) && !flags::is_const(OptionFlags)
|
||||
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank!=0) && (!IsConst)
|
||||
, result_of_call_as_view<false,true,Args...>
|
||||
>::type // enable_if
|
||||
operator()(Args const & ... args) & {
|
||||
// simplify
|
||||
return typename result_of_call_as_view<false,true,Args...>::type ( indexmaps::slicer<indexmap_type,Args...>::invoke(indexmap_,args...), storage()); }
|
||||
|
||||
template<typename... Args> // const version
|
||||
@ -215,21 +217,21 @@ namespace triqs { namespace arrays {
|
||||
template<typename... Args> // rvalue version : same value of weak as this
|
||||
typename boost::lazy_enable_if_c<
|
||||
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank!=0)
|
||||
, result_of_call_as_view<true,false,Args...>
|
||||
, result_of_call_as_view<false,false,Args...>
|
||||
>::type // enable_if
|
||||
operator()(Args const & ... args) && {
|
||||
//std::cerr << "slicing a temporary"<< this->storage().is_weak<< result_of_call_as_view<true,true,Args...>::type::storage_type::is_weak << std::endl;
|
||||
return typename result_of_call_as_view<true,false,Args...>::type ( indexmaps::slicer<indexmap_type,Args...>::invoke(indexmap_,args...), std::move(storage()));
|
||||
return typename result_of_call_as_view<false,false,Args...>::type ( indexmaps::slicer<indexmap_type,Args...>::invoke(indexmap_,args...), std::move(storage()));
|
||||
}
|
||||
|
||||
/// Equivalent to make_view
|
||||
typename ISPViewType<value_type,domain_type::rank, OptionFlags | ConstView, TraversalOrder, ViewTag, true >::type
|
||||
typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag, true, true >::type
|
||||
operator()() const & { return *this; }
|
||||
|
||||
typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag, true >::type
|
||||
typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag, true, IsConst >::type
|
||||
operator()() & { return *this; }
|
||||
|
||||
typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag, StorageType::is_weak >::type
|
||||
typename ISPViewType<value_type,domain_type::rank, OptionFlags, TraversalOrder, ViewTag, StorageType::is_weak,IsConst >::type
|
||||
operator()() && { return *this; }
|
||||
|
||||
// Interaction with the CLEF library : calling with any clef expression as argument build a new clef expression
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "vector.hpp"
|
||||
namespace triqs { namespace arrays {
|
||||
|
||||
template <typename ValueType, ull_t Opt=0, ull_t TraversalOrder= 0, bool Borrowed = false> class matrix_view;
|
||||
template <typename ValueType, ull_t Opt=0, ull_t TraversalOrder= 0, bool Borrowed = false, bool IsConst=false> class matrix_view;
|
||||
template <typename ValueType, ull_t Opt=0, ull_t TraversalOrder= 0> class matrix;
|
||||
|
||||
// ---------------------- matrix --------------------------------
|
||||
@ -44,13 +44,14 @@ namespace triqs { namespace arrays {
|
||||
bool memory_layout_is_fortran() const { return this->indexmap().strides()[0] < this->indexmap().strides()[1]; }
|
||||
|
||||
#define IMPL_TYPE indexmap_storage_pair < indexmaps::cuboid::map<2,Opt,TraversalOrder>, \
|
||||
storages::shared_block<ValueType,Borrowed>, Opt, TraversalOrder, Tag::matrix_view >
|
||||
storages::shared_block<ValueType,Borrowed>, Opt, TraversalOrder, IsConst, Tag::matrix_view >
|
||||
|
||||
template <typename ValueType, ull_t Opt, ull_t TraversalOrder, bool Borrowed>
|
||||
template <typename ValueType, ull_t Opt, ull_t TraversalOrder, bool Borrowed, bool IsConst>
|
||||
class matrix_view : Tag::matrix_view, TRIQS_CONCEPT_TAG_NAME(MutableMatrix), public IMPL_TYPE {
|
||||
public :
|
||||
typedef matrix <ValueType,Opt,TraversalOrder> regular_type;
|
||||
typedef matrix_view<ValueType,Opt,TraversalOrder> view_type;
|
||||
typedef matrix_view<ValueType, Opt, TraversalOrder, false, true> const_view_type;
|
||||
typedef matrix_view<ValueType,Opt,TraversalOrder,true> weak_view_type;
|
||||
|
||||
typedef typename IMPL_TYPE::indexmap_type indexmap_type;
|
||||
@ -94,15 +95,19 @@ namespace triqs { namespace arrays {
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// this traits is used by indexmap_storage_pair, when slicing to find the correct view type.
|
||||
template < class V, int R, ull_t OptionFlags, ull_t To, bool Borrowed >
|
||||
struct ISPViewType< V, R, OptionFlags, To, Tag::matrix_view, Borrowed> {
|
||||
typedef typename std::conditional <R == 1, vector_view<V,OptionFlags,Borrowed >, matrix_view<V,OptionFlags, To, Borrowed > >::type type;
|
||||
template < class V, int R, ull_t OptionFlags, ull_t To, bool Borrowed, bool IsConst>
|
||||
struct ISPViewType< V, R, OptionFlags, To, Tag::matrix_view, Borrowed,IsConst> {
|
||||
typedef typename std::conditional<R == 1, vector_view<V, OptionFlags, Borrowed, IsConst>,
|
||||
matrix_view<V, OptionFlags, To, Borrowed, IsConst>>::type type;
|
||||
};
|
||||
#undef IMPL_TYPE
|
||||
|
||||
template <typename ValueType, ull_t Opt = 0, ull_t TraversalOrder = 0, bool Borrowed = false>
|
||||
using matrix_const_view = matrix_view<ValueType, Opt, TraversalOrder, Borrowed, true>;
|
||||
|
||||
// ---------------------- matrix --------------------------------
|
||||
#define IMPL_TYPE indexmap_storage_pair < indexmaps::cuboid::map<2,Opt,TraversalOrder>, \
|
||||
storages::shared_block<ValueType>, Opt, TraversalOrder, Tag::matrix_view >
|
||||
storages::shared_block<ValueType>, Opt, TraversalOrder, false, Tag::matrix_view >
|
||||
|
||||
template <typename ValueType, ull_t Opt, ull_t TraversalOrder >
|
||||
class matrix: Tag::matrix, TRIQS_CONCEPT_TAG_NAME(MutableMatrix), public IMPL_TYPE {
|
||||
@ -112,6 +117,7 @@ namespace triqs { namespace arrays {
|
||||
typedef typename IMPL_TYPE::indexmap_type indexmap_type;
|
||||
typedef matrix <ValueType,Opt,TraversalOrder> regular_type;
|
||||
typedef matrix_view<ValueType,Opt,TraversalOrder> view_type;
|
||||
typedef matrix_view<ValueType, Opt, TraversalOrder, false, true> const_view_type;
|
||||
typedef matrix_view<ValueType,Opt,TraversalOrder,true> weak_view_type;
|
||||
|
||||
/// Empty matrix.
|
||||
@ -215,8 +221,8 @@ namespace triqs { namespace arrays {
|
||||
// The std::swap is WRONG for a view because of the copy/move semantics of view.
|
||||
// Use swap instead (the correct one, found by ADL).
|
||||
namespace std {
|
||||
template <typename V, triqs::ull_t Opt, triqs::ull_t To, bool B1, bool B2>
|
||||
void swap( triqs::arrays::matrix_view<V,Opt,To,B1> & a , triqs::arrays::matrix_view<V,Opt,To,B2> & b)= delete;
|
||||
template <typename V, triqs::ull_t Opt, triqs::ull_t To, bool B1, bool B2, bool C1, bool C2>
|
||||
void swap( triqs::arrays::matrix_view<V,Opt,To,B1,C1> & a , triqs::arrays::matrix_view<V,Opt,To,B2,C2> & b)= delete;
|
||||
}
|
||||
#include "./expression_template/matrix_algebra.hpp"
|
||||
#endif
|
||||
|
@ -38,6 +38,8 @@ namespace arrays {
|
||||
TRIQS_CONCEPT_TAG_NAME(ImmutableCuboidArray)>::type {
|
||||
|
||||
typedef typename std::remove_reference<A>::type A_t;
|
||||
static constexpr bool is_const = true;
|
||||
|
||||
A a;
|
||||
long n;
|
||||
|
||||
@ -45,8 +47,8 @@ namespace arrays {
|
||||
typedef indexmaps::slicer<typename A_t::indexmap_type, long, ellipsis> slicer_t;
|
||||
typedef typename slicer_t::r_type indexmap_type;
|
||||
typedef typename indexmap_type::domain_type domain_type;
|
||||
typedef typename std::conditional<IsMatrix, matrix_view<value_type>,
|
||||
array_view<value_type, domain_type::rank>>::type view_type;
|
||||
typedef typename std::conditional<IsMatrix, matrix_const_view<value_type>,
|
||||
array_const_view<value_type, domain_type::rank>>::type view_type;
|
||||
|
||||
template <typename AA> const_matrix_tensor_proxy(AA &&a_, long n_) : a(std::forward<AA>(a_)), n(n_) {}
|
||||
|
||||
@ -83,6 +85,8 @@ namespace arrays {
|
||||
TRIQS_CONCEPT_TAG_NAME(MutableCuboidArray)>::type {
|
||||
|
||||
typedef typename std::remove_reference<A>::type A_t;
|
||||
static constexpr bool is_const = false;
|
||||
|
||||
A a;
|
||||
long n;
|
||||
|
||||
|
@ -29,19 +29,20 @@
|
||||
|
||||
namespace triqs { namespace arrays {
|
||||
|
||||
template <typename ValueType, ull_t Opt=0, bool Borrowed =false> class vector_view;
|
||||
template <typename ValueType, ull_t Opt=0, bool Borrowed =false, bool IsConst=false> class vector_view;
|
||||
template <typename ValueType, ull_t Opt=0> class vector;
|
||||
|
||||
// ---------------------- vector_view --------------------------------
|
||||
|
||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<1,Opt,0> , storages::shared_block<ValueType,Borrowed>, Opt, 0, Tag::vector_view >
|
||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<1,Opt,0> , storages::shared_block<ValueType,Borrowed>, Opt, 0, IsConst, Tag::vector_view >
|
||||
|
||||
/** */
|
||||
template <typename ValueType, ull_t Opt, bool Borrowed>
|
||||
template <typename ValueType, ull_t Opt, bool Borrowed, bool IsConst>
|
||||
class vector_view : Tag::vector_view, TRIQS_CONCEPT_TAG_NAME(MutableVector), public IMPL_TYPE {
|
||||
public :
|
||||
typedef vector <ValueType,Opt> regular_type;
|
||||
typedef vector_view<ValueType,Opt,false> view_type;
|
||||
typedef vector_view<ValueType, Opt, false, true> const_view_type;
|
||||
typedef vector_view<ValueType,Opt,true> weak_view_type;
|
||||
|
||||
typedef typename IMPL_TYPE::indexmap_type indexmap_type;
|
||||
@ -95,10 +96,14 @@ namespace triqs { namespace arrays {
|
||||
};
|
||||
#undef IMPL_TYPE
|
||||
|
||||
template < class V, int R, ull_t OptionFlags, ull_t To, bool Borrowed >
|
||||
struct ISPViewType< V, R,OptionFlags,To, Tag::vector_view, Borrowed> { typedef vector_view<V,OptionFlags,Borrowed> type; };
|
||||
template < class V, int R, ull_t OptionFlags, ull_t To, bool Borrowed, bool IsConst>
|
||||
struct ISPViewType< V, R,OptionFlags,To, Tag::vector_view, Borrowed, IsConst> { typedef vector_view<V,OptionFlags,Borrowed,IsConst> type; };
|
||||
|
||||
template <typename ValueType, ull_t Opt = 0, bool Borrowed = false>
|
||||
using vector_const_view = vector_view<ValueType, Opt, Borrowed, true>;
|
||||
|
||||
// ---------------------- vector--------------------------------
|
||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<1,Opt,0> , storages::shared_block<ValueType>, Opt, 0, Tag::vector_view >
|
||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<1,Opt,0> , storages::shared_block<ValueType>, Opt, 0, false,Tag::vector_view >
|
||||
|
||||
template <typename ValueType, ull_t Opt>
|
||||
class vector: Tag::vector, TRIQS_CONCEPT_TAG_NAME(MutableVector), public IMPL_TYPE {
|
||||
@ -106,9 +111,10 @@ namespace triqs { namespace arrays {
|
||||
typedef typename IMPL_TYPE::value_type value_type;
|
||||
typedef typename IMPL_TYPE::storage_type storage_type;
|
||||
typedef typename IMPL_TYPE::indexmap_type indexmap_type;
|
||||
typedef vector <ValueType,Opt> regular_type;
|
||||
typedef vector_view<ValueType,Opt> view_type;
|
||||
typedef vector_view<ValueType,Opt,true> weak_view_type;
|
||||
typedef vector<ValueType, Opt> regular_type;
|
||||
typedef vector_view<ValueType, Opt> view_type;
|
||||
typedef vector_view<ValueType, Opt, false, true> const_view_type;
|
||||
typedef vector_view<ValueType, Opt, true> weak_view_type;
|
||||
|
||||
/// Empty vector.
|
||||
vector(){}
|
||||
@ -293,7 +299,8 @@ namespace triqs { namespace arrays {
|
||||
// The std::swap is WRONG for a view because of the copy/move semantics of view.
|
||||
// Use swap instead (the correct one, found by ADL).
|
||||
namespace std {
|
||||
template <typename V, triqs::ull_t S, bool B1, bool B2> void swap( triqs::arrays::vector_view<V,S,B1> & a , triqs::arrays::vector_view<V,S,B2> & b)= delete;
|
||||
template <typename V, triqs::ull_t S, bool B1, bool B2, bool C1, bool C2>
|
||||
void swap(triqs::arrays::vector_view<V, S, B1, C1>& a, triqs::arrays::vector_view<V, S, B2,C2>& b) = delete;
|
||||
}
|
||||
|
||||
#include "./expression_template/vector_algebra.hpp"
|
||||
|
@ -479,16 +479,16 @@ namespace triqs { namespace gfs {
|
||||
// ---------------------------------- slicing ------------------------------------
|
||||
|
||||
//slice
|
||||
template<typename Variable, typename Target, typename Opt, bool V, typename... Args>
|
||||
gf_view<Variable,matrix_valued,Opt> slice_target (gf_impl<Variable,Target,Opt,V> const & g, Args&& ... args) {
|
||||
template<typename Variable, typename Target, typename Opt, typename... Args>
|
||||
gf_view<Variable,matrix_valued,Opt> slice_target (gf_view<Variable,Target,Opt> g, Args&& ... args) {
|
||||
static_assert(std::is_same<Target,matrix_valued>::value, "slice_target only for matrix_valued GF's");
|
||||
using arrays::range;
|
||||
//auto sg=slice_target (g.singularity(),range(args,args+1)...);
|
||||
return gf_view<Variable,matrix_valued,Opt>(g.mesh(), g.data()(range(), std::forward<Args>(args)... ), slice_target (g.singularity(), std::forward<Args>(args)...) , g.symmetry());
|
||||
}
|
||||
|
||||
template<typename Variable, typename Target, typename Opt, bool V, typename... Args>
|
||||
gf_view<Variable,scalar_valued,Opt> slice_target_to_scalar (gf_impl<Variable,Target,Opt,V> const & g, Args&& ... args) {
|
||||
template<typename Variable, typename Target, typename Opt, typename... Args>
|
||||
gf_view<Variable,scalar_valued,Opt> slice_target_to_scalar (gf_view<Variable,Target,Opt> g, Args&& ... args) {
|
||||
static_assert(std::is_same<Target,matrix_valued>::value, "slice_target only for matrix_valued GF's");
|
||||
using arrays::range;
|
||||
auto sg=slice_target (g.singularity(),range(args,args+1)...);
|
||||
@ -496,8 +496,8 @@ namespace triqs { namespace gfs {
|
||||
}
|
||||
|
||||
// a scalar_valued gf can be viewed as a 1x1 matrix
|
||||
template<typename Variable, typename Opt, bool V, typename... Args>
|
||||
gf_view<Variable,matrix_valued,Opt> reinterpret_scalar_valued_gf_as_matrix_valued (gf_impl<Variable,scalar_valued,Opt,V> const & g) {
|
||||
template<typename Variable, typename Opt, typename... Args>
|
||||
gf_view<Variable,matrix_valued,Opt> reinterpret_scalar_valued_gf_as_matrix_valued (gf_view<Variable,scalar_valued,Opt> g) {
|
||||
typedef typename gf_view<Variable,matrix_valued,Opt>::data_view_t a_t;
|
||||
auto a = a_t {typename a_t::indexmap_type (join(g.data().shape(),make_shape(1,1))), g.data().storage()};
|
||||
return gf_view<Variable,matrix_valued,Opt>(g.mesh(), a, g.singularity(), g.symmetry());
|
||||
|
@ -266,7 +266,8 @@ namespace triqs { namespace gfs { namespace local {
|
||||
}
|
||||
|
||||
/// Slice in orbital space
|
||||
template<bool V> tail_view slice_target(tail_impl<V> const & t, tqa::range R1, tqa::range R2) {
|
||||
//template<bool V> tail_view slice_target(tail_impl<V> const & t, tqa::range R1, tqa::range R2) {
|
||||
inline tail_view slice_target(tail_view t, tqa::range R1, tqa::range R2) {
|
||||
return tail_view(t.data()(tqa::range(),R1,R2), t.mask_view()(R1,R2), t.order_min());
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,8 @@ namespace triqs { namespace gfs {
|
||||
// index[0] + component[0].size * (index[1] + component[1].size* (index[2] + ....))
|
||||
struct _aux2 { template<typename I, typename M> size_t operator()(M const & m, I const & i,size_t R) {return m.index_to_linear(i) + R * m.size();}};
|
||||
size_t index_to_linear(index_t const & ii) const { return triqs::tuple::fold_on_zip(_aux2(), reverse(m_tuple), reverse(ii), size_t(0)); }
|
||||
// size_t index_to_linear(index_t const & ii) const { return triqs::tuple::fold_on_zip([](auto const &m, auto const &i, auto R){return m.index_to_linear(i) + R * m.size();} , m_tuple, ii, size_t(0)); }
|
||||
|
||||
|
||||
// Same but a tuple of mesh_point_t
|
||||
struct _aux3 { template<typename P, typename M> size_t operator()(M const & m, P const & p,size_t R) {return p.linear_index() + R * m.size();}};
|
||||
|
@ -50,7 +50,7 @@ namespace triqs { namespace utility {
|
||||
}
|
||||
|
||||
template <typename VectorType>
|
||||
static TYPE_ENABLE_IF(R,ImmutableStdVector<VectorType>) invoke( VectorType const & v) {
|
||||
static TYPE_ENABLE_IF(R,ImmutableStdVector<VectorType>) invoke( VectorType & v) {
|
||||
static_assert(std::is_constructible<T,decltype(v[0])>::value, "Can not make std::vector<T> from the proposed type");
|
||||
R r; r.reserve(v.size());
|
||||
for(size_t i=0; i<v.size(); ++i) r.push_back(T(v[i]));
|
||||
|
@ -38,7 +38,7 @@ namespace triqs {
|
||||
|
||||
template<typename T, bool HasView = has_view<T>::value> struct const_view_type_if_exists_else_type;
|
||||
template<typename T> struct const_view_type_if_exists_else_type<T,false> {typedef T type;};
|
||||
template<typename T> struct const_view_type_if_exists_else_type<T,true> {typedef const typename T::view_type type;};
|
||||
template<typename T> struct const_view_type_if_exists_else_type<T,true> {typedef const typename T::const_view_type type;};
|
||||
|
||||
/*
|
||||
// replacement of std::plus for views ...
|
||||
|
Loading…
Reference in New Issue
Block a user