Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions src/core/include/SpinWait.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef SPIN_WAIT_HPP
#define SPIN_WAIT_HPP

#include <atomic>
#include <cstdint>
#include <functional>
#include <thread>
Expand Down Expand Up @@ -67,12 +68,12 @@ class SpinWait {
void reset() noexcept { _count = 0; }

template<typename T>
requires std::is_nothrow_invocable_r_v<bool, T>
requires std::is_nothrow_invocable_r_v<bool, T>
bool
spinUntil(const T &condition) const { return spinUntil(condition, -1); }

template<typename T>
requires std::is_nothrow_invocable_r_v<bool, T>
requires std::is_nothrow_invocable_r_v<bool, T>
bool
spinUntil(const T &condition, std::int64_t millisecondsTimeout) const {
if (millisecondsTimeout < -1) {
Expand Down Expand Up @@ -111,8 +112,8 @@ class AtomicMutex {
SPIN_WAIT _spin_wait;

public:
AtomicMutex() = default;
AtomicMutex(const AtomicMutex &) = delete;
AtomicMutex() = default;
AtomicMutex(const AtomicMutex &) = delete;
AtomicMutex &operator=(const AtomicMutex &) = delete;

//
Expand Down
10 changes: 7 additions & 3 deletions src/core/include/Topic.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,13 @@ struct Topic {
return opencmw::URI<STRICT>::factory().path(_service).setQuery({ _params.begin(), _params.end() }).build();
}

std::string toZmqTopic() const {
std::string toZmqTopic(const bool delimitWithPound = true) const {
using namespace std::string_literals;
std::string zmqTopic = _service;
if (_params.empty()) {
zmqTopic += "#"s;
if (delimitWithPound) {
zmqTopic += "#"s;
}
return zmqTopic;
}
zmqTopic += "?"s;
Expand All @@ -123,7 +125,9 @@ struct Topic {
}
isFirst = false;
}
zmqTopic += "#"s;
if (delimitWithPound) {
zmqTopic += "#"s;
}
return zmqTopic;
}

Expand Down
36 changes: 0 additions & 36 deletions src/core/include/opencmw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,47 +779,11 @@ inline constexpr void diffView(std::ostream &os, const T &lhs, const T &rhs) {

template<typename T>
static std::errc parseNumber(std::string_view str, T &number) {
// wrapper for missing std::from_chars() support for floating point types in clang < 20
// Note that this implementation is intolerant to trailing non-number junk in the given string.
#ifdef __clang__
if constexpr (std::is_same_v<T, float>) {
char *endPtr = nullptr;
float value = std::strtof(str.data(), &endPtr);
if (endPtr == str.data() + str.size() && errno == 0) {
number = value;
return std::errc{};
}
return std::errc::invalid_argument;
} else if constexpr (std::is_same_v<T, double>) {
char *endPtr = nullptr;
double value = std::strtod(str.data(), &endPtr);
if (endPtr == str.data() + str.size() && errno == 0) {
number = value;
return std::errc{};
}
return std::errc::invalid_argument;
} else if constexpr (std::is_same_v<T, long double>) {
char *endPtr = nullptr;
long double value = std::strtold(str.data(), &endPtr);
if (endPtr == str.data() + str.size() && errno == 0) {
number = value;
return std::errc{};
}
return std::errc::invalid_argument;
} else {
const auto rc = std::from_chars(str.data(), str.data() + str.size(), number);
if (rc.ptr == str.data() + str.size() && rc.ec == std::errc{}) {
return std::errc{};
}
return rc.ec == std::errc{} ? std::errc::invalid_argument : rc.ec;
}
#else
const auto rc = std::from_chars(str.data(), str.data() + str.size(), number);
if (rc.ptr == str.data() + str.size() && rc.ec == std::errc{}) {
return std::errc{};
}
return rc.ec == std::errc{} ? std::errc::invalid_argument : rc.ec;
#endif
}

} // namespace opencmw
Expand Down
20 changes: 14 additions & 6 deletions src/serialiser/include/IoSerialiser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,18 @@ struct IoSerialiser {
}
};

template<std::size_t N, refl::const_string<N> string>
constexpr const char *sanitizeFieldName() {
if constexpr (N > 2 && string.data[0] == 'x' && string.data[1] == '_') {
return string.c_str() + 2;
}
return string.c_str();
}

template<ReflectableClass T>
OPENCMW_FORCEINLINE int32_t findMemberIndex(const std::string_view &fieldName) noexcept {
static constexpr ConstExprMap<std::string_view, int32_t, refl::reflect<T>().members.size> m{ refl::util::map_to_array<std::pair<std::string_view, int32_t>>(refl::reflect<T>().members, [](auto field, auto index) {
return std::pair<std::string_view, int32_t>(field.name.c_str(), index);
return std::pair<std::string_view, int32_t>(sanitizeFieldName<field.name.size, field.name>(), index);
}) };
return m.at(fieldName, -1);
}
Expand Down Expand Up @@ -200,15 +208,15 @@ constexpr void serialise(IoBuffer &buffer, ReflectableClass auto const &value, F
using UnwrappedMemberType = std::remove_reference_t<decltype(getAnnotatedMember(unwrapPointer(fieldValue)))>;
if constexpr (isReflectableClass<UnwrappedMemberType>()) { // nested data-structure
const auto subfields = getNumberOfNonNullSubfields(getAnnotatedMember(unwrapPointer(fieldValue)));
FieldDescription auto field = newFieldHeader<protocol, writeMetaInfo>(buffer, member.name.c_str(), parent.hierarchyDepth + 1, FWD(fieldValue), subfields);
FieldDescription auto field = newFieldHeader<protocol, writeMetaInfo>(buffer, sanitizeFieldName<member.name.size, member.name>(), parent.hierarchyDepth + 1, FWD(fieldValue), subfields);
const std::size_t posSizePositionStart = FieldHeaderWriter<protocol>::template put<writeMetaInfo>(buffer, field, START_MARKER_INST);
const std::size_t posStartDataStart = buffer.size();
serialise<protocol, writeMetaInfo>(buffer, getAnnotatedMember(unwrapPointer(fieldValue)), field); // do not inspect annotation itself
FieldHeaderWriter<protocol>::template put<writeMetaInfo>(buffer, field, END_MARKER_INST);
updateSize<protocol>(buffer, posSizePositionStart, posStartDataStart);
return;
} else { // field is a (possibly annotated) primitive type
FieldDescription auto field = newFieldHeader<protocol, writeMetaInfo>(buffer, member.name.c_str(), parent.hierarchyDepth + 1, fieldValue, 0);
FieldDescription auto field = newFieldHeader<protocol, writeMetaInfo>(buffer, sanitizeFieldName<member.name.size, member.name>(), parent.hierarchyDepth + 1, fieldValue, 0);
FieldHeaderWriter<protocol>::template put<writeMetaInfo>(buffer, field, fieldValue);
}
}
Expand All @@ -220,7 +228,7 @@ template<SerialiserProtocol protocol, const bool writeMetaInfo = true>
constexpr void serialise(IoBuffer &buffer, ReflectableClass auto const &value) {
putHeaderInfo<protocol>(buffer);
const auto subfields = detail::getNumberOfNonNullSubfields(value);
auto field = detail::newFieldHeader<protocol, writeMetaInfo>(buffer, refl::reflect(value).name.c_str(), 0, value, subfields);
auto field = detail::newFieldHeader<protocol, writeMetaInfo>(buffer, sanitizeFieldName<refl::reflect<std::remove_reference_t<decltype(value)>>().name.size, refl::reflect<std::remove_reference_t<decltype(value)>>().name>(), 0, value, subfields);
const std::size_t posSizePositionStart = FieldHeaderWriter<protocol>::template put<writeMetaInfo>(buffer, field, START_MARKER_INST);
const std::size_t posStartDataStart = buffer.size();
detail::serialise<protocol, writeMetaInfo>(buffer, value, field);
Expand Down Expand Up @@ -338,7 +346,7 @@ constexpr void deserialise(IoBuffer &buffer, ReflectableClass auto &value, Deser
field.intDataType = IoSerialiser<protocol, START_MARKER>::getDataTypeId();
} else {
constexpr int requestedType = IoSerialiser<protocol, MemberType>::getDataTypeId();
if (requestedType != field.intDataType) { // mismatching data-type
if (requestedType != field.intDataType && requestedType != IoSerialiser<protocol, OTHER>::getDataTypeId()) { // mismatching data-type
moveToFieldEndBufferPosition(buffer, field);
if constexpr (check == ProtocolCheck::IGNORE) {
return; // don't write -> skip to next
Expand Down Expand Up @@ -387,7 +395,7 @@ constexpr void deserialise(IoBuffer &buffer, ReflectableClass auto &value, Deser
if constexpr (isReflectableClass<MemberType>()) {
buffer.set_position(field.headerStart); // reset buffer position for the nested deserialiser to read again
field.hierarchyDepth++;
field.fieldName = member.name.c_str(); // N.B. needed since member.name is referring to compile-time const string
field.fieldName = sanitizeFieldName<member.name.size, member.name>(); // N.B. needed since member.name is referring to compile-time const string
deserialise<protocol, check>(buffer, unwrapPointerCreateIfAbsent(member(value)), info, field);
field.hierarchyDepth--;
field.subfields = previousSubFields - 1;
Expand Down
Loading
Loading