#ifndef SPROUT_RANGE_ADAPTOR_CLAMPED_HPP #define SPROUT_RANGE_ADAPTOR_CLAMPED_HPP #include #include #include #include #include #include #include #include #include #include #include #include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT namespace sprout { namespace adaptors { // // clamped_range // template< typename Range, typename Compare = NS_SSCRISK_CEL_OR_SPROUT::less::value_type> > class clamped_range : public sprout::range::range_container< sprout::clamp_iterator::iterator, Compare> > , public sprout::detail::container_nosy_static_size , public sprout::detail::container_nosy_fixed_size { public: typedef Range range_type; typedef sprout::range::range_container< sprout::clamp_iterator::iterator, Compare> > base_type; typedef typename base_type::iterator iterator; typedef typename base_type::value_type value_type; typedef typename iterator::compare_type compare_type; public: clamped_range() = default; clamped_range(clamped_range const&) = default; explicit SPROUT_CONSTEXPR clamped_range( range_type& range, value_type const& low, value_type const& up, compare_type comp = compare_type() ) : base_type( iterator(sprout::begin(range), low, up, comp), iterator(sprout::end(range), low, up, comp) ) {} SPROUT_CONSTEXPR compare_type const& compare() const { return base_type::begin().compare(); } SPROUT_CONSTEXPR value_type const& lower() const { return base_type::begin().lower(); } SPROUT_CONSTEXPR value_type const& upper() const { return base_type::begin().upper(); } }; // // clamp_holder // template > class clamp_holder { public: typedef Value value_type; typedef Compare compare_type; private: compare_type comp_; value_type low_; value_type up_; public: SPROUT_CONSTEXPR clamp_holder(value_type const& low, value_type const& up, compare_type comp = compare_type()) : comp_(comp), low_(low), up_(up) {} SPROUT_CONSTEXPR compare_type const& compare() const { return comp_; } SPROUT_CONSTEXPR value_type const& lower() const { return low_; } SPROUT_CONSTEXPR value_type const& upper() const { return up_; } }; // // clamped_forwarder // class clamped_forwarder { public: template SPROUT_CONSTEXPR sprout::adaptors::clamp_holder operator()(Value const& low, Value const& up, Compare comp) { return sprout::adaptors::clamp_holder(low, up, comp); } template SPROUT_CONSTEXPR sprout::adaptors::clamp_holder operator()(Value const& low, Value const& up) { return sprout::adaptors::clamp_holder(low, up); } }; // // clamped // namespace { SPROUT_STATIC_CONSTEXPR sprout::adaptors::clamped_forwarder clamped{}; } // anonymous-namespace // // operator| // template inline SPROUT_CONSTEXPR sprout::adaptors::clamped_range< typename std::remove_reference::type>::type, Compare > operator|(Range&& lhs, sprout::adaptors::clamp_holder const& rhs) { return sprout::adaptors::clamped_range< typename std::remove_reference::type>::type, Compare >( sprout::lvalue_forward(lhs), rhs.lower(), rhs.upper(), rhs.compare() ); } } // namespace adaptors // // container_construct_traits // template struct container_construct_traits > { public: typedef typename sprout::container_construct_traits::copied_type copied_type; public: template static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); } template static SPROUT_CONSTEXPR copied_type make(Args&&... args) { return sprout::make(sprout::forward(args)...); } template static SPROUT_CONSTEXPR copied_type remake( Cont&& cont, typename sprout::container_traits >::difference_type size, Args&&... args ) { return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); } }; } // namespace sprout #endif // #ifndef SPROUT_RANGE_ADAPTOR_CLAMPED_HPP