mcc_epoch.h: fix operator=(std::chrono::time_point)
class MccKeyValueHolder: developing ...
This commit is contained in:
@@ -79,10 +79,10 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
template <typename ClockT, typename DurT>
|
template <typename ClockT, typename DurT>
|
||||||
MccCelestialCoordEpoch& operator=(std::chrono::time_point<ClockT, DurT>&& tp)
|
MccCelestialCoordEpoch& operator=(std::chrono::time_point<ClockT, DurT> const& tp)
|
||||||
{
|
{
|
||||||
// ignore possible errors!!!
|
// ignore possible errors!!!
|
||||||
auto ok = fromTimePoint(std::forward<decltype(tp)>(tp));
|
auto ok = fromTimePoint(tp);
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -139,17 +139,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename ClockT, typename DurT>
|
template <typename ClockT, typename DurT>
|
||||||
bool fromTimePoint(std::chrono::time_point<ClockT, DurT>&& tp)
|
bool fromTimePoint(std::chrono::time_point<ClockT, DurT> const& tp)
|
||||||
{
|
{
|
||||||
if constexpr (std::same_as<ClockT, std::chrono::system_clock>) {
|
if constexpr (std::same_as<ClockT, std::chrono::system_clock>) {
|
||||||
_UTC = std::chrono::time_point_cast<decltype(_UTC)::duration>(std::forward<decltype(tp)>(tp));
|
_UTC = std::chrono::time_point_cast<decltype(_UTC)::duration>(tp);
|
||||||
} else if constexpr (std::same_as<ClockT, std::chrono::utc_clock>) {
|
} else if constexpr (std::same_as<ClockT, std::chrono::utc_clock>) {
|
||||||
auto stp = std::chrono::utc_clock::to_sys(std::forward<decltype(tp)>(tp));
|
auto stp = std::chrono::utc_clock::to_sys(tp);
|
||||||
_UTC = std::chrono::time_point_cast<decltype(_UTC)::duration>(std::forward<decltype(tp)>(stp));
|
_UTC = std::chrono::time_point_cast<decltype(_UTC)::duration>(stp);
|
||||||
} else if constexpr (std::same_as<ClockT, std::chrono::tai_clock>) {
|
} else if constexpr (std::same_as<ClockT, std::chrono::tai_clock>) {
|
||||||
return fromTimePoint(ClockT::to_utc(std::forward<decltype(tp)>(tp)));
|
return fromTimePoint(ClockT::to_utc(tp));
|
||||||
} else if constexpr (std::same_as<ClockT, std::chrono::gps_clock>) {
|
} else if constexpr (std::same_as<ClockT, std::chrono::gps_clock>) {
|
||||||
return fromTimePoint(ClockT::to_utc(std::forward<decltype(tp)>(tp)));
|
return fromTimePoint(ClockT::to_utc(tp));
|
||||||
} else {
|
} else {
|
||||||
static_assert(false, "UNSUPPORTED CLOCK!!!");
|
static_assert(false, "UNSUPPORTED CLOCK!!!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include "mcc_constants.h"
|
|
||||||
#include "mcc_deserializer.h"
|
#include "mcc_deserializer.h"
|
||||||
#include "mcc_serializer.h"
|
#include "mcc_serializer.h"
|
||||||
#include "mcc_utils.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 <typename T>
|
template <typename T>
|
||||||
concept mcc_keyvalue_desc_c = requires(T t) { []<mcc_keyvalue_record_c... Ts>(std::tuple<Ts...>) {}(t); };
|
concept mcc_keyvalue_desc_c = requires(T t) { []<mcc_keyvalue_record_c... Ts>(std::tuple<Ts...>) {}(t); };
|
||||||
|
|
||||||
@@ -134,12 +135,23 @@ public:
|
|||||||
: ARR_DELIM[0] == '\0' ? constants::MCC_KV_VALUE_ARRAY_DELIM_SEQ_ARR
|
: ARR_DELIM[0] == '\0' ? constants::MCC_KV_VALUE_ARRAY_DELIM_SEQ_ARR
|
||||||
: ARR_DELIM};
|
: ARR_DELIM};
|
||||||
|
|
||||||
|
static constexpr size_t NUMBER_OF_RECORDS = std::tuple_size_v<DESCR_T>;
|
||||||
|
|
||||||
MccKeyValueHolder(DESCR_T desc) : _keyValue(desc)
|
MccKeyValueHolder(DESCR_T desc) : _keyValue(desc)
|
||||||
{
|
{
|
||||||
[this]<size_t... I>(std::index_sequence<I...>) {
|
[this]<size_t... I>(std::index_sequence<I...>) {
|
||||||
((_hashes[I] = utils::FNV1aHash(std::get<I>(_keyValue).key)), ...);
|
((_hashes[I] = utils::FNV1aHash(std::get<I>(_keyValue).key)), ...);
|
||||||
}(std::make_index_sequence<std::tuple_size_v<DESCR_T>>());
|
}(std::make_index_sequence<NUMBER_OF_RECORDS>());
|
||||||
|
|
||||||
|
_loadedKey.insert_range(_hashes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
constexpr 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...};
|
||||||
|
}(std::make_index_sequence<NUMBER_OF_RECORDS>{});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -181,43 +193,24 @@ 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)
|
||||||
{
|
{
|
||||||
using r_t = std::invoke_result_t<decltype(std::chrono::system_clock::now)>;
|
return forKey(key, [&value, key]<typename VT>(VT& val) -> std::error_code {
|
||||||
// static_assert(std::convertible_to<r_t, MccCelestialCoordEpoch>);
|
// std::println("FORKEY_FUN: {} = {}", key, value);
|
||||||
// static_assert(std::assignable_from<MccCelestialCoordEpoch, r_t>);
|
if constexpr (requires(VT v) { v = value; }) {
|
||||||
// static_assert(std::constructible_from<MccCelestialCoordEpoch, r_t>);
|
|
||||||
// static_assert(std::destructible<MccCelestialCoordEpoch>);
|
|
||||||
|
|
||||||
return forKey(key, [value, key]<typename VT>(VT& val) -> std::error_code {
|
|
||||||
if constexpr (requires(std::decay_t<VT> v) { v = value; }) {
|
|
||||||
val = value;
|
val = value;
|
||||||
|
} else if constexpr (std::convertible_to<T, VT>) {
|
||||||
|
val = value;
|
||||||
|
} else if constexpr (std::constructible_from<VT, T>) {
|
||||||
|
val = VT(value);
|
||||||
|
} else if constexpr (std::assignable_from<VT, T>) {
|
||||||
|
val = value;
|
||||||
|
} else {
|
||||||
|
return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE;
|
||||||
}
|
}
|
||||||
std::println("FORKEY_FUN: {} = {}", key, value);
|
|
||||||
// if constexpr (std::convertible_to<T, VT>) {
|
|
||||||
// val = value;
|
|
||||||
// } else if constexpr (std::constructible_from<VT, T>) {
|
|
||||||
// val = VT(value);
|
|
||||||
// } else if constexpr (std::assignable_from<VT, T>) {
|
|
||||||
// val = value;
|
|
||||||
// } else {
|
|
||||||
// return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE;
|
|
||||||
// }
|
|
||||||
|
|
||||||
return MccKeyValueHolderErrorCode::ERROR_OK;
|
return MccKeyValueHolderErrorCode::ERROR_OK;
|
||||||
// if constexpr (std::convertible_to<T, VT>) {
|
|
||||||
// val = value;
|
|
||||||
// } else if constexpr (std::constructible_from<VT, T>) {
|
|
||||||
// val = VT(value);
|
|
||||||
// } else if constexpr (std::assignable_from<VT, T>) {
|
|
||||||
// val = value;
|
|
||||||
// } else {
|
|
||||||
// return MccKeyValueHolderErrorCode::ERROR_INCOMPATIBLE_TYPE;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return MccKeyValueHolderErrorCode::ERROR_OK;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <traits::mcc_input_char_range R,
|
template <traits::mcc_input_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>
|
||||||
@@ -240,9 +233,13 @@ public:
|
|||||||
|
|
||||||
std::error_code ec{};
|
std::error_code ec{};
|
||||||
std::string_view rec, key, value, inline_comm;
|
std::string_view rec, key, value, inline_comm;
|
||||||
std::vector<std::string> head_comm;
|
std::vector<std::optional<std::string>> head_comm;
|
||||||
size_t key_hash;
|
size_t key_hash;
|
||||||
|
|
||||||
|
_headComment.clear();
|
||||||
|
_inlineComment.clear();
|
||||||
|
_loadedKey.clear();
|
||||||
|
|
||||||
auto recs = std::views::split(buffer, std::move(rec_delim));
|
auto recs = std::views::split(buffer, std::move(rec_delim));
|
||||||
|
|
||||||
for (auto const& el : recs) {
|
for (auto const& el : recs) {
|
||||||
@@ -255,8 +252,7 @@ public:
|
|||||||
inline_comm =
|
inline_comm =
|
||||||
std::string_view{found.begin() + COMMENT_SEQ.size(), rec.end()}; // mark inline comment
|
std::string_view{found.begin() + COMMENT_SEQ.size(), rec.end()}; // mark inline comment
|
||||||
} else { // head comment
|
} else { // head comment
|
||||||
head_comm.push_back({found.end(), rec.end()});
|
head_comm.push_back(std::string{found.end(), rec.end()});
|
||||||
std::println("COMM: <{}>", head_comm.back());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rec = std::string_view(rec.begin(), found.begin());
|
rec = std::string_view(rec.begin(), found.begin());
|
||||||
@@ -270,21 +266,14 @@ public:
|
|||||||
|
|
||||||
key_hash = utils::FNV1aHash(key);
|
key_hash = utils::FNV1aHash(key);
|
||||||
|
|
||||||
// ec = forKey(key, [value, &ser_params]<typename VT>(VT& v) {
|
ec = forHash(key_hash, [&key_hash, value, &ser_params, this]<typename VT>(VT& v) {
|
||||||
// auto err = MccDeserializer<VT>{}(value, v, ser_params);
|
|
||||||
// if (err) {
|
|
||||||
// return MccKeyValueHolderErrorCode::ERROR_DESERIAL;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return MccKeyValueHolderErrorCode::ERROR_OK;
|
|
||||||
// });
|
|
||||||
|
|
||||||
ec = forHash(key_hash, [value, &ser_params]<typename VT>(VT& v) {
|
|
||||||
auto err = MccDeserializer<VT>{}(value, v, ser_params);
|
auto err = MccDeserializer<VT>{}(value, v, ser_params);
|
||||||
if (err) {
|
if (err) {
|
||||||
return MccKeyValueHolderErrorCode::ERROR_DESERIAL;
|
return MccKeyValueHolderErrorCode::ERROR_DESERIAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_loadedKey.insert(key_hash);
|
||||||
|
|
||||||
return MccKeyValueHolderErrorCode::ERROR_OK;
|
return MccKeyValueHolderErrorCode::ERROR_OK;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -303,8 +292,8 @@ public:
|
|||||||
} // just comment string starting from the beginning, just skip it (no error)
|
} // just comment string starting from the beginning, just skip it (no error)
|
||||||
|
|
||||||
} else { // empty record, just skip it (no error)
|
} else { // empty record, just skip it (no error)
|
||||||
head_comm.push_back({el.begin(), el.end()});
|
// head_comm.push_back({el.begin(), el.end()});
|
||||||
std::println("EMPTY COMM: <{}>", head_comm.back());
|
head_comm.push_back(std::nullopt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,43 +309,53 @@ public:
|
|||||||
{
|
{
|
||||||
std::error_code ec{};
|
std::error_code ec{};
|
||||||
|
|
||||||
auto write_rec = [&output_buffer, &rec_delim, &ec, &ser_params, this]<size_t I>() {
|
auto write_rec = [&output_buffer, &rec_delim, &ec, &ser_params, this]<size_t I = 0>(this auto& self) {
|
||||||
auto key = std::get<I>(_keyValue).key;
|
if constexpr (I < NUMBER_OF_RECORDS) {
|
||||||
auto val = std::get<I>(_keyValue).value;
|
if (_loadedKey.count(_hashes[I])) {
|
||||||
using val_t = std::remove_cvref_t<decltype(val)>;
|
auto key = std::get<I>(_keyValue).key;
|
||||||
|
auto val = 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, val, ser_params);
|
||||||
if (err) {
|
if (err) {
|
||||||
ec = MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
ec = MccKeyValueHolderErrorCode::ERROR_SERIAL;
|
||||||
} else {
|
return;
|
||||||
size_t hash = _hashes[I];
|
} else {
|
||||||
// write head comment
|
size_t hash = _hashes[I];
|
||||||
if (_headComment[hash].size()) {
|
// write head comment
|
||||||
for (auto const& comm : _headComment[hash]) {
|
if (_headComment[hash].size()) {
|
||||||
// if (comm.size()) {
|
for (auto const& comm : _headComment[hash]) {
|
||||||
std::format_to(std::back_inserter(output_buffer), "{}{}", COMM_SEQ, comm);
|
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));
|
std::ranges::copy(rec_delim, std::back_inserter(output_buffer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// key and value
|
self.template operator()<I + 1>();
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
[&write_rec]<size_t... Is>(std::index_sequence<Is...>) {
|
write_rec();
|
||||||
(write_rec.template operator()<Is>(), ...);
|
|
||||||
}(std::make_index_sequence<std::tuple_size_v<DESCR_T>>());
|
// [&write_rec]<size_t... Is>(std::index_sequence<Is...>) {
|
||||||
|
// (write_rec.template operator()<Is>(), ...);
|
||||||
|
// }(std::make_index_sequence<NUMBER_OF_RECORDS>());
|
||||||
|
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
@@ -364,9 +363,11 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
DESCR_T _keyValue;
|
DESCR_T _keyValue;
|
||||||
|
|
||||||
std::array<size_t, std::tuple_size_v<DESCR_T>> _hashes; // key hashes
|
std::array<size_t, NUMBER_OF_RECORDS> _hashes{}; // key hashes
|
||||||
std::unordered_map<size_t, std::vector<std::string>> _headComment; // comment string/strings before key
|
std::unordered_map<size_t, std::vector<std::optional<std::string>>>
|
||||||
std::unordered_map<size_t, std::string> _inlineComment; // inline (after key=value pair) comment
|
_headComment{}; // comment string/strings before key
|
||||||
|
std::unordered_map<size_t, std::string> _inlineComment{}; // inline (after key=value pair) comment
|
||||||
|
std::unordered_set<size_t> _loadedKey{}; // loaded keys (see fromCharRange)
|
||||||
|
|
||||||
//
|
//
|
||||||
// NOTE: deduced this is needed here to use "forKey" method in getter and setter (const and non-const contexts)!!!
|
// 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 <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 < std::tuple_size_v<DESCR_T>) {
|
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).value);
|
std::get<I>(std::forward<decltype(self)>(self)._keyValue).value);
|
||||||
|
|||||||
@@ -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()
|
int main()
|
||||||
{
|
{
|
||||||
// MccKeyValueHolder<decltype(kv_desc)> kv(kv_desc);
|
|
||||||
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) {
|
if (err) {
|
||||||
std::println("ERR = {}", err);
|
std::println("ERR = {}", err);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -56,7 +66,13 @@ int main()
|
|||||||
return 1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user