sparrow 2.5.0
C++20 idiomatic APIs for the Apache Arrow Columnar Format
Loading...
Searching...
No Matches
mutable_array_base.hpp
Go to the documentation of this file.
1// Copyright 2024 Man Group Operations Limited
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or mplied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
20
21namespace sparrow
22{
34 template <class D>
36 {
37 public:
38
41 using derived_type = D;
43
46
47 using bitmap_type = typename inner_types::bitmap_type;
48 using const_bitmap_type = typename inner_types::const_bitmap_type;
49 using bitmap_reference = bitmap_type::reference;
50 using bitmap_const_reference = bitmap_type::const_reference;
51 using bitmap_iterator = bitmap_type::iterator;
52 using const_bitmap_iterator = const_bitmap_type::const_iterator;
53 using bitmap_range = std::ranges::subrange<bitmap_iterator>;
55
58
59 using inner_reference = typename inner_types::inner_reference;
61
64
65 using value_iterator = typename inner_types::value_iterator;
66
68
77
80
81 [[nodiscard]] constexpr reference operator[](size_type i);
82 using base_type::operator[];
83
84 [[nodiscard]] constexpr iterator begin();
85 [[nodiscard]] constexpr iterator end();
86
87 using base_type::begin;
88 using base_type::end;
89
90 template <typename T>
91 constexpr void resize(size_type new_size, const nullable<T>& value);
92
93 template <typename T>
94 constexpr iterator insert(const_iterator pos, const nullable<T>& value);
95 template <typename T>
96 constexpr iterator insert(const_iterator pos, const nullable<T>& value, size_type count);
97 template <typename T>
98 constexpr iterator insert(const_iterator pos, std::initializer_list<nullable<T>> values);
99
109 template <typename InputIt>
110 requires std::input_iterator<InputIt>
112 constexpr iterator insert(const_iterator pos, InputIt first, InputIt last)
113 {
114 SPARROW_ASSERT_TRUE(pos >= this->cbegin())
115 SPARROW_ASSERT_TRUE(pos <= this->cend());
116 const size_type old_size = this->size();
117 if constexpr (std::random_access_iterator<InputIt>)
118 {
119 SPARROW_ASSERT_TRUE(first <= last);
120 }
121 const difference_type distance = std::distance(this->cbegin(), pos);
122 const auto validity_range = std::ranges::subrange(first, last)
123 | std::views::transform(
124 [](const auto& obj)
125 {
126 return obj.has_value();
127 }
128 );
129 auto& derived = this->derived_cast();
130 derived.insert_bitmap(
131 sparrow::next(this->bitmap_cbegin(), distance),
132 validity_range.begin(),
133 validity_range.end()
134 );
135
136 const auto value_range = std::ranges::subrange(first, last) | std::views::transform(nullable_get);
137 derived.insert_values(
138 sparrow::next(derived.value_cbegin(), distance),
139 value_range.begin(),
140 value_range.end()
141 );
142 const difference_type count = std::distance(first, last);
143 // The following must be done after modifying the bitmap and values
144 this->get_arrow_proxy().set_length(old_size + static_cast<size_t>(count));
145 return sparrow::next(this->begin(), distance);
146 }
147
157 template <std::ranges::input_range R>
159 constexpr iterator insert(const_iterator pos, const R& range)
160 {
161 return insert(pos, std::ranges::begin(range), std::ranges::end(range));
162 }
163
164 constexpr iterator erase(const_iterator pos);
165 constexpr iterator erase(const_iterator first, const_iterator last);
166
167 template <typename T>
168 constexpr void push_back(const nullable<T>& value);
169 constexpr void pop_back();
170
171 constexpr void zero_null_values(const inner_value_type& value = inner_value_type());
172
173 protected:
174
176 constexpr mutable_array_base(const mutable_array_base&) noexcept = default;
177 constexpr mutable_array_base& operator=(const mutable_array_base&) noexcept = default;
178
179 constexpr mutable_array_base(mutable_array_base&&) noexcept = default;
180 constexpr mutable_array_base& operator=(mutable_array_base&&) noexcept = default;
181
182 [[nodiscard]] constexpr bitmap_reference has_value(size_type i);
183 using base_type::has_value;
184
185 [[nodiscard]] constexpr bitmap_iterator bitmap_begin();
186 [[nodiscard]] constexpr bitmap_iterator bitmap_end();
187
188 friend class layout_iterator<iterator_types>;
189 };
190
191 /*************************************
192 * mutable_array_base implementation *
193 *************************************/
194
195 template <class D>
197 : array_crtp_base<D>(std::forward<arrow_proxy>(proxy))
198 {
199 }
200
204 template <class D>
206 {
207 auto& derived_cast = this->derived_cast();
208 return iterator(derived_cast.value_begin(), derived_cast.bitmap_begin());
209 }
210
215 template <class D>
217 {
218 auto& derived_cast = this->derived_cast();
219 return iterator(derived_cast.value_end(), derived_cast.bitmap_end());
220 }
221
227 template <class D>
229 {
230 SPARROW_ASSERT_TRUE(i < this->size());
231 auto& derived_cast = this->derived_cast();
232 return reference(inner_reference(derived_cast.value(i)), derived_cast.has_value(i));
233 }
234
235 template <class D>
237 {
238 SPARROW_ASSERT_TRUE(i < this->size());
239 return *sparrow::next(bitmap_begin(), i);
240 }
241
242 template <class D>
244 {
245 return this->derived_cast().get_bitmap().begin();
246 }
247
248 template <class D>
250 {
251 return sparrow::next(bitmap_begin(), this->size());
252 }
253
262 template <class D>
263 template <typename T>
264 constexpr void mutable_array_base<D>::resize(size_type new_length, const nullable<T>& value)
265 {
266 auto& derived = this->derived_cast();
267 derived.resize_bitmap(new_length, value.has_value());
268 derived.resize_values(new_length, value.get());
269 this->get_arrow_proxy().set_length(new_length); // Must be done after resizing the bitmap and values
270 }
271
279 template <class D>
280 template <typename T>
282 {
283 return insert(pos, value, 1);
284 }
285
294 template <class D>
295 template <typename T>
296 constexpr auto
298 {
299 SPARROW_ASSERT_TRUE(pos >= this->cbegin());
300 SPARROW_ASSERT_TRUE(pos <= this->cend());
301 const size_type old_size = this->size();
302 const size_t distance = static_cast<size_t>(std::distance(this->cbegin(), pos));
303 auto& derived = this->derived_cast();
304 derived.insert_bitmap(sparrow::next(this->bitmap_cbegin(), distance), value.has_value(), count);
305 derived.insert_value(sparrow::next(derived.value_cbegin(), distance), value.get(), count);
306 this->get_arrow_proxy().set_length(old_size + count); // Must be done after resizing the bitmap and values
307 return sparrow::next(this->begin(), distance);
308 }
309
317 template <class D>
318 template <typename T>
319 constexpr auto
321 {
322 return insert(pos, values.begin(), values.end());
323 }
324
331 template <class D>
333 {
334 SPARROW_ASSERT_TRUE(this->cbegin() <= pos)
335 SPARROW_ASSERT_TRUE(pos < this->cend());
336 return erase(pos, pos + 1);
337 }
338
346 template <class D>
348 {
349 SPARROW_ASSERT_TRUE(first <= last);
350 SPARROW_ASSERT_TRUE(this->cbegin() <= first)
351 SPARROW_ASSERT_TRUE(last <= this->cend());
352 const size_type old_size = this->size();
353 const difference_type first_index = std::distance(this->cbegin(), first);
354 if (first == last)
355 {
356 return sparrow::next(begin(), first_index);
357 }
358 const auto count = static_cast<size_t>(std::distance(first, last));
359 auto& derived = this->derived_cast();
360 derived.erase_bitmap(sparrow::next(this->bitmap_cbegin(), first_index), count);
361 derived.erase_values(sparrow::next(derived.value_cbegin(), first_index), count);
362 this->get_arrow_proxy().set_length(old_size - count); // Must be done after modifying the bitmap and values
363 return sparrow::next(begin(), first_index);
364 }
365
371 template <class D>
372 template <typename T>
374 {
375 insert(this->cend(), value);
376 }
377
381 template <class D>
383 {
384 erase(std::prev(this->cend()));
385 }
386
392 template <class D>
394 {
395 sparrow::zero_null_values(*this, value);
396 }
397}
constexpr const_bitmap_iterator bitmap_cbegin() const
Gets const bitmap iterator to the beginning.
constexpr const_value_range values() const
Gets the raw values as a range.
array_crtp_base(arrow_proxy)
Protected constructor from Arrow proxy.
nullable< inner_const_reference, bitmap_const_reference > const_reference
constexpr const_iterator cbegin() const
Gets const iterator to the beginning of the array.
typename inner_types::iterator_tag iterator_tag
std::ranges::subrange< const_bitmap_iterator > const_bitmap_range
typename inner_types::inner_const_reference inner_const_reference
nullable< inner_value_type > value_type
std::ptrdiff_t difference_type
layout_iterator< iterator_types > const_iterator
constexpr arrow_proxy & get_arrow_proxy() noexcept
Gets mutable reference to the Arrow proxy.
constexpr const_iterator cend() const
Gets const iterator to the end of the array.
constexpr const_iterator end() const
Gets iterator to the end of the array.
constexpr const_iterator begin() const
Gets iterator to the beginning of the array.
typename inner_types::inner_value_type inner_value_type
constexpr size_type size() const
Gets the number of elements in the array.
SPARROW_API void set_length(size_t length)
Sets the number of elements in the array.
constexpr derived_type & derived_cast()
Definition crtp_base.hpp:39
Layout iterator class.
constexpr void zero_null_values(const inner_value_type &value=inner_value_type())
Sets all null values in the array to zero.
constexpr bitmap_iterator bitmap_end()
constexpr void push_back(const nullable< T > &value)
Appends a copy of value to the end of the array.
base_type::const_reference const_reference
typename base_type::inner_value_type inner_value_type
bitmap_type::const_reference bitmap_const_reference
constexpr mutable_array_base(mutable_array_base &&) noexcept=default
array_inner_types< derived_type > inner_types
constexpr iterator insert(const_iterator pos, InputIt first, InputIt last)
Inserts elements from range [first , last ) before pos in the array.
typename inner_types::value_iterator value_iterator
typename base_type::value_type value_type
mutable_array_base< D > self_type
constexpr iterator begin()
Returns an iterator to the first element of the array.
constexpr mutable_array_base(const mutable_array_base &) noexcept=default
constexpr void pop_back()
Removes the last element of the array.
base_type::difference_type difference_type
layout_iterator< iterator_types > iterator
base_type::const_iterator const_iterator
typename base_type::inner_const_reference inner_const_reference
constexpr iterator insert(const_iterator pos, const R &range)
Inserts elements from range range before pos in the array.
constexpr reference operator[](size_type i)
Returns a reference to the element at the specified position in the array.
typename inner_types::const_bitmap_type const_bitmap_type
typename inner_types::inner_reference inner_reference
constexpr bitmap_reference has_value(size_type i)
constexpr void resize(size_type new_size, const nullable< T > &value)
Resizes the array to contain new_length elements, does nothing if new_length == size().
base_type::iterator_tag iterator_tag
std::ranges::subrange< bitmap_iterator > bitmap_range
nullable< inner_reference, bitmap_reference > reference
bitmap_type::reference bitmap_reference
constexpr iterator insert(const_iterator pos, const nullable< T > &value)
bitmap_type::iterator bitmap_iterator
base_type::const_bitmap_range const_bitmap_range
const_bitmap_type::const_iterator const_bitmap_iterator
constexpr iterator erase(const_iterator pos)
Removes the element at pos from the array.
constexpr iterator end()
Returns a iterator to the element following the last element of the array.
typename inner_types::bitmap_type bitmap_type
constexpr iterator insert(const_iterator pos, std::initializer_list< nullable< T > > values)
constexpr bitmap_iterator bitmap_begin()
constexpr mutable_array_base & operator=(const mutable_array_base &) noexcept=default
constexpr iterator insert(const_iterator pos, const nullable< T > &value, size_type count)
constexpr bool has_value() const noexcept
Checks whether the nullable contains a valid value.
constexpr reference get() &noexcept
Gets mutable reference to the stored value.
Concept for iterator types.
#define SPARROW_ASSERT_TRUE(expr__)
constexpr bool is_type_instance_of_v
Variable template for convenient access to is_type_instance_of.
Definition mp_utils.hpp:102
constexpr void zero_null_values(R &range, const T &default_value=T{})
Sets null values in a range to a default value.
constexpr InputIt next(InputIt it, Distance n)
Definition iterator.hpp:605
constexpr nullable_get_fn nullable_get
Definition nullable.hpp:102
Extensions to the C++ standard library.
Traits class that must be specialized by array implementations.