File indexing completed on 2025-08-28 08:27:09
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #pragma once
0019
0020 #include <cstddef>
0021 #include <cstdint>
0022 #include <iterator>
0023 #include <numeric>
0024 #include <tuple>
0025 #include <utility>
0026 #include <vector>
0027
0028 namespace arrow::internal {
0029
0030
0031 template <typename T>
0032 std::vector<T> Iota(T start, T stop) {
0033 if (start > stop) {
0034 return {};
0035 }
0036 std::vector<T> result(static_cast<size_t>(stop - start));
0037 std::iota(result.begin(), result.end(), start);
0038 return result;
0039 }
0040
0041
0042 template <typename T>
0043 std::vector<T> Iota(T length) {
0044 return Iota(static_cast<T>(0), length);
0045 }
0046
0047
0048
0049
0050
0051 template <typename Generator>
0052 class LazyRange {
0053 private:
0054
0055
0056 const Generator gen_;
0057
0058 int64_t length_;
0059 #ifdef _MSC_VER
0060
0061
0062 static Generator gen_static_;
0063 #endif
0064
0065 public:
0066 #ifdef _MSC_VER
0067 using return_type = decltype(gen_static_(0));
0068 #else
0069 using return_type = decltype(gen_(0));
0070 #endif
0071
0072
0073 LazyRange(Generator gen, int64_t length) : gen_(gen), length_(length) {}
0074
0075
0076 class RangeIter {
0077 public:
0078 using difference_type = int64_t;
0079 using value_type = return_type;
0080 using reference = const value_type&;
0081 using pointer = const value_type*;
0082 using iterator_category = std::forward_iterator_tag;
0083
0084 #ifdef _MSC_VER
0085
0086
0087 using _Unchecked_type = typename LazyRange<Generator>::RangeIter;
0088 #endif
0089
0090 RangeIter() = delete;
0091 RangeIter(const RangeIter& other) = default;
0092 RangeIter& operator=(const RangeIter& other) = default;
0093
0094 RangeIter(const LazyRange<Generator>& range, int64_t index)
0095 : range_(&range), index_(index) {}
0096
0097 const return_type operator*() const { return range_->gen_(index_); }
0098
0099 RangeIter operator+(difference_type length) const {
0100 return RangeIter(*range_, index_ + length);
0101 }
0102
0103
0104 RangeIter& operator++() {
0105 ++index_;
0106 return *this;
0107 }
0108
0109
0110 RangeIter operator++(int) {
0111 auto copy = RangeIter(*this);
0112 ++index_;
0113 return copy;
0114 }
0115
0116 bool operator==(const typename LazyRange<Generator>::RangeIter& other) const {
0117 return this->index_ == other.index_ && this->range_ == other.range_;
0118 }
0119
0120 bool operator!=(const typename LazyRange<Generator>::RangeIter& other) const {
0121 return this->index_ != other.index_ || this->range_ != other.range_;
0122 }
0123
0124 int64_t operator-(const typename LazyRange<Generator>::RangeIter& other) const {
0125 return this->index_ - other.index_;
0126 }
0127
0128 bool operator<(const typename LazyRange<Generator>::RangeIter& other) const {
0129 return this->index_ < other.index_;
0130 }
0131
0132 private:
0133
0134 const LazyRange* range_;
0135
0136 int64_t index_;
0137 };
0138
0139 friend class RangeIter;
0140
0141
0142 RangeIter begin() { return RangeIter(*this, 0); }
0143
0144
0145 RangeIter end() { return RangeIter(*this, length_); }
0146 };
0147
0148
0149 template <typename Generator>
0150 LazyRange<Generator> MakeLazyRange(Generator&& gen, int64_t length) {
0151 return LazyRange<Generator>(std::forward<Generator>(gen), length);
0152 }
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188 template <typename Ranges, typename Indices>
0189 struct Zip;
0190
0191 template <typename... Ranges>
0192 Zip(Ranges&&...) -> Zip<std::tuple<Ranges...>, std::index_sequence_for<Ranges...>>;
0193
0194 template <typename... Ranges, size_t... I>
0195 struct Zip<std::tuple<Ranges...>, std::index_sequence<I...>> {
0196 explicit Zip(Ranges... ranges) : ranges_(std::forward<Ranges>(ranges)...) {}
0197
0198 std::tuple<Ranges...> ranges_;
0199
0200 using sentinel = std::tuple<decltype(std::end(std::get<I>(ranges_)))...>;
0201 constexpr sentinel end() { return {std::end(std::get<I>(ranges_))...}; }
0202
0203 struct iterator : std::tuple<decltype(std::begin(std::get<I>(ranges_)))...> {
0204 using std::tuple<decltype(std::begin(std::get<I>(ranges_)))...>::tuple;
0205
0206 constexpr auto operator*() {
0207 return std::tuple<decltype(*std::get<I>(*this))...>{*std::get<I>(*this)...};
0208 }
0209
0210 constexpr iterator& operator++() {
0211 (++std::get<I>(*this), ...);
0212 return *this;
0213 }
0214
0215 constexpr bool operator!=(const sentinel& s) const {
0216 bool all_iterators_valid = (... && (std::get<I>(*this) != std::get<I>(s)));
0217 return all_iterators_valid;
0218 }
0219 };
0220 constexpr iterator begin() { return {std::begin(std::get<I>(ranges_))...}; }
0221 };
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234 template <typename I = size_t>
0235 constexpr auto Enumerate = [] {
0236 struct {
0237 struct sentinel {};
0238 constexpr sentinel end() const { return {}; }
0239
0240 struct iterator {
0241 I value{0};
0242
0243 constexpr I operator*() { return value; }
0244
0245 constexpr iterator& operator++() {
0246 ++value;
0247 return *this;
0248 }
0249
0250 constexpr std::true_type operator!=(sentinel) const { return {}; }
0251 };
0252 constexpr iterator begin() const { return {}; }
0253 } out;
0254
0255 return out;
0256 }();
0257
0258 }