sparrow 0.9.0
Loading...
Searching...
No Matches
fixed_width_binary_array.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
17#include <cstddef>
18#include <cstdint>
19#include <iterator>
20#include <optional>
21#include <ranges>
22#include <string>
23#include <type_traits>
24#include <vector>
25
40
41namespace sparrow
42{
43 template <std::ranges::sized_range T, class CR>
45
47
49 fixed_width_binary_traits::value_type,
50 fixed_width_binary_traits::const_reference>;
51
52 template <std::ranges::sized_range T, class CR>
79
80 namespace detail
81 {
82 template <class T>
83 struct get_data_type_from_array;
84
85 template <>
87 {
88 [[nodiscard]] static constexpr sparrow::data_type get()
89 {
91 }
92 };
93 }
94
95 template <std::ranges::sized_range T, class CR>
97 : public mutable_array_bitmap_base<fixed_width_binary_array_impl<T, CR>>
98 {
99 private:
100
101 static_assert(
102 sizeof(std::ranges::range_value_t<T>) == sizeof(byte_t),
103 "Only sequences of types with the same size as byte_t are supported"
104 );
105
106 public:
107
110
112 using inner_value_type = typename inner_types::inner_value_type;
113 using inner_reference = typename inner_types::inner_reference;
114 using inner_const_reference = typename inner_types::inner_const_reference;
115
117 using bitmap_reference = typename base_type::bitmap_reference;
120
124
128 using data_iterator = typename inner_types::data_iterator;
129
130 using const_data_iterator = typename inner_types::const_data_iterator;
131 using data_value_type = typename inner_types::data_value_type;
132
133 using value_iterator = typename inner_types::value_iterator;
134 using const_value_iterator = typename inner_types::const_value_iterator;
135
136 using functor_type = typename inner_types::functor_type;
137 using const_functor_type = typename inner_types::const_functor_type;
138
140
145 template <class... ARGS>
148 : base_type(create_proxy(std::forward<ARGS>(args)...))
149 , m_element_size(num_bytes_for_fixed_sized_binary(this->get_arrow_proxy().format()))
150 {
151 }
152
153 using base_type::get_arrow_proxy;
154 using base_type::size;
155
157 [[nodiscard]] inner_const_reference value(size_type i) const;
158
159 private:
160
171 template <
174 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
175 [[nodiscard]] static arrow_proxy create_proxy(
176 u8_buffer<C>&& data_buffer,
177 size_t element_count,
178 size_t element_size,
179 VB&& validity_input = validity_bitmap{},
180 std::optional<std::string_view> name = std::nullopt,
181 std::optional<METADATA_RANGE> metadata = std::nullopt
182 );
183
184 template <input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
185 [[nodiscard]] static arrow_proxy create_proxy(
186 size_t element_size,
187 bool nullable = true,
188 std::optional<std::string_view> name = std::nullopt,
189 std::optional<METADATA_RANGE> metadata = std::nullopt
190 );
191
202 template <
203 std::ranges::input_range VALUES,
205 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
206 requires(
207 std::ranges::input_range<std::ranges::range_value_t<VALUES>> && // a range of ranges
209 // is a range
210 // of
211 // char-like
212 )
213 [[nodiscard]] static arrow_proxy create_proxy(
214 VALUES&& values,
215 VB&& validity_input,
216 std::optional<std::string_view> name = std::nullopt,
217 std::optional<METADATA_RANGE> metadata = std::nullopt
218 );
219
230 template <
231 std::ranges::input_range VALUES,
232 input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
233 requires(
234 std::ranges::input_range<std::ranges::range_value_t<VALUES>> && // a range of ranges
236 // is a range
237 // of
238 // char-like
239 )
240 [[nodiscard]] static arrow_proxy create_proxy(
241 VALUES&& values,
242 bool nullable = true,
243 std::optional<std::string_view> name = std::nullopt,
244 std::optional<METADATA_RANGE> metadata = std::nullopt
245 );
246
256 template <std::ranges::input_range NULLABLE_VALUES, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
258 && std::ranges::input_range<typename std::ranges::range_value_t<NULLABLE_VALUES>::value_type>
259 && std::is_same_v<
260 std::ranges::range_value_t<typename std::ranges::range_value_t<NULLABLE_VALUES>::value_type>,
261 byte_t>
262 [[nodiscard]] static arrow_proxy create_proxy(
263 NULLABLE_VALUES&&,
264 std::optional<std::string_view> name = std::nullopt,
265 std::optional<METADATA_RANGE> metadata = std::nullopt
266 );
267
268 template <mpl::char_like C, input_metadata_container METADATA_RANGE = std::vector<metadata_pair>>
269 [[nodiscard]] static arrow_proxy create_proxy_impl(
270 u8_buffer<C>&& data_buffer,
271 size_t element_count,
272 size_t element_size,
273 std::optional<validity_bitmap>&& validity_input,
274 std::optional<std::string_view> name = std::nullopt,
275 std::optional<METADATA_RANGE> metadata = std::nullopt
276 );
277
278 static constexpr size_t DATA_BUFFER_INDEX = 1;
279
280 [[nodiscard]] data_iterator data(size_type i);
281
282 [[nodiscard]] value_iterator value_begin();
283 [[nodiscard]] value_iterator value_end();
284
285 [[nodiscard]] const_value_iterator value_cbegin() const;
286 [[nodiscard]] const_value_iterator value_cend() const;
287
288 [[nodiscard]] const_data_iterator data(size_type i) const;
289
290 // Modifiers
291
292 template <std::ranges::sized_range U>
294 void resize_values(size_type new_length, U value);
295
296 template <std::ranges::sized_range U>
298 value_iterator insert_value(const_value_iterator pos, U value, size_type count);
299
300 template <typename InputIt>
301 requires std::input_iterator<InputIt>
303 value_iterator insert_values(const_value_iterator pos, InputIt first, InputIt last);
304
305 value_iterator erase_values(const_value_iterator pos, size_type count);
306
307 template <std::ranges::sized_range U>
309 void assign(U&& rhs, size_type index);
310
311 size_t m_element_size = 0;
312
315 friend base_type;
318 };
319
320 /************************************************
321 * fixed_width_binary_array_impl implementation *
322 ************************************************/
323
324 template <std::ranges::sized_range T, class CR>
326 : base_type(std::move(proxy))
327 , m_element_size(num_bytes_for_fixed_sized_binary(this->get_arrow_proxy().format()))
328 {
329 SPARROW_ASSERT_TRUE(this->get_arrow_proxy().data_type() == data_type::FIXED_WIDTH_BINARY);
330 }
331
332 template <std::ranges::sized_range T, class CR>
333 template <mpl::char_like C, validity_bitmap_input VB, input_metadata_container METADATA_RANGE>
334 arrow_proxy fixed_width_binary_array_impl<T, CR>::create_proxy(
335 u8_buffer<C>&& data_buffer,
336 size_t element_count,
337 size_t element_size,
338 VB&& validity_input,
339 std::optional<std::string_view> name,
340 std::optional<METADATA_RANGE> metadata
341 )
342 {
343 validity_bitmap bitmap = ensure_validity_bitmap(element_count, std::forward<VB>(validity_input));
344 return create_proxy_impl(
345 std::move(data_buffer),
346 element_count,
347 element_size,
348 std::move(bitmap),
349 std::move(name),
350 std::move(metadata)
351 );
352 }
353
354 template <std::ranges::sized_range T, class CR>
355 template <input_metadata_container METADATA_RANGE>
356 arrow_proxy fixed_width_binary_array_impl<T, CR>::create_proxy(
357 size_t element_size,
358 bool nullable,
359 std::optional<std::string_view> name,
360 std::optional<METADATA_RANGE> metadata
361 )
362 {
363 u8_buffer<char> data_buffer{};
364 std::optional<validity_bitmap> bitmap = nullable ? std::make_optional<validity_bitmap>(nullptr, 0)
365 : std::nullopt;
366 return create_proxy_impl(
367 std::move(data_buffer),
368 0,
369 element_size,
370 std::move(bitmap),
371 std::move(name),
372 std::move(metadata)
373 );
374 }
375
376 template <std::ranges::sized_range T, class CR>
377 template <std::ranges::input_range R, validity_bitmap_input VB, input_metadata_container METADATA_RANGE>
378 requires(
379 std::ranges::input_range<std::ranges::range_value_t<R>> && // a range of ranges
381 // range of char-like
382 )
383 arrow_proxy fixed_width_binary_array_impl<T, CR>::create_proxy(
384 R&& values,
385 VB&& validity_input,
386 std::optional<std::string_view> name,
387 std::optional<METADATA_RANGE> metadata
388 )
389 {
390 using values_type = std::ranges::range_value_t<R>;
391 using values_inner_value_type = std::ranges::range_value_t<values_type>;
392
394 const size_t element_size = std::ranges::empty(values) ? 0 : std::ranges::size(*values.begin());
395
396 auto data_buffer = u8_buffer<values_inner_value_type>(std::ranges::views::join(values));
397 return create_proxy(
398 std::move(data_buffer),
399 values.size(),
400 element_size,
401 std::forward<VB>(validity_input),
402 std::forward<std::optional<std::string_view>>(name),
403 std::forward<std::optional<METADATA_RANGE>>(metadata)
404 );
405 }
406
407 template <std::ranges::sized_range T, class CR>
408 template <std::ranges::input_range R, input_metadata_container METADATA_RANGE>
409 requires(
410 std::ranges::input_range<std::ranges::range_value_t<R>> && // a range of ranges
412 // range of char-like
413 )
414 arrow_proxy fixed_width_binary_array_impl<T, CR>::create_proxy(
415 R&& values,
416 bool nullable,
417 std::optional<std::string_view> name,
418 std::optional<METADATA_RANGE> metadata
419 )
420 {
421 if (nullable)
422 {
423 return create_proxy(std::forward<R>(values), validity_bitmap{}, std::move(name), std::move(metadata));
424 }
425 else
426 {
427 using values_type = std::ranges::range_value_t<R>;
428 using values_inner_value_type = std::ranges::range_value_t<values_type>;
429
431 const size_t element_size = std::ranges::empty(values) ? 0 : std::ranges::size(*values.begin());
432 auto data_buffer = u8_buffer<values_inner_value_type>(std::ranges::views::join(values));
433 return create_proxy_impl(
434 std::move(data_buffer),
435 values.size(), // element count
436 element_size,
437 std::nullopt, // validity bitmap
438 std::move(name),
439 std::move(metadata)
440 );
441 }
442 }
443
444 template <std::ranges::sized_range T, class CR>
445 template <std::ranges::input_range NULLABLE_RANGE, input_metadata_container METADATA_RANGE>
447 && std::ranges::input_range<typename std::ranges::range_value_t<NULLABLE_RANGE>::value_type>
448 && std::is_same_v<
449 std::ranges::range_value_t<typename std::ranges::range_value_t<NULLABLE_RANGE>::value_type>,
450 byte_t>
451 arrow_proxy fixed_width_binary_array_impl<T, CR>::create_proxy(
452 NULLABLE_RANGE&& range,
453 std::optional<std::string_view> name,
454 std::optional<METADATA_RANGE> metadata
455 )
456 {
457 // split into values and is_non_null ranges
458 const auto values = range
459 | std::views::transform(
460 [](const auto& v)
461 {
462 return v.get();
463 }
464 );
465 const auto is_non_null = range
466 | std::views::transform(
467 [](const auto& v)
468 {
469 return v.has_value();
470 }
471 );
472 return self_type::create_proxy(values, is_non_null, std::move(name), std::move(metadata));
473 }
474
475 template <std::ranges::sized_range T, class CR>
476 template <mpl::char_like C, input_metadata_container METADATA_RANGE>
477 arrow_proxy fixed_width_binary_array_impl<T, CR>::create_proxy_impl(
478 u8_buffer<C>&& data_buffer,
479 size_t element_count,
480 size_t element_size,
481 std::optional<validity_bitmap>&& bitmap,
482 std::optional<std::string_view> name,
483 std::optional<METADATA_RANGE> metadata
484 )
485 {
487 element_size == 0 ? (data_buffer.size() == 0) : (data_buffer.size() % element_size == 0)
488 );
489
490 const auto null_count = bitmap.has_value() ? bitmap->null_count() : 0;
491 std::string format_str = "w:" + std::to_string(element_size);
492 const std::optional<std::unordered_set<ArrowFlag>>
493 flags = bitmap.has_value()
494 ? std::make_optional<std::unordered_set<ArrowFlag>>({ArrowFlag::NULLABLE})
495 : std::nullopt;
496
498 std::move(format_str),
499 std::move(name), // name
500 std::move(metadata), // metadata
501 flags, // flags,
502 nullptr, // children
503 repeat_view<bool>(true, 0), // children_ownership
504 nullptr, // dictionary
505 true // dictionary ownership
506
507 );
508 std::vector<buffer<std::uint8_t>> arr_buffs = {
509 bitmap.has_value() ? std::move(*bitmap).extract_storage() : buffer<std::uint8_t>{nullptr, 0},
510 std::move(data_buffer).extract_storage()
511 };
512
513 ArrowArray arr = make_arrow_array(
514 static_cast<std::int64_t>(element_count), // length
515 static_cast<int64_t>(null_count),
516 0, // offset
517 std::move(arr_buffs),
518 nullptr, // children
519 repeat_view<bool>(true, 0), // children_ownership
520 nullptr, // dictionary
521 true // dictionary ownership
522 );
523 return arrow_proxy{std::move(arr), std::move(schema)};
524 }
525
526 template <std::ranges::sized_range T, class CR>
527 auto fixed_width_binary_array_impl<T, CR>::data(size_type i) -> data_iterator
528 {
529 const arrow_proxy& proxy = this->get_arrow_proxy();
530 auto data_buffer = proxy.buffers()[DATA_BUFFER_INDEX];
531 const size_t data_buffer_size = data_buffer.size();
532 const size_type index_offset = (static_cast<size_type>(proxy.offset()) * m_element_size) + i;
533 SPARROW_ASSERT_TRUE(data_buffer_size >= index_offset);
534 return data_buffer.template data<data_value_type>() + index_offset;
535 }
536
537 template <std::ranges::sized_range T, class CR>
538 auto fixed_width_binary_array_impl<T, CR>::data(size_type i) const -> const_data_iterator
539 {
540 const arrow_proxy& proxy = this->get_arrow_proxy();
541 const auto data_buffer = proxy.buffers()[DATA_BUFFER_INDEX];
542 const size_t data_buffer_size = data_buffer.size();
543 const size_type index_offset = (static_cast<size_type>(proxy.offset()) * m_element_size) + i;
544 SPARROW_ASSERT_TRUE(data_buffer_size >= index_offset);
545 return data_buffer.template data<const data_value_type>() + index_offset;
546 }
547
548 template <std::ranges::sized_range T, class CR>
549 template <std::ranges::sized_range U>
551 void fixed_width_binary_array_impl<T, CR>::assign(U&& rhs, size_type index)
552 {
553 SPARROW_ASSERT_TRUE(std::ranges::size(rhs) == m_element_size);
554 SPARROW_ASSERT_TRUE(index < size());
555 std::copy(std::ranges::begin(rhs), std::ranges::end(rhs), data(index * m_element_size));
556 }
557
558 template <std::ranges::sized_range T, class CR>
564
565 template <std::ranges::sized_range T, class CR>
567 {
568 SPARROW_ASSERT_TRUE(i < this->size());
569 const auto offset_begin = i * m_element_size;
570 const auto offset_end = offset_begin + m_element_size;
571 const const_data_iterator pointer_begin = data(static_cast<size_type>(offset_begin));
572 const const_data_iterator pointer_end = data(static_cast<size_type>(offset_end));
573 return inner_const_reference(pointer_begin, pointer_end);
574 }
575
576 template <std::ranges::sized_range T, class CR>
577 auto fixed_width_binary_array_impl<T, CR>::value_begin() -> value_iterator
578 {
579 return value_iterator{functor_type{&(this->derived_cast())}, 0};
580 }
581
582 template <std::ranges::sized_range T, class CR>
583 auto fixed_width_binary_array_impl<T, CR>::value_end() -> value_iterator
584 {
585 return sparrow::next(value_begin(), size());
586 }
587
588 template <std::ranges::sized_range T, class CR>
589 auto fixed_width_binary_array_impl<T, CR>::value_cbegin() const -> const_value_iterator
590 {
591 return const_value_iterator{const_functor_type{&(this->derived_cast())}, 0};
592 }
593
594 template <std::ranges::sized_range T, class CR>
595 auto fixed_width_binary_array_impl<T, CR>::value_cend() const -> const_value_iterator
596 {
597 return sparrow::next(value_cbegin(), this->size());
598 }
599
600 template <std::ranges::sized_range T, class CR>
601 template <std::ranges::sized_range U>
603 void fixed_width_binary_array_impl<T, CR>::resize_values(size_type new_length, U value)
604 {
605 SPARROW_ASSERT_TRUE(m_element_size == value.size());
606 if (new_length < size())
607 {
608 arrow_proxy& proxy = this->get_arrow_proxy();
609 const size_t new_size = new_length + static_cast<size_t>(proxy.offset());
610 const auto offset = new_size * m_element_size;
611 auto& data_buffer = proxy.get_array_private_data()->buffers()[DATA_BUFFER_INDEX];
612 data_buffer.resize(offset);
613 }
614 else if (new_length > size())
615 {
616 insert_value(value_cend(), value, new_length - size());
617 }
618 }
619
620 template <std::ranges::sized_range T, class CR>
621 template <std::ranges::sized_range U>
623 auto fixed_width_binary_array_impl<T, CR>::insert_value(const_value_iterator pos, U value, size_type count)
625 {
626 SPARROW_ASSERT_TRUE(m_element_size == value.size());
627 const auto idx = static_cast<size_t>(std::distance(value_cbegin(), pos));
628
629 const uint8_t* uint8_ptr = reinterpret_cast<const uint8_t*>(value.data());
630 const std::vector<uint8_t> casted_value(uint8_ptr, uint8_ptr + value.size());
631 const repeat_view<std::vector<uint8_t>> my_repeat_view{casted_value, count};
632 const auto joined_repeated_value_range = std::ranges::views::join(my_repeat_view);
633 arrow_proxy& proxy = this->get_arrow_proxy();
634 auto& data_buffer = proxy.get_array_private_data()->buffers()[DATA_BUFFER_INDEX];
635 const auto offset_begin = (idx + proxy.offset()) * m_element_size;
636 const auto pos_to_insert = sparrow::next(data_buffer.cbegin(), offset_begin);
637 data_buffer.insert(pos_to_insert, joined_repeated_value_range.begin(), joined_repeated_value_range.end());
638 return sparrow::next(value_begin(), idx);
639 }
640
641 template <std::ranges::sized_range T, class CR>
642 template <typename InputIt>
643 requires std::input_iterator<InputIt>
645 auto
646 fixed_width_binary_array_impl<T, CR>::insert_values(const_value_iterator pos, InputIt first, InputIt last)
648 {
649 SPARROW_ASSERT_TRUE(value_cbegin() <= pos)
650 SPARROW_ASSERT_TRUE(pos <= value_cend());
651 SPARROW_ASSERT_TRUE(first <= last);
652 SPARROW_ASSERT_TRUE(all_same_size(std::ranges::subrange(first, last)));
653 SPARROW_ASSERT_TRUE(m_element_size == std::ranges::size(*first));
654
655 auto values = std::ranges::subrange(first, last);
656 const size_t cumulative_sizes = values.size() * m_element_size;
657 auto& data_buffer = get_arrow_proxy().get_array_private_data()->buffers()[DATA_BUFFER_INDEX];
658 data_buffer.resize(data_buffer.size() + cumulative_sizes);
659 const auto idx = static_cast<size_t>(std::distance(value_cbegin(), pos));
660 std::span<byte_t> casted_values{reinterpret_cast<byte_t*>(data_buffer.data()), data_buffer.size()};
661 const auto offset_begin = m_element_size * (idx + get_arrow_proxy().offset());
662 auto insert_pos = sparrow::next(casted_values.begin(), offset_begin);
663
664 // Move elements to make space for the new value
665 std::move_backward(
666 insert_pos,
667 sparrow::next(casted_values.end(), -static_cast<difference_type>(cumulative_sizes)),
668 casted_values.end()
669 );
670
671 for (const auto& val : values)
672 {
673 std::copy(val.begin(), val.end(), insert_pos);
674 std::advance(insert_pos, m_element_size);
675 }
676 return sparrow::next(value_begin(), idx);
677 }
678
679 template <std::ranges::sized_range T, class CR>
680 auto fixed_width_binary_array_impl<T, CR>::erase_values(const_value_iterator pos, size_type count)
681 -> value_iterator
682 {
683 SPARROW_ASSERT_TRUE(pos >= value_cbegin());
684 SPARROW_ASSERT_TRUE(pos <= value_cend());
685 const size_t index = static_cast<size_t>(std::distance(value_cbegin(), pos));
686 if (count == 0)
687 {
688 return sparrow::next(value_begin(), index);
689 }
690 auto& data_buffer = get_arrow_proxy().get_array_private_data()->buffers()[DATA_BUFFER_INDEX];
691 const size_type byte_count = m_element_size * count;
692 const auto offset_begin = m_element_size * (index + static_cast<size_type>(get_arrow_proxy().offset()));
693 const auto offset_end = offset_begin + byte_count;
694 // move the values after the erased ones
695 std::move(
696 data_buffer.begin() + static_cast<difference_type>(offset_end),
697 data_buffer.end(),
698 data_buffer.begin() + static_cast<difference_type>(offset_begin)
699 );
700 data_buffer.resize(data_buffer.size() - byte_count);
701 return sparrow::next(value_begin(), index);
702 }
703}
typename base_type::const_bitmap_range const_bitmap_range
typename base_type::iterator_tag iterator_tag
std::conditional_t< is_mutable, mutable_array_base< D >, array_crtp_base< D > > base_type
typename base_type::bitmap_const_reference bitmap_const_reference
typename base_type::bitmap_type bitmap_type
typename base_type::difference_type difference_type
constexpr BufferType & buffers() noexcept
Proxy class over ArrowArray and ArrowSchema.
SPARROW_API size_t offset() const
SPARROW_API arrow_array_private_data * get_array_private_data()
bitset_iterator< self_type, true > const_iterator
fixed_width_binary_array_impl(ARGS &&... args)
Constructs a fixed-width binary array.
inner_const_reference value(size_type i) const
Implementation of reference to inner type used for layout L.
The nullable class models a value or a reference that can be "null", or missing, like values traditio...
Definition nullable.hpp:281
A view that repeats a value a given number of times.
This buffer class is use as storage buffer for all sparrow arrays.
Definition u8_buffer.hpp:75
Matches range types From whose elements are convertible to elements of range type To.
Definition mp_utils.hpp:450
#define SPARROW_ASSERT_TRUE(expr__)
constexpr std::size_t size(typelist< T... >={})
Definition mp_utils.hpp:107
constexpr bool excludes_copy_and_move_ctor_v
Definition mp_utils.hpp:507
constexpr bool is_type_instance_of_v
true if T is a concrete type template instanciation of U which is a type template.
Definition mp_utils.hpp:50
array_bitmap_base_impl< D, true > mutable_array_bitmap_base
Convenient typedef to be used as a crtp base class for arrays using a mutable validity buffer.
ArrowSchema make_arrow_schema(F format, N name, std::optional< M > metadata, std::optional< std::unordered_set< ArrowFlag > > flags, ArrowSchema **children, const CHILDREN_OWNERSHIP &children_ownership, ArrowSchema *dictionary, bool dictionary_ownership)
Creates an ArrowSchema owned by a unique_ptr and holding the provided data.
std::byte byte_t
constexpr bool all_same_size(const Range &range)
Definition ranges.hpp:45
arrow_traits< std::vector< byte_t > > fixed_width_binary_traits
constexpr InputIt next(InputIt it, Distance n)
Definition iterator.hpp:503
fixed_width_binary_array_impl< fixed_width_binary_traits::value_type, fixed_width_binary_traits::const_reference > fixed_width_binary_array
ArrowArray make_arrow_array(int64_t length, int64_t null_count, int64_t offset, B buffers, ArrowArray **children, const CHILDREN_OWNERSHIP &children_ownership, ArrowArray *dictionary, bool dictionary_ownership)
Creates an ArrowArray.
dynamic_bitset< std::uint8_t > validity_bitmap
SPARROW_API std::size_t num_bytes_for_fixed_sized_binary(std::string_view format)
Get the number of bytes for a fixed width binary layout from the ArrowArray format string.
validity_bitmap ensure_validity_bitmap(std::size_t size, R &&validity_input)
data_type
Runtime identifier of arrow data types, usually associated with raw bytes with the associated value.
detail::layout_value_functor< array_type, inner_reference > functor_type
detail::layout_value_functor< const array_type, inner_const_reference > const_functor_type
Base class for array_inner_types specialization.
Traits class that must be specialized by array classes inheriting from array_crtp_base.
Provides compile-time information about Arrow data types.