]> git.proxmox.com Git - ceph.git/blob - ceph/src/arrow/cpp/src/arrow/stl_iterator_test.cc
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / cpp / src / arrow / stl_iterator_test.cc
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing,
12 // software distributed under the License is distributed on an
13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 // KIND, either express or implied. See the License for the
15 // specific language governing permissions and limitations
16 // under the License.
17
18 #include <algorithm>
19 #include <cstdint>
20
21 #include <gtest/gtest.h>
22
23 #include "arrow/stl.h"
24 #include "arrow/stl_iterator.h"
25 #include "arrow/testing/gtest_util.h"
26 #include "arrow/type.h"
27 #include "arrow/util/checked_cast.h"
28
29 namespace arrow {
30
31 using internal::checked_cast;
32 using internal::checked_pointer_cast;
33 using util::nullopt;
34 using util::optional;
35
36 namespace stl {
37
38 TEST(ArrayIterator, Basics) {
39 auto array =
40 checked_pointer_cast<Int32Array>(ArrayFromJSON(int32(), "[4, 5, null, 6]"));
41
42 ArrayIterator<Int32Array> it(*array);
43 optional<int32_t> v = *it;
44 ASSERT_EQ(v, 4);
45 ASSERT_EQ(it[0], 4);
46 ++it;
47 ASSERT_EQ(it[0], 5);
48 ASSERT_EQ(*it, 5);
49 ASSERT_EQ(it[1], nullopt);
50 ASSERT_EQ(it[2], 6);
51 }
52
53 TEST(ArrayIterator, Arithmetic) {
54 auto array = checked_pointer_cast<Int32Array>(
55 ArrayFromJSON(int32(), "[4, 5, null, 6, null, 7]"));
56
57 ArrayIterator<Int32Array> it(*array);
58 auto it2 = it + 2;
59 ASSERT_EQ(*it, 4);
60 ASSERT_EQ(*it2, nullopt);
61 ASSERT_EQ(it2 - it, 2);
62 ASSERT_EQ(it - it2, -2);
63 auto it3 = it++;
64 ASSERT_EQ(it2 - it, 1);
65 ASSERT_EQ(it2 - it3, 2);
66 ASSERT_EQ(*it3, 4);
67 ASSERT_EQ(*it, 5);
68 auto it4 = ++it;
69 ASSERT_EQ(*it, nullopt);
70 ASSERT_EQ(*it4, nullopt);
71 ASSERT_EQ(it2 - it, 0);
72 ASSERT_EQ(it2 - it4, 0);
73 auto it5 = it + 3;
74 ASSERT_EQ(*it5, 7);
75 ASSERT_EQ(*(it5 - 2), 6);
76 ASSERT_EQ(*(it5 + (-2)), 6);
77 auto it6 = (--it5)--;
78 ASSERT_EQ(*it6, nullopt);
79 ASSERT_EQ(*it5, 6);
80 ASSERT_EQ(it6 - it5, 1);
81 }
82
83 TEST(ArrayIterator, Comparison) {
84 auto array = checked_pointer_cast<Int32Array>(
85 ArrayFromJSON(int32(), "[4, 5, null, 6, null, 7]"));
86
87 auto it = ArrayIterator<Int32Array>(*array) + 2;
88 auto it2 = ArrayIterator<Int32Array>(*array) + 2;
89 auto it3 = ArrayIterator<Int32Array>(*array) + 4;
90
91 ASSERT_TRUE(it == it2);
92 ASSERT_TRUE(it <= it2);
93 ASSERT_TRUE(it >= it2);
94 ASSERT_FALSE(it != it2);
95 ASSERT_FALSE(it < it2);
96 ASSERT_FALSE(it > it2);
97
98 ASSERT_FALSE(it == it3);
99 ASSERT_TRUE(it <= it3);
100 ASSERT_FALSE(it >= it3);
101 ASSERT_TRUE(it != it3);
102 ASSERT_TRUE(it < it3);
103 ASSERT_FALSE(it > it3);
104 }
105
106 TEST(ArrayIterator, BeginEnd) {
107 auto array =
108 checked_pointer_cast<Int32Array>(ArrayFromJSON(int32(), "[4, 5, null, 6]"));
109 std::vector<optional<int32_t>> values;
110 for (auto it = array->begin(); it != array->end(); ++it) {
111 values.push_back(*it);
112 }
113 std::vector<optional<int32_t>> expected{4, 5, {}, 6};
114 ASSERT_EQ(values, expected);
115 }
116
117 TEST(ArrayIterator, RangeFor) {
118 auto array =
119 checked_pointer_cast<Int32Array>(ArrayFromJSON(int32(), "[4, 5, null, 6]"));
120 std::vector<optional<int32_t>> values;
121 for (const auto v : *array) {
122 values.push_back(v);
123 }
124 std::vector<optional<int32_t>> expected{4, 5, {}, 6};
125 ASSERT_EQ(values, expected);
126 }
127
128 TEST(ArrayIterator, String) {
129 auto array = checked_pointer_cast<StringArray>(
130 ArrayFromJSON(utf8(), R"(["foo", "bar", null, "quux"])"));
131 std::vector<optional<util::string_view>> values;
132 for (const auto v : *array) {
133 values.push_back(v);
134 }
135 std::vector<optional<util::string_view>> expected{"foo", "bar", {}, "quux"};
136 ASSERT_EQ(values, expected);
137 }
138
139 TEST(ArrayIterator, Boolean) {
140 auto array = checked_pointer_cast<BooleanArray>(
141 ArrayFromJSON(boolean(), "[true, null, null, false]"));
142 std::vector<optional<bool>> values;
143 for (const auto v : *array) {
144 values.push_back(v);
145 }
146 std::vector<optional<bool>> expected{true, {}, {}, false};
147 ASSERT_EQ(values, expected);
148 }
149
150 TEST(ArrayIterator, FixedSizeBinary) {
151 auto array = checked_pointer_cast<FixedSizeBinaryArray>(
152 ArrayFromJSON(fixed_size_binary(3), R"(["foo", "bar", null, "quu"])"));
153 std::vector<optional<util::string_view>> values;
154 for (const auto v : *array) {
155 values.push_back(v);
156 }
157 std::vector<optional<util::string_view>> expected{"foo", "bar", {}, "quu"};
158 ASSERT_EQ(values, expected);
159 }
160
161 // Test compatibility with various STL algorithms
162
163 TEST(ArrayIterator, StdFind) {
164 auto array = checked_pointer_cast<StringArray>(
165 ArrayFromJSON(utf8(), R"(["foo", "bar", null, "quux"])"));
166
167 auto it = std::find(array->begin(), array->end(), "bar");
168 ASSERT_EQ(it.index(), 1);
169 it = std::find(array->begin(), array->end(), nullopt);
170 ASSERT_EQ(it.index(), 2);
171 it = std::find(array->begin(), array->end(), "zzz");
172 ASSERT_EQ(it, array->end());
173 }
174
175 TEST(ArrayIterator, StdCountIf) {
176 auto array = checked_pointer_cast<BooleanArray>(
177 ArrayFromJSON(boolean(), "[true, null, null, false]"));
178
179 auto n = std::count_if(array->begin(), array->end(),
180 [](optional<bool> v) { return !v.has_value(); });
181 ASSERT_EQ(n, 2);
182 }
183
184 TEST(ArrayIterator, StdCopy) {
185 auto array = checked_pointer_cast<BooleanArray>(
186 ArrayFromJSON(boolean(), "[true, null, null, false]"));
187 std::vector<optional<bool>> values;
188 std::copy(array->begin() + 1, array->end(), std::back_inserter(values));
189 std::vector<optional<bool>> expected{{}, {}, false};
190 ASSERT_EQ(values, expected);
191 }
192
193 TEST(ArrayIterator, StdPartitionPoint) {
194 auto array = checked_pointer_cast<DoubleArray>(
195 ArrayFromJSON(float64(), "[4.5, 2.5, 1e100, 3, null, null, null, null, null]"));
196 auto it = std::partition_point(array->begin(), array->end(),
197 [](optional<double> v) { return v.has_value(); });
198 ASSERT_EQ(it.index(), 4);
199 ASSERT_EQ(*it, nullopt);
200
201 array =
202 checked_pointer_cast<DoubleArray>(ArrayFromJSON(float64(), "[null, null, null]"));
203 it = std::partition_point(array->begin(), array->end(),
204 [](optional<double> v) { return v.has_value(); });
205 ASSERT_EQ(it, array->begin());
206 it = std::partition_point(array->begin(), array->end(),
207 [](optional<double> v) { return !v.has_value(); });
208 ASSERT_EQ(it, array->end());
209 }
210
211 TEST(ArrayIterator, StdEqualRange) {
212 auto array = checked_pointer_cast<Int8Array>(
213 ArrayFromJSON(int8(), "[1, 4, 5, 5, 5, 7, 8, null, null, null]"));
214 auto cmp_lt = [](optional<int8_t> u, optional<int8_t> v) {
215 return u.has_value() && (!v.has_value() || *u < *v);
216 };
217
218 auto pair = std::equal_range(array->begin(), array->end(), nullopt, cmp_lt);
219 ASSERT_EQ(pair.first, array->end() - 3);
220 ASSERT_EQ(pair.second, array->end());
221 pair = std::equal_range(array->begin(), array->end(), 6, cmp_lt);
222 ASSERT_EQ(pair.first, array->begin() + 5);
223 ASSERT_EQ(pair.second, pair.first);
224 pair = std::equal_range(array->begin(), array->end(), 5, cmp_lt);
225 ASSERT_EQ(pair.first, array->begin() + 2);
226 ASSERT_EQ(pair.second, array->begin() + 5);
227 pair = std::equal_range(array->begin(), array->end(), 1, cmp_lt);
228 ASSERT_EQ(pair.first, array->begin());
229 ASSERT_EQ(pair.second, array->begin() + 1);
230 pair = std::equal_range(array->begin(), array->end(), 0, cmp_lt);
231 ASSERT_EQ(pair.first, array->begin());
232 ASSERT_EQ(pair.second, pair.first);
233 }
234
235 TEST(ArrayIterator, StdMerge) {
236 auto array1 = checked_pointer_cast<Int8Array>(
237 ArrayFromJSON(int8(), "[1, 4, 5, 5, 7, null, null, null]"));
238 auto array2 =
239 checked_pointer_cast<Int8Array>(ArrayFromJSON(int8(), "[-1, 3, 3, 6, 42]"));
240 auto cmp_lt = [](optional<int8_t> u, optional<int8_t> v) {
241 return u.has_value() && (!v.has_value() || *u < *v);
242 };
243
244 std::vector<optional<int8_t>> values;
245 std::merge(array1->begin(), array1->end(), array2->begin(), array2->end(),
246 std::back_inserter(values), cmp_lt);
247 std::vector<optional<int8_t>> expected{-1, 1, 3, 3, 4, 5, 5, 6, 7, 42, {}, {}, {}};
248 ASSERT_EQ(values, expected);
249 }
250
251 } // namespace stl
252 } // namespace arrow