refactor(Placeholder): ifdef POCO_NO_SOO only in Placeholder and remove it anywhere else (#3566)

This commit is contained in:
Aleksandar Fabijanic 2022-04-18 14:28:27 -05:00 committed by GitHub
parent 4f5b7c1891
commit 45cbee7c0e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 65 additions and 232 deletions

View File

@ -23,6 +23,17 @@ jobs:
EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB" EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB"
./ci/runtests.sh ./ci/runtests.sh
linux-gcc-make-asan-no-soo:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- run: sudo apt update && sudo apt install libssl-dev unixodbc-dev libmysqlclient-dev redis-server
- run: ./configure --everything --omit=PDF --no-soo && make all -s -j4 SANITIZEFLAGS=-fsanitize=address && sudo make install
- run: >-
sudo -s
EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB"
./ci/runtests.sh
linux-gcc-make-ubsan: linux-gcc-make-ubsan:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
steps: steps:

View File

@ -48,9 +48,6 @@ struct TypeSizeGT:
std::integral_constant<bool, (sizeof(T) > S)>{}; std::integral_constant<bool, (sizeof(T) > S)>{};
#ifndef POCO_NO_SOO
template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE> template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE>
union Placeholder union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small /// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
@ -73,6 +70,8 @@ public:
Placeholder& operator=(const Placeholder&) = delete; Placeholder& operator=(const Placeholder&) = delete;
Placeholder& operator=(Placeholder&&) = delete; Placeholder& operator=(Placeholder&&) = delete;
#ifndef POCO_NO_SOO
Placeholder(): pHolder(0) Placeholder(): pHolder(0)
{ {
std::memset(holder, 0, sizeof(Placeholder)); std::memset(holder, 0, sizeof(Placeholder));
@ -154,51 +153,62 @@ private:
} }
} }
PlaceholderT* pHolder;
mutable unsigned char holder[SizeV+1]; mutable unsigned char holder[SizeV+1];
AlignerType aligner; AlignerType aligner;
};
#else // POCO_NO_SOO
#else // !POCO_NO_SOO Placeholder(): pHolder(0)
template <typename PlaceholderT>
union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
/// object optimization, when enabled).
///
/// 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:
Placeholder ()
{ {
} }
~Placeholder()
{
delete pHolder;
}
void swap(Placeholder& other)
{
std::swap(pHolder, other.pHolder);
}
void erase()
{
delete pHolder;
pHolder = 0;
}
bool isEmpty() const
{
return 0 == pHolder;
}
bool isLocal() const
{
return false;
}
template <typename T, typename V>
PlaceholderT* assignStack(const V& value)
{
return assignHeap<T, V>(value);
}
template <typename T, typename V>
PlaceholderT* assignHeap(const V& value)
{
erase();
return pHolder = new T(value);
}
PlaceholderT* content() const PlaceholderT* content() const
{ {
return pHolder; return pHolder;
} }
// MSVC71,80 won't extend friendship to nested class (Any::Holder)
#if !defined(POCO_MSVC_VERSION) || (defined(POCO_MSVC_VERSION) && (POCO_MSVC_VERSION > 80))
private:
#endif
PlaceholderT* pHolder;
friend class Any;
friend class Dynamic::Var;
friend class Dynamic::VarHolder;
template <class> friend class Dynamic::VarHolderImpl;
};
#endif // POCO_NO_SOO #endif // POCO_NO_SOO
PlaceholderT* pHolder;
};
class Any class Any
@ -213,8 +223,6 @@ class Any
{ {
public: public:
#ifndef POCO_NO_SOO
Any() Any()
/// Creates an empty any type. /// Creates an empty any type.
{ {
@ -391,123 +399,6 @@ private:
Placeholder<ValueHolder> _valueHolder; Placeholder<ValueHolder> _valueHolder;
#else // if POCO_NO_SOO
Any(): _pHolder(0)
/// Creates an empty any type.
{
}
template <typename ValueType>
Any(const ValueType& value):
_pHolder(new Holder<ValueType>(value))
/// Creates an any which stores the init parameter inside.
///
/// Example:
/// Any a(13);
/// Any a(string("12345"));
{
}
Any(const Any& other):
_pHolder(other._pHolder ? other._pHolder->clone() : 0)
/// Copy constructor, works with both empty and initialized Any values.
{
}
~Any()
{
delete _pHolder;
}
Any& swap(Any& rhs)
/// Swaps the content of the two Anys.
{
std::swap(_pHolder, rhs._pHolder);
return *this;
}
template <typename ValueType>
Any& operator = (const ValueType& rhs)
/// Assignment operator for all types != Any.
///
/// Example:
/// Any a = 13;
/// Any a = string("12345");
{
Any(rhs).swap(*this);
return *this;
}
Any& operator = (const Any& rhs)
/// Assignment operator for Any.
{
Any(rhs).swap(*this);
return *this;
}
bool empty() const
/// Returns true if the Any is empty.
{
return !_pHolder;
}
const std::type_info& type() const
/// 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 _pHolder ? _pHolder->type() : typeid(void);
}
private:
class ValueHolder
{
public:
virtual ~ValueHolder() = default;
virtual const std::type_info& type() const = 0;
virtual ValueHolder* clone() const = 0;
};
template <typename ValueType>
class Holder: public ValueHolder
{
public:
Holder(const ValueType& value):
_held(value)
{
}
virtual const std::type_info& type() const
{
return typeid(ValueType);
}
virtual ValueHolder* clone() const
{
return new Holder(_held);
}
ValueType _held;
private:
Holder & operator = (const Holder &);
};
ValueHolder* content() const
{
return _pHolder;
}
private:
ValueHolder* _pHolder;
#endif // POCO_NO_SOO
template <typename ValueType> template <typename ValueType>
friend ValueType* AnyCast(Any*); friend ValueType* AnyCast(Any*);

View File

@ -83,7 +83,7 @@
// objects larger than this value will be alocated on the heap, // objects larger than this value will be alocated on the heap,
// while those smaller will be placement new-ed into an // while those smaller will be placement new-ed into an
// internal stack-auto-allocated buffer. // internal stack-auto-allocated buffer.
#if !defined(POCO_SMALL_OBJECT_SIZE) && !defined(POCO_NO_SOO) #if !defined(POCO_SMALL_OBJECT_SIZE)
#define POCO_SMALL_OBJECT_SIZE 32 #define POCO_SMALL_OBJECT_SIZE 32
#endif #endif

View File

@ -91,15 +91,9 @@ public:
template <typename T> template <typename T>
Var(const T& val) Var(const 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); 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.
@ -231,12 +225,7 @@ 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);
swap(tmp);
#else
construct(other); construct(other);
#endif
return *this; return *this;
} }
@ -612,22 +601,6 @@ private:
return pStr->operator[](n); return pStr->operator[](n);
} }
#ifdef POCO_NO_SOO
VarHolder* content() const
{
return _pHolder;
}
void destruct()
{
delete _pHolder;
}
VarHolder* _pHolder = nullptr;
#else
VarHolder* content() const VarHolder* content() const
{ {
return _placeholder.content(); return _placeholder.content();
@ -671,8 +644,6 @@ private:
} }
Placeholder<VarHolder> _placeholder; Placeholder<VarHolder> _placeholder;
#endif // POCO_NO_SOO
}; };
@ -687,12 +658,6 @@ private:
inline void Var::swap(Var& other) inline void Var::swap(Var& other)
{ {
#ifdef POCO_NO_SOO
std::swap(_pHolder, other._pHolder);
#else
if (this == &other) return; if (this == &other) return;
if (!_placeholder.isLocal() && !other._placeholder.isLocal()) if (!_placeholder.isLocal() && !other._placeholder.isLocal())
@ -713,8 +678,6 @@ inline void Var::swap(Var& other)
throw; throw;
} }
} }
#endif
} }

View File

@ -305,13 +305,8 @@ protected:
/// the heap, otherwise it is instantiated in-place (in the /// the heap, otherwise it is instantiated in-place (in the
/// pre-allocated buffer inside the holder). /// pre-allocated buffer inside the holder).
{ {
#ifdef POCO_NO_SOO
(void)pVarHolder;
return new VarHolderImpl<T>(val);
#else
poco_check_ptr (pVarHolder); poco_check_ptr (pVarHolder);
return makeSOOHolder(pVarHolder, val); return makeSOOHolder(pVarHolder, val);
#endif
} }
template <typename F, typename T> template <typename F, typename T>
@ -411,8 +406,6 @@ protected:
} }
private: private:
#ifndef POCO_NO_SOO
template<typename T, template<typename T,
typename std::enable_if<TypeSizeLE<VarHolderImpl<T>, Placeholder<T>::Size::value>::value>::type* = nullptr> typename std::enable_if<TypeSizeLE<VarHolderImpl<T>, Placeholder<T>::Size::value>::value>::type* = nullptr>
VarHolder* makeSOOHolder(Placeholder<VarHolder>* pVarHolder, const T& val) const VarHolder* makeSOOHolder(Placeholder<VarHolder>* pVarHolder, const T& val) const
@ -428,7 +421,6 @@ private:
poco_check_ptr (pVarHolder); poco_check_ptr (pVarHolder);
return pVarHolder->assignHeap<VarHolderImpl<T>, T>(val); return pVarHolder->assignHeap<VarHolderImpl<T>, T>(val);
} }
#endif
template <typename F, typename T> template <typename F, typename T>
void checkUpperLimit(const F& from) const void checkUpperLimit(const F& from) const

View File

@ -26,38 +26,21 @@ namespace Dynamic {
Var::Var() Var::Var()
#ifdef POCO_NO_SOO
: _pHolder(0)
#endif
{ {
} }
Var::Var(const char* pVal) Var::Var(const char* pVal)
#ifdef POCO_NO_SOO
: _pHolder(new VarHolderImpl<std::string>(pVal))
{
}
#else
{ {
construct(std::string(pVal)); construct(std::string(pVal));
} }
#endif
Var::Var(const Var& other) Var::Var(const Var& other)
#ifdef POCO_NO_SOO
:_pHolder((this != &other) ?
(other._pHolder ? other._pHolder->clone() : nullptr) :
other._pHolder)
{
}
#else
{ {
if ((this != &other) && !other.isEmpty()) if ((this != &other) && !other.isEmpty())
construct(other); construct(other);
} }
#endif
Var::~Var() Var::~Var()
@ -68,16 +51,12 @@ Var::~Var()
Var& Var::operator = (const Var& rhs) Var& Var::operator = (const Var& rhs)
{ {
#ifdef POCO_NO_SOO
Var tmp(rhs);
swap(tmp);
#else
if (this == &rhs) return *this; if (this == &rhs) return *this;
if (!rhs.isEmpty()) if (!rhs.isEmpty())
construct(rhs); construct(rhs);
else else
_placeholder.erase(); _placeholder.erase();
#endif
return *this; return *this;
} }
@ -329,23 +308,13 @@ bool Var::operator && (const Var& other) const
void Var::empty() void Var::empty()
{ {
#ifdef POCO_NO_SOO
delete _pHolder;
_pHolder = 0;
#else
_placeholder.erase(); _placeholder.erase();
#endif
} }
void Var::clear() void Var::clear()
{ {
#ifdef POCO_NO_SOO
delete _pHolder;
_pHolder = 0;
#else
_placeholder.erase(); _placeholder.erase();
#endif
} }

7
configure vendored
View File

@ -74,6 +74,10 @@ Options:
Compile with -DPOCO_NET_NO_IPv6. Compile with -DPOCO_NET_NO_IPv6.
For systems that don't support IPv6. For systems that don't support IPv6.
--no-soo
Compile with -DPOCO_NO_SOO.
Disables small object optimization.
--sqlite-fts=<path> --sqlite-fts=<path>
Compile with -DPOCO_DATA_SQLITE_FTS. Compile with -DPOCO_DATA_SQLITE_FTS.
Compile SQLite with Full Text Search support. Compile SQLite with Full Text Search support.
@ -226,6 +230,9 @@ while [ $# -ge 1 ]; do
--no-ipv6) --no-ipv6)
flags="$flags -DPOCO_NET_NO_IPv6" ;; flags="$flags -DPOCO_NET_NO_IPv6" ;;
--no-soo)
flags="$flags -DPOCO_NO_SOO" ;;
--sqlite-thread-safe=*) --sqlite-thread-safe=*)
flags="$flags -DSQLITE_THREADSAFE=`echo ${1} | awk '{print substr($0,22)}'`" ;; flags="$flags -DSQLITE_THREADSAFE=`echo ${1} | awk '{print substr($0,22)}'`" ;;