13USERVER_NAMESPACE_BEGIN
15namespace utils::impl {
17template <
typename Iter>
18auto DetectEnumerateValueType() -> std::pair<
const std::size_t,
decltype(*std::declval<Iter>())>;
20template <
typename Iter,
typename... Args>
21auto DetectEnumerateValueType(Args&&...) ->
void;
23template <
typename Iter>
24struct IteratorWrapper {
25 using difference_type = std::ptrdiff_t;
26 using value_type =
decltype(DetectEnumerateValueType<Iter>());
27 using reference = value_type;
28 using iterator_category = std::input_iterator_tag;
33 constexpr IteratorWrapper& operator++() {
39 constexpr value_type operator*()
const {
return {pos, *iterator}; }
41 template <
typename OtherIter>
42 constexpr bool operator==(
const IteratorWrapper<OtherIter>& other)
const {
43 return iterator == other.iterator;
46 template <
typename OtherIter>
47 constexpr bool operator!=(
const IteratorWrapper<OtherIter>& other)
const {
48 return !(iterator == other.iterator);
52template <
typename Range>
53using IteratorTypeOf =
decltype(std::begin(std::declval<Range&>()));
55template <
typename Range>
56using SentinelTypeOf =
decltype(std::end(std::declval<Range&>()));
58template <
typename Container>
59struct ContainerWrapper {
60 constexpr IteratorWrapper<IteratorTypeOf<Container>> begin() {
return {std::begin(container), 0}; }
62 constexpr IteratorWrapper<SentinelTypeOf<Container>> end() {
return {std::end(container), 0}; }
64 constexpr IteratorWrapper<IteratorTypeOf<
const Container>> begin()
const {
return {std::begin(container), 0}; }
66 constexpr IteratorWrapper<SentinelTypeOf<
const Container>> end()
const {
return {std::end(container), 0}; }
84template <
typename Container>
86 return impl::ContainerWrapper<Container>{std::forward<Container>(iterable)};