StormByte C++ Library 0.0.9999
StormByte is a comprehensive, cross-platform C++ library aimed at easing system programming, configuration management, logging, and database handling tasks. This library provides a unified API that abstracts away the complexities and inconsistencies of different platforms (Windows, Linux).
Loading...
Searching...
No Matches
variadic_value.hxx
1#pragma once
2
3#include <StormByte/exception.hxx>
4
5#include <variant>
6#include <memory>
7#include <type_traits>
8#include <stdexcept>
9#include <concepts>
10
18namespace StormByte {
23 template <typename T> concept ValidVariadicType =
24 (!std::is_pointer_v<T>) &&
25 (std::is_same_v<T, std::shared_ptr<typename T::element_type>> ||
26 std::is_same_v<T, std::unique_ptr<typename T::element_type>> ||
27 !std::is_class_v<T> ||
28 std::is_class_v<T>);
29
40 public:
44 VariadicValue() = default;
45
51 template <typename T, typename = std::enable_if_t<(std::is_same_v<T, Types> || ...)>>
52 explicit VariadicValue(T value) : m_values(std::move(value)) {}
53
58
64 _processCopy(other.m_values);
65 }
66
73 if (this != &other) {
74 _processCopy(other.m_values);
75 }
76 return *this;
77 }
78
84
91
98 return m_values == other.m_values;
99 }
100
106 constexpr bool operator!=(const VariadicValue& other) const {
107 return !(*this == other);
108 }
109
116 template <typename T> T& Get() {
117 constexpr bool isDirectMatch = (std::is_same_v<T, Types> || ...);
118 constexpr bool isDereferencedMatch = (
119 ([]<typename U>() constexpr {
120 if constexpr (std::is_same_v<U, std::shared_ptr<T>> || std::is_same_v<U, std::unique_ptr<T>>) {
121 return true;
122 }
123 return false;
124 }.template operator()<Types>() || ...)
125 );
126
127 static_assert(isDirectMatch || isDereferencedMatch,
128 "Requested type is not in the variant or is not compatible with smart pointers");
129
130 if constexpr (isDirectMatch) {
131 if (std::holds_alternative<T>(m_values)) {
132 return std::get<T>(m_values);
133 }
134 throw Exception("Variant does not hold the requested type");
135 }
136
137 if constexpr (isDereferencedMatch) {
138 return std::visit([](auto& value) -> T& {
139 using ValueType = std::decay_t<decltype(value)>;
140 if constexpr (std::is_same_v<ValueType, std::shared_ptr<T>> || std::is_same_v<ValueType, std::unique_ptr<T>>) {
141 if (value) {
142 return *value;
143 }
144 throw Exception("Pointer is null");
145 }
146 throw Exception("Invalid type for dereferencing");
147 }, m_values);
148 }
149
150 throw Exception("Value type mismatch");
151 }
152
159 template <typename T> const T& Get() const {
160 return const_cast<VariadicValue*>(this)->Get<T>();
161 }
162
163 private:
168 template <typename T>
169 struct is_unique_ptr : std::false_type {};
170
175 template <typename T>
176 struct is_unique_ptr<std::unique_ptr<T>> : std::true_type {};
177
182 template <typename T>
183 struct is_shared_ptr : std::false_type {};
184
189 template <typename T>
190 struct is_shared_ptr<std::shared_ptr<T>> : std::true_type {};
191
196 void _processCopy(const std::variant<Types...>& variant) {
197 std::visit([this](const auto& value) {
198 using ValueType = std::decay_t<decltype(value)>;
199 if constexpr (is_unique_ptr<ValueType>::value) {
200 // Handle std::unique_ptr<Foo>
201 using Foo = typename ValueType::element_type;
202 if constexpr (!std::is_abstract_v<Foo>) { // Only process non-abstract types
203 if (value) {
204 m_values = std::make_unique<Foo>(*value);
205 } else {
206 m_values = std::unique_ptr<Foo>(); // Assign a null unique_ptr
207 }
208 } else {
209 static_assert(!std::is_abstract_v<Foo>, "Abstract classes cannot be copied directly");
210 }
211 } else if constexpr (is_shared_ptr<ValueType>::value) {
212 // Copy shared_ptr (no deep copy necessary)
213 m_values = value;
214 } else {
215 // For other types, simply copy the value
216 m_values = value;
217 }
218 }, variant);
219 }
220
221 std::variant<Types...> m_values;
222 };
223}
Base class for exceptions in the StormByte library.
Definition exception.hxx:23
A class that can hold a value of any of the specified types.
Definition variadic_value.hxx:39
const T & Get() const
Retrieves the stored value of the specified type (const version).
Definition variadic_value.hxx:159
VariadicValue & operator=(const VariadicValue &other)
Copy assignment operator with deep copy for std::unique_ptr.
Definition variadic_value.hxx:72
VariadicValue(VariadicValue &&) noexcept=default
Move constructor (default behavior).
VariadicValue()=default
Default constructor.
T & Get()
Retrieves the stored value of the specified type.
Definition variadic_value.hxx:116
constexpr bool operator!=(const VariadicValue &other) const
Inequality operator.
Definition variadic_value.hxx:106
VariadicValue(T value)
Constructor with a value of one of the specified types.
Definition variadic_value.hxx:52
~VariadicValue() noexcept=default
Destructor.
Concept to check if a type is a valid variadic type.
Definition variadic_value.hxx:23
Main namespace for the StormByte library.
std::conditional_t< is_reference< T >::value, std::expected< std::reference_wrapper< std::remove_reference_t< T > >, std::shared_ptr< E > >, std::expected< T, std::shared_ptr< E > > > Expected
Expected type with support for reference types.
Definition expected.hxx:32