mirror of
https://github.com/pocoproject/poco.git
synced 2025-05-29 07:25:53 +02:00
Dynamic::Var SOO
Dynamic::Var small object optimization and some refactoring
This commit is contained in:
parent
54a92c59e5
commit
21da0129b6
3
.gitignore
vendored
3
.gitignore
vendored
@ -100,3 +100,6 @@ lib/
|
|||||||
lib64/
|
lib64/
|
||||||
pocomsg.h
|
pocomsg.h
|
||||||
|
|
||||||
|
# Temporary files #
|
||||||
|
###################
|
||||||
|
*.bak
|
||||||
|
@ -225,9 +225,9 @@ public:
|
|||||||
val = DateTimeFormatter::format(dt, "%Y/%m/%d");
|
val = DateTimeFormatter::format(dt, "%Y/%m/%d");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Poco::Data::Date& value() const
|
const Poco::Data::Date& value() const
|
||||||
|
@ -272,9 +272,9 @@ public:
|
|||||||
val.assign(_val.begin(), _val.end());
|
val.assign(_val.begin(), _val.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Poco::Data::BLOB& value() const
|
const Poco::Data::BLOB& value() const
|
||||||
@ -310,9 +310,9 @@ public:
|
|||||||
val.assign(_val.begin(), _val.end());
|
val.assign(_val.begin(), _val.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Poco::Data::CLOB& value() const
|
const Poco::Data::CLOB& value() const
|
||||||
|
@ -229,9 +229,9 @@ public:
|
|||||||
val = DateTimeFormatter::format(dt, "%H:%M:%S");
|
val = DateTimeFormatter::format(dt, "%H:%M:%S");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Poco::Data::Time& value() const
|
const Poco::Data::Time& value() const
|
||||||
|
@ -48,6 +48,68 @@
|
|||||||
namespace Poco {
|
namespace Poco {
|
||||||
|
|
||||||
|
|
||||||
|
namespace Dynamic {
|
||||||
|
|
||||||
|
class Var;
|
||||||
|
class VarHolder;
|
||||||
|
template <class> class VarHolderImpl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE>
|
||||||
|
union Placeholder
|
||||||
|
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
|
||||||
|
/// object optimization).
|
||||||
|
///
|
||||||
|
/// If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
|
||||||
|
/// 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).
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static const unsigned int SIZE = SizeV;
|
||||||
|
|
||||||
|
Placeholder ()
|
||||||
|
{
|
||||||
|
erase();
|
||||||
|
}
|
||||||
|
|
||||||
|
void erase()
|
||||||
|
{
|
||||||
|
std::memset(holder, 0, sizeof(Placeholder));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLocal() const
|
||||||
|
{
|
||||||
|
return holder[SIZE] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setLocal(bool local) const
|
||||||
|
{
|
||||||
|
holder[SIZE] = local ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PlaceholderT* content() const
|
||||||
|
{
|
||||||
|
if(isLocal())
|
||||||
|
return reinterpret_cast<PlaceholderT*>(holder);
|
||||||
|
else
|
||||||
|
return pHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
PlaceholderT* pHolder;
|
||||||
|
mutable unsigned char holder[SIZE + 1];
|
||||||
|
|
||||||
|
friend class Any;
|
||||||
|
friend class Dynamic::Var;
|
||||||
|
friend class Dynamic::VarHolder;
|
||||||
|
template <class> friend class VarHolderImpl;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class Any
|
class Any
|
||||||
/// An Any class represents a general type and is capable of storing any type, supporting type-safe extraction
|
/// An Any class represents a general type and is capable of storing any type, supporting type-safe extraction
|
||||||
/// of the internally stored data.
|
/// of the internally stored data.
|
||||||
@ -58,13 +120,10 @@ class Any
|
|||||||
/// Modified for small object optimization support (optionally supported through conditional compilation)
|
/// Modified for small object optimization support (optionally supported through conditional compilation)
|
||||||
/// by Alex Fabijanic.
|
/// by Alex Fabijanic.
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
#ifndef POCO_NO_SOO
|
#ifndef POCO_NO_SOO
|
||||||
|
|
||||||
union PH;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
Any()
|
Any()
|
||||||
/// Creates an empty any type.
|
/// Creates an empty any type.
|
||||||
{
|
{
|
||||||
@ -75,8 +134,8 @@ public:
|
|||||||
/// Creates an any which stores the init parameter inside.
|
/// Creates an any which stores the init parameter inside.
|
||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
/// Any a(13);
|
/// Any a(13);
|
||||||
/// Any a(string("12345"));
|
/// Any a(string("12345"));
|
||||||
{
|
{
|
||||||
construct(value);
|
construct(value);
|
||||||
}
|
}
|
||||||
@ -89,13 +148,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
~Any()
|
~Any()
|
||||||
/// Destructor. If Any is locally held, calls Placeholder destructor;
|
/// Destructor. If Any is locally held, calls ValueHolder destructor;
|
||||||
/// otherwise, deletes the placeholder from the heap.
|
/// otherwise, deletes the placeholder from the heap.
|
||||||
{
|
{
|
||||||
if(!empty())
|
if(!empty())
|
||||||
{
|
{
|
||||||
if(_placeholder.isLocal())
|
if(_valueHolder.isLocal())
|
||||||
content()->~Placeholder();
|
content()->~ValueHolder();
|
||||||
else
|
else
|
||||||
delete content();
|
delete content();
|
||||||
}
|
}
|
||||||
@ -110,14 +169,14 @@ public:
|
|||||||
{
|
{
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
|
|
||||||
if (!_placeholder.isLocal() && !other._placeholder.isLocal())
|
if (!_valueHolder.isLocal() && !other._valueHolder.isLocal())
|
||||||
{
|
{
|
||||||
std::swap(_placeholder.pHolder, other._placeholder.pHolder);
|
std::swap(_valueHolder.pHolder, other._valueHolder.pHolder);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Any tmp(*this);
|
Any tmp(*this);
|
||||||
if (_placeholder.isLocal()) this->~Any();
|
if (_valueHolder.isLocal()) this->~Any();
|
||||||
construct(other);
|
construct(other);
|
||||||
other = tmp;
|
other = tmp;
|
||||||
}
|
}
|
||||||
@ -143,7 +202,7 @@ public:
|
|||||||
if ((this != &rhs) && !rhs.empty())
|
if ((this != &rhs) && !rhs.empty())
|
||||||
construct(rhs);
|
construct(rhs);
|
||||||
else if ((this != &rhs) && rhs.empty())
|
else if ((this != &rhs) && rhs.empty())
|
||||||
_placeholder.erase();
|
_valueHolder.erase();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -152,7 +211,7 @@ public:
|
|||||||
/// Returns true if the Any is empty.
|
/// Returns true if the Any is empty.
|
||||||
{
|
{
|
||||||
char buf[POCO_SMALL_OBJECT_SIZE] = { 0 };
|
char buf[POCO_SMALL_OBJECT_SIZE] = { 0 };
|
||||||
return 0 == std::memcmp(_placeholder.holder, buf, POCO_SMALL_OBJECT_SIZE);
|
return 0 == std::memcmp(_valueHolder.holder, buf, _valueHolder.SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::type_info & type() const
|
const std::type_info & type() const
|
||||||
@ -166,20 +225,20 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
class Placeholder
|
class ValueHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~Placeholder()
|
virtual ~ValueHolder()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const std::type_info & type() const = 0;
|
virtual const std::type_info & type() const = 0;
|
||||||
virtual void clone(Any::PH*) const = 0;
|
virtual void clone(Placeholder<ValueHolder>*) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
class Holder : public Placeholder
|
class Holder : public ValueHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Holder(const ValueType & value) : _held(value)
|
Holder(const ValueType & value) : _held(value)
|
||||||
@ -191,11 +250,11 @@ private:
|
|||||||
return typeid(ValueType);
|
return typeid(ValueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void clone(Any::PH* pPlaceholder) const
|
virtual void clone(Placeholder<ValueHolder>* pPlaceholder) const
|
||||||
{
|
{
|
||||||
if ((sizeof(Holder<ValueType>) <= POCO_SMALL_OBJECT_SIZE))
|
if ((sizeof(Holder<ValueType>) <= pPlaceholder->SIZE))
|
||||||
{
|
{
|
||||||
new ((Placeholder*) pPlaceholder->holder) Holder(_held);
|
new ((ValueHolder*) pPlaceholder->holder) Holder(_held);
|
||||||
pPlaceholder->setLocal(true);
|
pPlaceholder->setLocal(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -211,78 +270,40 @@ private:
|
|||||||
Holder & operator = (const Holder &);
|
Holder & operator = (const Holder &);
|
||||||
};
|
};
|
||||||
|
|
||||||
Placeholder* content() const
|
ValueHolder* content() const
|
||||||
{
|
{
|
||||||
return _placeholder.content();
|
return _valueHolder.content();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ValueType>
|
template<typename ValueType>
|
||||||
void construct(const ValueType& value)
|
void construct(const ValueType& value)
|
||||||
{
|
{
|
||||||
if (sizeof(Holder<ValueType>) <= POCO_SMALL_OBJECT_SIZE)
|
if (sizeof(Holder<ValueType>) <= _valueHolder.SIZE)
|
||||||
{
|
{
|
||||||
new (reinterpret_cast<Placeholder*>(_placeholder.holder)) Holder<ValueType>(value);
|
new (reinterpret_cast<ValueHolder*>(_valueHolder.holder)) Holder<ValueType>(value);
|
||||||
_placeholder.setLocal(true);
|
_valueHolder.setLocal(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_placeholder.pHolder = new Holder<ValueType>(value);
|
_valueHolder.pHolder = new Holder<ValueType>(value);
|
||||||
_placeholder.setLocal(false);
|
_valueHolder.setLocal(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void construct(const Any& other)
|
void construct(const Any& other)
|
||||||
{
|
{
|
||||||
if(!other.empty())
|
if(!other.empty())
|
||||||
other.content()->clone(&_placeholder);
|
other.content()->clone(&_valueHolder);
|
||||||
else
|
else
|
||||||
_placeholder.erase();
|
_valueHolder.erase();
|
||||||
}
|
}
|
||||||
|
|
||||||
union PH
|
Placeholder<ValueHolder> _valueHolder;
|
||||||
/// Placeholder union. If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE
|
|
||||||
/// bytes of storage, 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).
|
|
||||||
{
|
|
||||||
PH ()
|
|
||||||
{
|
|
||||||
erase();
|
|
||||||
}
|
|
||||||
|
|
||||||
void erase()
|
|
||||||
{
|
|
||||||
std::memset(holder, 0, sizeof(PH));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isLocal() const
|
|
||||||
{
|
|
||||||
return holder[POCO_SMALL_OBJECT_SIZE] != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setLocal(bool local) const
|
|
||||||
{
|
|
||||||
holder[POCO_SMALL_OBJECT_SIZE] = local ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Placeholder* content() const
|
|
||||||
{
|
|
||||||
if(isLocal())
|
|
||||||
return reinterpret_cast<Placeholder*>(holder);
|
|
||||||
else
|
|
||||||
return pHolder;
|
|
||||||
}
|
|
||||||
|
|
||||||
Placeholder* pHolder;
|
|
||||||
mutable unsigned char holder[POCO_SMALL_OBJECT_SIZE + 1];
|
|
||||||
} _placeholder;
|
|
||||||
|
|
||||||
|
|
||||||
#else // if POCO_NO_SOO
|
#else // if POCO_NO_SOO
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
Any(): _pHolder(0)
|
Any(): _pHolder(0)
|
||||||
/// Creates an empty any type.
|
/// Creates an empty any type.
|
||||||
{
|
{
|
||||||
@ -352,19 +373,19 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Placeholder
|
class ValueHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Placeholder()
|
virtual ~ValueHolder()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual const std::type_info& type() const = 0;
|
virtual const std::type_info& type() const = 0;
|
||||||
virtual Placeholder* clone() const = 0;
|
virtual ValueHolder* clone() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ValueType>
|
template <typename ValueType>
|
||||||
class Holder: public Placeholder
|
class Holder: public ValueHolder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Holder(const ValueType& value):
|
Holder(const ValueType& value):
|
||||||
@ -377,7 +398,7 @@ private:
|
|||||||
return typeid(ValueType);
|
return typeid(ValueType);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Placeholder* clone() const
|
virtual ValueHolder* clone() const
|
||||||
{
|
{
|
||||||
return new Holder(_held);
|
return new Holder(_held);
|
||||||
}
|
}
|
||||||
@ -388,13 +409,13 @@ private:
|
|||||||
Holder & operator=(const Holder &);
|
Holder & operator=(const Holder &);
|
||||||
};
|
};
|
||||||
|
|
||||||
Placeholder* content() const
|
ValueHolder* content() const
|
||||||
{
|
{
|
||||||
return _pHolder;
|
return _pHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Placeholder* _pHolder;
|
ValueHolder* _pHolder;
|
||||||
|
|
||||||
#endif // POCO_NO_SOO
|
#endif // POCO_NO_SOO
|
||||||
|
|
||||||
|
@ -93,6 +93,16 @@
|
|||||||
// (see Poco/Types.h for default values).
|
// (see Poco/Types.h for default values).
|
||||||
// #define POCO_NO_SOO
|
// #define POCO_NO_SOO
|
||||||
|
|
||||||
|
|
||||||
|
// Small object size in bytes. Where applicable (e.g.
|
||||||
|
// SmallObjectAllocator<char*> specialization, Any, Var, etc)
|
||||||
|
// objects longer than this value will be alocated on the heap.
|
||||||
|
// See Poco/SmallObjectAllocator.h for usage of this value.
|
||||||
|
#if !defined(POCO_SMALL_OBJECT_SIZE)
|
||||||
|
#define POCO_SMALL_OBJECT_SIZE 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Following are options to remove certain features
|
// Following are options to remove certain features
|
||||||
// to reduce library/executable size for smaller
|
// to reduce library/executable size for smaller
|
||||||
// embedded platforms. By enabling these options,
|
// embedded platforms. By enabling these options,
|
||||||
|
@ -229,9 +229,9 @@ public:
|
|||||||
throw BadCastException("Pair -> Poco::Timestamp");
|
throw BadCastException("Pair -> Poco::Timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Pair<std::string>& value() const
|
const Pair<std::string>& value() const
|
||||||
@ -378,9 +378,9 @@ public:
|
|||||||
throw BadCastException("Pair -> Poco::Timestamp");
|
throw BadCastException("Pair -> Poco::Timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Pair<int>& value() const
|
const Pair<int>& value() const
|
||||||
|
@ -325,9 +325,9 @@ public:
|
|||||||
throw BadCastException("Struct -> Poco::Timestamp");
|
throw BadCastException("Struct -> Poco::Timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Struct<std::string>& value() const
|
const Struct<std::string>& value() const
|
||||||
@ -496,9 +496,9 @@ public:
|
|||||||
throw BadCastException("Struct -> Poco::Timestamp");
|
throw BadCastException("Struct -> Poco::Timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Struct<int>& value() const
|
const Struct<int>& value() const
|
||||||
|
@ -53,6 +53,7 @@ namespace Dynamic {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
class Struct;
|
class Struct;
|
||||||
|
|
||||||
|
|
||||||
class Foundation_API Var
|
class Foundation_API Var
|
||||||
/// Var allows to store data of different types and to convert between these types transparently.
|
/// Var allows to store data of different types and to convert between these types transparently.
|
||||||
/// Var puts forth the best effort to provide intuitive and reasonable conversion semantics and prevent
|
/// Var puts forth the best effort to provide intuitive and reasonable conversion semantics and prevent
|
||||||
@ -88,7 +89,7 @@ class Foundation_API Var
|
|||||||
/// '+', '+=', '-', '-=', '*', '*=' , '/' and '/='
|
/// '+', '+=', '-', '-=', '*', '*=' , '/' and '/='
|
||||||
///
|
///
|
||||||
/// - for integral values, following operations are supported:
|
/// - for integral values, following operations are supported:
|
||||||
/// prefix and postfix increment (++) and decement (--)
|
/// prefix and postfix increment (++) and decrement (--)
|
||||||
///
|
///
|
||||||
/// - for all other types, InvalidArgumentException is thrown upon attempt of an arithmetic operation
|
/// - for all other types, InvalidArgumentException is thrown upon attempt of an arithmetic operation
|
||||||
///
|
///
|
||||||
@ -100,11 +101,15 @@ public:
|
|||||||
/// Creates an empty Var.
|
/// Creates an empty Var.
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Var(const T& val):
|
Var(const T& val)
|
||||||
_pHolder(new VarHolderImpl<T>(val))
|
|
||||||
/// Creates the Var from the given value.
|
/// Creates the Var from the given value.
|
||||||
|
#ifdef POCO_NO_SOO
|
||||||
|
:_pHolder(new VarHolderImpl<T>(val)) { }
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
|
construct(val);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
Var(const char* pVal);
|
Var(const char* pVal);
|
||||||
// Convenience constructor for const char* which gets mapped to a std::string internally, i.e. pVal is deep-copied.
|
// Convenience constructor for const char* which gets mapped to a std::string internally, i.e. pVal is deep-copied.
|
||||||
@ -133,10 +138,12 @@ public:
|
|||||||
/// not available for the given type.
|
/// not available for the given type.
|
||||||
/// Throws InvalidAccessException if Var is empty.
|
/// Throws InvalidAccessException if Var is empty.
|
||||||
{
|
{
|
||||||
if (!_pHolder)
|
VarHolder* pHolder = content();
|
||||||
|
|
||||||
|
if (!pHolder)
|
||||||
throw InvalidAccessException("Can not convert empty value.");
|
throw InvalidAccessException("Can not convert empty value.");
|
||||||
|
|
||||||
_pHolder->convert(val);
|
pHolder->convert(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -153,13 +160,15 @@ public:
|
|||||||
/// not available for the given type.
|
/// not available for the given type.
|
||||||
/// Throws InvalidAccessException if Var is empty.
|
/// Throws InvalidAccessException if Var is empty.
|
||||||
{
|
{
|
||||||
if (!_pHolder)
|
VarHolder* pHolder = content();
|
||||||
|
|
||||||
|
if (!pHolder)
|
||||||
throw InvalidAccessException("Can not convert empty value.");
|
throw InvalidAccessException("Can not convert empty value.");
|
||||||
|
|
||||||
if (typeid(T) == _pHolder->type()) return extract<T>();
|
if (typeid(T) == pHolder->type()) return extract<T>();
|
||||||
|
|
||||||
T result;
|
T result;
|
||||||
_pHolder->convert(result);
|
pHolder->convert(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,15 +186,17 @@ public:
|
|||||||
/// not available for the given type.
|
/// not available for the given type.
|
||||||
/// Throws InvalidAccessException if Var is empty.
|
/// Throws InvalidAccessException if Var is empty.
|
||||||
{
|
{
|
||||||
if (!_pHolder)
|
VarHolder* pHolder = content();
|
||||||
|
|
||||||
|
if (!pHolder)
|
||||||
throw InvalidAccessException("Can not convert empty value.");
|
throw InvalidAccessException("Can not convert empty value.");
|
||||||
|
|
||||||
if (typeid(T) == _pHolder->type())
|
if (typeid(T) == pHolder->type())
|
||||||
return extract<T>();
|
return extract<T>();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
T result;
|
T result;
|
||||||
_pHolder->convert(result);
|
pHolder->convert(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -199,16 +210,18 @@ public:
|
|||||||
/// is thrown.
|
/// is thrown.
|
||||||
/// Throws InvalidAccessException if Var is empty.
|
/// Throws InvalidAccessException if Var is empty.
|
||||||
{
|
{
|
||||||
if (_pHolder && _pHolder->type() == typeid(T))
|
VarHolder* pHolder = content();
|
||||||
|
|
||||||
|
if (pHolder && pHolder->type() == typeid(T))
|
||||||
{
|
{
|
||||||
VarHolderImpl<T>* pHolderImpl = static_cast<VarHolderImpl<T>*>(_pHolder);
|
VarHolderImpl<T>* pHolderImpl = static_cast<VarHolderImpl<T>*>(pHolder);
|
||||||
return pHolderImpl->value();
|
return pHolderImpl->value();
|
||||||
}
|
}
|
||||||
else if (!_pHolder)
|
else if (!pHolder)
|
||||||
throw InvalidAccessException("Can not extract empty value.");
|
throw InvalidAccessException("Can not extract empty value.");
|
||||||
else
|
else
|
||||||
throw BadCastException(format("Can not convert %s to %s.",
|
throw BadCastException(format("Can not convert %s to %s.",
|
||||||
_pHolder->type().name(),
|
pHolder->type().name(),
|
||||||
typeid(T).name()));
|
typeid(T).name()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,8 +229,12 @@ public:
|
|||||||
Var& operator = (const T& other)
|
Var& operator = (const T& other)
|
||||||
/// Assignment operator for assigning POD to Var
|
/// Assignment operator for assigning POD to Var
|
||||||
{
|
{
|
||||||
|
#ifdef POCO_NO_SOO
|
||||||
Var tmp(other);
|
Var tmp(other);
|
||||||
swap(tmp);
|
swap(tmp);
|
||||||
|
#else
|
||||||
|
construct(other);
|
||||||
|
#endif
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,9 +553,11 @@ private:
|
|||||||
template <typename T, typename E>
|
template <typename T, typename E>
|
||||||
VarHolderImpl<T>* holderImpl(const std::string errorMessage = "") const
|
VarHolderImpl<T>* holderImpl(const std::string errorMessage = "") const
|
||||||
{
|
{
|
||||||
if (_pHolder && _pHolder->type() == typeid(T))
|
VarHolder* pHolder = content();
|
||||||
return static_cast<VarHolderImpl<T>*>(_pHolder);
|
|
||||||
else if (!_pHolder)
|
if (pHolder && pHolder->type() == typeid(T))
|
||||||
|
return static_cast<VarHolderImpl<T>*>(pHolder);
|
||||||
|
else if (!pHolder)
|
||||||
throw InvalidAccessException("Can not access empty value.");
|
throw InvalidAccessException("Can not access empty value.");
|
||||||
else
|
else
|
||||||
throw E(errorMessage);
|
throw E(errorMessage);
|
||||||
@ -546,7 +565,64 @@ private:
|
|||||||
|
|
||||||
Var& structIndexOperator(VarHolderImpl<Struct<int> >* pStr, int n) const;
|
Var& structIndexOperator(VarHolderImpl<Struct<int> >* pStr, int n) const;
|
||||||
|
|
||||||
|
#ifdef POCO_NO_SOO
|
||||||
|
|
||||||
|
VarHolder* content() const
|
||||||
|
{
|
||||||
|
return _pHolder;
|
||||||
|
}
|
||||||
|
|
||||||
VarHolder* _pHolder;
|
VarHolder* _pHolder;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
VarHolder* content() const
|
||||||
|
{
|
||||||
|
return _placeholder.content();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename ValueType>
|
||||||
|
void construct(const ValueType& value)
|
||||||
|
{
|
||||||
|
if (sizeof(VarHolderImpl<ValueType>) <= _placeholder.SIZE)
|
||||||
|
{
|
||||||
|
new (reinterpret_cast<VarHolder*>(_placeholder.holder)) VarHolderImpl<ValueType>(value);
|
||||||
|
_placeholder.setLocal(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_placeholder.pHolder = new VarHolderImpl<ValueType>(value);
|
||||||
|
_placeholder.setLocal(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void construct(const char* value)
|
||||||
|
{
|
||||||
|
std::string val(value);
|
||||||
|
if (sizeof(VarHolderImpl<std::string>) <= _placeholder.SIZE)
|
||||||
|
{
|
||||||
|
new (reinterpret_cast<VarHolder*>(_placeholder.holder)) VarHolderImpl<std::string>(val);
|
||||||
|
_placeholder.setLocal(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_placeholder.pHolder = new VarHolderImpl<std::string>(val);
|
||||||
|
_placeholder.setLocal(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void construct(const Var& other)
|
||||||
|
{
|
||||||
|
if(!other.isEmpty())
|
||||||
|
other.content()->clone(&_placeholder);
|
||||||
|
else
|
||||||
|
_placeholder.erase();
|
||||||
|
}
|
||||||
|
|
||||||
|
Placeholder<VarHolder> _placeholder;
|
||||||
|
|
||||||
|
#endif // POCO_NO_SOO
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -559,15 +635,36 @@ private:
|
|||||||
/// Var members
|
/// Var members
|
||||||
///
|
///
|
||||||
|
|
||||||
inline void Var::swap(Var& ptr)
|
inline void Var::swap(Var& other)
|
||||||
{
|
{
|
||||||
std::swap(_pHolder, ptr._pHolder);
|
#ifdef POCO_NO_SOO
|
||||||
|
|
||||||
|
std::swap(_pHolder, other._pHolder);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
if (this == &other) return;
|
||||||
|
|
||||||
|
if (!_placeholder.isLocal() && !other._placeholder.isLocal())
|
||||||
|
{
|
||||||
|
std::swap(_placeholder.pHolder, other._placeholder.pHolder);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Var tmp(*this);
|
||||||
|
if (_placeholder.isLocal()) this->~Var();
|
||||||
|
construct(other);
|
||||||
|
other = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const std::type_info& Var::type() const
|
inline const std::type_info& Var::type() const
|
||||||
{
|
{
|
||||||
return _pHolder ? _pHolder->type() : typeid(void);
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->type() : typeid(void);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -603,49 +700,56 @@ inline bool Var::operator ! () const
|
|||||||
|
|
||||||
inline bool Var::isEmpty() const
|
inline bool Var::isEmpty() const
|
||||||
{
|
{
|
||||||
return 0 == _pHolder;
|
return 0 == content();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Var::isArray() const
|
inline bool Var::isArray() const
|
||||||
{
|
{
|
||||||
return _pHolder ? _pHolder->isArray() : false;
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->isArray() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Var::isStruct() const
|
inline bool Var::isStruct() const
|
||||||
{
|
{
|
||||||
return _pHolder ? _pHolder->isStruct() : false;
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->isStruct() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Var::isInteger() const
|
inline bool Var::isInteger() const
|
||||||
{
|
{
|
||||||
return _pHolder ? _pHolder->isInteger() : false;
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->isInteger() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Var::isSigned() const
|
inline bool Var::isSigned() const
|
||||||
{
|
{
|
||||||
return _pHolder ? _pHolder->isSigned() : false;
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->isSigned() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Var::isNumeric() const
|
inline bool Var::isNumeric() const
|
||||||
{
|
{
|
||||||
return _pHolder ? _pHolder->isNumeric() : false;
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->isNumeric() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool Var::isString() const
|
inline bool Var::isString() const
|
||||||
{
|
{
|
||||||
return _pHolder ? _pHolder->isString() : false;
|
VarHolder* pHolder = content();
|
||||||
|
return pHolder ? pHolder->isString() : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Var non-member functions
|
/// Var non-member functions
|
||||||
///
|
///
|
||||||
|
|
||||||
inline const Var operator + (const char* other, const Var& da)
|
inline const Var operator + (const char* other, const Var& da)
|
||||||
/// Addition operator for adding Var to const char*
|
/// Addition operator for adding Var to const char*
|
||||||
{
|
{
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include "Poco/DateTimeFormatter.h"
|
#include "Poco/DateTimeFormatter.h"
|
||||||
#include "Poco/DateTimeParser.h"
|
#include "Poco/DateTimeParser.h"
|
||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
|
#include "Poco/Any.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
@ -68,6 +69,7 @@ class Var;
|
|||||||
bool Foundation_API isJSONString(const Var& any);
|
bool Foundation_API isJSONString(const Var& any);
|
||||||
/// Returns true for values that should be JSON-formatted as string.
|
/// Returns true for values that should be JSON-formatted as string.
|
||||||
|
|
||||||
|
|
||||||
void Foundation_API appendJSONString(std::string& val, const Var& any);
|
void Foundation_API appendJSONString(std::string& val, const Var& any);
|
||||||
/// Converts the any to a JSON value and adds it to val
|
/// Converts the any to a JSON value and adds it to val
|
||||||
|
|
||||||
@ -92,13 +94,17 @@ public:
|
|||||||
virtual ~VarHolder();
|
virtual ~VarHolder();
|
||||||
/// Destroys the VarHolder.
|
/// Destroys the VarHolder.
|
||||||
|
|
||||||
virtual VarHolder* clone() const;
|
virtual VarHolder* clone(Placeholder<VarHolder>* pHolder = 0) const = 0;
|
||||||
/// Throws NotImplementedException. Implementation should
|
/// Implementation must implement this function to
|
||||||
/// deep-copy the VarHolder.
|
/// deep-copy the VarHolder.
|
||||||
|
/// If small object optimization is enabled (i.e. if
|
||||||
virtual const std::type_info& type() const;
|
/// POCO_NO_SOO is not defined), VarHolder will be
|
||||||
/// Throws NotImplementedException. Implementation should
|
/// instantiated in-place if it's size is smaller
|
||||||
/// return the type information for the stored content.
|
/// than POCO_SMALL_OBJECT_SIZE.
|
||||||
|
|
||||||
|
virtual const std::type_info& type() const = 0;
|
||||||
|
/// Implementation must return the type information
|
||||||
|
/// (typeid) for the stored content.
|
||||||
|
|
||||||
virtual void convert(Int8& val) const;
|
virtual void convert(Int8& val) const;
|
||||||
/// Throws BadCastException. Must be overriden in a type
|
/// Throws BadCastException. Must be overriden in a type
|
||||||
@ -145,12 +151,15 @@ public:
|
|||||||
/// specialization in order to suport the conversion.
|
/// specialization in order to suport the conversion.
|
||||||
|
|
||||||
#ifndef POCO_LONG_IS_64_BIT
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
|
|
||||||
void convert(long& val) const;
|
void convert(long& val) const;
|
||||||
/// Calls convert(Int32).
|
/// Calls convert(Int32).
|
||||||
|
|
||||||
void convert(unsigned long& val) const;
|
void convert(unsigned long& val) const;
|
||||||
/// Calls convert(UInt32).
|
/// Calls convert(UInt32).
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
virtual void convert(bool& val) const;
|
virtual void convert(bool& val) const;
|
||||||
/// Throws BadCastException. Must be overriden in a type
|
/// Throws BadCastException. Must be overriden in a type
|
||||||
/// specialization in order to suport the conversion.
|
/// specialization in order to suport the conversion.
|
||||||
@ -199,6 +208,35 @@ protected:
|
|||||||
VarHolder();
|
VarHolder();
|
||||||
/// Creates the VarHolder.
|
/// Creates the VarHolder.
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
VarHolder* cloneHolder(Placeholder<VarHolder>* pVarHolder, const T& val) const
|
||||||
|
/// Instantiates value holder wrapper. If size of the wrapper is
|
||||||
|
/// larger than POCO_SMALL_OBJECT_SIZE, holder is instantiated on
|
||||||
|
/// the heap, otherwise it is instantiated in-place (in the
|
||||||
|
/// pre-allocated buffer inside the holder).
|
||||||
|
///
|
||||||
|
/// Called from clone() member function of the implementation when
|
||||||
|
/// smal object optimization is enabled.
|
||||||
|
{
|
||||||
|
#ifdef POCO_NO_SOO
|
||||||
|
return new VarHolderImpl<T>(val);
|
||||||
|
#else
|
||||||
|
poco_check_ptr (pVarHolder);
|
||||||
|
if ((sizeof(VarHolderImpl<T>) <= pVarHolder->SIZE))
|
||||||
|
{
|
||||||
|
new ((VarHolder*) pVarHolder->holder) VarHolderImpl<T>(val);
|
||||||
|
pVarHolder->setLocal(true);
|
||||||
|
return (VarHolder*) pVarHolder->holder;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pVarHolder->pHolder = new VarHolderImpl<T>(val);
|
||||||
|
pVarHolder->setLocal(false);
|
||||||
|
return pVarHolder->pHolder;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <typename F, typename T>
|
template <typename F, typename T>
|
||||||
void convertToSmaller(const F& from, T& to) const
|
void convertToSmaller(const F& from, T& to) const
|
||||||
/// This function is meant to convert signed numeric values from
|
/// This function is meant to convert signed numeric values from
|
||||||
@ -338,16 +376,6 @@ private:
|
|||||||
// inlines
|
// inlines
|
||||||
//
|
//
|
||||||
|
|
||||||
inline VarHolder* VarHolder::clone() const
|
|
||||||
{
|
|
||||||
throw NotImplementedException("Not implemented: VarHolder::clone()");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline const std::type_info& VarHolder::type() const
|
|
||||||
{
|
|
||||||
throw NotImplementedException("Not implemented: VarHolder::type()");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void VarHolder::convert(Int8& /*val*/) const
|
inline void VarHolder::convert(Int8& /*val*/) const
|
||||||
{
|
{
|
||||||
@ -414,8 +442,8 @@ inline void VarHolder::convert(Timestamp& /*val*/) const
|
|||||||
throw BadCastException("Can not convert to Timestamp");
|
throw BadCastException("Can not convert to Timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef POCO_LONG_IS_64_BIT
|
#ifndef POCO_LONG_IS_64_BIT
|
||||||
|
|
||||||
inline void VarHolder::convert(long& val) const
|
inline void VarHolder::convert(long& val) const
|
||||||
{
|
{
|
||||||
Int32 tmp;
|
Int32 tmp;
|
||||||
@ -430,8 +458,8 @@ inline void VarHolder::convert(unsigned long& val) const
|
|||||||
convert(tmp);
|
convert(tmp);
|
||||||
val = tmp;
|
val = tmp;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
inline void VarHolder::convert(bool& /*val*/) const
|
inline void VarHolder::convert(bool& /*val*/) const
|
||||||
{
|
{
|
||||||
@ -533,9 +561,9 @@ public:
|
|||||||
return typeid(T);
|
return typeid(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T& value() const
|
const T& value() const
|
||||||
@ -634,9 +662,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Int8& value() const
|
const Int8& value() const
|
||||||
@ -767,9 +795,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Int16& value() const
|
const Int16& value() const
|
||||||
@ -900,9 +928,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Int32& value() const
|
const Int32& value() const
|
||||||
@ -1048,9 +1076,9 @@ public:
|
|||||||
val = Timestamp(_val);
|
val = Timestamp(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Int64& value() const
|
const Int64& value() const
|
||||||
@ -1181,9 +1209,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const UInt8& value() const
|
const UInt8& value() const
|
||||||
@ -1314,9 +1342,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const UInt16& value() const
|
const UInt16& value() const
|
||||||
@ -1447,9 +1475,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const UInt32& value() const
|
const UInt32& value() const
|
||||||
@ -1601,9 +1629,9 @@ public:
|
|||||||
val = Timestamp(tmp);
|
val = Timestamp(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const UInt64& value() const
|
const UInt64& value() const
|
||||||
@ -1732,9 +1760,9 @@ public:
|
|||||||
val = (_val ? "true" : "false");
|
val = (_val ? "true" : "false");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool& value() const
|
const bool& value() const
|
||||||
@ -1866,9 +1894,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const float& value() const
|
const float& value() const
|
||||||
@ -2006,9 +2034,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const double& value() const
|
const double& value() const
|
||||||
@ -2137,9 +2165,9 @@ public:
|
|||||||
val = std::string(1, _val);
|
val = std::string(1, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char& value() const
|
const char& value() const
|
||||||
@ -2316,9 +2344,9 @@ public:
|
|||||||
ts = tmp.timestamp();
|
ts = tmp.timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& value() const
|
const std::string& value() const
|
||||||
@ -2452,9 +2480,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const long& value() const
|
const long& value() const
|
||||||
@ -2585,9 +2613,9 @@ public:
|
|||||||
val = NumberFormatter::format(_val);
|
val = NumberFormatter::format(_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned long& value() const
|
const unsigned long& value() const
|
||||||
@ -2678,9 +2706,9 @@ public:
|
|||||||
val.append(" ]");
|
val.append(" ]");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<T>& value() const
|
const std::vector<T>& value() const
|
||||||
@ -2799,9 +2827,9 @@ public:
|
|||||||
ts = _val.timestamp();
|
ts = _val.timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const DateTime& value() const
|
const DateTime& value() const
|
||||||
@ -2895,9 +2923,9 @@ public:
|
|||||||
ts = _val.timestamp();
|
ts = _val.timestamp();
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const LocalDateTime& value() const
|
const LocalDateTime& value() const
|
||||||
@ -2991,9 +3019,9 @@ public:
|
|||||||
ts = _val;
|
ts = _val;
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Timestamp& value() const
|
const Timestamp& value() const
|
||||||
|
@ -150,7 +150,7 @@ class SmallObjectAllocator <char*>
|
|||||||
///
|
///
|
||||||
/// The treshold between auto and heap allocation
|
/// The treshold between auto and heap allocation
|
||||||
/// is controlled through POCO_SMALL_OBJECT_SIZE compile
|
/// is controlled through POCO_SMALL_OBJECT_SIZE compile
|
||||||
/// time constant, which on 32 or 64 systems defaults
|
/// time constant, which on 32 or 64-bit systems defaults
|
||||||
/// to 31 or 63 bytes respectively. This specialization
|
/// to 31 or 63 bytes respectively. This specialization
|
||||||
/// adds an extra byte to indicate the allocation strategy.
|
/// adds an extra byte to indicate the allocation strategy.
|
||||||
///
|
///
|
||||||
|
@ -220,17 +220,6 @@ namespace Poco {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// Small object size in bytes. Where applicable (e.g.
|
|
||||||
// SmallObjectAllocator<char*> specialization of , Any, etc)
|
|
||||||
// objects longer than this value will be alocated on the heap.
|
|
||||||
// See Poco/SmallObjectAllocator.h for details.
|
|
||||||
#if (POCO_PTR_IS_64_BIT == 1)
|
|
||||||
#define POCO_SMALL_OBJECT_SIZE 63
|
|
||||||
#else
|
|
||||||
#define POCO_SMALL_OBJECT_SIZE 31
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace Poco
|
} // namespace Poco
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,35 +44,64 @@ namespace Poco {
|
|||||||
namespace Dynamic {
|
namespace Dynamic {
|
||||||
|
|
||||||
|
|
||||||
Var::Var(): _pHolder(0)
|
Var::Var()
|
||||||
|
#ifdef POCO_NO_SOO
|
||||||
|
: _pHolder(0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Var::Var(const char* pVal):
|
Var::Var(const char* pVal)
|
||||||
_pHolder(new VarHolderImpl<std::string>(pVal))
|
#ifdef POCO_NO_SOO
|
||||||
|
: _pHolder(new VarHolderImpl<std::string>(pVal)) { }
|
||||||
|
#else
|
||||||
{
|
{
|
||||||
|
construct(std::string(pVal));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Var::Var(const Var& other):
|
Var::Var(const Var& other)
|
||||||
_pHolder(0)
|
#ifdef POCO_NO_SOO
|
||||||
|
: _pHolder(0)
|
||||||
{
|
{
|
||||||
if (other._pHolder)
|
if (other._pHolder)
|
||||||
_pHolder = other._pHolder->clone();
|
_pHolder = other._pHolder->clone();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
if ((this != &other) && !other.isEmpty())
|
||||||
|
construct(other);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
Var::~Var()
|
Var::~Var()
|
||||||
{
|
{
|
||||||
delete _pHolder;
|
if(!isEmpty())
|
||||||
|
{
|
||||||
|
#ifndef POCO_NO_SOO
|
||||||
|
if(_placeholder.isLocal())
|
||||||
|
content()->~VarHolder();
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
delete content();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Var& Var::operator = (const Var& other)
|
Var& Var::operator = (const Var& rhs)
|
||||||
{
|
{
|
||||||
Var tmp(other);
|
#ifdef POCO_NO_SOO
|
||||||
|
Var tmp(rhs);
|
||||||
swap(tmp);
|
swap(tmp);
|
||||||
|
#else
|
||||||
|
if ((this != &rhs) && !rhs.isEmpty())
|
||||||
|
construct(rhs);
|
||||||
|
else if ((this != &rhs) && rhs.isEmpty())
|
||||||
|
_placeholder.erase();
|
||||||
|
#endif
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,8 +349,14 @@ bool Var::operator && (const Var& other) const
|
|||||||
|
|
||||||
void Var::empty()
|
void Var::empty()
|
||||||
{
|
{
|
||||||
|
#ifdef POCO_NO_SOO
|
||||||
delete _pHolder;
|
delete _pHolder;
|
||||||
_pHolder = 0;
|
_pHolder = 0;
|
||||||
|
#else
|
||||||
|
if (_placeholder.isLocal()) this->~Var();
|
||||||
|
else delete content();
|
||||||
|
_placeholder.erase();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,22 +279,22 @@ public:
|
|||||||
|
|
||||||
void convert(DateTime& /*val*/) const
|
void convert(DateTime& /*val*/) const
|
||||||
{
|
{
|
||||||
throw BadCastException();
|
throw BadCastException("Cannot convert Array to DateTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(LocalDateTime& /*ldt*/) const
|
void convert(LocalDateTime& /*ldt*/) const
|
||||||
{
|
{
|
||||||
throw BadCastException();
|
throw BadCastException("Cannot convert Array to LocalDateTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Timestamp& /*ts*/) const
|
void convert(Timestamp& /*ts*/) const
|
||||||
{
|
{
|
||||||
throw BadCastException();
|
throw BadCastException("Cannot convert Array to Timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolder* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const JSON::Array::Ptr& value() const
|
const JSON::Array::Ptr& value() const
|
||||||
|
@ -291,21 +291,24 @@ public:
|
|||||||
void convert(DateTime& /*val*/) const
|
void convert(DateTime& /*val*/) const
|
||||||
{
|
{
|
||||||
//TODO: val = _val;
|
//TODO: val = _val;
|
||||||
|
throw NotImplementedException("Conversion not implemented: JSON:Object => DateTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(LocalDateTime& /*ldt*/) const
|
void convert(LocalDateTime& /*ldt*/) const
|
||||||
{
|
{
|
||||||
//TODO: ldt = _val.timestamp();
|
//TODO: ldt = _val.timestamp();
|
||||||
|
throw NotImplementedException("Conversion not implemented: JSON:Object => LocalDateTime");
|
||||||
}
|
}
|
||||||
|
|
||||||
void convert(Timestamp& /*ts*/) const
|
void convert(Timestamp& /*ts*/) const
|
||||||
{
|
{
|
||||||
//TODO: ts = _val.timestamp();
|
//TODO: ts = _val.timestamp();
|
||||||
|
throw NotImplementedException("Conversion not implemented: JSON:Object => Timestamp");
|
||||||
}
|
}
|
||||||
|
|
||||||
VarHolderImpl* clone() const
|
VarHolder* clone(Placeholder<VarHolder>* pVarHolder = 0) const
|
||||||
{
|
{
|
||||||
return new VarHolderImpl(_val);
|
return cloneHolder(pVarHolder, _val);
|
||||||
}
|
}
|
||||||
|
|
||||||
const JSON::Object::Ptr& value() const
|
const JSON::Object::Ptr& value() const
|
||||||
|
@ -393,8 +393,8 @@ private:
|
|||||||
|
|
||||||
char _memory[sizeof(Poco::Net::Impl::IPv6AddressImpl)];
|
char _memory[sizeof(Poco::Net::Impl::IPv6AddressImpl)];
|
||||||
|
|
||||||
friend class IPv4AddressImpl;
|
friend class Poco::Net::Impl::IPv4AddressImpl;
|
||||||
friend class IPv6AddressImpl;
|
friend class Poco::Net::Impl::IPv6AddressImpl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user