fix: use PIP_HAS_RTTI in state machine formatHash and make no-RTTI builds work

- pistatemachine_base.h checked non-existent macros __GXX_RTTI__/__RTTI__,
  so on GCC/Clang desktop builds formatHash() always returned 0 and the
  guard signature check in testGuard() never fired (UB on incompatible
  signatures). Now the real PIP_HAS_RTTI (pibase_macros.h) is used.
- no-RTTI fallback: each Function<Args...> instantiation takes a unique
  hash from a process-wide counter (a per-instantiation counter would
  give every signature the same hash on first call).
- __pip_typename__ primary template: replace hard static_assert with a
  generic fallback; containers/stream operators instantiate it for
  arbitrary T in no-RTTI builds (Pico/arm-none-eabi has no RTTI), so the
  assert made any no-RTTI build impossible. Explicit
  __PIP_TYPENAME_DECLARE specializations still take precedence.
This commit is contained in:
2026-08-22 13:56:27 +03:00
parent b82ad8e6cd
commit 35d3136ffc
2 changed files with 18 additions and 6 deletions
+4 -2
View File
@@ -233,10 +233,12 @@ extern char ** environ;
# if PIP_HAS_RTTI
# define __PIP_TYPENAME__(T) typeid(T).name()
# else
// fallback for types without an explicit __PIP_TYPENAME_DECLARE: containers and
// stream operators instantiate this for arbitrary T in no-RTTI builds, so the
// primary template must not fail compilation
template<typename T>
inline const char * __pip_typename__() {
static_assert(false, "this type must declare typename via __PIP_TYPENAME_DECLARE");
return "?";
return "T";
}
# define __PIP_TYPENAME_DECLARE(T, NAME) \
+14 -4
View File
@@ -5,8 +5,8 @@
//! \~russian Объявляет вспомогательные типы, общие для API машины состояний
/*
PIP - Platform Independent Primitives
Some template helpers for PIStateMachine
Ivan Pelipenko peri4ko@yandex.ru
Some template helpers for PIStateMachine
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
@@ -25,6 +25,7 @@
#ifndef pistatemachine_base_H
#define pistatemachine_base_H
#include "pibase.h"
#include "piconstchars.h"
@@ -36,15 +37,24 @@ public:
virtual uint formatHash() = 0;
};
#if !PIP_HAS_RTTI
// without RTTI each template instantiation of Function<Args...> takes a unique
// hash from a process-wide counter, so incompatible signatures are still detected
inline uint __nextFormatHash() {
static uint cnt = 0;
return (uint)(++cnt) * 2654435761u;
}
#endif
template<typename... Args>
class Function: public FunctionBase {
public:
uint formatHash() override {
#if defined(__GXX_RTTI__) || defined(__RTTI__)
#if PIP_HAS_RTTI
static uint ret = PIConstChars(typeid(std::function<void(Args...)>).name()).hash();
#else
static uint ret = 0;
static uint ret = __nextFormatHash();
#endif
return ret;
}