13USERVER_NAMESPACE_BEGIN
15namespace utils::impl {
17template <
typename Iter>
18auto DetectEnumerateValueType()
19 -> std::pair<
const std::size_t,
decltype(*std::declval<Iter>())>;
21template <
typename Iter,
typename... Args>
22auto DetectEnumerateValueType(Args&&...) ->
void;
24template <
typename Iter>
25struct IteratorWrapper {
26 using difference_type = std::ptrdiff_t;
27 using value_type =
decltype(DetectEnumerateValueType<Iter>());
28 using reference = value_type;
29 using iterator_category = std::input_iterator_tag;
34 constexpr IteratorWrapper& operator++() {
40 constexpr value_type operator*()
const {
return {pos, *iterator}; }
42 template <
typename OtherIter>
43 constexpr bool operator==(
const IteratorWrapper<OtherIter>& other)
const {
44 return iterator == other.iterator;
47 template <
typename OtherIter>
48 constexpr bool operator!=(
const IteratorWrapper<OtherIter>& other)
const {
49 return !(iterator == other.iterator);
53template <
typename Range>
54using IteratorTypeOf =
decltype(std::begin(std::declval<Range&>()));
56template <
typename Range>
57using SentinelTypeOf =
decltype(std::end(std::declval<Range&>()));
59template <
typename Container>
60struct ContainerWrapper {
61 constexpr IteratorWrapper<IteratorTypeOf<Container>> begin() {
62 return {std::begin(container), 0};
65 constexpr IteratorWrapper<SentinelTypeOf<Container>> end() {
66 return {std::end(container), 0};
69 constexpr IteratorWrapper<IteratorTypeOf<
const Container>> begin()
const {
70 return {std::begin(container), 0};
73 constexpr IteratorWrapper<SentinelTypeOf<
const Container>> end()
const {
74 return {std::end(container), 0};
93template <
typename Container>
95 return impl::ContainerWrapper<Container>{std::forward<Container>(iterable)};