From 2ee20575b944d16d44528653aa4ae158099493c8 Mon Sep 17 00:00:00 2001 From: Philip Trettner <Philip.Trettner@rwth-aachen.de> Date: Fri, 2 Oct 2020 14:07:00 +0200 Subject: [PATCH] fixed attribute views --- src/polymesh/attributes.hh | 8 +++++--- src/polymesh/impl/impl_attributes.hh | 9 ++++++++- src/polymesh/view.hh | 22 ++++++++++++++-------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/polymesh/attributes.hh b/src/polymesh/attributes.hh index d30c5b8..8e3688f 100644 --- a/src/polymesh/attributes.hh +++ b/src/polymesh/attributes.hh @@ -108,11 +108,13 @@ public: void compute(FuncT&& f); template <class FuncT> - auto view(FuncT&& f) const -> attribute_view<primitive_attribute<tag, AttrT> const&, FuncT>; -#ifndef _MSC_VER // cannot overload this apparently + auto view(FuncT&& f) & -> attribute_view<primitive_attribute<tag, AttrT>&, FuncT>; + template <class FuncT> + auto view(FuncT&& f) const& -> attribute_view<primitive_attribute<tag, AttrT> const&, FuncT>; template <class FuncT> void view(FuncT&& f) && = delete; -#endif + template <class FuncT> + void view(FuncT&& f) const&& = delete; // template <class ReadT, class WriteT> // auto view(ReadT&& r, WriteT&& w) -> readwrite_property<primitive_attribute<tag, AttrT>, ReadT, WriteT>; diff --git a/src/polymesh/impl/impl_attributes.hh b/src/polymesh/impl/impl_attributes.hh index b8aa5a8..470586c 100644 --- a/src/polymesh/impl/impl_attributes.hh +++ b/src/polymesh/impl/impl_attributes.hh @@ -439,9 +439,16 @@ void primitive_attribute<tag, AttrT>::compute(FuncT&& f) template <class tag, class AttrT> template <class FuncT> -auto primitive_attribute<tag, AttrT>::view(FuncT&& f) const -> attribute_view<primitive_attribute<tag, AttrT> const&, FuncT> +auto primitive_attribute<tag, AttrT>::view(FuncT&& f) const& -> attribute_view<primitive_attribute<tag, AttrT> const&, FuncT> { return attribute_view<primitive_attribute<tag, AttrT> const&, FuncT>(*this, std::forward<FuncT>(f)); } +template <class tag, class AttrT> +template <class FuncT> +auto primitive_attribute<tag, AttrT>::view(FuncT&& f) & -> attribute_view<primitive_attribute<tag, AttrT>&, FuncT> +{ + return attribute_view<primitive_attribute<tag, AttrT>&, FuncT>(*this, std::forward<FuncT>(f)); +} + } // namespace polymesh diff --git a/src/polymesh/view.hh b/src/polymesh/view.hh index 86e64ef..f0a7065 100644 --- a/src/polymesh/view.hh +++ b/src/polymesh/view.hh @@ -8,30 +8,36 @@ namespace polymesh template <class CollectionT, class FuncT> struct attribute_view { - attribute_view(CollectionT collection, FuncT func) : mCollection(collection), mFunc(std::move(func)) {} + attribute_view(CollectionT& collection, FuncT func) : mCollection(collection), mFunc(std::move(func)) {} using index_t = typename std::decay<CollectionT>::type::index_t; using handle_t = typename std::decay<CollectionT>::type::handle_t; using input_t = decltype(std::declval<CollectionT>()[index_t()]); using output_t = typename tmp::decayed_result_type_of<FuncT, input_t>; - output_t operator[](handle_t h) const { return mFunc(mCollection(h)); } - output_t operator[](index_t h) const { return mFunc(mCollection(h)); } + decltype(auto) operator[](handle_t h) const { return mFunc(mCollection(h)); } + decltype(auto) operator[](index_t h) const { return mFunc(mCollection(h)); } - output_t operator()(handle_t h) const { return mFunc(mCollection(h)); } - output_t operator()(index_t h) const { return mFunc(mCollection(h)); } + decltype(auto) operator()(handle_t h) const { return mFunc(mCollection(h)); } + decltype(auto) operator()(index_t h) const { return mFunc(mCollection(h)); } + + decltype(auto) operator[](handle_t h) { return mFunc(mCollection(h)); } + decltype(auto) operator[](index_t h) { return mFunc(mCollection(h)); } + + decltype(auto) operator()(handle_t h) { return mFunc(mCollection(h)); } + decltype(auto) operator()(index_t h) { return mFunc(mCollection(h)); } int size() const { return mCollection.size(); } template <class F> auto map(F&& f) const { - auto f2 = [ff = std::forward<F>(f)](output_t const& v) { return ff(v); }; - return attribute_view<CollectionT, decltype(f2)>(mCollection, std::move(f2)); + auto new_f = [f0 = mFunc, f1 = std::forward<F>(f)](auto&& v) -> decltype(auto) { return f1(f0(v)); }; + return attribute_view<CollectionT, decltype(new_f)>(mCollection, std::move(new_f)); } private: - CollectionT mCollection; + CollectionT& mCollection; FuncT mFunc; }; } -- GitLab