#pragma once #if __cplusplus >= 202302L #include #if __cpp_lib_ranges_enumerate >= 202302L #define JVALIDATE_USE_STD_RANGES_ENUMERATE #endif #endif #ifdef JVALIDATE_USE_STD_RANGES_ENUMERATE namespace jvalidate::detail { using std::ranges::views::enumerate; } #else #include #include #include namespace jvalidate::detail { template class enumurate_iterator { public: using traits_t = std::iterator_traits; using value_type = std::pair; using reference = std::pair; using pointer = DerefProxy; using difference_type = typename traits_t::difference_type; using iterator_category = typename traits_t::iterator_category; private: size_t index_ = 0; It iter_; public: enumurate_iterator(It iter) : iter_(iter) {} reference operator*() const { return {index_, *iter_}; } pointer operator->() const { return operator*(); } enumurate_iterator & operator++() { ++index_; ++iter_; return *this; } friend bool operator==(enumurate_iterator rhs, enumurate_iterator lhs) { return rhs.iter_ == lhs.iter_; } friend bool operator!=(enumurate_iterator rhs, enumurate_iterator lhs) { return rhs.iter_ != lhs.iter_; } }; template auto enumerate(C && container) { struct { auto begin() const { return enumurate_iterator(c.begin()); } auto end() const { return enumurate_iterator(c.end()); } C c; } rval{std::forward(container)}; return rval; } } #endif