mirror of
https://github.com/triqs/dft_tools
synced 2025-01-12 22:18:23 +01:00
arrays: change operator() && for const_view
Changed operator()(int, int...) && for array, and views. - For const_view and regular type, returns value_type (i.e. a copy). NB : does make a copy, not a move. Ok for scalar type. TODO: think for complicated types. This allows codes like : f(x)(0,0) where f : x-> matrix or const_view to be correct in clef expression evaluation. - For _view : return a value_type &, as before to allow : A(....)(0,0) = rhs; It is not possible to detect dangling refs in that case at compile time. Added a security in TRIQS_ARRAYS_DEBUG mode to detect a dangling ref at run time, i.e. the case where the view is "unique" (ref count ==1). This would be a quite bad design anyway ... - also : - clean operator[] for vector (old workaround for old gcc...) - add IsView flag in ISP impl class, for the impl. of operator() &&
This commit is contained in:
parent
1e220d24c7
commit
5128126055
@ -34,7 +34,7 @@ namespace triqs { namespace arrays {
|
|||||||
// ---------------------- array_view --------------------------------
|
// ---------------------- array_view --------------------------------
|
||||||
|
|
||||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<Rank,Opt,TraversalOrder>, \
|
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<Rank,Opt,TraversalOrder>, \
|
||||||
storages::shared_block<ValueType, Borrowed>, Opt, TraversalOrder, IsConst, Tag::array_view >
|
storages::shared_block<ValueType, Borrowed>, Opt, TraversalOrder, IsConst, true, Tag::array_view >
|
||||||
|
|
||||||
template <typename ValueType, int Rank, ull_t Opt, ull_t TraversalOrder, bool Borrowed, bool IsConst>
|
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 {
|
class array_view: Tag::array_view, TRIQS_CONCEPT_TAG_NAME(MutableArray), public IMPL_TYPE {
|
||||||
@ -106,7 +106,7 @@ namespace triqs { namespace arrays {
|
|||||||
//------------------------------- array ---------------------------------------------------
|
//------------------------------- array ---------------------------------------------------
|
||||||
|
|
||||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<Rank,Opt,TraversalOrder>, \
|
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<Rank,Opt,TraversalOrder>, \
|
||||||
storages::shared_block<ValueType>, Opt, TraversalOrder, false, Tag::array_view >
|
storages::shared_block<ValueType>, Opt, TraversalOrder, false, false, Tag::array_view >
|
||||||
|
|
||||||
template <typename ValueType, int Rank, ull_t Opt, ull_t TraversalOrder>
|
template <typename ValueType, int Rank, ull_t Opt, ull_t TraversalOrder>
|
||||||
class array: Tag::array, TRIQS_CONCEPT_TAG_NAME(MutableArray), public IMPL_TYPE {
|
class array: Tag::array, TRIQS_CONCEPT_TAG_NAME(MutableArray), public IMPL_TYPE {
|
||||||
|
@ -52,7 +52,7 @@ namespace triqs { namespace arrays {
|
|||||||
|
|
||||||
template <class V, int R, ull_t OptionFlags, ull_t TraversalOrder, class ViewTag, bool Borrowed, bool IsConst> 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, bool IsConst, typename ViewTag>
|
template <typename IndexMapType, typename StorageType, ull_t OptionFlags, ull_t TraversalOrder, bool IsConst, bool IsView, typename ViewTag>
|
||||||
class indexmap_storage_pair : Tag::indexmap_storage_pair, TRIQS_CONCEPT_TAG_NAME(MutableCuboidArray) {
|
class indexmap_storage_pair : Tag::indexmap_storage_pair, TRIQS_CONCEPT_TAG_NAME(MutableCuboidArray) {
|
||||||
|
|
||||||
public :
|
public :
|
||||||
@ -182,13 +182,33 @@ namespace triqs { namespace arrays {
|
|||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0) && (!IsConst)
|
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0) && (!IsConst)
|
||||||
, value_type &>::type
|
, value_type &>::type
|
||||||
operator()(Args const & ... args) { return storage_[indexmap_(args...)]; }
|
operator()(Args const & ... args) & { return storage_[indexmap_(args...)]; }
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
typename std::enable_if<
|
typename std::enable_if<
|
||||||
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0)
|
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0)
|
||||||
, value_type const &>::type
|
, value_type const &>::type
|
||||||
operator()(Args const & ... args) const { return storage_[indexmap_(args...)]; }
|
operator()(Args const & ... args) const & { return storage_[indexmap_(args...)]; }
|
||||||
|
|
||||||
|
// && : return a & iif it is a non const view
|
||||||
|
template<typename... Args>
|
||||||
|
typename std::enable_if<
|
||||||
|
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0) && (!IsConst&&IsView)
|
||||||
|
, value_type &>::type
|
||||||
|
operator()(Args const & ... args) && {
|
||||||
|
// add here a security check in case it is a view, unique. For a regular type, move the result...
|
||||||
|
#ifdef TRIQS_ARRAYS_DEBUG
|
||||||
|
if (storage_.is_unique()) TRIQS_RUNTIME_ERROR <<"BUG : array : rvalue ref for an array...";
|
||||||
|
#endif
|
||||||
|
return storage_[indexmap_(args...)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// && return a value if this is not a view (regular class) or it is a const_view
|
||||||
|
template<typename... Args>
|
||||||
|
typename std::enable_if<
|
||||||
|
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0) && (!(!IsConst&&IsView))
|
||||||
|
, value_type>::type
|
||||||
|
operator()(Args const & ... args) && { return storage_[indexmap_(args...)]; }
|
||||||
|
|
||||||
template<bool is_const, bool ForceBorrowed, typename ... Args> struct result_of_call_as_view {
|
template<bool is_const, bool ForceBorrowed, typename ... Args> struct result_of_call_as_view {
|
||||||
typedef typename indexmaps::slicer<indexmap_type,Args...>::r_type IM2;
|
typedef typename indexmaps::slicer<indexmap_type,Args...>::r_type IM2;
|
||||||
|
@ -44,7 +44,7 @@ namespace triqs { namespace arrays {
|
|||||||
bool memory_layout_is_fortran() const { return this->indexmap().strides()[0] < this->indexmap().strides()[1]; }
|
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>, \
|
#define IMPL_TYPE indexmap_storage_pair < indexmaps::cuboid::map<2,Opt,TraversalOrder>, \
|
||||||
storages::shared_block<ValueType,Borrowed>, Opt, TraversalOrder, IsConst, Tag::matrix_view >
|
storages::shared_block<ValueType,Borrowed>, Opt, TraversalOrder, IsConst, true, Tag::matrix_view >
|
||||||
|
|
||||||
template <typename ValueType, ull_t Opt, ull_t TraversalOrder, bool Borrowed, bool IsConst>
|
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 {
|
class matrix_view : Tag::matrix_view, TRIQS_CONCEPT_TAG_NAME(MutableMatrix), public IMPL_TYPE {
|
||||||
@ -116,7 +116,7 @@ namespace triqs { namespace arrays {
|
|||||||
|
|
||||||
// ---------------------- matrix --------------------------------
|
// ---------------------- matrix --------------------------------
|
||||||
#define IMPL_TYPE indexmap_storage_pair < indexmaps::cuboid::map<2,Opt,TraversalOrder>, \
|
#define IMPL_TYPE indexmap_storage_pair < indexmaps::cuboid::map<2,Opt,TraversalOrder>, \
|
||||||
storages::shared_block<ValueType>, Opt, TraversalOrder, false, Tag::matrix_view >
|
storages::shared_block<ValueType>, Opt, TraversalOrder, false, false, Tag::matrix_view >
|
||||||
|
|
||||||
template <typename ValueType, ull_t Opt, ull_t TraversalOrder >
|
template <typename ValueType, ull_t Opt, ull_t TraversalOrder >
|
||||||
class matrix: Tag::matrix, TRIQS_CONCEPT_TAG_NAME(MutableMatrix), public IMPL_TYPE {
|
class matrix: Tag::matrix, TRIQS_CONCEPT_TAG_NAME(MutableMatrix), public IMPL_TYPE {
|
||||||
|
@ -261,6 +261,8 @@ namespace triqs { namespace arrays { namespace storages { //namespace details {
|
|||||||
|
|
||||||
size_t size() const {return size_;}
|
size_t size() const {return size_;}
|
||||||
|
|
||||||
|
bool is_unique() const { return (ref_count + weak_ref_count) == 1; }
|
||||||
|
|
||||||
template<class Archive>
|
template<class Archive>
|
||||||
void save(Archive & ar, const unsigned int version) const {
|
void save(Archive & ar, const unsigned int version) const {
|
||||||
ar << boost::serialization::make_nvp("size",size_);
|
ar << boost::serialization::make_nvp("size",size_);
|
||||||
|
@ -81,6 +81,8 @@ namespace triqs { namespace arrays { namespace storages {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_unique() const { return sptr && sptr->is_unique();}
|
||||||
|
|
||||||
/// True copy of the data
|
/// True copy of the data
|
||||||
shared_block clone() const {
|
shared_block clone() const {
|
||||||
shared_block res;
|
shared_block res;
|
||||||
|
@ -34,7 +34,7 @@ namespace triqs { namespace arrays {
|
|||||||
|
|
||||||
// ---------------------- vector_view --------------------------------
|
// ---------------------- 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 >
|
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<1,Opt,0> , storages::shared_block<ValueType,Borrowed>, Opt, 0, IsConst, true, Tag::vector_view >
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
template <typename ValueType, ull_t Opt, bool Borrowed, bool IsConst>
|
template <typename ValueType, ull_t Opt, bool Borrowed, bool IsConst>
|
||||||
@ -97,11 +97,8 @@ namespace triqs { namespace arrays {
|
|||||||
TRIQS_DEFINE_COMPOUND_OPERATORS(vector_view);
|
TRIQS_DEFINE_COMPOUND_OPERATORS(vector_view);
|
||||||
|
|
||||||
// to make interface similar to std::vector : forward [] to ()
|
// to make interface similar to std::vector : forward [] to ()
|
||||||
template<typename Arg> typename std::result_of<const IMPL_TYPE(Arg)>::type operator[](Arg && arg) const { return (*this) (std::forward<Arg>(arg));}
|
template<typename Arg> auto operator[](Arg && arg) const DECL_AND_RETURN((*this)(std::forward<Arg>(arg)));
|
||||||
template<typename Arg> typename std::result_of<IMPL_TYPE(Arg)>::type operator[](Arg && arg) { return (*this) (std::forward<Arg>(arg));}
|
template<typename Arg> auto operator[](Arg && arg) DECL_AND_RETURN((*this)(std::forward<Arg>(arg)));
|
||||||
// gcc 4.6 does not like this one...
|
|
||||||
//template<typename Arg> auto operator[](Arg && arg) const DECL_AND_RETURN((*this)(std::forward<Arg>(arg)));
|
|
||||||
//template<typename Arg> auto operator[](Arg && arg) DECL_AND_RETURN((*this)(std::forward<Arg>(arg)));
|
|
||||||
};
|
};
|
||||||
#undef IMPL_TYPE
|
#undef IMPL_TYPE
|
||||||
|
|
||||||
@ -112,7 +109,7 @@ namespace triqs { namespace arrays {
|
|||||||
using vector_const_view = vector_view<ValueType, Opt, Borrowed, true>;
|
using vector_const_view = vector_view<ValueType, Opt, Borrowed, true>;
|
||||||
|
|
||||||
// ---------------------- vector--------------------------------
|
// ---------------------- vector--------------------------------
|
||||||
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<1,Opt,0> , storages::shared_block<ValueType>, Opt, 0, false,Tag::vector_view >
|
#define IMPL_TYPE indexmap_storage_pair< indexmaps::cuboid::map<1,Opt,0> , storages::shared_block<ValueType>, Opt, 0, false, false,Tag::vector_view >
|
||||||
|
|
||||||
template <typename ValueType, ull_t Opt>
|
template <typename ValueType, ull_t Opt>
|
||||||
class vector: Tag::vector, TRIQS_CONCEPT_TAG_NAME(MutableVector), public IMPL_TYPE {
|
class vector: Tag::vector, TRIQS_CONCEPT_TAG_NAME(MutableVector), public IMPL_TYPE {
|
||||||
@ -206,11 +203,9 @@ namespace triqs { namespace arrays {
|
|||||||
|
|
||||||
TRIQS_DEFINE_COMPOUND_OPERATORS(vector);
|
TRIQS_DEFINE_COMPOUND_OPERATORS(vector);
|
||||||
|
|
||||||
// to make interface similar to std::vector : forward [] to ()
|
// to make interface similar to std::vector : forward [] to ()
|
||||||
template<typename Arg> typename std::result_of<const IMPL_TYPE(Arg)>::type operator[](Arg && arg) const { return (*this) (std::forward<Arg>(arg));}
|
template<typename Arg> auto operator[](Arg && arg) const DECL_AND_RETURN((*this)(std::forward<Arg>(arg)));
|
||||||
template<typename Arg> typename std::result_of<IMPL_TYPE(Arg)>::type operator[](Arg && arg) { return (*this) (std::forward<Arg>(arg));}
|
template<typename Arg> auto operator[](Arg && arg) DECL_AND_RETURN((*this)(std::forward<Arg>(arg)));
|
||||||
//template<typename Arg> auto operator[](Arg && arg) const DECL_AND_RETURN((*this)(std::forward<Arg>(arg)));
|
|
||||||
//template<typename Arg> auto operator[](Arg && arg) DECL_AND_RETURN((*this)(std::forward<Arg>(arg)));
|
|
||||||
|
|
||||||
};//vector class
|
};//vector class
|
||||||
}}//namespace triqs::arrays
|
}}//namespace triqs::arrays
|
||||||
|
@ -202,13 +202,12 @@ namespace gfs {
|
|||||||
/// Calls are (perfectly) forwarded to the evaluator::operator(), except mesh_point_t and when
|
/// Calls are (perfectly) forwarded to the evaluator::operator(), except mesh_point_t and when
|
||||||
/// there is at least one lazy argument ...
|
/// there is at least one lazy argument ...
|
||||||
template <typename... Args> // match any argument list, picking out the first type : () is not permitted
|
template <typename... Args> // match any argument list, picking out the first type : () is not permitted
|
||||||
typename std::add_const<typename boost::lazy_disable_if_c< // disable the template if one the following conditions it true
|
typename boost::lazy_disable_if_c< // disable the template if one the following conditions it true
|
||||||
(sizeof...(Args) == 0) || clef::is_any_lazy<Args...>::value ||
|
(sizeof...(Args) == 0) || clef::is_any_lazy<Args...>::value ||
|
||||||
((sizeof...(Args) != evaluator_t::arity) && (evaluator_t::arity != -1)) // if -1 : no check
|
((sizeof...(Args) != evaluator_t::arity) && (evaluator_t::arity != -1)) // if -1 : no check
|
||||||
,
|
,
|
||||||
std::result_of<evaluator_t(gf_impl *, Args...)> // what is the result type of call
|
std::result_of<evaluator_t(gf_impl *, Args...)> // what is the result type of call
|
||||||
>::type // end of lazy_disable_if
|
>::type // end of lazy_disable_if
|
||||||
>::type // end of add_Const
|
|
||||||
operator()(Args &&... args) const {
|
operator()(Args &&... args) const {
|
||||||
return _evaluator(this, std::forward<Args>(args)...);
|
return _evaluator(this, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user