#ifndef SPROUT_RANGE_ADAPTOR_ADAPTED_WINDOW_HPP #define SPROUT_RANGE_ADAPTOR_ADAPTED_WINDOW_HPP #include #include #include #include #include #include #include namespace sprout { namespace adaptors { // // adapt_window_holder // template class adapt_window_holder { public: typedef Adaptor adaptor_type; typedef typename sprout::arithmetic_promote::type difference_type; private: adaptor_type adaptor_; difference_type to_first_; difference_type to_last_; public: explicit SPROUT_CONSTEXPR adapt_window_holder(adaptor_type const& adaptor, difference_type to_first, difference_type to_last) : adaptor_(adaptor), to_first_(to_first), to_last_(to_last) {} SPROUT_CONSTEXPR adaptor_type const& adaptor() const { return adaptor_; } SPROUT_CONSTEXPR difference_type const& to_first() const { return to_first_; } SPROUT_CONSTEXPR difference_type const& to_last() const { return to_last_; } }; template class adapt_window_holder { public: typedef Adaptor adaptor_type; typedef Difference difference_type; private: adaptor_type adaptor_; difference_type to_first_; public: explicit SPROUT_CONSTEXPR adapt_window_holder(adaptor_type const& adaptor, difference_type to_first) : adaptor_(adaptor), to_first_(to_first) {} SPROUT_CONSTEXPR adaptor_type const& adaptor() const { return adaptor_; } SPROUT_CONSTEXPR difference_type const& to_first() const { return to_first_; } }; // // adapted_window_forwarder // class adapted_window_forwarder { public: template SPROUT_CONSTEXPR sprout::adaptors::adapt_window_holder operator()(Adaptor const& adaptor, Difference1 to_first, Difference2 to_last) { return sprout::adaptors::adapt_window_holder(adaptor, to_first, to_last); } template SPROUT_CONSTEXPR sprout::adaptors::adapt_window_holder operator()(Adaptor const& adaptor, Difference to_first) { return sprout::adaptors::adapt_window_holder(adaptor, to_first); } }; // // adapted_window // namespace { SPROUT_STATIC_CONSTEXPR sprout::adaptors::adapted_window_forwarder adapted_window{}; } // anonymous-namespace // // operator| // template inline SPROUT_CONSTEXPR auto operator|(Range&& lhs, sprout::adaptors::adapt_window_holder const& rhs) -> decltype( sprout::lvalue_forward(lhs) | sprout::adaptors::taken(rhs.to_first()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::window(rhs.to_first(), rhs.to_last()) | rhs.adaptor()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::dropped(rhs.to_last())) ) { return sprout::lvalue_forward(lhs) | sprout::adaptors::taken(rhs.to_first()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::window(rhs.to_first(), rhs.to_last()) | rhs.adaptor()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::dropped(rhs.to_last())) ; } template inline SPROUT_CONSTEXPR auto operator|(Range&& lhs, sprout::adaptors::adapt_window_holder const& rhs) -> decltype( sprout::lvalue_forward(lhs) | sprout::adaptors::taken(rhs.to_first()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::window(rhs.to_first()) | rhs.adaptor()) ) { return sprout::lvalue_forward(lhs) | sprout::adaptors::taken(rhs.to_first()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::window(rhs.to_first()) | rhs.adaptor()) ; } } // namespace adaptors } // namespace sprout #endif // #ifndef SPROUT_RANGE_ADAPTOR_ADAPTED_WINDOW_HPP