Container System 0.1.0
High-performance C++20 type-safe container framework with SIMD-accelerated serialization
Loading...
Searching...
No Matches
value.h
Go to the documentation of this file.
1/*****************************************************************************
2BSD 3-Clause License
3
4Copyright (c) 2024, 🍀☀🌕🌥 🌊
5All rights reserved.
6*****************************************************************************/
7
8#pragma once
9
10#include "core/value_types.h"
11#include "core/concepts.h"
12#include <variant>
13#include <string>
14#include <string_view>
15#include <vector>
16#include <memory>
17#include <optional>
18#include <mutex>
19#include <shared_mutex>
20#include <atomic>
21#include <type_traits>
22#include <concepts>
23
24namespace kcenon::container
25{
26 // Forward declarations
27 class thread_safe_container;
28 class value;
29
30 // Note: Positions 6-9 in ValueVariant use unaliased C++ fundamental types
31 // (long, unsigned long, long long, unsigned long long) instead of
32 // int64_t/uint64_t. This avoids duplicate-type issues in std::variant
33 // because int64_t is a typedef for long long on most platforms, which
34 // would conflict with a separate long long entry. Using the unaliased
35 // types ensures they are always distinct in the C++ type system:
36 // - LP64 (macOS/Linux): long=64bit, long long=64bit (distinct types)
37 // - LLP64 (Windows): long=32bit, long long=64bit (distinct types)
38
46 std::vector<std::shared_ptr<value>> values;
47
48 array_variant() = default;
49 array_variant(const array_variant& other);
50 array_variant(array_variant&& other) noexcept = default;
52 array_variant& operator=(array_variant&& other) noexcept = default;
53
54 bool operator==(const array_variant& other) const;
55 bool operator!=(const array_variant& other) const { return !(*this == other); }
56 bool operator<(const array_variant& other) const;
57 };
58
72 using ValueVariant = std::variant<
73 std::monostate, // 0: null_value
74 bool, // 1: bool_value
75 int16_t, // 2: short_value
76 uint16_t, // 3: ushort_value
77 int32_t, // 4: int_value
78 uint32_t, // 5: uint_value
79 long, // 6: long_value (unaliased fundamental type)
80 unsigned long, // 7: ulong_value (unaliased fundamental type)
81 long long, // 8: llong_value (always distinct from long)
82 unsigned long long, // 9: ullong_value (always distinct from unsigned long)
83 float, // 10: float_value
84 double, // 11: double_value
85 std::string, // 12: string_value
86 std::vector<uint8_t>, // 13: bytes_value
87 std::shared_ptr<thread_safe_container>, // 14: container_value
88 array_variant // 15: array_value
89 >;
90
97 namespace detail {
98 template<typename T, typename Variant>
99 constexpr size_t variant_index_of() {
100 return std::variant<T, Variant>::index();
101 }
102
103 // Verify critical type alignments
104 static_assert(std::variant_size_v<ValueVariant> == 16,
105 "ValueVariant must have exactly 16 types");
106 static_assert(std::is_same_v<std::variant_alternative_t<0, ValueVariant>, std::monostate>,
107 "Index 0 must be std::monostate");
108 static_assert(std::is_same_v<std::variant_alternative_t<1, ValueVariant>, bool>,
109 "Index 1 must be bool");
110 static_assert(std::is_same_v<std::variant_alternative_t<12, ValueVariant>, std::string>,
111 "Index 12 must be string");
112 static_assert(std::is_same_v<std::variant_alternative_t<13, ValueVariant>, std::vector<uint8_t>>,
113 "Index 13 must be bytes (vector<uint8_t>)");
114 static_assert(std::is_same_v<std::variant_alternative_t<15, ValueVariant>, array_variant>,
115 "Index 15 must be array_variant");
116 }
117
128 class value
129 {
130 public:
134 value() : name_(""), data_(std::in_place_index<0>) {}
135
139 explicit value(std::string_view name)
140 : name_(name), data_(std::in_place_index<0>) {}
141
145 template<typename T>
146 value(std::string_view name, T&& value)
147 : name_(name), data_(std::forward<T>(value)) {}
148
152 value(std::string_view name, value_types type, const std::vector<uint8_t>& raw_data);
153
157 value(const value& other);
158
162 value(value&& other) noexcept;
163
167 value& operator=(const value& other);
168
172 value& operator=(value&& other) noexcept;
173
177 std::string_view name() const noexcept { return name_; }
178
189 value_types type() const;
190
194 size_t variant_index() const {
195 std::shared_lock lock(mutex_);
196 return data_.index();
197 }
198
202 bool is_null() const {
203 std::shared_lock lock(mutex_);
204 return data_.index() == 0;
205 }
206
212 template<concepts::ValueVariantType T>
213 std::optional<T> get() const {
214 std::shared_lock lock(mutex_);
215 if (auto* ptr = std::get_if<T>(&data_)) {
216 return *ptr;
217 }
218 return std::nullopt;
219 }
220
225 template<concepts::ValueVariantType T>
226 void set(T&& value) {
227 std::unique_lock lock(mutex_);
228 data_ = std::forward<T>(value);
229 write_count_.fetch_add(1, std::memory_order_relaxed);
230 }
231
236 template<concepts::ValueVisitor Visitor>
237 auto visit(Visitor&& vis) const {
238 std::shared_lock lock(mutex_);
239 read_count_.fetch_add(1, std::memory_order_relaxed);
240 return std::visit(std::forward<Visitor>(vis), data_);
241 }
242
247 template<concepts::ValueVisitor Visitor>
248 auto visit_mut(Visitor&& vis) {
249 std::unique_lock lock(mutex_);
250 write_count_.fetch_add(1, std::memory_order_relaxed);
251 return std::visit(std::forward<Visitor>(vis), data_);
252 }
253
257 std::string to_string() const;
258
262 std::string to_json() const;
263
272 std::vector<uint8_t> serialize() const;
273
283 static std::optional<value> deserialize(const std::vector<uint8_t>& data);
284
288 size_t read_count() const { return read_count_.load(std::memory_order_relaxed); }
289 size_t write_count() const { return write_count_.load(std::memory_order_relaxed); }
290
294 bool operator==(const value& other) const;
295 bool operator!=(const value& other) const { return !(*this == other); }
296 bool operator<(const value& other) const;
297
298 private:
302 void serialize_data(std::vector<uint8_t>& result) const;
303
307 static bool deserialize_data(value& result,
308 value_types type,
309 const std::vector<uint8_t>& data,
310 size_t& offset);
311
312 const std::string name_; // Immutable for lock-free access
314 mutable std::shared_mutex mutex_;
315 mutable std::atomic<size_t> read_count_{0};
316 mutable std::atomic<size_t> write_count_{0};
317 };
318
322 template<typename T>
323 struct is_variant_type_v2 : std::false_type {};
324
325 // Specialize for each variant type
326 template<> struct is_variant_type_v2<std::monostate> : std::true_type {};
327 template<> struct is_variant_type_v2<bool> : std::true_type {};
328 template<> struct is_variant_type_v2<int16_t> : std::true_type {};
329 template<> struct is_variant_type_v2<uint16_t> : std::true_type {};
330 template<> struct is_variant_type_v2<int32_t> : std::true_type {};
331 template<> struct is_variant_type_v2<uint32_t> : std::true_type {};
332 template<> struct is_variant_type_v2<int64_t> : std::true_type {};
333 template<> struct is_variant_type_v2<uint64_t> : std::true_type {};
334 template<> struct is_variant_type_v2<float> : std::true_type {};
335 template<> struct is_variant_type_v2<double> : std::true_type {};
336 template<> struct is_variant_type_v2<std::vector<uint8_t>> : std::true_type {};
337 template<> struct is_variant_type_v2<std::string> : std::true_type {};
338 template<> struct is_variant_type_v2<std::shared_ptr<thread_safe_container>> : std::true_type {};
339 template<> struct is_variant_type_v2<array_variant> : std::true_type {};
340
341 template<typename T>
343
344} // namespace kcenon::container
Enhanced type-safe value with perfect legacy compatibility.
Definition value.h:129
ValueVariant data_
Definition value.h:313
static bool deserialize_data(value &result, value_types type, const std::vector< uint8_t > &data, size_t &offset)
Deserialize data portion based on type.
Definition value.cpp:359
std::string to_json() const
Convert to JSON representation.
Definition value.cpp:186
value_types type() const
Get the value_types enum (NOT variant::index()!)
Definition value.cpp:138
bool operator==(const value &other) const
Comparison operators (thread-safe)
Definition value.cpp:595
value & operator=(const value &other)
Copy assignment (thread-safe)
Definition value.cpp:118
std::string to_string() const
Convert to string representation.
Definition value.cpp:146
std::optional< T > get() const
Type-safe getter with optional return.
Definition value.h:213
value(std::string_view name, T &&value)
Construct with name and typed value.
Definition value.h:146
size_t write_count() const
Definition value.h:289
std::shared_mutex mutex_
Definition value.h:314
void set(T &&value)
Type-safe setter.
Definition value.h:226
const std::string name_
Definition value.h:312
std::string_view name() const noexcept
Get the name of this value (lock-free, immutable)
Definition value.h:177
value()
Default constructor - creates null value.
Definition value.h:134
auto visit_mut(Visitor &&vis)
Apply visitor to contained value (mutable)
Definition value.h:248
void serialize_data(std::vector< uint8_t > &result) const
Serialize data portion based on type.
Definition value.cpp:259
bool operator<(const value &other) const
Definition value.cpp:601
bool is_null() const
Check if null value.
Definition value.h:202
value(std::string_view name)
Construct with name (null value)
Definition value.h:139
size_t read_count() const
Get read/write statistics.
Definition value.h:288
static std::optional< value > deserialize(const std::vector< uint8_t > &data)
Deserialize from binary format (legacy compatible)
Definition value.cpp:555
std::atomic< size_t > write_count_
Definition value.h:316
auto visit(Visitor &&vis) const
Apply visitor to contained value (const)
Definition value.h:237
std::atomic< size_t > read_count_
Definition value.h:315
std::vector< uint8_t > serialize() const
Serialize to binary format (legacy compatible)
Definition value.cpp:339
size_t variant_index() const
Get variant index (for internal use only)
Definition value.h:194
bool operator!=(const value &other) const
Definition value.h:295
constexpr size_t variant_index_of()
Definition value.h:99
constexpr bool is_variant_type_v2_v
Definition value.h:342
std::variant< std::monostate, bool, int16_t, uint16_t, int32_t, uint32_t, long, unsigned long, long long, unsigned long long, float, double, std::string, std::vector< uint8_t >, std::shared_ptr< thread_safe_container >, array_variant > ValueVariant
Type-aligned variant matching value_types enum EXACTLY.
Definition value.h:72
Recursive array type for variant.
Definition value.h:45
bool operator==(const array_variant &other) const
Definition value.cpp:69
std::vector< std::shared_ptr< value > > values
Definition value.h:46
bool operator!=(const array_variant &other) const
Definition value.h:55
array_variant & operator=(const array_variant &other)
Definition value.cpp:56
array_variant & operator=(array_variant &&other) noexcept=default
array_variant(array_variant &&other) noexcept=default
bool operator<(const array_variant &other) const
Definition value.cpp:79
Type traits for variant types.
Definition value.h:323