psemek/libs/util/include/psemek/util/range.hpp

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)};
}
}