2012-04-29 20:52:25 +02:00
//
// Any.h
//
// Library: Foundation
// Package: Core
2013-02-01 04:12:13 +01:00
// Module: Any
2012-04-29 20:52:25 +02:00
//
// Copyright Kevlin Henney, 2000, 2001, 2002. All rights reserved.
// Extracted from Boost 1.33.1 lib and adapted for poco: Peter Schojer/AppliedInformatics 2006-02-02
//
2014-05-04 21:02:42 +02:00
// SPDX-License-Identifier: BSL-1.0
2012-04-29 20:52:25 +02:00
//
# ifndef Foundation_Any_INCLUDED
# define Foundation_Any_INCLUDED
# include "Poco/Exception.h"
2013-02-03 03:37:39 +01:00
# include "Poco/MetaProgramming.h"
2012-04-29 20:52:25 +02:00
# include <algorithm>
# include <typeinfo>
2013-02-04 05:39:09 +01:00
# include <cstring>
2023-07-18 09:05:32 +02:00
# include <cstddef>
2013-07-22 08:10:36 +02:00
2012-04-29 20:52:25 +02:00
namespace Poco {
2013-03-30 19:02:16 +01:00
class Any ;
2024-02-16 09:34:19 +01:00
using namespace std : : string_literals ;
2013-02-06 05:12:21 +01:00
namespace Dynamic {
class Var ;
class VarHolder ;
2020-01-09 10:08:09 +01:00
template < class T > class VarHolderImpl ;
2013-02-06 05:12:21 +01:00
}
2020-01-09 10:08:09 +01:00
2024-02-06 09:59:38 +01:00
# ifndef POCO_DOC
2022-04-16 13:38:55 +02:00
template < class T , std : : size_t S >
struct TypeSizeLE :
std : : integral_constant < bool , ( sizeof ( T ) < = S ) > { } ;
template < class T , std : : size_t S >
struct TypeSizeGT :
std : : integral_constant < bool , ( sizeof ( T ) > S ) > { } ;
2024-02-06 09:59:38 +01:00
# endif
2022-04-16 13:38:55 +02:00
2013-04-04 04:05:22 +02:00
template < typename PlaceholderT , unsigned int SizeV = POCO_SMALL_OBJECT_SIZE >
2013-02-06 05:12:21 +01:00
union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
2013-05-30 06:36:28 +02:00
/// object optimization, when enabled).
2020-02-13 21:56:59 +01:00
///
/// If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
2013-02-06 05:12:21 +01:00
/// it will be placement-new-allocated into the local buffer
/// (i.e. there will be no heap-allocation). The local buffer size is one byte
/// larger - [POCO_SMALL_OBJECT_SIZE + 1], additional byte value indicating
/// where the object was allocated (0 => heap, 1 => local).
2022-06-28 19:14:36 +02:00
///
/// Important: for SOO builds, only same-type (or trivial both-empty no-op)
/// swap operation is allowed.
2013-02-06 05:12:21 +01:00
{
public :
2013-02-06 05:56:03 +01:00
struct Size
{
2022-07-26 13:54:56 +02:00
enum { value = SizeV } ;
2013-02-06 05:56:03 +01:00
} ;
2013-02-06 05:12:21 +01:00
2022-04-16 13:38:55 +02:00
Placeholder ( const Placeholder & ) = delete ;
Placeholder ( Placeholder & & ) = delete ;
Placeholder & operator = ( const Placeholder & ) = delete ;
Placeholder & operator = ( Placeholder & & ) = delete ;
2022-04-18 21:28:27 +02:00
# ifndef POCO_NO_SOO
2022-04-16 13:38:55 +02:00
Placeholder ( ) : pHolder ( 0 )
2013-02-06 05:12:21 +01:00
{
2024-09-26 18:42:48 +02:00
std : : memset ( holder , 0 , sizeof ( holder ) ) ;
2022-04-16 13:38:55 +02:00
}
~ Placeholder ( )
{
destruct ( false ) ;
}
2022-06-28 19:14:36 +02:00
void swap ( Placeholder & other ) noexcept
2022-04-16 13:38:55 +02:00
{
2022-06-28 19:14:36 +02:00
if ( ! isEmpty ( ) | | ! other . isEmpty ( ) )
std : : swap ( holder , other . holder ) ;
2013-02-06 05:12:21 +01:00
}
void erase ( )
{
2022-04-16 13:38:55 +02:00
destruct ( true ) ;
}
bool isEmpty ( ) const
{
2024-09-26 18:42:48 +02:00
static char buf [ sizeof ( holder ) ] = { } ;
return 0 = = std : : memcmp ( holder , buf , sizeof ( holder ) ) ;
2013-02-06 05:12:21 +01:00
}
bool isLocal ( ) const
{
2013-05-31 06:23:37 +02:00
return holder [ SizeV ] ! = 0 ;
2013-02-06 05:12:21 +01:00
}
2022-04-19 11:03:47 +02:00
template < typename T , typename V ,
typename std : : enable_if < TypeSizeLE < T , Placeholder : : Size : : value > : : value > : : type * = nullptr >
PlaceholderT * assign ( const V & value )
2022-04-16 13:38:55 +02:00
{
erase ( ) ;
new ( reinterpret_cast < PlaceholderT * > ( holder ) ) T ( value ) ;
setLocal ( true ) ;
return reinterpret_cast < PlaceholderT * > ( holder ) ;
}
2022-04-19 11:03:47 +02:00
template < typename T , typename V ,
typename std : : enable_if < TypeSizeGT < T , Placeholder : : Size : : value > : : value > : : type * = nullptr >
PlaceholderT * assign ( const V & value )
2022-04-16 13:38:55 +02:00
{
erase ( ) ;
pHolder = new T ( value ) ;
setLocal ( false ) ;
return pHolder ;
}
2013-02-06 05:12:21 +01:00
PlaceholderT * content ( ) const
{
2014-09-19 09:46:49 +02:00
if ( isLocal ( ) )
2013-05-31 06:23:37 +02:00
return reinterpret_cast < PlaceholderT * > ( holder ) ;
2013-02-06 05:12:21 +01:00
else
return pHolder ;
}
2013-04-04 04:05:22 +02:00
private :
2023-07-18 09:05:32 +02:00
typedef std : : max_align_t AlignerType ;
2023-07-18 09:30:29 +02:00
static_assert ( sizeof ( AlignerType ) < = SizeV + 1 , " Aligner type is bigger than the actual storage, so SizeV should be made bigger otherwise you simply waste unused memory. " ) ;
2020-02-13 21:56:59 +01:00
2022-04-19 11:03:47 +02:00
void setLocal ( bool local ) const
{
holder [ SizeV ] = local ? 1 : 0 ;
}
2022-04-16 13:38:55 +02:00
void destruct ( bool clear )
{
if ( ! isEmpty ( ) )
{
if ( ! isLocal ( ) )
delete pHolder ;
else
reinterpret_cast < PlaceholderT * > ( holder ) - > ~ PlaceholderT ( ) ;
2013-02-06 05:12:21 +01:00
2024-09-26 18:42:48 +02:00
if ( clear ) std : : memset ( holder , 0 , sizeof ( holder ) ) ;
2022-04-16 13:38:55 +02:00
}
}
mutable unsigned char holder [ SizeV + 1 ] ;
AlignerType aligner ;
2013-02-06 05:12:21 +01:00
2022-04-18 21:28:27 +02:00
# else // POCO_NO_SOO
2013-02-06 05:12:21 +01:00
2022-04-18 21:28:27 +02:00
Placeholder ( ) : pHolder ( 0 )
{
}
2013-04-04 04:05:22 +02:00
2022-04-18 21:28:27 +02:00
~ Placeholder ( )
{
delete pHolder ;
}
2013-04-04 04:05:22 +02:00
2022-06-28 19:14:36 +02:00
void swap ( Placeholder & other ) noexcept
2013-04-04 04:05:22 +02:00
{
2022-04-18 21:28:27 +02:00
std : : swap ( pHolder , other . pHolder ) ;
2013-04-04 04:05:22 +02:00
}
2022-04-18 21:28:27 +02:00
void erase ( )
2013-04-04 04:05:22 +02:00
{
2022-04-18 21:28:27 +02:00
delete pHolder ;
pHolder = 0 ;
2013-04-04 04:05:22 +02:00
}
2022-04-18 21:28:27 +02:00
bool isEmpty ( ) const
{
return 0 = = pHolder ;
}
2020-02-13 21:56:59 +01:00
2022-04-18 21:28:27 +02:00
bool isLocal ( ) const
{
return false ;
}
2013-04-04 04:05:22 +02:00
2022-04-18 21:28:27 +02:00
template < typename T , typename V >
2022-04-19 11:03:47 +02:00
PlaceholderT * assign ( const V & value )
2022-04-18 21:28:27 +02:00
{
erase ( ) ;
return pHolder = new T ( value ) ;
}
2013-04-04 04:05:22 +02:00
2022-04-18 21:28:27 +02:00
PlaceholderT * content ( ) const
{
return pHolder ;
}
2013-04-04 04:05:22 +02:00
2022-04-29 05:24:43 +02:00
private :
2013-04-04 04:05:22 +02:00
# endif // POCO_NO_SOO
2022-04-18 21:28:27 +02:00
PlaceholderT * pHolder ;
} ;
2013-04-04 04:05:22 +02:00
2012-04-29 20:52:25 +02:00
class Any
2022-06-28 19:14:36 +02:00
/// Any class represents a general type and is capable of storing any type, supporting type-safe extraction
2012-04-29 20:52:25 +02:00
/// of the internally stored data.
///
/// Code taken from the Boost 1.33.1 library. Original copyright by Kevlin Henney. Modified for Poco
/// by Applied Informatics.
2013-02-01 04:12:13 +01:00
///
/// Modified for small object optimization support (optionally supported through conditional compilation)
/// by Alex Fabijanic.
2012-04-29 20:52:25 +02:00
{
2013-02-06 05:12:21 +01:00
public :
2013-02-01 04:12:13 +01:00
Any ( )
/// Creates an empty any type.
{
}
template < typename ValueType >
Any ( const ValueType & value )
/// Creates an any which stores the init parameter inside.
///
2020-02-13 21:56:59 +01:00
/// Example:
/// Any a(13);
2013-02-06 05:12:21 +01:00
/// Any a(string("12345"));
2013-02-01 04:12:13 +01:00
{
construct ( value ) ;
}
Any ( const Any & other )
/// Copy constructor, works with both empty and initialized Any values.
{
2013-02-03 19:03:01 +01:00
if ( ( this ! = & other ) & & ! other . empty ( ) )
construct ( other ) ;
2013-02-01 04:12:13 +01:00
}
~ Any ( )
2013-02-06 05:12:21 +01:00
/// Destructor. If Any is locally held, calls ValueHolder destructor;
2013-02-03 03:37:39 +01:00
/// otherwise, deletes the placeholder from the heap.
2013-02-01 04:12:13 +01:00
{
}
2022-06-28 19:14:36 +02:00
Any & swap ( Any & other ) noexcept
2013-02-03 03:37:39 +01:00
/// Swaps the content of the two Anys.
2020-02-13 21:56:59 +01:00
///
2022-06-28 19:14:36 +02:00
/// If an exception occurs during swapping, the program
/// execution is aborted.
2013-02-03 03:37:39 +01:00
{
2013-02-03 19:03:01 +01:00
if ( this = = & other ) return * this ;
2013-02-06 05:12:21 +01:00
if ( ! _valueHolder . isLocal ( ) & & ! other . _valueHolder . isLocal ( ) )
2013-02-03 03:37:39 +01:00
{
2022-04-16 13:38:55 +02:00
_valueHolder . swap ( other . _valueHolder ) ;
2013-02-03 03:37:39 +01:00
}
else
{
2013-03-31 23:28:53 +02:00
try
{
2022-06-28 19:14:36 +02:00
Any tmp ( * this ) ;
2013-03-31 23:28:53 +02:00
construct ( other ) ;
other = tmp ;
}
catch ( . . . )
{
2022-06-28 19:14:36 +02:00
std : : abort ( ) ;
2013-03-31 23:28:53 +02:00
}
2013-02-03 03:37:39 +01:00
}
return * this ;
}
2013-02-01 04:12:13 +01:00
template < typename ValueType >
2013-03-31 23:28:53 +02:00
Any & operator = ( const ValueType & rhs )
2013-02-01 04:12:13 +01:00
/// Assignment operator for all types != Any.
///
2020-02-13 21:56:59 +01:00
/// Example:
/// Any a = 13;
2013-02-01 04:12:13 +01:00
/// Any a = string("12345");
{
2013-02-03 19:03:01 +01:00
construct ( rhs ) ;
2013-02-01 04:12:13 +01:00
return * this ;
}
2020-02-13 21:56:59 +01:00
2013-02-03 19:03:01 +01:00
Any & operator = ( const Any & rhs )
2013-02-01 04:12:13 +01:00
/// Assignment operator for Any.
{
2013-02-03 19:03:01 +01:00
if ( ( this ! = & rhs ) & & ! rhs . empty ( ) )
construct ( rhs ) ;
else if ( ( this ! = & rhs ) & & rhs . empty ( ) )
2013-02-06 05:12:21 +01:00
_valueHolder . erase ( ) ;
2013-02-03 19:03:01 +01:00
2013-02-01 04:12:13 +01:00
return * this ;
}
2020-02-13 21:56:59 +01:00
2013-02-01 04:12:13 +01:00
bool empty ( ) const
/// Returns true if the Any is empty.
{
2022-04-16 13:38:55 +02:00
return _valueHolder . isEmpty ( ) ;
2013-02-01 04:12:13 +01:00
}
2020-02-13 21:56:59 +01:00
2022-06-28 19:14:36 +02:00
const std : : type_info & type ( ) const
2013-02-01 04:12:13 +01:00
/// Returns the type information of the stored content.
/// If the Any is empty typeid(void) is returned.
/// It is recommended to always query an Any for its type info before
/// trying to extract data via an AnyCast/RefAnyCast.
{
return empty ( ) ? typeid ( void ) : content ( ) - > type ( ) ;
}
2022-06-28 19:14:36 +02:00
bool local ( ) const
/// Returns true if data is held locally (ie. not allocated on the heap).
/// If POCO_NO_SOO is defined, it always return false.
/// The main purpose of this function is use for testing.
{
return _valueHolder . isLocal ( ) ;
}
2013-02-01 04:12:13 +01:00
private :
2013-02-06 05:12:21 +01:00
class ValueHolder
2013-02-01 04:12:13 +01:00
{
public :
2020-01-09 10:08:09 +01:00
virtual ~ ValueHolder ( ) = default ;
2013-02-02 22:10:20 +01:00
2013-02-01 04:12:13 +01:00
virtual const std : : type_info & type ( ) const = 0 ;
2013-02-06 05:12:21 +01:00
virtual void clone ( Placeholder < ValueHolder > * ) const = 0 ;
2013-02-01 04:12:13 +01:00
} ;
template < typename ValueType >
2013-02-06 05:12:21 +01:00
class Holder : public ValueHolder
2013-02-01 04:12:13 +01:00
{
public :
Holder ( const ValueType & value ) : _held ( value )
{
}
2013-02-02 22:10:20 +01:00
2022-06-28 19:14:36 +02:00
virtual const std : : type_info & type ( ) const
2013-02-01 04:12:13 +01:00
{
return typeid ( ValueType ) ;
}
2013-02-02 22:10:20 +01:00
2013-02-06 05:12:21 +01:00
virtual void clone ( Placeholder < ValueHolder > * pPlaceholder ) const
2013-02-02 22:10:20 +01:00
{
2022-04-19 11:03:47 +02:00
pPlaceholder - > assign < Holder < ValueType > , ValueType > ( _held ) ;
2013-02-01 04:12:13 +01:00
}
ValueType _held ;
private :
2022-04-16 13:38:55 +02:00
2013-02-01 04:12:13 +01:00
Holder & operator = ( const Holder & ) ;
} ;
2013-02-06 05:12:21 +01:00
ValueHolder * content ( ) const
2013-02-01 04:12:13 +01:00
{
2013-02-06 05:12:21 +01:00
return _valueHolder . content ( ) ;
2013-02-01 04:12:13 +01:00
}
2022-04-19 11:03:47 +02:00
template < typename ValueType >
2022-04-16 13:38:55 +02:00
void construct ( const ValueType & value )
{
2022-04-19 11:03:47 +02:00
_valueHolder . assign < Holder < ValueType > , ValueType > ( value ) ;
2013-02-01 04:12:13 +01:00
}
2013-02-02 22:10:20 +01:00
2013-02-03 03:37:39 +01:00
void construct ( const Any & other )
2013-02-01 04:12:13 +01:00
{
2014-09-19 09:46:49 +02:00
if ( ! other . empty ( ) )
2013-02-06 05:12:21 +01:00
other . content ( ) - > clone ( & _valueHolder ) ;
2013-02-02 22:10:20 +01:00
else
2013-02-06 05:12:21 +01:00
_valueHolder . erase ( ) ;
2013-02-01 04:12:13 +01:00
}
2020-02-13 21:56:59 +01:00
2013-02-06 05:12:21 +01:00
Placeholder < ValueHolder > _valueHolder ;
2013-02-01 04:12:13 +01:00
2012-09-21 07:11:25 +02:00
template < typename ValueType >
friend ValueType * AnyCast ( Any * ) ;
2012-04-29 20:52:25 +02:00
2024-07-29 20:16:18 +02:00
template < typename ValueType >
friend const ValueType * AnyCast ( const Any * ) ;
2012-09-21 07:11:25 +02:00
template < typename ValueType >
friend ValueType * UnsafeAnyCast ( Any * ) ;
2012-04-29 20:52:25 +02:00
2020-01-09 10:08:09 +01:00
template < typename ValueType >
friend const ValueType & RefAnyCast ( const Any & ) ;
template < typename ValueType >
friend ValueType & RefAnyCast ( Any & ) ;
template < typename ValueType >
friend ValueType AnyCast ( Any & ) ;
2012-04-29 20:52:25 +02:00
} ;
template < typename ValueType >
ValueType * AnyCast ( Any * operand )
/// AnyCast operator used to extract the ValueType from an Any*. Will return a pointer
2020-02-13 21:56:59 +01:00
/// to the stored value.
2012-04-29 20:52:25 +02:00
///
2020-02-13 21:56:59 +01:00
/// Example Usage:
2024-02-16 09:34:19 +01:00
/// MyType* pTmp = AnyCast<MyType>(pAny).
/// Returns nullptr if the types don't match.
2012-04-29 20:52:25 +02:00
{
2012-09-21 07:11:25 +02:00
return operand & & operand - > type ( ) = = typeid ( ValueType )
2013-02-01 04:12:13 +01:00
? & static_cast < Any : : Holder < ValueType > * > ( operand - > content ( ) ) - > _held
2024-02-16 09:34:19 +01:00
: nullptr ;
2012-04-29 20:52:25 +02:00
}
template < typename ValueType >
const ValueType * AnyCast ( const Any * operand )
/// AnyCast operator used to extract a const ValueType pointer from an const Any*. Will return a const pointer
2020-02-13 21:56:59 +01:00
/// to the stored value.
2012-04-29 20:52:25 +02:00
///
/// Example Usage:
2024-02-16 09:34:19 +01:00
/// const MyType* pTmp = AnyCast<MyType>(pAny).
/// Returns nullptr if the types don't match.
2012-04-29 20:52:25 +02:00
{
2024-07-29 20:16:18 +02:00
return operand & & operand - > type ( ) = = typeid ( ValueType )
? & static_cast < const Any : : Holder < ValueType > * > ( operand - > content ( ) ) - > _held
: nullptr ;
2012-04-29 20:52:25 +02:00
}
template < typename ValueType >
2013-06-08 06:15:02 +02:00
ValueType AnyCast ( Any & operand )
/// AnyCast operator used to extract a copy of the ValueType from an Any&.
2012-04-29 20:52:25 +02:00
///
2020-02-13 21:56:59 +01:00
/// Example Usage:
2012-09-21 07:11:25 +02:00
/// MyType tmp = AnyCast<MyType>(anAny).
2012-04-29 20:52:25 +02:00
/// Will throw a BadCastException if the cast fails.
2020-01-09 10:08:09 +01:00
/// Do not use an AnyCast in combination with references, i.e. MyType& tmp = ... or const MyType& tmp = ...
2012-04-29 20:52:25 +02:00
/// Some compilers will accept this code although a copy is returned. Use the RefAnyCast in
/// these cases.
{
2024-02-16 09:34:19 +01:00
using NonRef = typename TypeWrapper < ValueType > : : TYPE ;
2013-02-03 03:37:39 +01:00
2013-06-08 06:15:02 +02:00
NonRef * result = AnyCast < NonRef > ( & operand ) ;
2020-01-09 10:08:09 +01:00
if ( ! result )
{
2024-02-16 09:34:19 +01:00
std : : string s ( __func__ ) ;
s . append ( " : Failed to convert between Any types " s ) ;
2022-04-13 21:10:56 +02:00
if ( operand . content ( ) )
2020-01-09 10:08:09 +01:00
{
s . append ( 1 , ' ( ' ) ;
2024-02-16 09:34:19 +01:00
s . append ( Poco : : demangle ( operand . content ( ) - > type ( ) . name ( ) ) ) ;
2020-01-09 10:08:09 +01:00
s . append ( " => " ) ;
2024-02-16 09:34:19 +01:00
s . append ( Poco : : demangle < ValueType > ( ) ) ;
2020-01-09 10:08:09 +01:00
s . append ( 1 , ' ) ' ) ;
}
throw BadCastException ( s ) ;
}
2013-06-08 06:15:02 +02:00
return * result ;
2012-04-29 20:52:25 +02:00
}
template < typename ValueType >
2013-06-08 06:15:02 +02:00
ValueType AnyCast ( const Any & operand )
/// AnyCast operator used to extract a copy of the ValueType from an const Any&.
2012-04-29 20:52:25 +02:00
///
2020-02-13 21:56:59 +01:00
/// Example Usage:
2012-09-21 07:11:25 +02:00
/// MyType tmp = AnyCast<MyType>(anAny).
2012-04-29 20:52:25 +02:00
/// Will throw a BadCastException if the cast fails.
2020-01-09 10:08:09 +01:00
/// Do not use an AnyCast in combination with references, i.e. MyType& tmp = ... or const MyType& = ...
2012-04-29 20:52:25 +02:00
/// Some compilers will accept this code although a copy is returned. Use the RefAnyCast in
/// these cases.
{
2024-02-16 09:34:19 +01:00
using NonRef = typename TypeWrapper < ValueType > : : TYPE ;
2013-02-03 03:37:39 +01:00
2013-06-08 06:15:02 +02:00
return AnyCast < NonRef & > ( const_cast < Any & > ( operand ) ) ;
2012-04-29 20:52:25 +02:00
}
template < typename ValueType >
const ValueType & RefAnyCast ( const Any & operand )
2020-02-13 21:56:59 +01:00
/// AnyCast operator used to return a const reference to the internal data.
2012-04-29 20:52:25 +02:00
///
2020-02-13 21:56:59 +01:00
/// Example Usage:
2012-09-21 07:11:25 +02:00
/// const MyType& tmp = RefAnyCast<MyType>(anAny);
2012-04-29 20:52:25 +02:00
{
2012-09-21 07:11:25 +02:00
ValueType * result = AnyCast < ValueType > ( const_cast < Any * > ( & operand ) ) ;
2020-02-13 21:56:59 +01:00
if ( ! result )
2020-01-09 10:08:09 +01:00
{
2024-02-16 09:34:19 +01:00
std : : string s ( __func__ ) ;
s . append ( " : Failed to convert between Any types " s ) ;
2022-04-13 21:10:56 +02:00
if ( operand . content ( ) )
2020-02-13 21:56:59 +01:00
{
s . append ( 1 , ' ( ' ) ;
2024-02-16 09:34:19 +01:00
s . append ( Poco : : demangle ( operand . content ( ) - > type ( ) . name ( ) ) ) ;
2020-02-13 21:56:59 +01:00
s . append ( " => " ) ;
2024-02-16 09:34:19 +01:00
s . append ( Poco : : demangle < ValueType > ( ) ) ;
2020-02-13 21:56:59 +01:00
s . append ( 1 , ' ) ' ) ;
}
throw BadCastException ( s ) ;
2020-01-09 10:08:09 +01:00
}
2012-09-21 07:11:25 +02:00
return * result ;
2012-04-29 20:52:25 +02:00
}
template < typename ValueType >
ValueType & RefAnyCast ( Any & operand )
/// AnyCast operator used to return a reference to the internal data.
///
2020-02-13 21:56:59 +01:00
/// Example Usage:
2012-09-21 07:11:25 +02:00
/// MyType& tmp = RefAnyCast<MyType>(anAny);
2012-04-29 20:52:25 +02:00
{
2012-09-21 07:11:25 +02:00
ValueType * result = AnyCast < ValueType > ( & operand ) ;
2020-01-09 10:08:09 +01:00
if ( ! result )
{
2024-02-16 09:34:19 +01:00
std : : string s ( __func__ ) ;
s . append ( " : Failed to convert between Any types " s ) ;
2022-04-13 21:10:56 +02:00
if ( operand . content ( ) )
2020-01-09 10:08:09 +01:00
{
s . append ( 1 , ' ( ' ) ;
2024-02-16 09:34:19 +01:00
s . append ( Poco : : demangle ( operand . content ( ) - > type ( ) . name ( ) ) ) ;
2020-01-09 10:08:09 +01:00
s . append ( " => " ) ;
2024-02-16 09:34:19 +01:00
s . append ( Poco : : demangle < ValueType > ( ) ) ;
2020-01-09 10:08:09 +01:00
s . append ( 1 , ' ) ' ) ;
}
throw BadCastException ( s ) ;
}
2012-09-21 07:11:25 +02:00
return * result ;
2012-04-29 20:52:25 +02:00
}
template < typename ValueType >
ValueType * UnsafeAnyCast ( Any * operand )
/// The "unsafe" versions of AnyCast are not part of the
/// public interface and may be removed at any time. They are
/// required where we know what type is stored in the any and can't
/// use typeid() comparison, e.g., when our types may travel across
/// different shared libraries.
{
2013-02-03 14:16:06 +01:00
return & static_cast < Any : : Holder < ValueType > * > ( operand - > content ( ) ) - > _held ;
2012-04-29 20:52:25 +02:00
}
template < typename ValueType >
const ValueType * UnsafeAnyCast ( const Any * operand )
/// The "unsafe" versions of AnyCast are not part of the
/// public interface and may be removed at any time. They are
/// required where we know what type is stored in the any and can't
/// use typeid() comparison, e.g., when our types may travel across
/// different shared libraries.
{
2012-09-21 07:11:25 +02:00
return AnyCast < ValueType > ( const_cast < Any * > ( operand ) ) ;
2012-04-29 20:52:25 +02:00
}
2024-02-16 09:34:19 +01:00
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 ) ) ;
}
2012-04-29 20:52:25 +02:00
} // namespace Poco
# endif