AsyncObserver (#4444)

* feat(AsyncObserver): Improve NotificationCenter speed and usability #4414

* fix(Notification): add missing header

* feat(Any): add checkers for holding nullptr #4447

* feat(NotificationCenter): g++ build and refactoring #4414

* fix(Observer): compile errors on some compilers #4414

* fix(NotificationCenter): compile errors #4414

* chore(ParallelSocketAcceptor): remove unnecessary include and using from header

* feat(AsyncNotificationCenter): add #4414

* test(AsyncNotificationCenter): add mixed observer types to the test #4414

* fix(AsyncNotificationCenter): hangs on program exit #4414

* fix(dev): friend not honored, temporarily make private members public

* fix(AsyncNotificationCenter); remove default #4414
This commit is contained in:
Aleksandar Fabijanic
2024-02-16 09:34:19 +01:00
committed by GitHub
parent 30a0a06bac
commit 88be66972a
24 changed files with 882 additions and 139 deletions

View File

@@ -24,13 +24,12 @@
#include <cstddef>
#define poco_any_assert(cond) do { if (!(cond)) std::abort(); } while (0)
namespace Poco {
class Any;
using namespace std::string_literals;
namespace Dynamic {
class Var;
@@ -409,12 +408,12 @@ ValueType* AnyCast(Any* operand)
/// to the stored value.
///
/// Example Usage:
/// MyType* pTmp = AnyCast<MyType*>(pAny).
/// Will return NULL if the cast fails, i.e. types don't match.
/// MyType* pTmp = AnyCast<MyType>(pAny).
/// Returns nullptr if the types don't match.
{
return operand && operand->type() == typeid(ValueType)
? &static_cast<Any::Holder<ValueType>*>(operand->content())->_held
: 0;
: nullptr;
}
@@ -424,8 +423,8 @@ const ValueType* AnyCast(const Any* operand)
/// to the stored value.
///
/// Example Usage:
/// const MyType* pTmp = AnyCast<MyType*>(pAny).
/// Will return NULL if the cast fails, i.e. types don't match.
/// const MyType* pTmp = AnyCast<MyType>(pAny).
/// Returns nullptr if the types don't match.
{
return AnyCast<ValueType>(const_cast<Any*>(operand));
}
@@ -442,18 +441,19 @@ ValueType AnyCast(Any& operand)
/// Some compilers will accept this code although a copy is returned. Use the RefAnyCast in
/// these cases.
{
typedef typename TypeWrapper<ValueType>::TYPE NonRef;
using NonRef = typename TypeWrapper<ValueType>::TYPE;
NonRef* result = AnyCast<NonRef>(&operand);
if (!result)
{
std::string s = "RefAnyCast: Failed to convert between Any types ";
std::string s(__func__);
s.append(": Failed to convert between Any types "s);
if (operand.content())
{
s.append(1, '(');
s.append(operand.content()->type().name());
s.append(Poco::demangle(operand.content()->type().name()));
s.append(" => ");
s.append(typeid(ValueType).name());
s.append(Poco::demangle<ValueType>());
s.append(1, ')');
}
throw BadCastException(s);
@@ -473,7 +473,7 @@ ValueType AnyCast(const Any& operand)
/// Some compilers will accept this code although a copy is returned. Use the RefAnyCast in
/// these cases.
{
typedef typename TypeWrapper<ValueType>::TYPE NonRef;
using NonRef = typename TypeWrapper<ValueType>::TYPE;
return AnyCast<NonRef&>(const_cast<Any&>(operand));
}
@@ -489,13 +489,14 @@ const ValueType& RefAnyCast(const Any & operand)
ValueType* result = AnyCast<ValueType>(const_cast<Any*>(&operand));
if (!result)
{
std::string s = "RefAnyCast: Failed to convert between Any types ";
std::string s(__func__);
s.append(": Failed to convert between Any types "s);
if (operand.content())
{
s.append(1, '(');
s.append(operand.content()->type().name());
s.append(Poco::demangle(operand.content()->type().name()));
s.append(" => ");
s.append(typeid(ValueType).name());
s.append(Poco::demangle<ValueType>());
s.append(1, ')');
}
throw BadCastException(s);
@@ -514,13 +515,14 @@ ValueType& RefAnyCast(Any& operand)
ValueType* result = AnyCast<ValueType>(&operand);
if (!result)
{
std::string s = "RefAnyCast: Failed to convert between Any types ";
std::string s(__func__);
s.append(": Failed to convert between Any types "s);
if (operand.content())
{
s.append(1, '(');
s.append(operand.content()->type().name());
s.append(Poco::demangle(operand.content()->type().name()));
s.append(" => ");
s.append(typeid(ValueType).name());
s.append(Poco::demangle<ValueType>());
s.append(1, ')');
}
throw BadCastException(s);
@@ -553,6 +555,26 @@ const ValueType* UnsafeAnyCast(const Any* operand)
}
template <typename ValueType>
bool AnyHoldsNullPtr(const Any& any)
/// Returns true if any holds a null pointer.
/// Fails to compile if `ValueType` is not a pointer.
{
poco_static_assert_ptr(ValueType);
return (AnyCast<ValueType>(any) == nullptr);
}
template <typename ValueType>
bool AnyHoldsNullPtr(const Any* pAny)
/// Returns true if the Any pointed to holds a null pointer.
/// Returns false if `pAny` is a null pointer.
{
if (!pAny) return false;
return (AnyHoldsNullPtr<ValueType>(*pAny));
}
} // namespace Poco