80 lines
1.5 KiB
C++
80 lines
1.5 KiB
C++
#pragma once
|
|
|
|
#include <iterator>
|
|
#include <utility>
|
|
|
|
namespace psemek::util
|
|
{
|
|
|
|
namespace detail
|
|
{
|
|
|
|
template <typename Container>
|
|
auto begin_helper(Container & x)
|
|
{
|
|
using std::begin;
|
|
return begin(x);
|
|
}
|
|
|
|
template <typename Container>
|
|
auto end_helper(Container & x)
|
|
{
|
|
using std::end;
|
|
return end(x);
|
|
}
|
|
|
|
}
|
|
|
|
template <typename Container>
|
|
auto begin(Container & x)
|
|
{
|
|
return detail::begin_helper(x);
|
|
}
|
|
|
|
template <typename Container>
|
|
auto end(Container & x)
|
|
{
|
|
return detail::end_helper(x);
|
|
}
|
|
|
|
template <typename T>
|
|
struct range_traits
|
|
{
|
|
using iterator = decltype(begin(std::declval<T>()));
|
|
using iterator_traits = std::iterator_traits<iterator>;
|
|
|
|
using iterator_category = typename iterator_traits::iterator_category;
|
|
using value_type = typename iterator_traits::value_type ;
|
|
using difference = typename iterator_traits::difference ;
|
|
using pointer = typename iterator_traits::pointer ;
|
|
using reference = typename iterator_traits::reference ;
|
|
};
|
|
|
|
template <typename Iterator>
|
|
struct range
|
|
{
|
|
Iterator it_begin;
|
|
Iterator it_end;
|
|
|
|
Iterator begin() const
|
|
{
|
|
return it_begin;
|
|
}
|
|
|
|
Iterator end() const
|
|
{
|
|
return it_end;
|
|
}
|
|
};
|
|
|
|
template <typename Range>
|
|
auto reversed(Range const & r)
|
|
{
|
|
auto it1 = begin(r);
|
|
auto it2 = end(r);
|
|
|
|
using ReverseIterator = std::reverse_iterator<decltype(it1)>;
|
|
return range<ReverseIterator>{std::make_reverse_iterator(it2), std::make_reverse_iterator(it1)};
|
|
}
|
|
|
|
}
|