mirror of
https://github.com/triqs/dft_tools
synced 2024-12-25 05:43:40 +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 --------------------------------
|
||||
|
||||
#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>
|
||||
class array_view: Tag::array_view, TRIQS_CONCEPT_TAG_NAME(MutableArray), public IMPL_TYPE {
|
||||
@ -106,7 +106,7 @@ namespace triqs { namespace arrays {
|
||||
//------------------------------- array ---------------------------------------------------
|
||||
|
||||
#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>
|
||||
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 <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) {
|
||||
|
||||
public :
|
||||
@ -182,13 +182,33 @@ namespace triqs { namespace arrays {
|
||||
typename std::enable_if<
|
||||
(!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...)]; }
|
||||
operator()(Args const & ... args) & { return storage_[indexmap_(args...)]; }
|
||||
|
||||
template<typename... Args>
|
||||
typename std::enable_if<
|
||||
(!clef::is_any_lazy<Args...>::value) && (indexmaps::slicer<indexmap_type,Args...>::r_type::domain_type::rank==0)
|
||||
, 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 {
|
||||
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]; }
|
||||
|
||||
#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>
|
||||
class matrix_view : Tag::matrix_view, TRIQS_CONCEPT_TAG_NAME(MutableMatrix), public IMPL_TYPE {
|
||||
@ -116,7 +116,7 @@ namespace triqs { namespace arrays {
|
||||
|
||||
// ---------------------- matrix --------------------------------
|
||||
#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 >
|
||||
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_;}
|
||||
|
||||
bool is_unique() const { return (ref_count + weak_ref_count) == 1; }
|
||||
|
||||
template<class Archive>
|
||||
void save(Archive & ar, const unsigned int version) const {
|
||||
ar << boost::serialization::make_nvp("size",size_);
|
||||
|
@ -81,6 +81,8 @@ namespace triqs { namespace arrays { namespace storages {
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool is_unique() const { return sptr && sptr->is_unique();}
|
||||
|
||||
/// True copy of the data
|
||||
shared_block clone() const {
|
||||
shared_block res;
|
||||
|
@ -34,7 +34,7 @@ namespace triqs { namespace arrays {
|
||||
|
||||
// ---------------------- 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>
|
||||
@ -97,11 +97,8 @@ namespace triqs { namespace arrays {
|
||||
TRIQS_DEFINE_COMPOUND_OPERATORS(vector_view);
|
||||
|
||||
// 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> typename std::result_of<IMPL_TYPE(Arg)>::type operator[](Arg && arg) { 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)));
|
||||
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
|
||||
|
||||
@ -112,7 +109,7 @@ namespace triqs { namespace arrays {
|
||||
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, 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>
|
||||
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);
|
||||
|
||||
// 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> typename std::result_of<IMPL_TYPE(Arg)>::type operator[](Arg && arg) { 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)));
|
||||
// to make interface similar to std::vector : forward [] to ()
|
||||
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
|
||||
}}//namespace triqs::arrays
|
||||
|
@ -202,13 +202,12 @@ namespace gfs {
|
||||
/// Calls are (perfectly) forwarded to the evaluator::operator(), except mesh_point_t and when
|
||||
/// there is at least one lazy argument ...
|
||||
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) != 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
|
||||
>::type // end of lazy_disable_if
|
||||
>::type // end of add_Const
|
||||
operator()(Args &&... args) const {
|
||||
return _evaluator(this, std::forward<Args>(args)...);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user