sparrow 2.4.0
C++20 idiomatic APIs for the Apache Arrow Columnar Format
Loading...
Searching...
No Matches
array_wrapper.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 <memory>
18#include <variant>
19
23
24namespace sparrow
25{
26 namespace detail
27 {
28 // Helper struct to allow overloading on the type of ARRAY
29 // to get the data_type for an array. This is needed since
30 // some arrays (for instance run_length_encoded_array)
31 // do not have a inner_value_type, therefore we specialize
32 // this in their respecitve headers.
33 template <class ARRAY>
35
36 template <class ARRAY>
38 {
39 [[nodiscard]] static constexpr bool get() noexcept
40 {
41 return false;
42 }
43 };
44 }
45
50 {
51 public:
52
53 using wrapper_ptr = std::unique_ptr<array_wrapper>;
54
55 virtual ~array_wrapper() = default;
56
60
61 [[nodiscard]] wrapper_ptr clone() const;
62
63 [[nodiscard]] constexpr enum data_type data_type() const noexcept;
64 [[nodiscard]] constexpr bool is_dictionary() const;
65
66 [[nodiscard]] constexpr arrow_proxy& get_arrow_proxy();
67 [[nodiscard]] constexpr const arrow_proxy& get_arrow_proxy() const;
68
69 protected:
70
71 constexpr array_wrapper(enum data_type dt);
72 constexpr array_wrapper(const array_wrapper&) = default;
73
74 private:
75
76 enum data_type m_data_type;
77 [[nodiscard]] virtual bool is_dictionary_impl() const = 0;
78 [[nodiscard]] virtual arrow_proxy& get_arrow_proxy_impl() = 0;
79 [[nodiscard]] virtual const arrow_proxy& get_arrow_proxy_impl() const = 0;
80 [[nodiscard]] virtual wrapper_ptr clone_impl() const = 0;
81 };
82
83 template <class T>
85 {
86 public:
87
88 array_wrapper_impl(T&& ar);
89 array_wrapper_impl(T* ar);
90 array_wrapper_impl(std::shared_ptr<T> ar);
91
92 ~array_wrapper_impl() override = default;
93
94 T& get_wrapped();
95 const T& get_wrapped() const;
96
97 private:
98
99 using wrapper_ptr = array_wrapper::wrapper_ptr;
100
101 [[nodiscard]] constexpr enum data_type get_data_type() const noexcept;
102
103 constexpr array_wrapper_impl(const array_wrapper_impl&);
104 [[nodiscard]] constexpr bool is_dictionary_impl() const noexcept override;
105 [[nodiscard]] constexpr arrow_proxy& get_arrow_proxy_impl() override;
106 [[nodiscard]] constexpr const arrow_proxy& get_arrow_proxy_impl() const override;
107 [[nodiscard]] wrapper_ptr clone_impl() const override;
108
109 using storage_type = std::variant<value_ptr<T>, std::shared_ptr<T>, T*>;
110 storage_type m_storage;
111 T* p_array;
112 };
113
114 template <class T>
116
117 template <class T>
118 const T& unwrap_array(const array_wrapper&);
119
120 /********************************
121 * array_wrapper implementation *
122 ********************************/
123
125 {
126 return clone_impl();
127 }
128
129 constexpr enum data_type array_wrapper::data_type() const noexcept
130 {
131 return m_data_type;
132 }
133
134 constexpr bool array_wrapper::is_dictionary() const
135 {
136 return is_dictionary_impl();
137 }
138
143
145 {
146 return get_arrow_proxy_impl();
147 }
148
150 : m_data_type(dt)
151 {
152 }
153
154 /*************************************
155 * array_wrapper_impl implementation *
156 *************************************/
157
158 template <class T>
160 : array_wrapper(get_data_type())
161 , m_storage(value_ptr<T>(std::move(ar)))
162 , p_array(std::get<value_ptr<T>>(m_storage).get())
163 {
164 }
165
166 template <class T>
168 : array_wrapper(get_data_type())
169 , m_storage(ar)
170 , p_array(ar)
171 {
172 }
173
174 template <class T>
176 : array_wrapper(get_data_type())
177 , m_storage(std::move(ar))
178 , p_array(std::get<std::shared_ptr<T>>(m_storage).get())
179 {
180 }
181
182 template <class T>
184 {
185 return *p_array;
186 }
187
188 template <class T>
190 {
191 return *p_array;
192 }
193
194 template <class T>
195 constexpr enum data_type array_wrapper_impl<T>::get_data_type() const noexcept
196 {
198 }
199
200 template <class T>
201 constexpr array_wrapper_impl<T>::array_wrapper_impl(const array_wrapper_impl& rhs)
202 : array_wrapper(rhs)
203 , m_storage(value_ptr<T>(T(rhs.get_wrapped())))
204 , p_array(
205 std::visit(
206 [](auto&& arg)
207 {
208 using U = std::decay_t<decltype(arg)>;
209 if constexpr (std::is_same_v<U, T*>)
210 {
211 return arg;
212 }
213 else
214 {
215 return arg.get();
216 }
217 },
218 m_storage
219 )
220 ) // Always deep copy
221 {
222 }
223
224 template <class T>
225 constexpr bool array_wrapper_impl<T>::is_dictionary_impl() const noexcept
226 {
228 }
229
230 template <class T>
235
236 template <class T>
241
242 template <class T>
243 auto array_wrapper_impl<T>::clone_impl() const -> wrapper_ptr
244 {
245 return wrapper_ptr{new array_wrapper_impl<T>(*this)};
246 }
247
248 template <class T>
250 {
251 return static_cast<array_wrapper_impl<T>&>(ar).get_wrapped();
252 }
253
254 template <class T>
255 const T& unwrap_array(const array_wrapper& ar)
256 {
257 return static_cast<const array_wrapper_impl<T>&>(ar).get_wrapped();
258 }
259}
wrapper_ptr clone_impl() const override
~array_wrapper_impl() override=default
constexpr arrow_proxy & get_arrow_proxy_impl() override
constexpr bool is_dictionary_impl() const noexcept override
Base class for array type erasure.
wrapper_ptr clone() const
std::unique_ptr< array_wrapper > wrapper_ptr
array_wrapper & operator=(array_wrapper &&)=delete
array_wrapper & operator=(const array_wrapper &)=delete
virtual ~array_wrapper()=default
virtual arrow_proxy & get_arrow_proxy_impl()=0
virtual bool is_dictionary_impl() const =0
constexpr bool is_dictionary() const
constexpr arrow_proxy & get_arrow_proxy()
array_wrapper(array_wrapper &&)=delete
constexpr enum data_type data_type() const noexcept
virtual wrapper_ptr clone_impl() const =0
static const sparrow::arrow_proxy & get_arrow_proxy(const ARRAY &array)
A value_ptr is a smart pointer that behaves like a value.
Definition memory.hpp:36
#define inline
Definition libpopcnt.h:65
auto visit(F &&func, const array_wrapper &ar) -> std::invoke_result_t< F, null_array >
T & unwrap_array(array_wrapper &)
data_type
Runtime identifier of arrow data types, usually associated with raw bytes with the associated value.
Extensions to the C++ standard library.
Metafunction for retrieving the data_type of a typed array.
static constexpr bool get() noexcept