#ifndef SPROUT_ITERATOR_NEXT_HPP #define SPROUT_ITERATOR_NEXT_HPP #include #include #include #include namespace sprout { namespace detail { template SPROUT_CONSTEXPR typename std::enable_if< std::is_literal_type::type>::value, typename std::decay::type >::type next_impl( Iterator&& it, std::random_access_iterator_tag* ) { return sprout::forward(it) + 1; } template SPROUT_CONSTEXPR typename std::decay::type next_impl( Iterator&& it, void* ) { using std::next; return next(sprout::forward(it)); } template SPROUT_CONSTEXPR typename std::enable_if< std::is_literal_type::type>::value, typename std::decay::type >::type next_impl( Iterator&& it, typename std::iterator_traits::type>::difference_type n, std::random_access_iterator_tag* ) { return sprout::forward(it) + n; } template SPROUT_CONSTEXPR typename std::decay::type next_impl( Iterator it, typename std::iterator_traits::type>::difference_type n, void* ) { using std::next; return next(sprout::forward(it), n); } } // namespace detail // // next // template SPROUT_CONSTEXPR typename std::decay::type next(Iterator&& it) { return sprout::detail::next_impl( sprout::forward(it), static_cast::type>::iterator_category*>(nullptr) ); } template SPROUT_CONSTEXPR typename std::decay::type next( Iterator&& it, typename std::iterator_traits::type>::difference_type n ) { return sprout::detail::next_impl( sprout::forward(it), n, static_cast::type>::iterator_category*>(nullptr) ); } } // namespace sprout #endif // #ifndef SPROUT_ITERATOR_NEXT_HPP