1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
#include <iostream>
#include <iterator>
#include <algorithm>
#include <list>
#include <type_traits>
namespace utility
{
namespace detail
{
template < typename BIDIRECTIONAL_ITERATOR >
void reverse( BIDIRECTIONAL_ITERATOR begin, BIDIRECTIONAL_ITERATOR end, std::bidirectional_iterator_tag tag )
{
if( ( begin != end ) && ( begin != --end ) )
{
std::iter_swap( begin, end ) ;
reverse( ++begin, end, tag ) ;
}
}
template < typename RANDOM_ACCESS_ITERATOR >
void reverse( RANDOM_ACCESS_ITERATOR begin, RANDOM_ACCESS_ITERATOR end, std::random_access_iterator_tag tag )
{
if( begin < --end )
{
std::iter_swap( begin, end ) ;
reverse( ++begin, end, tag ) ;
}
}
template < typename ITERATOR > using category = typename std::iterator_traits<ITERATOR>::iterator_category ;
template < typename ITERATOR >
constexpr auto swappable_values = std::is_swappable<typename std::iterator_traits<ITERATOR>::value_type>::value ;
template < typename ITERATOR >
constexpr auto nothrow_swappable_values = std::is_nothrow_swappable<typename std::iterator_traits<ITERATOR>::value_type>::value ;
}
template < typename ITERATOR >
void reverse( ITERATOR begin, ITERATOR end ) noexcept( detail::nothrow_swappable_values<ITERATOR> )
{
static_assert( detail::swappable_values<ITERATOR> ) ;
detail::reverse( begin, end, typename detail::category<ITERATOR>{} ) ;
}
template < typename SEQUENCE >
void reverse( SEQUENCE& seq ) noexcept( detail::nothrow_swappable_values< decltype( std::begin(seq) ) > )
{ utility::reverse( std::begin(seq), std::end(seq) ) ; }
}
int main()
{
int a[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } ;
utility::reverse(a) ;
for( int v : a ) std::cout << v << ' ' ;
std::cout << '\n' ;
std::list b { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } ;
utility::reverse(b) ;
for( int v : b ) std::cout << v << ' ' ;
std::cout << '\n' ;
}
|