enumerate.h 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #pragma once
  2. #if __cplusplus >= 202302L
  3. #include <ranges>
  4. #if __cpp_lib_ranges_enumerate >= 202302L
  5. #define JVALIDATE_USE_STD_RANGES_ENUMERATE
  6. #endif
  7. #endif
  8. #ifdef JVALIDATE_USE_STD_RANGES_ENUMERATE
  9. namespace jvalidate::detail {
  10. using std::ranges::views::enumerate;
  11. }
  12. #else
  13. #include <iterator>
  14. #include <utility>
  15. #include <jvalidate/detail/deref_proxy.h>
  16. namespace jvalidate::detail {
  17. template <typename It> class enumurate_iterator {
  18. public:
  19. using traits_t = std::iterator_traits<It>;
  20. using value_type = std::pair<size_t, typename traits_t::value_type>;
  21. using reference = std::pair<size_t const &, typename traits_t::reference>;
  22. using pointer = DerefProxy<reference>;
  23. using difference_type = typename traits_t::difference_type;
  24. using iterator_category = typename traits_t::iterator_category;
  25. private:
  26. size_t index_ = 0;
  27. It iter_;
  28. public:
  29. enumurate_iterator(It iter) : iter_(iter) {}
  30. reference operator*() const { return {index_, *iter_}; }
  31. pointer operator->() const { return operator*(); }
  32. enumurate_iterator & operator++() {
  33. ++index_;
  34. ++iter_;
  35. return *this;
  36. }
  37. friend bool operator==(enumurate_iterator<It> rhs, enumurate_iterator<It> lhs) {
  38. return rhs.iter_ == lhs.iter_;
  39. }
  40. friend bool operator!=(enumurate_iterator<It> rhs, enumurate_iterator<It> lhs) {
  41. return rhs.iter_ != lhs.iter_;
  42. }
  43. };
  44. template <typename C> auto enumerate(C && container) {
  45. struct {
  46. auto begin() const { return enumurate_iterator(c.begin()); }
  47. auto end() const { return enumurate_iterator(c.end()); }
  48. C c;
  49. } rval{std::forward<C>(container)};
  50. return rval;
  51. }
  52. }
  53. #endif