Container System 0.1.0
High-performance C++20 type-safe container framework with SIMD-accelerated serialization
Loading...
Searching...
No Matches
value_view.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
29#pragma once
30
31#include "core/value_types.h"
32
33#include <string>
34#include <string_view>
35#include <cstdlib>
36#include <optional>
37#include <type_traits>
38
39namespace kcenon::container
40{
41
56{
57public:
66 value_view(const char* name_data, size_t name_length,
67 const char* value_data, size_t value_length,
68 value_types type) noexcept
69 : name_data_(name_data)
70 , name_length_(name_length)
71 , value_data_(value_data)
72 , value_length_(value_length)
73 , type_(type)
74 {}
75
79 [[nodiscard]] std::string_view name() const noexcept
80 {
81 return {name_data_, name_length_};
82 }
83
87 [[nodiscard]] value_types type() const noexcept
88 {
89 return type_;
90 }
91
97 [[nodiscard]] std::string_view as_string_view() const noexcept
98 {
99 return {value_data_, value_length_};
100 }
101
106 [[nodiscard]] std::string as_string() const
107 {
108 return {value_data_, value_length_};
109 }
110
116 template<typename T>
117 [[nodiscard]] std::optional<T> as() const noexcept
118 {
119 if constexpr (std::is_same_v<T, std::string_view>) {
120 if (type_ == value_types::string_value ||
121 type_ == value_types::bytes_value) {
122 return as_string_view();
123 }
124 return std::nullopt;
125 }
126 else if constexpr (std::is_same_v<T, std::string>) {
127 if (type_ == value_types::string_value ||
128 type_ == value_types::bytes_value) {
129 return as_string();
130 }
131 return std::nullopt;
132 }
133 else if constexpr (std::is_same_v<T, bool>) {
134 if (type_ == value_types::bool_value && value_length_ > 0) {
135 return (value_data_[0] == 't' || value_data_[0] == 'T' ||
136 value_data_[0] == '1');
137 }
138 return std::nullopt;
139 }
140 else if constexpr (std::is_integral_v<T>) {
141 return parse_integral<T>();
142 }
143 else if constexpr (std::is_floating_point_v<T>) {
144 return parse_floating<T>();
145 }
146 else {
147 return std::nullopt;
148 }
149 }
150
154 [[nodiscard]] bool is_null() const noexcept
155 {
156 return type_ == value_types::null_value;
157 }
158
162 [[nodiscard]] const char* data() const noexcept
163 {
164 return value_data_;
165 }
166
170 [[nodiscard]] size_t size() const noexcept
171 {
172 return value_length_;
173 }
174
175private:
179 template<typename T>
180 [[nodiscard]] std::optional<T> parse_integral() const noexcept
181 {
182 if (!is_integral_type(type_)) {
183 return std::nullopt;
184 }
185
186 if (value_length_ == 0) {
187 return std::nullopt;
188 }
189
190 // Use strtoll/strtoull for parsing
191 char* end = nullptr;
192 std::string temp(value_data_, value_length_);
193
194 if constexpr (std::is_signed_v<T>) {
195 long long val = std::strtoll(temp.c_str(), &end, 10);
196 if (end != temp.c_str() + temp.size()) {
197 return std::nullopt;
198 }
199 return static_cast<T>(val);
200 } else {
201 unsigned long long val = std::strtoull(temp.c_str(), &end, 10);
202 if (end != temp.c_str() + temp.size()) {
203 return std::nullopt;
204 }
205 return static_cast<T>(val);
206 }
207 }
208
212 template<typename T>
213 [[nodiscard]] std::optional<T> parse_floating() const noexcept
214 {
215 if (type_ != value_types::float_value &&
216 type_ != value_types::double_value) {
217 return std::nullopt;
218 }
219
220 if (value_length_ == 0) {
221 return std::nullopt;
222 }
223
224 char* end = nullptr;
225 std::string temp(value_data_, value_length_);
226
227 if constexpr (std::is_same_v<T, float>) {
228 float val = std::strtof(temp.c_str(), &end);
229 if (end != temp.c_str() + temp.size()) {
230 return std::nullopt;
231 }
232 return val;
233 } else {
234 double val = std::strtod(temp.c_str(), &end);
235 if (end != temp.c_str() + temp.size()) {
236 return std::nullopt;
237 }
238 return static_cast<T>(val);
239 }
240 }
241
245 [[nodiscard]] static bool is_integral_type(value_types t) noexcept
246 {
247 switch (t) {
248 case value_types::short_value:
249 case value_types::ushort_value:
250 case value_types::int_value:
251 case value_types::uint_value:
252 case value_types::long_value:
253 case value_types::ulong_value:
254 case value_types::llong_value:
255 case value_types::ullong_value:
256 return true;
257 default:
258 return false;
259 }
260 }
261
262 const char* name_data_;
264 const char* value_data_;
266 value_types type_;
267};
268
276{
277 std::string_view name;
280 value_types type;
281
283 : value_offset(0)
284 , value_length(0)
285 , type(value_types::null_value)
286 {}
287
288 value_index_entry(std::string_view n, size_t offset, size_t length, value_types t) noexcept
289 : name(n)
290 , value_offset(offset)
291 , value_length(length)
292 , type(t)
293 {}
294};
295
296} // namespace kcenon::container
Zero-copy value view for efficient read access.
Definition value_view.h:56
std::optional< T > parse_integral() const noexcept
Parse integral value from string data.
Definition value_view.h:180
std::string_view name() const noexcept
Get the value name as string_view (zero-copy)
Definition value_view.h:79
bool is_null() const noexcept
Check if this is a null value.
Definition value_view.h:154
size_t size() const noexcept
Get value data length.
Definition value_view.h:170
value_view(const char *name_data, size_t name_length, const char *value_data, size_t value_length, value_types type) noexcept
Construct a value view.
Definition value_view.h:66
std::string_view as_string_view() const noexcept
Get string value as string_view (zero-copy)
Definition value_view.h:97
std::optional< T > parse_floating() const noexcept
Parse floating-point value from string data.
Definition value_view.h:213
std::string as_string() const
Get string value as owned copy.
Definition value_view.h:106
value_types type() const noexcept
Get the value type.
Definition value_view.h:87
std::optional< T > as() const noexcept
Type-safe value extraction.
Definition value_view.h:117
const char * data() const noexcept
Get raw value data pointer.
Definition value_view.h:162
static bool is_integral_type(value_types t) noexcept
Check if type is an integral type.
Definition value_view.h:245
Value index entry for lazy parsing.
Definition value_view.h:276
value_index_entry() noexcept
Definition value_view.h:282
value_types type
Value type.
Definition value_view.h:280
size_t value_length
Length of value data.
Definition value_view.h:279
std::string_view name
Key name (points into raw_data_ptr_)
Definition value_view.h:277
size_t value_offset
Offset to value data in buffer.
Definition value_view.h:278
value_index_entry(std::string_view n, size_t offset, size_t length, value_types t) noexcept
Definition value_view.h:288