| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- #pragma once
- #if __cplusplus >= 202302L
- #include <ranges>
- #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 <iterator>
- #include <utility>
- #include <jvalidate/detail/deref_proxy.h>
- namespace jvalidate::detail {
- /**
- * @brief A replacement for std::ranges::views::enumerate in C++20 (as enumerate
- * is a C++23 feature).
- * Much like python's enumerate() function, this is an iterator adapter that
- * attaches the "index" of the iteration to each element - incrementing it as
- * we go.
- */
- template <typename It> class enumurate_iterator {
- public:
- using traits_t = std::iterator_traits<It>;
- using value_type = std::pair<size_t, typename traits_t::value_type>;
- using reference = std::pair<size_t const &, typename traits_t::reference>;
- using pointer = DerefProxy<reference>;
- using difference_type = typename traits_t::difference_type;
- using iterator_category = std::forward_iterator_tag;
- 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<It> rhs, enumurate_iterator<It> lhs) {
- return rhs.iter_ == lhs.iter_;
- }
- friend bool operator!=(enumurate_iterator<It> rhs, enumurate_iterator<It> lhs) {
- return rhs.iter_ != lhs.iter_;
- }
- };
- template <typename C> 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<C>(container)};
- return rval;
- }
- }
- #endif
|