diff --git a/src/polymesh/properties.hh b/src/polymesh/properties.hh index ce977a94a21f98e7987c9d93790e56496f3476f2..34ebbc900c37b4303615e9b8080aa9a33c26bd54 100644 --- a/src/polymesh/properties.hh +++ b/src/polymesh/properties.hh @@ -1,11 +1,38 @@ #pragma once #include "primitives.hh" +#include "ranges.hh" #include "tmp.hh" namespace polymesh { +template <class IteratorT, class FuncT> +struct readonly_property_iterator +{ + using input_t = typename std::decay<decltype(std::declval<IteratorT>().operator*())>::type; + using output_t = typename tmp::decayed_result_type_of<FuncT, input_t>; + + output_t operator*() { return func(*original_iterator); } + + readonly_property_iterator& operator++() + { + ++original_iterator; + return *this; + } + + bool operator==(readonly_property_iterator const& rhs) const { return original_iterator == rhs.original_iterator; } + bool operator!=(readonly_property_iterator const& rhs) const { return original_iterator != rhs.original_iterator; } + + IteratorT original_iterator; + FuncT const& func; +}; + template <class CollectionT, class FuncT> -struct readonly_property +struct readonly_property : smart_range< // + readonly_property<CollectionT, FuncT>, // + tmp::decayed_result_type_of< // + FuncT, // + decltype(std::declval<CollectionT>().operator[](typename std::decay<CollectionT>::type::index_t()))>> + { readonly_property(CollectionT collection, FuncT func) : mCollection(collection), mFunc(func) {} @@ -29,6 +56,10 @@ struct readonly_property return {*this, f}; } + using base_iter_t = typename std::decay<decltype(std::declval<CollectionT>().begin())>::type; + readonly_property_iterator<base_iter_t, FuncT> begin() const { return {mCollection.begin(), mFunc}; } + readonly_property_iterator<base_iter_t, FuncT> end() const { return {mCollection.end(), mFunc}; } + private: CollectionT mCollection; FuncT mFunc;