|
|
@@ -107,11 +107,15 @@ namespace stream {
|
|
|
using noref = typename std::remove_reference<T>::type;
|
|
|
using element_type = typename std::pointer_traits<noref>::element_type;
|
|
|
public:
|
|
|
- auto deref() const -> stream_base<element_type &> {
|
|
|
+ auto deref() const & -> stream_base<element_type &> {
|
|
|
return static_cast<stream_base<T> const *>(this)->map([](T const & p) -> element_type & { return *p; });
|
|
|
}
|
|
|
+
|
|
|
+ auto deref() && -> stream_base<element_type &> {
|
|
|
+ return static_cast<stream_base<T> &&>(*this).map([](T const & p) -> element_type & { return *p; });
|
|
|
+ }
|
|
|
};
|
|
|
-
|
|
|
+
|
|
|
template <typename T>
|
|
|
class stream_base : public stream_base_pointer_impl<T> {
|
|
|
private:
|
|
|
@@ -119,6 +123,14 @@ namespace stream {
|
|
|
using map_f = decltype(std::declval<F>()(std::declval<T>()));
|
|
|
template <typename F>
|
|
|
using flatmap_f = typename decltype(std::declval<F>()(std::declval<T>()))::value_type;
|
|
|
+ template <typename F>
|
|
|
+ using memvar_f = typename map_member_object<F>::type;
|
|
|
+ template <typename F>
|
|
|
+ using memfun_f = typename map_member_function<F>::type;
|
|
|
+ template <typename F>
|
|
|
+ using is_memvar = std::is_member_object_pointer<F>;
|
|
|
+ template <typename F>
|
|
|
+ using is_memfun = std::is_member_function_pointer<F>;
|
|
|
|
|
|
using self = stream_base<T>;
|
|
|
using noref = typename std::remove_reference<T>::type;
|
|
|
@@ -149,42 +161,62 @@ namespace stream {
|
|
|
}
|
|
|
|
|
|
template <typename F>
|
|
|
- clean accumulate(F&& fold, clean const& accum) {
|
|
|
+ clean accumulate(F&& fold, clean const& accum) const {
|
|
|
return std::accumulate(begin(), end(), accum, fold);
|
|
|
}
|
|
|
|
|
|
- clean accumulate(clean const& accum) {
|
|
|
+ clean accumulate(clean const& accum) const {
|
|
|
return std::accumulate(begin(), end(), accum);
|
|
|
}
|
|
|
|
|
|
template <typename F>
|
|
|
- void each(F && consumer) {
|
|
|
+ void each(F && consumer) const {
|
|
|
std::for_each(begin(), end(), consumer);
|
|
|
}
|
|
|
|
|
|
template <typename F>
|
|
|
- stream_base<map_f<F>> map(F&& func) const;
|
|
|
-
|
|
|
- template <typename F, typename = typename std::enable_if<std::is_member_object_pointer<F>::value>::type>
|
|
|
- auto map(F && memvar) const -> stream_base<typename map_member_object<F>::type> {
|
|
|
+ stream_base<map_f<F>> map(F&& func) const &;
|
|
|
+ template <typename F>
|
|
|
+ stream_base<T> filter(F&& func) const &;
|
|
|
+ template <typename F>
|
|
|
+ stream_base<flatmap_f<F>> flatmap(F&& func) const &;
|
|
|
+
|
|
|
+ template <typename F>
|
|
|
+ stream_base<map_f<F>> map(F&& func) &&;
|
|
|
+ template <typename F>
|
|
|
+ stream_base<T> filter(F&& func) &&;
|
|
|
+ template <typename F>
|
|
|
+ stream_base<flatmap_f<F>> flatmap(F&& func) &&;
|
|
|
+
|
|
|
+ template <typename Cast>
|
|
|
+ auto cast() const & -> stream_base<Cast const &> {
|
|
|
+ return map([](T const & p) -> Cast const & { return p; });
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename Cast>
|
|
|
+ auto cast() && -> stream_base<Cast const &> {
|
|
|
+ return std::move(*this).map([](T const & p) -> Cast const & { return p; });
|
|
|
+ }
|
|
|
+
|
|
|
+ template <typename F, typename = typename std::enable_if<is_memvar<F>::value>::type>
|
|
|
+ auto map(F && memvar) const & -> stream_base<memvar_f<F>> {
|
|
|
return map(map_member_object<F>{memvar});
|
|
|
}
|
|
|
-
|
|
|
- template <typename F, typename = typename std::enable_if<std::is_member_function_pointer<F>::value>::type>
|
|
|
- auto map(F && memvar) const -> stream_base<typename map_member_function<F>::type> {
|
|
|
+
|
|
|
+ template <typename F, typename = typename std::enable_if<is_memfun<F>::value>::type>
|
|
|
+ auto map(F && memvar) const & -> stream_base<memfun_f<F>> {
|
|
|
return map(map_member_function<F>{memvar});
|
|
|
}
|
|
|
-
|
|
|
- template <typename Cast>
|
|
|
- auto cast() const -> stream_base<Cast const &> {
|
|
|
- return map([](T const & p) -> Cast const & { return p; });
|
|
|
+
|
|
|
+ template <typename F, typename = typename std::enable_if<is_memvar<F>::value>::type>
|
|
|
+ auto map(F && memvar) && -> stream_base<memvar_f<F>> {
|
|
|
+ return std::move(*this).map(map_member_object<F>{memvar});
|
|
|
}
|
|
|
|
|
|
- template <typename F>
|
|
|
- stream_base<T> filter(F&& func) const;
|
|
|
-
|
|
|
- template <typename F>
|
|
|
- stream_base<flatmap_f<F>> flatmap(F&& func) const;
|
|
|
+ template <typename F, typename = typename std::enable_if<is_memfun<F>::value>::type>
|
|
|
+ auto map(F && memvar) && -> stream_base<memfun_f<F>> {
|
|
|
+ return std::move(*this).map(map_member_function<F>{memvar});
|
|
|
+ }
|
|
|
private:
|
|
|
iterator<T> (*do_begin)(std::shared_ptr<void>){nullptr};
|
|
|
iterator<T> (*do_end)(std::shared_ptr<void>){nullptr};
|