3
0
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:
Olivier Parcollet 2014-03-02 14:14:59 +01:00
parent 1e220d24c7
commit 5128126055
7 changed files with 39 additions and 21 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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_);

View File

@ -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;

View File

@ -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

View File

@ -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)...);
}