diff --git a/include/mcc/mcc_keyvalue.h b/include/mcc/mcc_keyvalue.h index 6ed7c21..77ce774 100644 --- a/include/mcc/mcc_keyvalue.h +++ b/include/mcc/mcc_keyvalue.h @@ -97,7 +97,7 @@ template concept mcc_keyvalue_record_c = requires(T t) { requires std::same_as; // key name is immutable!!! requires mcc_variant_valid_type_c; // value is mutable - requires mcc_variant_valid_type_c; // value is mutable + requires mcc_variant_valid_type_c; // default value is mutable requires mcc_serialization_params_c; // 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 + 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; MccKeyValueHolder(DESCR_T desc) : _keyValue(desc) @@ -155,7 +150,7 @@ public: } - constexpr std::array keys() const + std::array keys() const { return [this](std::index_sequence) { return std::array{std::get(_keyValue).key...}; @@ -322,62 +317,64 @@ public: template + 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>) { // 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](this auto& self) { if constexpr (I < NUMBER_OF_RECORDS) { - using val_t = std::remove_cvref_t(_keyValue).value)>; - const val_t* value_cptr = &std::get(_keyValue).value; - if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_CHANGED_ONLY) { if (_changedKey.count(_hashes[I]) == 0) { self.template operator()(); return; } - } else if constexpr (OPOLICY == MccKeyValueHolder::OPOLICY_FULL) { - if (_changedKey.count(_hashes[I]) == 0) { - value_cptr = &std::get(_keyValue).default_value; - } - } else { - static_assert(false, "UNKNOWN OUTPUT POLICY VALUE!"); } - auto key = std::get(_keyValue).key; - - std::string buff; - auto err = - MccSerializer{}(buff, std::get(_keyValue).value, std::get(_keyValue).serial_pars); - if (err) { - ec = MccKeyValueHolderErrorCode::ERROR_SERIAL; + ec = formatRecord(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); - - // 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)); } + // using val_t = std::remove_cvref_t(_keyValue).value)>; + + // auto key = std::get(_keyValue).key; + + // std::string buff; + // auto err = + // MccSerializer{}(buff, std::get(_keyValue).value, std::get(_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()(); } }; @@ -433,47 +430,51 @@ protected: return MccKeyValueHolderErrorCode::ERROR_INVALID_KEY; } - // template - // std::error_code writeRecord(DESCR_T const& holder, R& output_buffer, RecDelimT rec_delim) - // { - // if constexpr (I < NUMBER_OF_RECORDS) { - // auto key = std::get(holder).key; - // using val_t = std::remove_cvref_t(holder).value)>; + template + std::error_code formatRecord(R& output_buffer, RecDelimT rec_delim, bool is_default = false) + { + if constexpr (I < NUMBER_OF_RECORDS) { + auto key = std::get(_keyValue).key; + using val_t = std::remove_cvref_t(_keyValue).value)>; - // std::string buff; - // auto err = MccSerializer{}(buff, std::get(holder).value, std::get(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(_keyValue).value; + if (is_default) { + val_ptr = std::get(_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{}(buff, std::get(_keyValue).value, + // std::get(_keyValue).serial_pars); + auto err = MccSerializer{}(buff, val_ptr, std::get(_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 diff --git a/tests/mcc_keyvalue_test.cpp b/tests/mcc_keyvalue_test.cpp index ce8eb35..063dc1c 100644 --- a/tests/mcc_keyvalue_test.cpp +++ b/tests/mcc_keyvalue_test.cpp @@ -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{1, 2, 3, 4, 5, 6, 7}));