mcc_keyvalue.h: add serial_pars field to mcc_keyvalue_record_c concept,
rewrite MccKeyValueHolder class methods accordinally
This commit is contained in:
@@ -96,8 +96,8 @@ concept mcc_variant_valid_type_c = requires { !std::is_array_v<T> && !std::is_vo
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
concept mcc_keyvalue_record_c = requires(T t) {
|
concept mcc_keyvalue_record_c = requires(T t) {
|
||||||
requires std::same_as<decltype(t.key), const std::string_view>; // key name is immutable!!!
|
requires std::same_as<decltype(t.key), const std::string_view>; // key name is immutable!!!
|
||||||
requires mcc_variant_valid_type_c<decltype(t.value)>;
|
requires mcc_variant_valid_type_c<decltype(t.value)>; // value is mutable
|
||||||
// requires mcc_serialization_params_c<decltype(t.serial_pars)>;
|
requires mcc_serialization_params_c<decltype(t.serial_pars)>; // serialization parameters
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -172,11 +172,12 @@ public:
|
|||||||
std::expected<T, std::error_code> getValue(std::string_view key) const
|
std::expected<T, std::error_code> getValue(std::string_view key) const
|
||||||
{
|
{
|
||||||
T v;
|
T v;
|
||||||
auto err = forKey(key, [&v]<typename VT>(const VT& val) -> std::error_code {
|
auto err = forKey(key, [&v](auto const& rec) -> std::error_code {
|
||||||
|
using VT = decltype(rec.value);
|
||||||
if constexpr (std::convertible_to<VT, T>) {
|
if constexpr (std::convertible_to<VT, T>) {
|
||||||
v = val;
|
v = rec.value;
|
||||||
} else if constexpr (std::constructible_from<T, VT>) {
|
} else if constexpr (std::constructible_from<T, VT>) {
|
||||||
v = T(val);
|
v = T(rec.value);
|
||||||
} else {
|
} else {
|
||||||
return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE;
|
return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE;
|
||||||
}
|
}
|
||||||
@@ -200,16 +201,16 @@ public:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
std::error_code setValue(std::string_view key, const T& value)
|
std::error_code setValue(std::string_view key, const T& value)
|
||||||
{
|
{
|
||||||
return forKey(key, [&value, key]<typename VT>(VT& val) -> std::error_code {
|
return forKey(key, [&value](auto& rec) -> std::error_code {
|
||||||
// std::println("FORKEY_FUN: {} = {}", key, value);
|
using VT = decltype(rec.value);
|
||||||
if constexpr (requires(VT v) { v = value; }) {
|
if constexpr (requires(VT v) { v = value; }) {
|
||||||
val = value;
|
rec.value = value;
|
||||||
} else if constexpr (std::convertible_to<T, VT>) {
|
} else if constexpr (std::convertible_to<T, VT>) {
|
||||||
val = value;
|
rec.value = value;
|
||||||
} else if constexpr (std::constructible_from<VT, T>) {
|
} else if constexpr (std::constructible_from<VT, T>) {
|
||||||
val = VT(value);
|
rec.value = VT(value);
|
||||||
} else if constexpr (std::assignable_from<VT, T>) {
|
} else if constexpr (std::assignable_from<VT, T>) {
|
||||||
val = value;
|
rec.value = value;
|
||||||
} else {
|
} else {
|
||||||
return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE;
|
return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE;
|
||||||
}
|
}
|
||||||
@@ -222,8 +223,8 @@ public:
|
|||||||
traits::mcc_input_char_range RecDelimT = std::string_view,
|
traits::mcc_input_char_range RecDelimT = std::string_view,
|
||||||
mcc_serialization_params_c SerParamsT = mcc_serialization_params_t>
|
mcc_serialization_params_c SerParamsT = mcc_serialization_params_t>
|
||||||
std::error_code fromCharRange(const R& buffer,
|
std::error_code fromCharRange(const R& buffer,
|
||||||
RecDelimT rec_delim = std::string_view("\n"), // records delimiter
|
RecDelimT rec_delim = std::string_view("\n") // records delimiter
|
||||||
SerParamsT const& ser_params = mcc_serialization_params_t{})
|
)
|
||||||
requires std::ranges::contiguous_range<R>
|
requires std::ranges::contiguous_range<R>
|
||||||
{
|
{
|
||||||
if constexpr (std::is_array_v<std::decay_t<R>>) { // char*, const char*
|
if constexpr (std::is_array_v<std::decay_t<R>>) { // char*, const char*
|
||||||
@@ -239,7 +240,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::error_code ec{};
|
std::error_code ec{};
|
||||||
std::string_view rec, key, value, inline_comm;
|
std::string_view rec, key, svalue, inline_comm;
|
||||||
std::vector<std::optional<std::string>> head_comm;
|
std::vector<std::optional<std::string>> head_comm;
|
||||||
size_t key_hash;
|
size_t key_hash;
|
||||||
|
|
||||||
@@ -269,12 +270,13 @@ public:
|
|||||||
found = std::ranges::search(rec, KEY_VALUE_DELIM);
|
found = std::ranges::search(rec, KEY_VALUE_DELIM);
|
||||||
if (found.begin() != rec.begin()) {
|
if (found.begin() != rec.begin()) {
|
||||||
key = trimSpaces(std::string_view(rec.begin(), found.begin()), utils::TrimType::TRIM_RIGHT);
|
key = trimSpaces(std::string_view(rec.begin(), found.begin()), utils::TrimType::TRIM_RIGHT);
|
||||||
value = std::string_view(found.end(), rec.end());
|
svalue = std::string_view(found.end(), rec.end());
|
||||||
|
|
||||||
key_hash = utils::FNV1aHash(key);
|
key_hash = utils::FNV1aHash(key);
|
||||||
|
|
||||||
ec = forHash(key_hash, [&key_hash, value, &ser_params, this]<typename VT>(VT& v) {
|
ec = forHash(key_hash, [&key_hash, svalue, this]<typename REC_T>(REC_T& v) {
|
||||||
auto err = MccDeserializer<VT>{}(value, v, ser_params);
|
using VT = decltype(v.value);
|
||||||
|
auto err = MccDeserializer<VT>{}(svalue, v.value, v.serial_pars);
|
||||||
if (err) {
|
if (err) {
|
||||||
return MccKeyValueHolderErrorCode::ERROR_DESERIAL;
|
return MccKeyValueHolderErrorCode::ERROR_DESERIAL;
|
||||||
}
|
}
|
||||||
@@ -311,13 +313,11 @@ public:
|
|||||||
traits::mcc_output_char_range R,
|
traits::mcc_output_char_range R,
|
||||||
traits::mcc_input_char_range RecDelimT = std::string_view,
|
traits::mcc_input_char_range RecDelimT = std::string_view,
|
||||||
mcc_serialization_params_c SerParamsT = mcc_serialization_params_t>
|
mcc_serialization_params_c SerParamsT = mcc_serialization_params_t>
|
||||||
std::error_code toCharRange(R& output_buffer,
|
std::error_code toCharRange(R& output_buffer, RecDelimT rec_delim = std::string_view{"\n"})
|
||||||
RecDelimT rec_delim = std::string_view{"\n"},
|
|
||||||
SerParamsT const& ser_params = mcc_serialization_params_t{})
|
|
||||||
{
|
{
|
||||||
std::error_code ec{};
|
std::error_code ec{};
|
||||||
|
|
||||||
auto write_rec = [&output_buffer, &rec_delim, &ec, &ser_params, this]<size_t I = 0>(this auto& self) {
|
auto write_rec = [&output_buffer, &rec_delim, &ec, this]<size_t I = 0>(this auto& self) {
|
||||||
if constexpr (I < NUMBER_OF_RECORDS) {
|
if constexpr (I < NUMBER_OF_RECORDS) {
|
||||||
if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_CHANGED_ONLY) {
|
if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_CHANGED_ONLY) {
|
||||||
if (_changedKey.count(_hashes[I]) == 0) {
|
if (_changedKey.count(_hashes[I]) == 0) {
|
||||||
@@ -325,13 +325,13 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if (_changedKey.count(_hashes[I])) {
|
|
||||||
auto key = std::get<I>(_keyValue).key;
|
auto key = std::get<I>(_keyValue).key;
|
||||||
auto val = std::get<I>(_keyValue).value;
|
using val_t = std::remove_cvref_t<decltype(std::get<I>(_keyValue).value)>;
|
||||||
using val_t = std::remove_cvref_t<decltype(val)>;
|
|
||||||
|
|
||||||
std::string buff;
|
std::string buff;
|
||||||
auto err = MccSerializer<val_t>{}(buff, val, ser_params);
|
auto err =
|
||||||
|
MccSerializer<val_t>{}(buff, std::get<I>(_keyValue).value, std::get<I>(_keyValue).serial_pars);
|
||||||
if (err) {
|
if (err) {
|
||||||
ec = MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
ec = MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
||||||
return;
|
return;
|
||||||
@@ -358,7 +358,6 @@ public:
|
|||||||
// record delimiter
|
// record delimiter
|
||||||
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
self.template operator()<I + 1>();
|
self.template operator()<I + 1>();
|
||||||
}
|
}
|
||||||
@@ -393,13 +392,19 @@ protected:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// 'func' signature:
|
||||||
|
// std::error func(mcc_keyvalue_record_c&&)
|
||||||
|
// e.g.:
|
||||||
|
// [](auto const& rec)->std::error_code {}
|
||||||
|
// [](auto& rec)->std::error_code {}
|
||||||
|
//
|
||||||
template <size_t I = 0>
|
template <size_t I = 0>
|
||||||
std::error_code forHash(this auto&& self, size_t hash, auto&& func)
|
std::error_code forHash(this auto&& self, size_t hash, auto&& func)
|
||||||
{
|
{
|
||||||
if constexpr (I < NUMBER_OF_RECORDS) {
|
if constexpr (I < NUMBER_OF_RECORDS) {
|
||||||
if (hash == std::forward<decltype(self)>(self)._hashes[I]) {
|
if (hash == std::forward<decltype(self)>(self)._hashes[I]) {
|
||||||
return std::forward<decltype(func)>(func)(
|
return std::forward<decltype(func)>(func)(std::get<I>(std::forward<decltype(self)>(self)._keyValue));
|
||||||
std::get<I>(std::forward<decltype(self)>(self)._keyValue).value);
|
|
||||||
} else {
|
} else {
|
||||||
return std::forward<decltype(self)>(self).template forHash<I + 1>(hash,
|
return std::forward<decltype(self)>(self).template forHash<I + 1>(hash,
|
||||||
std::forward<decltype(func)>(func));
|
std::forward<decltype(func)>(func));
|
||||||
@@ -409,61 +414,62 @@ protected:
|
|||||||
return MccKeyValueHolderErrorCode::ERROR_INVALID_KEY;
|
return MccKeyValueHolderErrorCode::ERROR_INVALID_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t I = 0,
|
// template <size_t I = 0,
|
||||||
OutputPolicy OPOLICY = MccKeyValueHolder::OPOLICY_CHANGED_ONLY,
|
// OutputPolicy OPOLICY = MccKeyValueHolder::OPOLICY_CHANGED_ONLY,
|
||||||
traits::mcc_output_char_range R,
|
// traits::mcc_output_char_range R,
|
||||||
traits::mcc_input_char_range RecDelimT,
|
// traits::mcc_input_char_range RecDelimT,
|
||||||
mcc_serialization_params_c SerParamsT>
|
// mcc_serialization_params_c SerParamsT>
|
||||||
std::error_code writeRecord(R& output_buffer, RecDelimT rec_delim, SerParamsT const& ser_params)
|
// std::error_code writeRecord(R& output_buffer, RecDelimT rec_delim, SerParamsT const& ser_params)
|
||||||
{
|
// {
|
||||||
if constexpr (I < NUMBER_OF_RECORDS) {
|
// if constexpr (I < NUMBER_OF_RECORDS) {
|
||||||
if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_CHANGED_ONLY) {
|
// if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_CHANGED_ONLY) {
|
||||||
if (_changedKey.count(_hashes[I]) == 0) {
|
// if (_changedKey.count(_hashes[I]) == 0) {
|
||||||
return MccKeyValueHolderErrorCode::ERROR_OK;
|
// return MccKeyValueHolderErrorCode::ERROR_OK;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
auto key = std::get<I>(_keyValue).key;
|
// auto key = std::get<I>(_keyValue).key;
|
||||||
auto val = std::get<I>(_keyValue).value;
|
// auto val = std::get<I>(_keyValue).value;
|
||||||
using val_t = std::remove_cvref_t<decltype(val)>;
|
// using val_t = std::remove_cvref_t<decltype(val)>;
|
||||||
|
|
||||||
std::string buff;
|
// std::string buff;
|
||||||
auto err = MccSerializer<val_t>{}(buff, val, ser_params);
|
// auto err = MccSerializer<val_t>{}(buff, val, ser_params);
|
||||||
if (err) {
|
// if (err) {
|
||||||
return MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
// return MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
||||||
} else {
|
// } else {
|
||||||
size_t hash = _hashes[I];
|
// size_t hash = _hashes[I];
|
||||||
// write head comment
|
// // write head comment
|
||||||
if (_headComment[hash].size()) {
|
// if (_headComment[hash].size()) {
|
||||||
for (auto const& comm : _headComment[hash]) {
|
// for (auto const& comm : _headComment[hash]) {
|
||||||
if (comm.has_value()) {
|
// if (comm.has_value()) {
|
||||||
std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
|
// std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
|
||||||
}
|
// }
|
||||||
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
// std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// key and value
|
// // key and value
|
||||||
std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
|
// std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
|
||||||
|
|
||||||
// inline comment
|
// // inline comment
|
||||||
if (_inlineComment[hash].size()) {
|
// if (_inlineComment[hash].size()) {
|
||||||
std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ, _inlineComment[hash]);
|
// std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ, _inlineComment[hash]);
|
||||||
}
|
// }
|
||||||
|
|
||||||
// record delimiter
|
// // record delimiter
|
||||||
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
// std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
return MccKeyValueHolderErrorCode::ERROR_OK;
|
// return MccKeyValueHolderErrorCode::ERROR_OK;
|
||||||
}
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <mcc_variant_valid_type_c T>
|
template <mcc_variant_valid_type_c T>
|
||||||
struct mcc_simple_kv_record_t {
|
struct mcc_simple_kv_record_t {
|
||||||
const std::string_view key;
|
const std::string_view key;
|
||||||
T value;
|
T value;
|
||||||
|
mcc_serialization_params_t serial_pars;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mcc::impl
|
} // namespace mcc::impl
|
||||||
@@ -4,9 +4,13 @@
|
|||||||
|
|
||||||
using namespace mcc::impl;
|
using namespace mcc::impl;
|
||||||
|
|
||||||
static auto kv_desc = std::make_tuple(mcc_simple_kv_record_t{"bb", MccAngle{11.5_degs}},
|
static auto kv_desc = std::make_tuple(
|
||||||
mcc_simple_kv_record_t{"aaa", std::string("AAA")},
|
mcc_simple_kv_record_t{"bb", MccAngle{11.5_degs}, mcc_serialization_params_t{}},
|
||||||
mcc_simple_kv_record_t{"cc", MccCelestialCoordEpoch{}});
|
mcc_simple_kv_record_t{"aaa", std::string("AAA"), mcc_serialization_params_t{}},
|
||||||
|
mcc_simple_kv_record_t{"cc", MccCelestialCoordEpoch{}, mcc_serialization_params_t{}},
|
||||||
|
mcc_simple_kv_record_t{
|
||||||
|
"ddd", MccAngle{11.5_degs},
|
||||||
|
mcc_serialization_params_t{.angle_format = mcc::MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS}});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +32,7 @@ aaa = dewl_ewkj23+23998
|
|||||||
# this is obs date
|
# this is obs date
|
||||||
cc= 2026-05-15T05:53:20.921723918 # date UTC
|
cc= 2026-05-15T05:53:20.921723918 # date UTC
|
||||||
|
|
||||||
|
ddd = 01:02:33.434 # HA in hours:mins:secs
|
||||||
)--";
|
)--";
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
@@ -49,12 +54,19 @@ int main()
|
|||||||
std::println("ERR = {}", err);
|
std::println("ERR = {}", err);
|
||||||
// return 1;
|
// return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = kv.setValue("aaa", "OK");
|
err = kv.setValue("aaa", "OK");
|
||||||
if (err) {
|
if (err) {
|
||||||
std::println("ERR = {}", err);
|
std::println("ERR = {}", err);
|
||||||
// return 1;
|
// return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = kv.setValue("ddd", 37.5_degs);
|
||||||
|
if (err) {
|
||||||
|
std::println("ERR = {}", err);
|
||||||
|
// return 1;
|
||||||
|
}
|
||||||
|
|
||||||
std::println("------------------------------------");
|
std::println("------------------------------------");
|
||||||
|
|
||||||
std::string buff;
|
std::string buff;
|
||||||
|
|||||||
Reference in New Issue
Block a user