mirror of
https://github.com/pocoproject/poco.git
synced 2025-01-19 00:46:03 +01:00
refactor(Placeholder): more SOO consolidation and optimization
This commit is contained in:
parent
45cbee7c0e
commit
a1819107de
@ -97,8 +97,8 @@ public:
|
||||
|
||||
bool isEmpty() const
|
||||
{
|
||||
char buf[POCO_SMALL_OBJECT_SIZE] = {};
|
||||
return 0 == std::memcmp(holder, buf, POCO_SMALL_OBJECT_SIZE);
|
||||
char buf[SizeV] = {};
|
||||
return 0 == std::memcmp(holder, buf, SizeV);
|
||||
}
|
||||
|
||||
bool isLocal() const
|
||||
@ -106,13 +106,9 @@ public:
|
||||
return holder[SizeV] != 0;
|
||||
}
|
||||
|
||||
void setLocal(bool local) const
|
||||
{
|
||||
holder[SizeV] = local ? 1 : 0;
|
||||
}
|
||||
|
||||
template <typename T, typename V>
|
||||
PlaceholderT* assignStack(const V& value)
|
||||
template<typename T, typename V,
|
||||
typename std::enable_if<TypeSizeLE<T, Placeholder::Size::value>::value>::type* = nullptr>
|
||||
PlaceholderT* assign(const V& value)
|
||||
{
|
||||
erase();
|
||||
new (reinterpret_cast<PlaceholderT*>(holder)) T(value);
|
||||
@ -120,8 +116,9 @@ public:
|
||||
return reinterpret_cast<PlaceholderT*>(holder);
|
||||
}
|
||||
|
||||
template <typename T, typename V>
|
||||
PlaceholderT* assignHeap(const V& value)
|
||||
template<typename T, typename V,
|
||||
typename std::enable_if<TypeSizeGT<T, Placeholder::Size::value>::value>::type* = nullptr>
|
||||
PlaceholderT* assign(const V& value)
|
||||
{
|
||||
erase();
|
||||
pHolder = new T(value);
|
||||
@ -140,6 +137,11 @@ public:
|
||||
private:
|
||||
typedef typename std::aligned_storage<SizeV+1>::type AlignerType;
|
||||
|
||||
void setLocal(bool local) const
|
||||
{
|
||||
holder[SizeV] = local ? 1 : 0;
|
||||
}
|
||||
|
||||
void destruct(bool clear)
|
||||
{
|
||||
if (!isEmpty())
|
||||
@ -189,13 +191,7 @@ private:
|
||||
}
|
||||
|
||||
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)
|
||||
PlaceholderT* assign(const V& value)
|
||||
{
|
||||
erase();
|
||||
return pHolder = new T(value);
|
||||
@ -346,27 +342,13 @@ private:
|
||||
|
||||
virtual void clone(Placeholder<ValueHolder>* pPlaceholder) const
|
||||
{
|
||||
cloneSOO(pPlaceholder, _held);
|
||||
pPlaceholder->assign<Holder<ValueType>, ValueType>(_held);
|
||||
}
|
||||
|
||||
ValueType _held;
|
||||
|
||||
private:
|
||||
|
||||
template<typename VT,
|
||||
typename std::enable_if<TypeSizeLE<Holder<VT>, Placeholder<VT>::Size::value>::value>::type* = nullptr>
|
||||
static void cloneSOO(Placeholder<ValueHolder>* pPlaceholder, VT& held)
|
||||
{
|
||||
pPlaceholder->assignStack<Holder<ValueType>, ValueType>(held);
|
||||
}
|
||||
|
||||
template<typename VT,
|
||||
typename std::enable_if<TypeSizeGT<Holder<VT>, Placeholder<VT>::Size::value>::value>::type* = nullptr>
|
||||
static void cloneSOO(Placeholder<ValueHolder>* pPlaceholder, VT& held)
|
||||
{
|
||||
pPlaceholder->assignHeap<Holder<ValueType>, ValueType>(held);
|
||||
}
|
||||
|
||||
Holder & operator = (const Holder &);
|
||||
};
|
||||
|
||||
@ -375,18 +357,10 @@ private:
|
||||
return _valueHolder.content();
|
||||
}
|
||||
|
||||
template<typename ValueType,
|
||||
typename std::enable_if<TypeSizeLE<Holder<ValueType>, Placeholder<ValueType>::Size::value>::value>::type* = nullptr>
|
||||
template<typename ValueType>
|
||||
void construct(const ValueType& value)
|
||||
{
|
||||
_valueHolder.assignStack<Holder<ValueType>, ValueType>(value);
|
||||
}
|
||||
|
||||
template<typename ValueType,
|
||||
typename std::enable_if<TypeSizeGT<Holder<ValueType>, Placeholder<ValueType>::Size::value>::value>::type* = nullptr>
|
||||
void construct(const ValueType& value)
|
||||
{
|
||||
_valueHolder.assignHeap<Holder<ValueType>, ValueType>(value);
|
||||
_valueHolder.assign<Holder<ValueType>, ValueType>(value);
|
||||
}
|
||||
|
||||
void construct(const Any& other)
|
||||
|
@ -71,12 +71,7 @@
|
||||
// cases when value holder fits into POCO_SMALL_OBJECT_SIZE
|
||||
// (see below).
|
||||
//
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!! NOTE: Any/Dynamic::Var SOO will NOT work reliably !!!
|
||||
// !!! without C++11 (std::aligned_storage in particular). !!!
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
//
|
||||
//#define POCO_NO_SOO
|
||||
// #define POCO_NO_SOO
|
||||
|
||||
|
||||
// Small object size in bytes. When assigned to Any or Var,
|
||||
|
@ -225,6 +225,7 @@ public:
|
||||
Var& operator = (const T& other)
|
||||
/// Assignment operator for assigning POD to Var
|
||||
{
|
||||
clear();
|
||||
construct(other);
|
||||
return *this;
|
||||
}
|
||||
@ -610,35 +611,20 @@ private:
|
||||
{
|
||||
}
|
||||
|
||||
template<typename ValueType,
|
||||
typename std::enable_if<TypeSizeLE<VarHolderImpl<ValueType>, Placeholder<ValueType>::Size::value>::value>::type* = nullptr>
|
||||
void constructSOO(const ValueType& value)
|
||||
{
|
||||
_placeholder.assignStack<VarHolderImpl<ValueType>, ValueType>(value);
|
||||
}
|
||||
|
||||
template<typename ValueType,
|
||||
typename std::enable_if<TypeSizeGT<VarHolderImpl<ValueType>, Placeholder<ValueType>::Size::value>::value>::type* = nullptr>
|
||||
void constructSOO(const ValueType& value)
|
||||
{
|
||||
_placeholder.assignHeap<VarHolderImpl<ValueType>, ValueType>(value);
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void construct(const ValueType& value)
|
||||
{
|
||||
constructSOO(value);
|
||||
_placeholder.assign<VarHolderImpl<ValueType>, ValueType>(value);
|
||||
}
|
||||
|
||||
void construct(const char* value)
|
||||
{
|
||||
std::string val(value);
|
||||
constructSOO(val);
|
||||
_placeholder.assign<VarHolderImpl<std::string>, std::string>(val);
|
||||
}
|
||||
|
||||
void construct(const Var& other)
|
||||
{
|
||||
_placeholder.erase();
|
||||
if (!other.isEmpty())
|
||||
other.content()->clone(&_placeholder);
|
||||
}
|
||||
|
@ -306,7 +306,7 @@ protected:
|
||||
/// pre-allocated buffer inside the holder).
|
||||
{
|
||||
poco_check_ptr (pVarHolder);
|
||||
return makeSOOHolder(pVarHolder, val);
|
||||
return pVarHolder->assign<VarHolderImpl<T>, T>(val);
|
||||
}
|
||||
|
||||
template <typename F, typename T>
|
||||
@ -406,21 +406,6 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
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
|
||||
{
|
||||
poco_check_ptr (pVarHolder);
|
||||
return pVarHolder->assignStack<VarHolderImpl<T>, T>(val);
|
||||
}
|
||||
|
||||
template<typename T,
|
||||
typename std::enable_if<TypeSizeGT<VarHolderImpl<T>, Placeholder<T>::Size::value>::value>::type* = nullptr>
|
||||
VarHolder* makeSOOHolder(Placeholder<VarHolder>* pVarHolder, const T& val) const
|
||||
{
|
||||
poco_check_ptr (pVarHolder);
|
||||
return pVarHolder->assignHeap<VarHolderImpl<T>, T>(val);
|
||||
}
|
||||
|
||||
template <typename F, typename T>
|
||||
void checkUpperLimit(const F& from) const
|
||||
|
@ -52,11 +52,8 @@ Var::~Var()
|
||||
Var& Var::operator = (const Var& rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
if (!rhs.isEmpty())
|
||||
construct(rhs);
|
||||
else
|
||||
_placeholder.erase();
|
||||
|
||||
clear();
|
||||
if (!rhs.isEmpty()) construct(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -281,73 +281,43 @@ void AnyTest::testPlaceholder()
|
||||
assertTrue(ph.isEmpty());
|
||||
assertFalse(ph.isLocal());
|
||||
|
||||
char c = *ph.assignStack<char, char>(1);
|
||||
char c = *ph.assign<char, char>(1);
|
||||
assertTrue(1 == c);
|
||||
assertFalse(ph.isEmpty());
|
||||
assertTrue(ph.isLocal());
|
||||
|
||||
c = *ph.assignHeap<char, char>(2);
|
||||
assertTrue(2 == c);
|
||||
assertFalse(ph.isEmpty());
|
||||
assertFalse(ph.isLocal());
|
||||
|
||||
ph.erase();
|
||||
assertTrue(ph.isEmpty());
|
||||
assertFalse(ph.isLocal());
|
||||
|
||||
if (sizeof(std::shared_ptr<int>) <= POCO_SMALL_OBJECT_SIZE)
|
||||
{
|
||||
Placeholder<std::shared_ptr<int>> sph;
|
||||
assertTrue(sph.isEmpty());
|
||||
assertFalse(sph.isLocal());
|
||||
|
||||
int i = **sph.assignStack<std::shared_ptr<int>, int*>(new int(1));
|
||||
int i = **sph.assign<std::shared_ptr<int>, int*>(new int(1));
|
||||
assertTrue(1 == i);
|
||||
assertFalse(sph.isEmpty());
|
||||
assertTrue(sph.isLocal());
|
||||
|
||||
i = **sph.assignHeap<std::shared_ptr<int>, int*>(new int(1));
|
||||
assertTrue(1 == i);
|
||||
assertFalse(sph.isEmpty());
|
||||
assertFalse(sph.isLocal());
|
||||
}
|
||||
|
||||
if (sizeof(Poco::SharedPtr<int>) <= POCO_SMALL_OBJECT_SIZE)
|
||||
{
|
||||
Placeholder<Poco::SharedPtr<int>> psph;
|
||||
assertTrue(psph.isEmpty());
|
||||
assertFalse(psph.isLocal());
|
||||
|
||||
int i = **psph.assignStack<Poco::SharedPtr<int>, int*>(new int(1));
|
||||
assertTrue(1 == i);
|
||||
i = **psph.assign<Poco::SharedPtr<int>, int*>(new int(2));
|
||||
assertTrue(2 == i);
|
||||
assertFalse(psph.isEmpty());
|
||||
assertTrue(psph.isLocal());
|
||||
|
||||
i = **psph.assignHeap<Poco::SharedPtr<int>, int*>(new int(1));
|
||||
assertTrue(1 == i);
|
||||
assertFalse(psph.isEmpty());
|
||||
assertFalse(psph.isLocal());
|
||||
}
|
||||
|
||||
if (sizeof(std::vector<int>) <= POCO_SMALL_OBJECT_SIZE)
|
||||
{
|
||||
Placeholder<std::vector<int>> vph;
|
||||
assertTrue(vph.isEmpty());
|
||||
assertFalse(vph.isLocal());
|
||||
|
||||
std::vector<int> inv{1,2,3};
|
||||
std::vector<int> outv = *vph.assignStack<std::vector<int>, std::vector<int>>(inv);
|
||||
std::vector<int> outv = *vph.assign<std::vector<int>, std::vector<int>>(inv);
|
||||
assertTrue(inv == outv);
|
||||
assertFalse(vph.isEmpty());
|
||||
assertTrue(vph.isLocal());
|
||||
|
||||
outv.clear();
|
||||
outv = *vph.assignHeap<std::vector<int>, std::vector<int>>(inv);
|
||||
assertTrue(inv == outv);
|
||||
assertFalse(vph.isEmpty());
|
||||
assertFalse(vph.isLocal());
|
||||
}
|
||||
|
||||
// ...
|
||||
#endif
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user