#ifndef SPROUT_RANGE_ADAPTOR_ADAPTED_OFFSET_HPP #define SPROUT_RANGE_ADAPTOR_ADAPTED_OFFSET_HPP #include #include #include #include #include #include #include namespace sprout { namespace adaptors { // // adapt_offset_holder // template class adapt_offset_holder { public: typedef Adaptor adaptor_type; typedef typename sprout::arithmetic_promote::type difference_type; private: adaptor_type adaptor_; difference_type from_begin_; difference_type from_end_; public: explicit SPROUT_CONSTEXPR adapt_offset_holder(adaptor_type const& adaptor, difference_type from_begin, difference_type from_end) : adaptor_(adaptor), from_begin_(from_begin), from_end_(from_end) {} SPROUT_CONSTEXPR adaptor_type const& adaptor() const { return adaptor_; } SPROUT_CONSTEXPR difference_type const& from_begin() const { return from_begin_; } SPROUT_CONSTEXPR difference_type const& from_end() const { return from_end_; } }; template class adapt_offset_holder { public: typedef Adaptor adaptor_type; typedef Difference difference_type; private: adaptor_type adaptor_; difference_type from_begin_; public: explicit SPROUT_CONSTEXPR adapt_offset_holder(adaptor_type const& adaptor, difference_type from_begin) : adaptor_(adaptor), from_begin_(from_begin) {} SPROUT_CONSTEXPR adaptor_type const& adaptor() const { return adaptor_; } SPROUT_CONSTEXPR difference_type const& from_begin() const { return from_begin_; } }; // // adapted_offset_forwarder // class adapted_offset_forwarder { public: template SPROUT_CONSTEXPR sprout::adaptors::adapt_offset_holder operator()(Adaptor const& adaptor, Difference1 from_begin, Difference2 from_end) { return sprout::adaptors::adapt_offset_holder(adaptor, from_begin, from_end); } template SPROUT_CONSTEXPR sprout::adaptors::adapt_offset_holder operator()(Adaptor const& adaptor, Difference from_begin) { return sprout::adaptors::adapt_offset_holder(adaptor, from_begin); } }; // // adapted_offset // namespace { SPROUT_STATIC_CONSTEXPR sprout::adaptors::adapted_offset_forwarder adapted_offset{}; } // anonymous-namespace // // operator| // template inline SPROUT_CONSTEXPR auto operator|(Range&& lhs, sprout::adaptors::adapt_offset_holder const& rhs) -> decltype( sprout::lvalue_forward(lhs) | sprout::adaptors::taken(rhs.from_begin()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::offset(rhs.from_begin(), rhs.from_end()) | rhs.adaptor()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::taken_end(rhs.from_end())) ) { return sprout::lvalue_forward(lhs) | sprout::adaptors::taken(rhs.from_begin()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::offset(rhs.from_begin(), rhs.from_end()) | rhs.adaptor()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::taken_end(rhs.from_end())) ; } template inline SPROUT_CONSTEXPR auto operator|(Range&& lhs, sprout::adaptors::adapt_offset_holder const& rhs) -> decltype( sprout::lvalue_forward(lhs) | sprout::adaptors::taken(rhs.from_begin()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::offset(rhs.from_begin()) | rhs.adaptor()) ) { return sprout::lvalue_forward(lhs) | sprout::adaptors::taken(rhs.from_begin()) | sprout::adaptors::jointed(sprout::lvalue_forward(lhs) | sprout::adaptors::offset(rhs.from_begin()) | rhs.adaptor()) ; } } // namespace adaptors } // namespace sprout #endif // #ifndef SPROUT_RANGE_ADAPTOR_ADAPTED_OFFSET_HPP