/*============================================================================= Copyright (c) 2011-2015 Bolero MURAKAMI https://github.com/bolero-MURAKAMI/Sprout Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #ifndef SPROUT_RANGE_ADAPTOR_OFFSET_HPP #define SPROUT_RANGE_ADAPTOR_OFFSET_HPP #include #include #include #include #include #include #include #include #include #include HDR_ALGORITHM_MIN_MAX_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace adaptors { // // offset_holder // template class offset_holder { public: typedef typename sprout::arithmetic_promote::type difference_type; private: difference_type from_begin_; difference_type from_end_; public: SPROUT_CONSTEXPR offset_holder(difference_type from_begin, difference_type from_end) : from_begin_(from_begin), from_end_(from_end) {} SPROUT_CONSTEXPR difference_type const& from_begin() const { return from_begin_; } SPROUT_CONSTEXPR difference_type const& from_end() const { return from_end_; } }; template class offset_holder { public: typedef Difference difference_type; private: difference_type from_begin_; public: explicit SPROUT_CONSTEXPR offset_holder(difference_type from_begin) : from_begin_(from_begin) {} SPROUT_CONSTEXPR difference_type const& from_begin() const { return from_begin_; } }; // // offset_forwarder // class offset_forwarder { public: template SPROUT_CONSTEXPR sprout::adaptors::offset_holder operator()(Difference1 from_begin, Difference2 from_end) const { return sprout::adaptors::offset_holder(from_begin, from_end); } template SPROUT_CONSTEXPR sprout::adaptors::offset_holder operator()(Difference from_begin) const { return sprout::adaptors::offset_holder(from_begin); } }; // // offset // namespace { SPROUT_STATIC_CONSTEXPR sprout::adaptors::offset_forwarder offset = {}; } // anonymous-namespace // // operator| // template inline SPROUT_CONSTEXPR sprout::adaptors::detail::adapted_range_default< typename std::remove_reference::type>::type > operator|(Range&& lhs, sprout::adaptors::offset_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.from_begin(), sprout::size(sprout::lvalue_forward(lhs))) ), sprout::next( sprout::end(sprout::lvalue_forward(lhs)), NS_SSCRISK_CEL_OR_SPROUT::max( rhs.from_end(), NS_SSCRISK_CEL_OR_SPROUT::min(rhs.from_begin() - sprout::size(sprout::lvalue_forward(lhs)), 0) ) ) ); } template inline SPROUT_CONSTEXPR sprout::adaptors::detail::adapted_range_default< typename std::remove_reference::type>::type > operator|(Range&& lhs, sprout::adaptors::offset_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.from_begin(), sprout::size(sprout::lvalue_forward(lhs))) ), sprout::end(sprout::lvalue_forward(lhs)) ); } } // namespace adaptors } // namespace sprout #endif // #ifndef SPROUT_RANGE_ADAPTOR_OFFSET_HPP