sparrow 2.3.0
C++20 idiomatic APIs for the Apache Arrow Columnar Format
Loading...
Searching...
No Matches
arrow_array_schema_utils.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 implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#include <algorithm>
18#include <optional>
19#include <ranges>
20#include <tuple>
21#include <type_traits>
22#include <vector>
23
26
27namespace sparrow
28{
39 template <class T>
40 [[nodiscard]] constexpr int64_t ssize(const T& value);
41
54 template <typename T, typename U>
55 [[nodiscard]] constexpr T* get_raw_ptr(U& var);
56
67 template <class T, std::ranges::input_range Range, class Allocator = std::allocator<T*>>
68 requires(!std::ranges::view<Range>)
69 [[nodiscard]] constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Range& range);
70
81 template <class T, class Optional, class Allocator = std::allocator<T*>>
83 [[nodiscard]] constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Optional& optional);
84
97 template <class T, class Tuple, class Allocator = std::allocator<T*>>
99 [[nodiscard]] constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Tuple& tuple);
100
105 template <class T>
106 requires std::same_as<T, std::nullopt_t>
109 || (std::ranges::range<T> && mpl::testable<std::ranges::range_value_t<T>>)
110 [[nodiscard]] constexpr bool all_element_are_true(const T& elements);
111
112 /******************
113 * Implementation *
114 ******************/
115
116 template <class T>
117 constexpr int64_t ssize(const T& value)
118 {
119 if constexpr (std::ranges::sized_range<T>)
120 {
121 return static_cast<int64_t>(std::ranges::size(value));
122 }
124 {
125 return std::tuple_size_v<T>;
126 }
128 {
129 if (value.has_value())
130 {
131 return ssize(*value);
132 }
133 else
134 {
135 return 0;
136 }
137 }
138 else
139 {
140 return 0;
141 }
142 }
143
144 template <typename T, typename U>
145 constexpr T* get_raw_ptr(U& var)
146 {
147 if constexpr (std::is_pointer_v<U>)
148 {
149 return var;
150 }
151 else if constexpr (requires { typename U::element_type; })
152 {
153 if constexpr (
154 mpl::smart_ptr<U> || std::is_base_of_v<std::shared_ptr<typename U::element_type>, U>
156 )
157 {
158 if constexpr (std::ranges::contiguous_range<typename U::element_type>)
159 {
160 return std::ranges::data(*var.get());
161 }
162 else if constexpr (std::same_as<typename U::element_type, T> || std::same_as<T, void>)
163 {
164 return var.get();
165 }
166 }
167 }
168 else if constexpr (std::ranges::contiguous_range<U>)
169 {
170 return std::ranges::data(var);
171 }
172 else if constexpr (std::same_as<T, U> || std::same_as<T, void>)
173 {
174 return &var;
175 }
176 else
177 {
178 static_assert(mpl::dependent_false<T, U>::value, "get_raw_ptr: unsupported type.");
180 }
181 }
182
183 template <class T, std::ranges::input_range Range, class Allocator>
184 requires(!std::ranges::view<Range>)
185 constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Range& range)
186 {
187 std::vector<T*, Allocator> raw_ptr_vec;
188 raw_ptr_vec.reserve(range.size());
189 std::ranges::transform(
190 range,
191 std::back_inserter(raw_ptr_vec),
192 [](auto& elem) -> T*
193 {
194 return get_raw_ptr<T>(elem);
195 }
196 );
197 return raw_ptr_vec;
198 }
199
200 template <class T, class Optional, class Allocator>
202 constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Optional& optional)
203 {
204 if (!optional.has_value())
205 {
206 return {};
207 }
208 return to_raw_ptr_vec<T>(*optional);
209 }
210
211 template <class T, class Tuple, class Allocator>
213 constexpr std::vector<T*, Allocator> to_raw_ptr_vec(Tuple& tuple)
214 {
215 std::vector<T*, Allocator> raw_ptr_vec;
216 raw_ptr_vec.reserve(std::tuple_size_v<Tuple>);
217 std::apply(
218 [&raw_ptr_vec](auto&&... args)
219 {
220 (raw_ptr_vec.push_back(get_raw_ptr<T>(args)), ...);
221 },
222 tuple
223 );
224 return raw_ptr_vec;
225 }
226
227 template <class T>
228 requires std::same_as<T, std::nullopt_t>
230 && mpl::testable<std::ranges::range_value_t<typename T::value_type>>)
231 || (std::ranges::range<T> && mpl::testable<std::ranges::range_value_t<T>>)
232 constexpr bool all_element_are_true(const T& elements)
233 {
234 if constexpr (!std::same_as<T, std::nullopt_t>)
235 {
237 {
238 if (elements.has_value())
239 {
240 return std::ranges::all_of(
241 *elements,
242 [](const auto& child)
243 {
244 return bool(child);
245 }
246 );
247 }
248 else
249 {
250 return true;
251 }
252 }
253 else
254 {
255 return std::ranges::all_of(
256 elements,
257 [](const auto& element)
258 {
259 return bool(element);
260 }
261 );
262 }
263 }
264 else
265 {
266 return true;
267 }
268 }
269
270}
Concept for any smart pointer type.
Definition mp_utils.hpp:983
Concept for testable types in boolean contexts.
constexpr bool is_type_instance_of_v
Variable template for convenient access to is_type_instance_of.
Definition mp_utils.hpp:102
void unreachable()
Invokes undefined behavior for optimization purposes.
Definition mp_utils.hpp:882
constexpr int64_t ssize(const T &value)
Get the size of a range, a tuple or an optional.
constexpr std::vector< T *, Allocator > to_raw_ptr_vec(Range &range)
Create a vector of pointers to elements from a range.
constexpr bool all_element_are_true(const T &elements)
Check if all elements of a range or std::optional<range> are valid by caling their bool operator.
constexpr T * get_raw_ptr(U &var)
Get a raw pointer from a smart pointer, a range, an object or a pointer.
Workaround to replace static_assert(false) in template code.
Definition mp_utils.hpp:54