From 18e34e4c070ddd73dc340aef00250d5262b3b240 Mon Sep 17 00:00:00 2001
From: Christian Mattes <christian.mattes@rwth-aachen.de>
Date: Tue, 14 Aug 2018 14:02:12 +0200
Subject: [PATCH] Turned readonly_properties into a smart_range.

---
 src/polymesh/properties.hh | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/polymesh/properties.hh b/src/polymesh/properties.hh
index ce977a9..34ebbc9 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;
-- 
GitLab