sparrow 0.9.0
Loading...
Searching...
No Matches
variable_size_binary_reference.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 <algorithm>
18#include <concepts>
19#include <ranges>
20#include <string>
21#include <type_traits>
22#include <vector>
23
24#if defined(__cpp_lib_format)
25# include <format>
26# include <ostream>
27#endif
28
31
32namespace sparrow
33{
39 template <class L>
41 {
42 public:
43
45 using value_type = typename L::inner_value_type;
46 using reference = typename L::inner_reference;
47 using const_reference = typename L::inner_const_reference;
48 using size_type = typename L::size_type;
49 using difference_type = std::ptrdiff_t;
50 using iterator = typename L::data_iterator;
51 using const_iterator = typename L::const_data_iterator;
52 using offset_type = typename L::offset_type;
53
57
58 template <std::ranges::sized_range T>
61
62 // This is to avoid const char* from begin caught by the previous
63 // operator= overload. It would convert const char* to const char[N],
64 // including the null-terminating char.
65 template <class U = typename L::inner_value_type>
66 requires std::assignable_from<U&, const char*>
67 self_type& operator=(const char* rhs);
68
69 [[nodiscard]] size_type size() const;
70 [[nodiscard]] bool empty() const;
71
72 [[nodiscard]] [[nodiscard]] iterator begin();
74
75 [[nodiscard]] const_iterator begin() const;
76 [[nodiscard]] const_iterator end() const;
77 [[nodiscard]] const_iterator cbegin() const;
78 [[nodiscard]] const_iterator cend() const;
79
80 template <std::ranges::input_range T>
82 bool operator==(const T& rhs) const;
83
84 template <class U = typename L::inner_value_type>
85 requires std::assignable_from<U&, const char*>
86 bool operator==(const char* rhs) const;
87
88 template <std::ranges::input_range T>
90 auto operator<=>(const T& rhs) const;
91
92 template <class U = typename L::inner_value_type>
93 requires std::assignable_from<U&, const char*>
94 auto operator<=>(const char* rhs) const;
95
96 private:
97
98 [[nodiscard]] offset_type offset(size_type index) const;
99 [[nodiscard]] size_type uoffset(size_type index) const;
100
101 L* p_layout = nullptr;
102 size_type m_index = size_type(0);
103 };
104}
105
106namespace std
107{
108 template <typename Layout, template <typename> typename TQual, template <typename> typename UQual>
109 struct basic_common_reference<sparrow::variable_size_binary_reference<Layout>, std::string, TQual, UQual>
110 {
111 using type = std::string;
112 };
113
114 template <typename Layout, template <typename> typename TQual, template <class> class UQual>
115 struct basic_common_reference<std::string, sparrow::variable_size_binary_reference<Layout>, TQual, UQual>
116 {
117 using type = std::string;
118 };
119
120 template <typename Layout, template <typename> typename TQual, template <typename> typename UQual>
121 struct basic_common_reference<sparrow::variable_size_binary_reference<Layout>, std::vector<std::byte>, TQual, UQual>
122 {
123 using type = std::vector<std::byte>;
124 };
125
126 template <typename Layout, template <typename> typename TQual, template <class> class UQual>
127 struct basic_common_reference<std::vector<std::byte>, sparrow::variable_size_binary_reference<Layout>, TQual, UQual>
128 {
129 using type = std::vector<std::byte>;
130 };
131}
132
133namespace sparrow
134{
135 /*************************************************
136 * variable_size_binary_reference implementation *
137 *************************************************/
138
139 template <class L>
141 : p_layout(layout)
142 , m_index(index)
143 {
144 }
145
146 template <class L>
147 template <std::ranges::sized_range T>
150 {
151 p_layout->assign(std::forward<T>(rhs), m_index);
152 p_layout->get_arrow_proxy().update_buffers();
153 return *this;
154 }
155
156 template <class L>
157 template <class U>
158 requires std::assignable_from<U&, const char*>
160 {
161 return *this = std::string_view(rhs);
162 }
163
164 template <class L>
166 {
167 return static_cast<size_type>(offset(m_index + 1) - offset(m_index));
168 }
169
170 template <class L>
172 {
173 return size() == 0;
174 }
175
176 template <class L>
178 {
179 return iterator(p_layout->data(uoffset(m_index)));
180 }
181
182 template <class L>
184 {
185 return iterator(p_layout->data(uoffset(m_index + 1)));
186 }
187
188 template <class L>
190 {
191 return cbegin();
192 }
193
194 template <class L>
196 {
197 return cend();
198 }
199
200 template <class L>
202 {
203 return const_iterator(p_layout->data(uoffset(m_index)));
204 }
205
206 template <class L>
208 {
209 return const_iterator(p_layout->data(uoffset(m_index + 1)));
210 }
211
212 template <class L>
213 template <std::ranges::input_range T>
216 {
217 return std::equal(cbegin(), cend(), std::cbegin(rhs), std::cend(rhs));
218 }
219
220 template <class L>
221 template <class U>
222 requires std::assignable_from<U&, const char*>
224 {
225 return operator==(std::string_view(rhs));
226 }
227
228 template <class L>
229 template <std::ranges::input_range T>
232 {
233 return lexicographical_compare_three_way(*this, rhs);
234 }
235
236 template <class L>
237 template <class U>
238 requires std::assignable_from<U&, const char*>
240 {
241 return operator<=>(std::string_view(rhs));
242 }
243
244 template <class L>
245 auto variable_size_binary_reference<L>::offset(size_type index) const -> offset_type
246 {
247 return *(p_layout->offset(index));
248 }
249
250 template <class L>
251 auto variable_size_binary_reference<L>::uoffset(size_type index) const -> size_type
252 {
253 return static_cast<size_type>(offset(index));
254 }
255}
256
257#if defined(__cpp_lib_format)
258template <typename Layout>
259struct std::formatter<sparrow::variable_size_binary_reference<Layout>>
260{
261 constexpr auto parse(std::format_parse_context& ctx)
262 {
263 return ctx.begin(); // Simple implementation
264 }
265
266 auto format(const sparrow::variable_size_binary_reference<Layout>& ref, std::format_context& ctx) const
267 {
268 std::for_each(
269 ref.cbegin(),
270 sparrow::next(ref.cbegin(), ref.size() - 1),
271 [&ctx](const auto& value)
272 {
273 std::format_to(ctx.out(), "{}, ", value);
274 }
275 );
276
277 return std::format_to(ctx.out(), "{}>", *std::prev(ref.cend()));
278 }
279};
280
281template <typename Layout>
282inline std::ostream& operator<<(std::ostream& os, const sparrow::variable_size_binary_reference<Layout>& value)
283{
284 os << std::format("{}", value);
285 return os;
286}
287
288#endif
Implementation of reference to inner type used for layout L.
variable_size_binary_reference(variable_size_binary_reference &&)=default
variable_size_binary_reference(const variable_size_binary_reference &)=default
self_type & operator=(const char *rhs)
Matches range types From whose elements are convertible to elements of range type To.
Definition mp_utils.hpp:450
constexpr std::compare_three_way_result_t< typename cloning_ptr< T1 >::pointer, typename cloning_ptr< T2 >::pointer > operator<=>(const cloning_ptr< T1 > &lhs, const cloning_ptr< T2 > &rhs) noexcept
Definition memory.hpp:474
SPARROW_API bool operator==(const array &lhs, const array &rhs)
Compares the content of two arrays.
constexpr InputIt next(InputIt it, Distance n)
Definition iterator.hpp:503
std::ostream & operator<<(std::ostream &os, const sparrow::nullval_t &)
Definition nullable.hpp:933