mcc_keyvalue.h: worked

This commit is contained in:
2026-05-19 12:16:22 +03:00
parent d40ecb5df7
commit 8d36444c51
2 changed files with 90 additions and 88 deletions

View File

@@ -97,7 +97,7 @@ template <typename 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 mcc_variant_valid_type_c<decltype(t.value)>; // value is mutable
requires mcc_variant_valid_type_c<decltype(t.default_value)>; // value is mutable
requires mcc_variant_valid_type_c<decltype(t.default_value)>; // default value is mutable
requires mcc_serialization_params_c<decltype(t.serial_pars)>; // serialization parameters
};
@@ -112,15 +112,15 @@ namespace constants
static constexpr char MCC_KV_COMMENT_SEQ_ARR[] = "#";
static constexpr char MCC_KV_KEY_VALUE_DELIM_SEQ_ARR[] = "=";
static constexpr char MCC_KV_VALUE_ARRAY_DELIM_SEQ_ARR[] = ",";
static constexpr char MCC_KV_COMPOSITE_VALUE_DELIM_SEQ_ARR[] = ",";
} // namespace constants
template <mcc_keyvalue_desc_c DESCR_T,
const char* COMM_SEQ = constants::MCC_KV_COMMENT_SEQ_ARR,
const char* KV_DELIM = constants::MCC_KV_KEY_VALUE_DELIM_SEQ_ARR,
const char* ARR_DELIM = constants::MCC_KV_VALUE_ARRAY_DELIM_SEQ_ARR>
const char* COMM_SEQ = constants::MCC_KV_COMMENT_SEQ_ARR, // comment char sequence
const char* KV_DELIM = constants::MCC_KV_KEY_VALUE_DELIM_SEQ_ARR // key-value delimiter
>
class MccKeyValueHolder
{
public:
@@ -138,11 +138,6 @@ public:
: KV_DELIM[0] == '\0' ? constants::MCC_KV_KEY_VALUE_DELIM_SEQ_ARR
: KV_DELIM};
static constexpr std::string_view VALUE_ARRAY_DELIM{
ARR_DELIM == nullptr ? constants::MCC_KV_VALUE_ARRAY_DELIM_SEQ_ARR
: ARR_DELIM[0] == '\0' ? constants::MCC_KV_VALUE_ARRAY_DELIM_SEQ_ARR
: ARR_DELIM};
static constexpr size_t NUMBER_OF_RECORDS = std::tuple_size_v<DESCR_T>;
MccKeyValueHolder(DESCR_T desc) : _keyValue(desc)
@@ -155,7 +150,7 @@ public:
}
constexpr std::array<std::string_view, NUMBER_OF_RECORDS> keys() const
std::array<std::string_view, NUMBER_OF_RECORDS> keys() const
{
return [this]<size_t... Is>(std::index_sequence<Is...>) {
return std::array<std::string_view, NUMBER_OF_RECORDS>{std::get<Is>(_keyValue).key...};
@@ -322,61 +317,63 @@ public:
template <OutputPolicy OPOLICY = MccKeyValueHolder::OPOLICY_CHANGED_ONLY,
traits::mcc_output_char_range R,
traits::mcc_input_char_range RecDelimT = std::string_view,
mcc_serialization_params_c SerParamsT = mcc_serialization_params_t>
traits::mcc_input_char_range RecDelimT = std::string_view>
std::error_code toCharRange(R& output_buffer, RecDelimT rec_delim = std::string_view{"\n"})
{
if (std::is_pointer_v<std::decay_t<RecDelimT>>) { // char*, const char*, char[], conat char[]
return toCharRange(output_buffer, std::string_view{rec_delim});
}
std::error_code ec{};
auto write_rec = [&output_buffer, &rec_delim, &ec, this]<size_t I = 0>(this auto& self) {
if constexpr (I < NUMBER_OF_RECORDS) {
using val_t = std::remove_cvref_t<decltype(std::get<I>(_keyValue).value)>;
const val_t* value_cptr = &std::get<I>(_keyValue).value;
if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_CHANGED_ONLY) {
if (_changedKey.count(_hashes[I]) == 0) {
self.template operator()<I + 1>();
return;
}
} else if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_FULL) {
if (_changedKey.count(_hashes[I]) == 0) {
value_cptr = &std::get<I>(_keyValue).default_value;
}
} else {
static_assert(false, "UNKNOWN OUTPUT POLICY VALUE!");
}
auto key = std::get<I>(_keyValue).key;
std::string buff;
auto err =
MccSerializer<val_t>{}(buff, std::get<I>(_keyValue).value, std::get<I>(_keyValue).serial_pars);
if (err) {
ec = MccKeyValueHolderErrorCode::ERROR_SERIAL;
ec = formatRecord<I>(output_buffer, rec_delim);
if (ec) {
return;
} else {
size_t hash = _hashes[I];
// write head comment
if (_headComment[hash].size()) {
for (auto const& comm : _headComment[hash]) {
if (comm.has_value()) {
std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
}
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
}
}
// key and value
std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
// using val_t = std::remove_cvref_t<decltype(std::get<I>(_keyValue).value)>;
// inline comment
if (_inlineComment[hash].size()) {
std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ, _inlineComment[hash]);
}
// auto key = std::get<I>(_keyValue).key;
// record delimiter
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
}
// std::string buff;
// auto err =
// MccSerializer<val_t>{}(buff, std::get<I>(_keyValue).value, std::get<I>(_keyValue).serial_pars);
// if (err) {
// ec = MccKeyValueHolderErrorCode::ERROR_SERIAL;
// return;
// } else {
// size_t hash = _hashes[I];
// // write head comment
// if (_headComment[hash].size()) {
// for (auto const& comm : _headComment[hash]) {
// if (comm.has_value()) {
// std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
// }
// std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
// }
// }
// // key and value
// std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
// // inline comment
// if (_inlineComment[hash].size()) {
// std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ,
// _inlineComment[hash]);
// }
// // record delimiter
// std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
// }
self.template operator()<I + 1>();
}
@@ -433,47 +430,51 @@ protected:
return MccKeyValueHolderErrorCode::ERROR_INVALID_KEY;
}
// template <size_t I = 0,
// traits::mcc_output_char_range R,
// traits::mcc_input_char_range RecDelimT,
// mcc_serialization_params_c SerParamsT>
// std::error_code writeRecord(DESCR_T const& holder, R& output_buffer, RecDelimT rec_delim)
// {
// if constexpr (I < NUMBER_OF_RECORDS) {
// auto key = std::get<I>(holder).key;
// using val_t = std::remove_cvref_t<decltype(std::get<I>(holder).value)>;
template <size_t I = 0, traits::mcc_output_char_range R, traits::mcc_input_char_range RecDelimT>
std::error_code formatRecord(R& output_buffer, RecDelimT rec_delim, bool is_default = false)
{
if constexpr (I < NUMBER_OF_RECORDS) {
auto key = std::get<I>(_keyValue).key;
using val_t = std::remove_cvref_t<decltype(std::get<I>(_keyValue).value)>;
// std::string buff;
// auto err = MccSerializer<val_t>{}(buff, std::get<I>(holder).value, std::get<I>(holder).serial_pars);
// if (err) {
// return MccKeyValueHolderErrorCode::ERROR_SERIAL;
// } else {
// size_t hash = _hashes[I];
// // write head comment
// if (_headComment[hash].size()) {
// for (auto const& comm : _headComment[hash]) {
// if (comm.has_value()) {
// std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
// }
// std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
// }
// }
val_t& val_ptr = std::get<I>(_keyValue).value;
if (is_default) {
val_ptr = std::get<I>(_keyValue).default_value;
}
// // key and value
// std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
std::string buff;
// auto err = MccSerializer<val_t>{}(buff, std::get<I>(_keyValue).value,
// std::get<I>(_keyValue).serial_pars);
auto err = MccSerializer<val_t>{}(buff, val_ptr, std::get<I>(_keyValue).serial_pars);
if (err) {
return MccKeyValueHolderErrorCode::ERROR_SERIAL;
} else {
size_t hash = _hashes[I];
// write head comment
if (_headComment[hash].size()) {
for (auto const& comm : _headComment[hash]) {
if (comm.has_value()) {
std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm.value());
}
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
}
}
// // inline comment
// if (_inlineComment[hash].size()) {
// std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ, _inlineComment[hash]);
// }
// key and value
std::format_to(std::back_inserter(output_buffer), "{}{}{}", key, KEY_VALUE_DELIM, buff);
// // record delimiter
// std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
// }
// }
// inline comment
if (_inlineComment[hash].size()) {
std::format_to(std::back_inserter(output_buffer), " {}{}", COMMENT_SEQ, _inlineComment[hash]);
}
// return MccKeyValueHolderErrorCode::ERROR_OK;
// }
// record delimiter
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
}
}
return MccKeyValueHolderErrorCode::ERROR_OK;
}
};
template <mcc_variant_valid_type_c T>

View File

@@ -11,7 +11,8 @@ static auto kv_desc = std::make_tuple(
mcc_simple_kv_record_t{
"ddd", MccAngle{11.5_degs}, MccAngle{11.5_degs},
mcc_serialization_params_t{.angle_format = mcc::MccSerializedAngleFormat::MCC_SERIALIZED_FORMAT_SXGM_HOURS}},
mcc_make_simple_kv_record("eee", 1.5));
mcc_make_simple_kv_record("eee", 1.5),
mcc_make_simple_kv_record("arr", std::vector<int>{1, 2, 3, 4, 5, 6, 7}));