diff --git a/arbor/util/piecewise.hpp b/arbor/util/piecewise.hpp index ff83d6ea01..f047b2bbdd 100644 --- a/arbor/util/piecewise.hpp +++ b/arbor/util/piecewise.hpp @@ -103,7 +103,6 @@ #include "util/iterutil.hpp" #include "util/transform.hpp" -#include "util/meta.hpp" #include "util/partition.hpp" namespace arb { @@ -160,8 +159,8 @@ struct pw_element_proxy { extent(pw.extent(i)), value(pw.value(i)) {} operator pw_element() const { return pw_element{extent, value}; } - operator X() const { return value; } - pw_element_proxy& operator=(X x) {value = std::move(x); return *this; }; + operator X&() const { return value; } + pw_element_proxy& operator=(X x) { value = std::move(x); return *this; }; double lower_bound() const { return extent.first; } double upper_bound() const { return extent.second; } @@ -170,6 +169,21 @@ struct pw_element_proxy { X& value; }; +template +struct pw_element_proxy { + pw_element_proxy(const pw_elements& pw, pw_size_type i): + extent(pw.extent(i)), value(pw.value(i)) {} + + operator pw_element() const { return pw_element{extent, value}; } + operator const X&() const { return value; } + + double lower_bound() const { return extent.first; } + double upper_bound() const { return extent.second; } + + const std::pair extent; + const X& value; +}; + // Compute indices into vertex set corresponding to elements that cover a point x: namespace { @@ -239,12 +253,12 @@ struct pw_elements { const_iterator(): pw_(nullptr) {} using value_type = pw_element; - using pointer = const pointer_proxy>; - using reference = pw_element; + using pointer = const pointer_proxy>; + using reference = pw_element_proxy; - reference operator[](difference_type j) const { return (*pw_)[j+*c_]; } - reference operator*() const { return (*pw_)[*c_]; } - pointer operator->() const { return pointer{(*pw_)[*c_]}; } + reference operator[](difference_type j) const { return {*pw_, j + *c_}; } + reference operator*() const { return {*pw_, *c_}; } + pointer operator->() const { return pointer{reference{*pw_, *c_}}; } // (required for iterator_adaptor) counter& inner() { return c_; } diff --git a/arbor/util/pw_over_cable.hpp b/arbor/util/pw_over_cable.hpp index ee699a9fcb..73ce40e0a9 100644 --- a/arbor/util/pw_over_cable.hpp +++ b/arbor/util/pw_over_cable.hpp @@ -16,7 +16,10 @@ struct get_value { // Convert mcable_map values to a piecewise function over an mcable. // The projection gives the map from the values in the mcable_map to the values in the piecewise function. template -util::pw_elements pw_over_cable(const mcable_map& mm, mcable cable, U dflt_value, Proj projection = Proj{}) { +util::pw_elements pw_over_cable(const mcable_map& mm, + mcable cable, + U dflt_value, + Proj projection = Proj{}) { using value_type = typename mcable_map::value_type; msize_t bid = cable.branch; @@ -26,8 +29,11 @@ util::pw_elements pw_over_cable(const mcable_map& mm, mcable cable, U dflt as_branch(msize_t x): value(x) {} }; - auto map_on_branch = util::make_range( - std::equal_range(mm.begin(), mm.end(), bid, [](as_branch a, as_branch b) { return a.value({cable.prox_pos, cable.dist_pos}, {dflt_value});