Skip to content
Merged
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 @@
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,13 +112,13 @@
SPIN_WAIT _spin_wait;

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

//
void lock() {
while (_lock.test_and_set(std::memory_order_acquire)) {

Check failure on line 121 in src/core/include/SpinWait.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use 'std::memory_order::seq_cst' (or remove this argument to use its default value) to ensure sequential consistency.

See more on https://sonarcloud.io/project/issues?id=fair-acc_opencmw-cpp&issues=AZ0FVrcxQsj-WQT-cXSg&open=AZ0FVrcxQsj-WQT-cXSg&pullRequest=348
if constexpr (requires { _spin_wait.spin_once(); }) {
_spin_wait.spin_once();
}
Expand All @@ -126,7 +127,7 @@
_spin_wait.reset();
}
}
void unlock() { _lock.clear(std::memory_order::release); }

Check failure on line 130 in src/core/include/SpinWait.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use 'std::memory_order::seq_cst' (or remove this argument to use its default value) to ensure sequential consistency.

See more on https://sonarcloud.io/project/issues?id=fair-acc_opencmw-cpp&issues=AZ0FVrcxQsj-WQT-cXSh&open=AZ0FVrcxQsj-WQT-cXSh&pullRequest=348
};

} // namespace opencmw
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 @@
}
};

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 @@
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 @@ -217,10 +225,10 @@
} // namespace detail

template<SerialiserProtocol protocol, const bool writeMetaInfo = true>
constexpr void serialise(IoBuffer &buffer, ReflectableClass auto const &value) {

Check warning on line 228 in src/serialiser/include/IoSerialiser.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "auto" with an explicit template parameter.

See more on https://sonarcloud.io/project/issues?id=fair-acc_opencmw-cpp&issues=AZx8aoWpa6TmzXSb9FF_&open=AZx8aoWpa6TmzXSb9FF_&pullRequest=348
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 @@
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

Check warning on line 349 in src/serialiser/include/IoSerialiser.hpp

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use the init-statement to declare "requestedType" inside the if statement.

See more on https://sonarcloud.io/project/issues?id=fair-acc_opencmw-cpp&issues=AZ0FVrcTQsj-WQT-cXSf&open=AZ0FVrcTQsj-WQT-cXSf&pullRequest=348
moveToFieldEndBufferPosition(buffer, field);
if constexpr (check == ProtocolCheck::IGNORE) {
return; // don't write -> skip to next
Expand Down Expand Up @@ -387,7 +395,7 @@
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