#ifndef SPROUT_RANGE_ADAPTOR_WINDOW_HPP #define SPROUT_RANGE_ADAPTOR_WINDOW_HPP #include #include #include #include #include #include #include #include #include #include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace adaptors { // // window_holder // template class window_holder { public: typedef typename sprout::arithmetic_promote::type difference_type; private: difference_type to_first_; difference_type to_last_; public: SPROUT_CONSTEXPR window_holder(difference_type to_first, difference_type to_last) : to_first_(to_first), to_last_(to_last) {} SPROUT_CONSTEXPR difference_type const& to_first() const { return to_first_; } SPROUT_CONSTEXPR difference_type const& to_last() const { return to_last_; } }; template class window_holder { public: typedef Difference difference_type; private: difference_type to_first_; public: explicit SPROUT_CONSTEXPR window_holder(difference_type to_first) : to_first_(to_first) {} SPROUT_CONSTEXPR difference_type const& to_first() const { return to_first_; } }; // // window_forwarder // class window_forwarder { public: template SPROUT_CONSTEXPR sprout::adaptors::window_holder operator()(Difference1 to_first, Difference2 to_last) { return sprout::adaptors::window_holder(to_first, to_last); } template SPROUT_CONSTEXPR sprout::adaptors::window_holder operator()(Difference to_first) { return sprout::adaptors::window_holder(to_first); } }; // // window // namespace { SPROUT_STATIC_CONSTEXPR sprout::adaptors::window_forwarder window = {}; } // anonymous-namespace // // operator| // template inline SPROUT_CONSTEXPR sprout::adaptors::detail::adapted_range_default< typename std::remove_reference::type>::type > operator|(Range&& lhs, sprout::adaptors::window_holder const& rhs) { typedef typename sprout::container_traits< typename std::remove_reference::type>::type >::difference_type difference_type; return sprout::adaptors::detail::adapted_range_default< typename std::remove_reference::type>::type >( sprout::next( sprout::begin(sprout::lvalue_forward(lhs)), NS_SSCRISK_CEL_OR_SPROUT::min(rhs.to_first(), sprout::size(sprout::lvalue_forward(lhs))) ), sprout::next( sprout::begin(sprout::lvalue_forward(lhs)), NS_SSCRISK_CEL_OR_SPROUT::min(rhs.to_last(), sprout::size(sprout::lvalue_forward(lhs))) ) ); } template inline SPROUT_CONSTEXPR sprout::adaptors::detail::adapted_range_default< typename std::remove_reference::type>::type > operator|(Range&& lhs, sprout::adaptors::window_holder const& rhs) { typedef typename sprout::container_traits< typename std::remove_reference::type>::type >::difference_type difference_type; return sprout::adaptors::detail::adapted_range_default< typename std::remove_reference::type>::type >( sprout::next( sprout::begin(sprout::lvalue_forward(lhs)), NS_SSCRISK_CEL_OR_SPROUT::min(rhs.to_first(), sprout::size(sprout::lvalue_forward(lhs))) ), sprout::end(sprout::lvalue_forward(lhs)) ); } } // namespace adaptors } // namespace sprout #endif // #ifndef SPROUT_RANGE_ADAPTOR_WINDOW_HPP