sparrow 1.0.0
Loading...
Searching...
No Matches
decimal_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 implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15#pragma once
16
17#if defined(__cpp_lib_format)
18# include <format>
19# include <ostream>
20#endif
21
23
24namespace sparrow
25{
58 template <class L>
60 {
61 public:
62
64 using value_type = typename L::inner_value_type;
65 using reference = typename L::inner_reference;
66 using const_reference = typename L::inner_const_reference;
67 using size_type = typename L::size_type;
68 using difference_type = std::ptrdiff_t;
69
81 constexpr decimal_reference(L* layout, size_type index) noexcept;
82
83 constexpr decimal_reference(const decimal_reference&) = default;
84 constexpr decimal_reference(decimal_reference&&) noexcept = default;
85
96 constexpr self_type& operator=(self_type&& rhs) noexcept;
97
108 constexpr self_type& operator=(const self_type& rhs);
109
121 constexpr self_type& operator=(value_type&& rhs);
122
134 constexpr self_type& operator=(const value_type& rhs);
135
148 constexpr explicit operator float() const
149 requires(!is_int_placeholder_v<typename value_type::integer_type>);
150
163 constexpr explicit operator double() const
164 requires(!is_int_placeholder_v<typename value_type::integer_type>);
165
178 constexpr explicit operator long double() const
179 requires(!is_int_placeholder_v<typename value_type::integer_type>);
180
193 [[nodiscard]] explicit operator std::string() const
194 requires(!is_int_placeholder_v<typename value_type::integer_type>);
195
205 constexpr bool operator==(const value_type& rhs) const;
206
216 constexpr auto operator<=>(const value_type& rhs) const;
217
227 [[nodiscard]] constexpr const_reference value() const;
228
237 [[nodiscard]] constexpr value_type::integer_type storage() const;
238
247 [[nodiscard]] constexpr int scale() const;
248
249 private:
250
251 L* p_layout = nullptr;
252 size_type m_index = size_type(0);
253 };
254
255 /*************************************
256 * decimal_reference implementation *
257 *************************************/
258
259 template <typename L>
260 constexpr decimal_reference<L>::decimal_reference(L* layout, size_type index) noexcept
261 : p_layout(layout)
262 , m_index(index)
263 {
264 }
265
266 template <typename L>
268 {
269 p_layout->assign(std::forward<value_type>(rhs), m_index);
270 return *this;
271 }
272
273 template <typename L>
275 {
276 p_layout->assign(rhs, m_index);
277 return *this;
278 }
279
280 template <typename L>
281 constexpr auto decimal_reference<L>::operator=(self_type&& rhs) noexcept -> self_type&
282 {
283 this->operator=(rhs.value());
284 return *this;
285 }
286
287 template <typename L>
289 {
290 this->operator=(rhs.value());
291 return *this;
292 }
293
294 template <typename L>
295 constexpr bool decimal_reference<L>::operator==(const value_type& rhs) const
296 {
297 return value() == rhs;
298 }
299
300 template <typename L>
301 constexpr auto decimal_reference<L>::operator<=>(const value_type& rhs) const
302 {
303 return value() <=> rhs;
304 }
305
306 template <typename L>
308 {
309 return static_cast<const L*>(p_layout)->value(m_index);
310 }
311
312 template <typename L>
313 constexpr auto decimal_reference<L>::storage() const -> value_type::integer_type
314 {
315 return value().storage();
316 }
317
318 template <typename L>
319 constexpr int decimal_reference<L>::scale() const
320 {
321 return value().scale();
322 }
323
324 template <typename L>
325 constexpr decimal_reference<L>::operator float() const
326 requires(!is_int_placeholder_v<typename value_type::integer_type>)
327 {
328 return static_cast<float>(value());
329 }
330
331 template <typename L>
332 constexpr decimal_reference<L>::operator double() const
333 requires(!is_int_placeholder_v<typename value_type::integer_type>)
334 {
335 return static_cast<double>(value());
336 }
337
338 template <typename L>
339 constexpr decimal_reference<L>::operator long double() const
340 requires(!is_int_placeholder_v<typename value_type::integer_type>)
341 {
342 return static_cast<long double>(value());
343 }
344}
345
346#if defined(__cpp_lib_format)
347
348
349template <typename L>
350struct std::formatter<sparrow::decimal_reference<L>>
351{
352 constexpr auto parse(std::format_parse_context& ctx)
353 {
354 return ctx.begin(); // Simple implementation
355 }
356
357 auto format(const sparrow::decimal_reference<L>& ref, std::format_context& ctx) const
358 {
359 const auto& value = ref.value();
360 return std::format_to(ctx.out(), "{}", value);
361 }
362};
363
364namespace sparrow
365{
366 template <typename L>
367 std::ostream& operator<<(std::ostream& os, const decimal_reference<L>& value)
368 {
369 os << std::format("{}", value);
370 return os;
371 }
372}
373
374#endif
constexpr bool operator==(const value_type &rhs) const
Equality comparison with decimal value.
constexpr decimal_reference(L *layout, size_type index) noexcept
Constructs a decimal reference for the given layout and index.
constexpr value_type::integer_type storage() const
constexpr self_type & operator=(self_type &&rhs) noexcept
Move assignment from another decimal reference.
typename array_type::inner_value_type value_type
decimal_reference< array_type > self_type
constexpr const_reference value() const
typename array_type::inner_reference reference
constexpr decimal_reference(const decimal_reference &)=default
constexpr auto operator<=>(const value_type &rhs) const
Three-way comparison with decimal value.
typename array_type::size_type size_type
constexpr decimal_reference(decimal_reference &&) noexcept=default
typename array_type::inner_const_reference const_reference
Concept for layouts.
constexpr bool is_int_placeholder_v
Definition large_int.hpp:82
std::ostream & operator<<(std::ostream &os, const nullval_t &)