sparrow 0.9.0
Loading...
Searching...
No Matches
/home/runner/work/sparrow/sparrow/include/sparrow/layout/decimal_reference.hpp

Reference proxy for decimal values in array layouts.

Reference proxy for decimal values in array layouts. This class provides a reference-like interface for accessing and modifying decimal values stored in array layouts. It acts as a proxy that forwards operations to the underlying layout while maintaining value semantics similar to built-in references.

The decimal_reference supports:

Template Parameters
LThe layout type that stores decimal values
Precondition
L must provide assign(value_type, size_type) method
L must provide value(size_type) const method returning decimal values
L must define inner_value_type as a decimal type
Postcondition
Reference operations modify the underlying layout storage
Provides value semantics while maintaining reference behavior
Thread-safe for read operations, requires external synchronization for writes
decimal_array<int64_t> arr = ...;
auto ref = arr[0]; // Get decimal reference
ref = decimal<int64_t>(12345, 2); // Assign new value (123.45)
double val = static_cast<double>(ref); // Convert to double
int64_t storage = ref.storage(); // Get raw storage value
// Copyright 2024 Man Group Operations Limited
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#if defined(__cpp_lib_format)
# include <format>
# include <ostream>
#endif
namespace sparrow
{
template <class L>
class decimal_reference
{
public:
using value_type = typename L::inner_value_type;
using reference = typename L::inner_reference;
using const_reference = typename L::inner_const_reference;
using size_type = typename L::size_type;
using difference_type = std::ptrdiff_t;
constexpr decimal_reference(L* layout, size_type index) noexcept;
constexpr decimal_reference(const decimal_reference&) = default;
constexpr decimal_reference(decimal_reference&&) noexcept = default;
constexpr self_type& operator=(self_type&& rhs) noexcept;
constexpr self_type& operator=(const self_type& rhs);
constexpr self_type& operator=(value_type&& rhs);
constexpr self_type& operator=(const value_type& rhs);
constexpr explicit operator float() const
constexpr explicit operator double() const
constexpr explicit operator long double() const
[[nodiscard]] explicit operator std::string() const
constexpr bool operator==(const value_type& rhs) const;
constexpr auto operator<=>(const value_type& rhs) const;
[[nodiscard]] constexpr const_reference value() const;
[[nodiscard]] constexpr value_type::integer_type storage() const;
[[nodiscard]] constexpr int scale() const;
private:
L* p_layout = nullptr;
size_type m_index = size_type(0);
};
/*************************************
* decimal_reference implementation *
*************************************/
template <typename L>
constexpr decimal_reference<L>::decimal_reference(L* layout, size_type index) noexcept
: p_layout(layout)
, m_index(index)
{
}
template <typename L>
constexpr auto decimal_reference<L>::operator=(value_type&& rhs) -> self_type&
{
p_layout->assign(std::forward<value_type>(rhs), m_index);
return *this;
}
template <typename L>
constexpr auto decimal_reference<L>::operator=(const value_type& rhs) -> self_type&
{
p_layout->assign(rhs, m_index);
return *this;
}
template <typename L>
constexpr auto decimal_reference<L>::operator=(self_type&& rhs) noexcept -> self_type&
{
this->operator=(rhs.value());
return *this;
}
template <typename L>
constexpr auto decimal_reference<L>::operator=(const self_type& rhs) -> self_type&
{
this->operator=(rhs.value());
return *this;
}
template <typename L>
constexpr bool decimal_reference<L>::operator==(const value_type& rhs) const
{
return value() == rhs;
}
template <typename L>
constexpr auto decimal_reference<L>::operator<=>(const value_type& rhs) const
{
return value() <=> rhs;
}
template <typename L>
constexpr auto decimal_reference<L>::value() const -> const_reference
{
return static_cast<const L*>(p_layout)->value(m_index);
}
template <typename L>
constexpr auto decimal_reference<L>::storage() const -> value_type::integer_type
{
return value().storage();
}
template <typename L>
constexpr int decimal_reference<L>::scale() const
{
return value().scale();
}
template <typename L>
constexpr decimal_reference<L>::operator float() const
{
return static_cast<float>(value());
}
template <typename L>
constexpr decimal_reference<L>::operator double() const
{
return static_cast<double>(value());
}
template <typename L>
constexpr decimal_reference<L>::operator long double() const
{
return static_cast<long double>(value());
}
}
#if defined(__cpp_lib_format)
template <typename L>
struct std::formatter<sparrow::decimal_reference<L>>
{
constexpr auto parse(std::format_parse_context& ctx)
{
return ctx.begin(); // Simple implementation
}
auto format(const sparrow::decimal_reference<L>& ref, std::format_context& ctx) const
{
const auto& value = ref.value();
return std::format_to(ctx.out(), "{}", value);
}
};
template <typename L>
inline std::ostream& operator<<(std::ostream& os, const sparrow::decimal_reference<L>& value)
{
os << std::format("{}", value);
return os;
}
#endif
constexpr int scale() const
Gets the scale of the decimal.
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
Gets the raw storage value of the decimal.
constexpr self_type & operator=(self_type &&rhs) noexcept
Move assignment from another decimal reference.
typename L::inner_value_type value_type
decimal_reference< L > self_type
constexpr const_reference value() const
Gets the referenced decimal value.
typename L::inner_reference reference
constexpr auto operator<=>(const value_type &rhs) const
Three-way comparison with decimal value.
typename L::size_type size_type
typename L::inner_const_reference const_reference
constexpr bool is_int_placeholder_v
Definition large_int.hpp:82
std::ostream & operator<<(std::ostream &os, const sparrow::nullval_t &)