From 9630751a4dac55f36006c01b23b174f30f23e14d Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Sun, 17 May 2026 22:33:31 +0300 Subject: [PATCH] mcc_epoch.h: fix operator=(std::chrono::time_point) class MccKeyValueHolder: developing ... --- include/mcc/mcc_epoch.h | 16 ++-- include/mcc/mcc_keyvalue.h | 161 ++++++++++++++++++------------------ tests/mcc_keyvalue_test.cpp | 22 ++++- 3 files changed, 108 insertions(+), 91 deletions(-) diff --git a/include/mcc/mcc_epoch.h b/include/mcc/mcc_epoch.h index 1493365..a71ebae 100644 --- a/include/mcc/mcc_epoch.h +++ b/include/mcc/mcc_epoch.h @@ -79,10 +79,10 @@ public: template - MccCelestialCoordEpoch& operator=(std::chrono::time_point&& tp) + MccCelestialCoordEpoch& operator=(std::chrono::time_point const& tp) { // ignore possible errors!!! - auto ok = fromTimePoint(std::forward(tp)); + auto ok = fromTimePoint(tp); return *this; } @@ -139,17 +139,17 @@ public: } template - bool fromTimePoint(std::chrono::time_point&& tp) + bool fromTimePoint(std::chrono::time_point const& tp) { if constexpr (std::same_as) { - _UTC = std::chrono::time_point_cast(std::forward(tp)); + _UTC = std::chrono::time_point_cast(tp); } else if constexpr (std::same_as) { - auto stp = std::chrono::utc_clock::to_sys(std::forward(tp)); - _UTC = std::chrono::time_point_cast(std::forward(stp)); + auto stp = std::chrono::utc_clock::to_sys(tp); + _UTC = std::chrono::time_point_cast(stp); } else if constexpr (std::same_as) { - return fromTimePoint(ClockT::to_utc(std::forward(tp))); + return fromTimePoint(ClockT::to_utc(tp)); } else if constexpr (std::same_as) { - return fromTimePoint(ClockT::to_utc(std::forward(tp))); + return fromTimePoint(ClockT::to_utc(tp)); } else { static_assert(false, "UNSUPPORTED CLOCK!!!"); } diff --git a/include/mcc/mcc_keyvalue.h b/include/mcc/mcc_keyvalue.h index 24088bc..fd53231 100644 --- a/include/mcc/mcc_keyvalue.h +++ b/include/mcc/mcc_keyvalue.h @@ -12,8 +12,8 @@ #include +#include -#include "mcc_constants.h" #include "mcc_deserializer.h" #include "mcc_serializer.h" #include "mcc_utils.h" @@ -100,6 +100,7 @@ concept mcc_keyvalue_record_c = requires(T t) { }; +// must be a std::tuple of mcc_keyvalue_record_c template concept mcc_keyvalue_desc_c = requires(T t) { [](std::tuple) {}(t); }; @@ -134,12 +135,23 @@ public: : 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) { [this](std::index_sequence) { ((_hashes[I] = utils::FNV1aHash(std::get(_keyValue).key)), ...); - }(std::make_index_sequence>()); + }(std::make_index_sequence()); + + _loadedKey.insert_range(_hashes); + } + + + constexpr std::array keys() const + { + return [this](std::index_sequence) { + return std::array{std::get(_keyValue).key...}; + }(std::make_index_sequence{}); } @@ -181,43 +193,24 @@ public: template std::error_code setValue(std::string_view key, const T& value) { - using r_t = std::invoke_result_t; - // static_assert(std::convertible_to); - // static_assert(std::assignable_from); - // static_assert(std::constructible_from); - // static_assert(std::destructible); - - return forKey(key, [value, key](VT& val) -> std::error_code { - if constexpr (requires(std::decay_t v) { v = value; }) { + return forKey(key, [&value, key](VT& val) -> std::error_code { + // std::println("FORKEY_FUN: {} = {}", key, value); + if constexpr (requires(VT v) { v = value; }) { val = value; + } else if constexpr (std::convertible_to) { + val = value; + } else if constexpr (std::constructible_from) { + val = VT(value); + } else if constexpr (std::assignable_from) { + val = value; + } else { + return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE; } - std::println("FORKEY_FUN: {} = {}", key, value); - // if constexpr (std::convertible_to) { - // val = value; - // } else if constexpr (std::constructible_from) { - // val = VT(value); - // } else if constexpr (std::assignable_from) { - // val = value; - // } else { - // return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE; - // } return MccKeyValueHolderErrorCode::ERROR_OK; - // if constexpr (std::convertible_to) { - // val = value; - // } else if constexpr (std::constructible_from) { - // val = VT(value); - // } else if constexpr (std::assignable_from) { - // val = value; - // } else { - // return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE; - // } - - // return MccKeyValueHolderErrorCode::ERROR_OK; }); } - template @@ -240,9 +233,13 @@ public: std::error_code ec{}; std::string_view rec, key, value, inline_comm; - std::vector head_comm; + std::vector> head_comm; size_t key_hash; + _headComment.clear(); + _inlineComment.clear(); + _loadedKey.clear(); + auto recs = std::views::split(buffer, std::move(rec_delim)); for (auto const& el : recs) { @@ -255,8 +252,7 @@ public: inline_comm = std::string_view{found.begin() + COMMENT_SEQ.size(), rec.end()}; // mark inline comment } else { // head comment - head_comm.push_back({found.end(), rec.end()}); - std::println("COMM: <{}>", head_comm.back()); + head_comm.push_back(std::string{found.end(), rec.end()}); } rec = std::string_view(rec.begin(), found.begin()); @@ -270,21 +266,14 @@ public: key_hash = utils::FNV1aHash(key); - // ec = forKey(key, [value, &ser_params](VT& v) { - // auto err = MccDeserializer{}(value, v, ser_params); - // if (err) { - // return MccKeyValueHolderErrorCode::ERROR_DESERIAL; - // } - - // return MccKeyValueHolderErrorCode::ERROR_OK; - // }); - - ec = forHash(key_hash, [value, &ser_params](VT& v) { + ec = forHash(key_hash, [&key_hash, value, &ser_params, this](VT& v) { auto err = MccDeserializer{}(value, v, ser_params); if (err) { return MccKeyValueHolderErrorCode::ERROR_DESERIAL; } + _loadedKey.insert(key_hash); + return MccKeyValueHolderErrorCode::ERROR_OK; }); @@ -303,8 +292,8 @@ public: } // just comment string starting from the beginning, just skip it (no error) } else { // empty record, just skip it (no error) - head_comm.push_back({el.begin(), el.end()}); - std::println("EMPTY COMM: <{}>", head_comm.back()); + // head_comm.push_back({el.begin(), el.end()}); + head_comm.push_back(std::nullopt); } } @@ -320,43 +309,53 @@ public: { std::error_code ec{}; - auto write_rec = [&output_buffer, &rec_delim, &ec, &ser_params, this]() { - auto key = std::get(_keyValue).key; - auto val = std::get(_keyValue).value; - using val_t = std::remove_cvref_t; + auto write_rec = [&output_buffer, &rec_delim, &ec, &ser_params, this](this auto& self) { + if constexpr (I < NUMBER_OF_RECORDS) { + if (_loadedKey.count(_hashes[I])) { + auto key = std::get(_keyValue).key; + auto val = std::get(_keyValue).value; + using val_t = std::remove_cvref_t; - std::string buff; - auto err = MccSerializer{}(buff, val, ser_params); - if (err) { - ec = MccKeyValueHolderErrorCode::ERROR_SERIAL; - } else { - size_t hash = _hashes[I]; - // write head comment - if (_headComment[hash].size()) { - for (auto const& comm : _headComment[hash]) { - // if (comm.size()) { - std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm); - // } + std::string buff; + auto err = MccSerializer{}(buff, val, ser_params); + 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)); } } - // key and value - std::format_to(std::back_inserter(output_buffer), "{}{}{}{}", rec_delim, 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()(); } }; - [&write_rec](std::index_sequence) { - (write_rec.template operator()(), ...); - }(std::make_index_sequence>()); + write_rec(); + + // [&write_rec](std::index_sequence) { + // (write_rec.template operator()(), ...); + // }(std::make_index_sequence()); return ec; } @@ -364,9 +363,11 @@ public: protected: DESCR_T _keyValue; - std::array> _hashes; // key hashes - std::unordered_map> _headComment; // comment string/strings before key - std::unordered_map _inlineComment; // inline (after key=value pair) comment + std::array _hashes{}; // key hashes + std::unordered_map>> + _headComment{}; // comment string/strings before key + std::unordered_map _inlineComment{}; // inline (after key=value pair) comment + std::unordered_set _loadedKey{}; // loaded keys (see fromCharRange) // // NOTE: deduced this is needed here to use "forKey" method in getter and setter (const and non-const contexts)!!! @@ -382,7 +383,7 @@ protected: template std::error_code forHash(this auto&& self, size_t hash, auto&& func) { - if constexpr (I < std::tuple_size_v) { + if constexpr (I < NUMBER_OF_RECORDS) { if (hash == std::forward(self)._hashes[I]) { return std::forward(func)( std::get(std::forward(self)._keyValue).value); diff --git a/tests/mcc_keyvalue_test.cpp b/tests/mcc_keyvalue_test.cpp index ac4f399..29f54f2 100644 --- a/tests/mcc_keyvalue_test.cpp +++ b/tests/mcc_keyvalue_test.cpp @@ -21,12 +21,22 @@ cc= 2026-05-15T05:53:20.921723918 # date UTC )--"; +static std::string STR1 = R"--( + +aaa = dewl_ewkj23+23998 + +# +# this is obs date +cc= 2026-05-15T05:53:20.921723918 # date UTC + +)--"; + int main() { - // MccKeyValueHolder kv(kv_desc); MccKeyValueHolder kv(kv_desc); - auto err = kv.fromCharRange(STR); + // auto err = kv.fromCharRange(STR); + auto err = kv.fromCharRange(STR1); if (err) { std::println("ERR = {}", err); return 1; @@ -56,7 +66,13 @@ int main() return 1; } - std::println("{}", buff); + std::println("--(\n{}\n)--'", buff); + + std::print("KEYS: "); + for (auto const& k : kv.keys()) { + std::print("{} ", k); + } + std::println(""); return 0; } \ No newline at end of file