#ifndef SPROUT_COMPOST_EFFECTS_SUPERPOSED_HPP #define SPROUT_COMPOST_EFFECTS_SUPERPOSED_HPP #include #include #include #include #include #include #include namespace sprout { namespace compost { namespace effects { // // superpose_holder // template class superpose_holder { public: typedef RRange range2_type; private: sprout::value_holder range_; public: superpose_holder() = default; superpose_holder(superpose_holder const&) = default; explicit SPROUT_CONSTEXPR superpose_holder(range2_type& range) : range_(range) {} SPROUT_CONSTEXPR range2_type& range() const { return range_; } }; // // superposed_forwarder // class superposed_forwarder { public: template SPROUT_CONSTEXPR sprout::compost::effects::superpose_holder< typename std::remove_reference::type>::type > operator()(RRange&& range) { return sprout::compost::effects::superpose_holder< typename std::remove_reference::type>::type >( sprout::lvalue_forward(range) ); } }; // // superposed // namespace { SPROUT_STATIC_CONSTEXPR sprout::compost::effects::superposed_forwarder superposed = {}; } // anonymous-namespace // // operator| // template inline SPROUT_CONSTEXPR auto operator|(Range&& lhs, sprout::compost::effects::superpose_holder const& rhs) -> decltype( sprout::forward(lhs) | sprout::adaptors::transformed(rhs.range(), sprout::plus<>()) ) { return sprout::forward(lhs) | sprout::adaptors::transformed(rhs.range(), sprout::plus<>()) ; } } // namespace effects using sprout::compost::effects::superposed; } // namespace compost } // namespace sprout #endif // #ifndef SPROUT_COMPOST_EFFECTS_SUPERPOSED_HPP