Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(Placeholder): ifdef POCO_NO_SOO only in Placeholder and remo… #3566

Merged
merged 1 commit into from Apr 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Expand Up @@ -23,6 +23,17 @@ jobs:
EXCLUDE_TESTS="Data/MySQL Data/ODBC Data/PostgreSQL MongoDB"
./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:
runs-on: ubuntu-20.04
steps:
Expand Down
191 changes: 41 additions & 150 deletions Foundation/include/Poco/Any.h
Expand Up @@ -48,9 +48,6 @@ struct TypeSizeGT:
std::integral_constant<bool, (sizeof(T) > S)>{};


#ifndef POCO_NO_SOO


template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE>
union Placeholder
/// ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
Expand All @@ -73,6 +70,8 @@ union Placeholder
Placeholder& operator=(const Placeholder&) = delete;
Placeholder& operator=(Placeholder&&) = delete;

#ifndef POCO_NO_SOO

Placeholder(): pHolder(0)
{
std::memset(holder, 0, sizeof(Placeholder));
Expand Down Expand Up @@ -154,51 +153,62 @@ union Placeholder
}
}

PlaceholderT* pHolder;
mutable unsigned char holder[SizeV+1];
AlignerType aligner;
};

#else // POCO_NO_SOO

#else // !POCO_NO_SOO
Placeholder(): pHolder(0)
{
}

~Placeholder()
{
delete pHolder;
}

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 ()
void swap(Placeholder& other)
{
std::swap(pHolder, other.pHolder);
}

PlaceholderT* content() const
void erase()
{
return pHolder;
delete pHolder;
pHolder = 0;
}

// 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
bool isEmpty() const
{
return 0 == pHolder;
}

PlaceholderT* pHolder;
bool isLocal() const
{
return false;
}

friend class Any;
friend class Dynamic::Var;
friend class Dynamic::VarHolder;
template <class> friend class Dynamic::VarHolderImpl;
};
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
{
return pHolder;
}

#endif // POCO_NO_SOO
PlaceholderT* pHolder;
};


class Any
Expand All @@ -213,8 +223,6 @@ class Any
{
public:

#ifndef POCO_NO_SOO

Any()
/// Creates an empty any type.
{
Expand Down Expand Up @@ -391,123 +399,6 @@ class Any

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>
friend ValueType* AnyCast(Any*);

Expand Down
2 changes: 1 addition & 1 deletion Foundation/include/Poco/Config.h
Expand Up @@ -83,7 +83,7 @@
// objects larger than this value will be alocated on the heap,
// while those smaller will be placement new-ed into an
// 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
#endif

Expand Down
37 changes: 0 additions & 37 deletions Foundation/include/Poco/Dynamic/Var.h
Expand Up @@ -91,15 +91,9 @@ class Foundation_API Var
template <typename T>
Var(const T& val)
/// Creates the Var from the given value.
#ifdef POCO_NO_SOO
: _pHolder(new VarHolderImpl<T>(val))
{
}
#else
{
construct(val);
}
#endif

Var(const char* pVal);
// Convenience constructor for const char* which gets mapped to a std::string internally, i.e. pVal is deep-copied.
Expand Down Expand Up @@ -231,12 +225,7 @@ class Foundation_API Var
Var& operator = (const T& other)
/// Assignment operator for assigning POD to Var
{
#ifdef POCO_NO_SOO
Var tmp(other);
swap(tmp);
#else
construct(other);
#endif
return *this;
}

Expand Down Expand Up @@ -612,22 +601,6 @@ class Foundation_API Var
return pStr->operator[](n);
}

#ifdef POCO_NO_SOO

VarHolder* content() const
{
return _pHolder;
}

void destruct()
{
delete _pHolder;
}

VarHolder* _pHolder = nullptr;

#else

VarHolder* content() const
{
return _placeholder.content();
Expand Down Expand Up @@ -671,8 +644,6 @@ class Foundation_API Var
}

Placeholder<VarHolder> _placeholder;

#endif // POCO_NO_SOO
};


Expand All @@ -687,12 +658,6 @@ class Foundation_API Var

inline void Var::swap(Var& other)
{
#ifdef POCO_NO_SOO

std::swap(_pHolder, other._pHolder);

#else

if (this == &other) return;

if (!_placeholder.isLocal() && !other._placeholder.isLocal())
Expand All @@ -713,8 +678,6 @@ inline void Var::swap(Var& other)
throw;
}
}

#endif
}


Expand Down
8 changes: 0 additions & 8 deletions Foundation/include/Poco/Dynamic/VarHolder.h
Expand Up @@ -305,13 +305,8 @@ class Foundation_API VarHolder
/// the heap, otherwise it is instantiated in-place (in the
/// pre-allocated buffer inside the holder).
{
#ifdef POCO_NO_SOO
(void)pVarHolder;
return new VarHolderImpl<T>(val);
#else
poco_check_ptr (pVarHolder);
return makeSOOHolder(pVarHolder, val);
#endif
}

template <typename F, typename T>
Expand Down Expand Up @@ -411,8 +406,6 @@ class Foundation_API VarHolder
}

private:

#ifndef POCO_NO_SOO
template<typename T,
typename std::enable_if<TypeSizeLE<VarHolderImpl<T>, Placeholder<T>::Size::value>::value>::type* = nullptr>
VarHolder* makeSOOHolder(Placeholder<VarHolder>* pVarHolder, const T& val) const
Expand All @@ -428,7 +421,6 @@ class Foundation_API VarHolder
poco_check_ptr (pVarHolder);
return pVarHolder->assignHeap<VarHolderImpl<T>, T>(val);
}
#endif

template <typename F, typename T>
void checkUpperLimit(const F& from) const
Expand Down