|  | 
| 1 | 1 | /* | 
| 2 | 2 |  * The MIT License (MIT) | 
| 3 | 3 |  * | 
| 4 |  | - * Copyright (c) 2015-2022 Advanced Micro Devices, Inc. All rights reserved. | 
|  | 4 | + * Copyright (c) 2015-2025 Advanced Micro Devices, Inc. All rights reserved. | 
| 5 | 5 |  * | 
| 6 | 6 |  * Permission is hereby granted, free of charge, to any person obtaining a copy | 
| 7 | 7 |  * of this software and associated documentation files (the "Software"), to deal | 
|  | 
| 26 | 26 | 
 | 
| 27 | 27 | #include <migraphx/config.hpp> | 
| 28 | 28 | #include <migraphx/functional.hpp> | 
|  | 29 | +#include <migraphx/iterator.hpp> | 
| 29 | 30 | #include <iterator> | 
| 30 |  | -#include <type_traits> | 
| 31 | 31 | 
 | 
| 32 | 32 | namespace migraphx { | 
| 33 | 33 | inline namespace MIGRAPHX_INLINE_NS { | 
| 34 | 34 | 
 | 
| 35 | 35 | template <class F, class Iterator = std::ptrdiff_t> | 
| 36 |  | -struct basic_iota_iterator | 
|  | 36 | +struct basic_iota_iterator : iterator_operators<basic_iota_iterator<F, Iterator>>, | 
|  | 37 | +                             iterator_types<decltype(std::declval<F>()(std::declval<Iterator>())), | 
|  | 38 | +                                            std::random_access_iterator_tag> | 
| 37 | 39 | { | 
| 38 | 40 |     Iterator index; | 
| 39 | 41 |     F f; | 
| 40 | 42 | 
 | 
| 41 |  | -    using difference_type   = std::ptrdiff_t; | 
| 42 |  | -    using reference         = decltype(f(std::declval<Iterator>())); | 
| 43 |  | -    using value_type        = typename std::remove_reference<reference>::type; | 
| 44 |  | -    using pointer           = typename std::add_pointer<value_type>::type; | 
| 45 |  | -    using iterator_category = std::random_access_iterator_tag; | 
|  | 43 | +    using reference = decltype(std::declval<F>()(std::declval<Iterator>())); | 
| 46 | 44 | 
 | 
| 47 |  | -    basic_iota_iterator& operator+=(int n) | 
|  | 45 | +    // cppcheck-suppress uninitMemberVar | 
|  | 46 | +    constexpr basic_iota_iterator() = default; | 
|  | 47 | + | 
|  | 48 | +    template <class... Ts> | 
|  | 49 | +    constexpr basic_iota_iterator(Iterator i, Ts&&... xs) : index(i), f{std::forward<Ts>(xs)...} | 
|  | 50 | +    { | 
|  | 51 | +    } | 
|  | 52 | + | 
|  | 53 | +    constexpr basic_iota_iterator::reference operator*() const { return f(index); } | 
|  | 54 | + | 
|  | 55 | +    template <class U> | 
|  | 56 | +    static constexpr auto increment(U& x) -> decltype(++x.index) | 
| 48 | 57 |     { | 
| 49 |  | -        index += n; | 
| 50 |  | -        return *this; | 
|  | 58 | +        return ++x.index; | 
| 51 | 59 |     } | 
| 52 | 60 | 
 | 
| 53 |  | -    basic_iota_iterator& operator-=(int n) | 
|  | 61 | +    template <class U> | 
|  | 62 | +    static constexpr auto decrement(U& x) -> decltype(--x.index) | 
| 54 | 63 |     { | 
| 55 |  | -        index -= n; | 
| 56 |  | -        return *this; | 
|  | 64 | +        return --x.index; | 
| 57 | 65 |     } | 
| 58 | 66 | 
 | 
| 59 |  | -    basic_iota_iterator& operator++() | 
|  | 67 | +    template <class U, class I> | 
|  | 68 | +    static constexpr auto advance(U& x, I n) -> decltype(x.index += n) | 
| 60 | 69 |     { | 
| 61 |  | -        index++; | 
| 62 |  | -        return *this; | 
|  | 70 | +        return x.index += n; | 
| 63 | 71 |     } | 
| 64 | 72 | 
 | 
| 65 |  | -    basic_iota_iterator& operator--() | 
|  | 73 | +    template <class U, class V> | 
|  | 74 | +    static constexpr auto distance(const U& x, const V& y) -> decltype(y.index - x.index) | 
| 66 | 75 |     { | 
| 67 |  | -        index--; | 
| 68 |  | -        return *this; | 
|  | 76 | +        return y.index - x.index; | 
| 69 | 77 |     } | 
| 70 | 78 | 
 | 
| 71 |  | -    basic_iota_iterator operator++(int) // NOLINT | 
|  | 79 | +    template <class U, class V> | 
|  | 80 | +    static constexpr auto equal(const U& x, const V& y) -> decltype(x.index == y.index) | 
| 72 | 81 |     { | 
| 73 |  | -        basic_iota_iterator it = *this; | 
| 74 |  | -        index++; | 
| 75 |  | -        return it; | 
|  | 82 | +        return x.index == y.index; | 
| 76 | 83 |     } | 
| 77 | 84 | 
 | 
| 78 |  | -    basic_iota_iterator operator--(int) // NOLINT | 
|  | 85 | +    template <class Stream> | 
|  | 86 | +    friend Stream& operator<<(Stream& s, const basic_iota_iterator& x) | 
| 79 | 87 |     { | 
| 80 |  | -        basic_iota_iterator it = *this; | 
| 81 |  | -        index--; | 
| 82 |  | -        return it; | 
|  | 88 | +        return s << x.index; | 
| 83 | 89 |     } | 
| 84 |  | -    reference operator*() const { return f(index); } | 
| 85 |  | -    pointer operator->() const { return &f(index); } | 
| 86 |  | -    reference operator[](int n) const { return f(index + n); } | 
| 87 | 90 | }; | 
| 88 | 91 | 
 | 
| 89 | 92 | template <class T, class F> | 
| 90 |  | -inline basic_iota_iterator<F, T> make_basic_iota_iterator(T x, F f) | 
| 91 |  | -{ | 
| 92 |  | -    return basic_iota_iterator<F, T>{x, f}; | 
| 93 |  | -} | 
| 94 |  | - | 
| 95 |  | -template <class F, class Iterator> | 
| 96 |  | -inline basic_iota_iterator<F, Iterator> operator+(basic_iota_iterator<F, Iterator> x, | 
| 97 |  | -                                                  std::ptrdiff_t y) | 
| 98 |  | -{ | 
| 99 |  | -    return x += y; | 
| 100 |  | -} | 
| 101 |  | - | 
| 102 |  | -template <class F, class Iterator> | 
| 103 |  | -inline basic_iota_iterator<F, Iterator> operator+(std::ptrdiff_t x, | 
| 104 |  | -                                                  basic_iota_iterator<F, Iterator> y) | 
| 105 |  | -{ | 
| 106 |  | -    return y + x; | 
| 107 |  | -} | 
| 108 |  | - | 
| 109 |  | -template <class F, class Iterator> | 
| 110 |  | -inline std::ptrdiff_t operator-(basic_iota_iterator<F, Iterator> x, | 
| 111 |  | -                                basic_iota_iterator<F, Iterator> y) | 
| 112 |  | -{ | 
| 113 |  | -    return x.index - y.index; | 
| 114 |  | -} | 
| 115 |  | - | 
| 116 |  | -template <class F, class Iterator> | 
| 117 |  | -inline basic_iota_iterator<F, Iterator> operator-(basic_iota_iterator<F, Iterator> x, | 
| 118 |  | -                                                  std::ptrdiff_t y) | 
| 119 |  | -{ | 
| 120 |  | -    return x -= y; | 
| 121 |  | -} | 
| 122 |  | - | 
| 123 |  | -template <class F, class Iterator> | 
| 124 |  | -inline bool operator==(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y) | 
| 125 |  | -{ | 
| 126 |  | -    return x.index == y.index; | 
| 127 |  | -} | 
| 128 |  | - | 
| 129 |  | -template <class F, class Iterator> | 
| 130 |  | -inline bool operator!=(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y) | 
| 131 |  | -{ | 
| 132 |  | -    return x.index != y.index; | 
| 133 |  | -} | 
| 134 |  | - | 
| 135 |  | -template <class F, class Iterator> | 
| 136 |  | -inline bool operator<(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y) | 
| 137 |  | -{ | 
| 138 |  | -    return x.index < y.index; | 
| 139 |  | -} | 
| 140 |  | - | 
| 141 |  | -template <class F, class Iterator> | 
| 142 |  | -inline bool operator>(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y) | 
| 143 |  | -{ | 
| 144 |  | -    return x.index > y.index; | 
| 145 |  | -} | 
| 146 |  | - | 
| 147 |  | -template <class F, class Iterator> | 
| 148 |  | -inline bool operator>=(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y) | 
| 149 |  | -{ | 
| 150 |  | -    return x.index >= y.index; | 
| 151 |  | -} | 
| 152 |  | - | 
| 153 |  | -template <class F, class Iterator> | 
| 154 |  | -inline bool operator<=(basic_iota_iterator<F, Iterator> x, basic_iota_iterator<F, Iterator> y) | 
|  | 93 | +basic_iota_iterator<F, T> make_basic_iota_iterator(T x, F f) | 
| 155 | 94 | { | 
| 156 |  | -    return x.index <= y.index; | 
|  | 95 | +    return {x, f}; | 
| 157 | 96 | } | 
| 158 | 97 | 
 | 
| 159 | 98 | using iota_iterator = basic_iota_iterator<id>; | 
|  | 
0 commit comments