#ifndef SPROUT_RANGE_ADAPTOR_SIZED_HPP #define SPROUT_RANGE_ADAPTOR_SIZED_HPP #include #include #include #include #include #include #include #include #include #include #include #include namespace sprout { namespace adaptors { namespace detail { template::size_type Size, typename = void> class sized_impl; template::size_type Size> class sized_impl< Range, Size, typename std::enable_if >::value>::type > { public: SPROUT_STATIC_CONSTEXPR typename sprout::container_traits::size_type static_size = Size < sprout::container_traits::static_size ? Size : sprout::container_traits::static_size ; static SPROUT_CONSTEXPR typename sprout::container_traits::size_type fixed_size() { return static_size; } }; template::size_type Size> SPROUT_CONSTEXPR_OR_CONST typename sprout::container_traits::size_type sized_impl< Range, Size, typename std::enable_if >::value>::type >::static_size; template::size_type Size> class sized_impl< Range, Size, typename std::enable_if >::value>::type > { public: SPROUT_STATIC_CONSTEXPR typename sprout::container_traits::size_type static_size = Size; static SPROUT_CONSTEXPR typename sprout::container_traits::size_type fixed_size() { return static_size; } }; template::size_type Size> SPROUT_CONSTEXPR_OR_CONST typename sprout::container_traits::size_type sized_impl< Range, Size, typename std::enable_if >::value>::type >::static_size; } // namespace detail // // sized_range // template::size_type Size> class sized_range : public sprout::range::range_container< typename sprout::container_traits::iterator > , public sprout::adaptors::detail::sized_impl { public: typedef Range range_type; typedef sprout::range::range_container< typename sprout::container_traits::iterator > base_type; private: typedef sprout::adaptors::detail::sized_impl sized_impl_type; public: sized_range() = default; sized_range(sized_range const&) = default; explicit SPROUT_CONSTEXPR sized_range(range_type& range) : base_type( sprout::begin(range), sized_impl_type::static_size < static_cast::size_type>(sprout::size(range)) ? sprout::next(sprout::begin(range), sized_impl_type::static_size) : sprout::end(range) ) {} }; // // size_holder // template class size_holder : public std::integral_constant {}; // // sized // template inline SPROUT_CONSTEXPR sprout::adaptors::size_holder sized() { return sprout::adaptors::size_holder(); } // // operator| // template inline SPROUT_CONSTEXPR sprout::adaptors::sized_range< typename std::remove_reference::type>::type, Size > operator|(Range&& lhs, sprout::adaptors::size_holder const& rhs) { return sprout::adaptors::sized_range< typename std::remove_reference::type>::type, Size >( sprout::lvalue_forward(lhs) ); } } // namespace adaptors // // container_construct_traits // template::size_type Size> struct container_construct_traits > { private: typedef typename sprout::container_construct_traits::copied_type range_copied_type; public: typedef typename sprout::containers::weak_rebind_size< range_copied_type, sprout::adaptors::sized_range::static_size >::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_SIZED_HPP