4848namespace Poco {
4949
5050
51+ namespace Dynamic {
52+
53+ class Var ;
54+ class VarHolder ;
55+ template <class > class VarHolderImpl ;
56+
57+ }
58+
59+
60+ template <typename PlaceholderT, unsigned int SizeV = POCO_SMALL_OBJECT_SIZE>
61+ union Placeholder
62+ // / ValueHolder union (used by Poco::Any and Poco::Dynamic::Var for small
63+ // / object optimization).
64+ // /
65+ // / If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE bytes of storage,
66+ // / it will be placement-new-allocated into the local buffer
67+ // / (i.e. there will be no heap-allocation). The local buffer size is one byte
68+ // / larger - [POCO_SMALL_OBJECT_SIZE + 1], additional byte value indicating
69+ // / where the object was allocated (0 => heap, 1 => local).
70+ {
71+ public:
72+ static const unsigned int SIZE = SizeV;
73+
74+ Placeholder ()
75+ {
76+ erase ();
77+ }
78+
79+ void erase ()
80+ {
81+ std::memset (holder, 0 , sizeof (Placeholder));
82+ }
83+
84+ bool isLocal () const
85+ {
86+ return holder[SIZE] != 0 ;
87+ }
88+
89+ void setLocal (bool local) const
90+ {
91+ holder[SIZE] = local ? 1 : 0 ;
92+ }
93+
94+ PlaceholderT* content () const
95+ {
96+ if (isLocal ())
97+ return reinterpret_cast <PlaceholderT*>(holder);
98+ else
99+ return pHolder;
100+ }
101+
102+ private:
103+ PlaceholderT* pHolder;
104+ mutable unsigned char holder[SIZE + 1 ];
105+
106+ friend class Any ;
107+ friend class Dynamic ::Var;
108+ friend class Dynamic ::VarHolder;
109+ template <class > friend class VarHolderImpl ;
110+ };
111+
112+
51113class Any
52114 // / An Any class represents a general type and is capable of storing any type, supporting type-safe extraction
53115 // / of the internally stored data.
@@ -58,13 +120,10 @@ class Any
58120 // / Modified for small object optimization support (optionally supported through conditional compilation)
59121 // / by Alex Fabijanic.
60122{
123+ public:
61124
62125#ifndef POCO_NO_SOO
63126
64- union PH;
65-
66- public:
67-
68127 Any ()
69128 // / Creates an empty any type.
70129 {
@@ -75,8 +134,8 @@ class Any
75134 // / Creates an any which stores the init parameter inside.
76135 // /
77136 // / Example:
78- // / Any a(13);
79- // / Any a(string("12345"));
137+ // / Any a(13);
138+ // / Any a(string("12345"));
80139 {
81140 construct (value);
82141 }
@@ -89,13 +148,13 @@ class Any
89148 }
90149
91150 ~Any ()
92- // / Destructor. If Any is locally held, calls Placeholder destructor;
151+ // / Destructor. If Any is locally held, calls ValueHolder destructor;
93152 // / otherwise, deletes the placeholder from the heap.
94153 {
95154 if (!empty ())
96155 {
97- if (_placeholder .isLocal ())
98- content ()->~Placeholder ();
156+ if (_valueHolder .isLocal ())
157+ content ()->~ValueHolder ();
99158 else
100159 delete content ();
101160 }
@@ -110,14 +169,14 @@ class Any
110169 {
111170 if (this == &other) return *this ;
112171
113- if (!_placeholder .isLocal () && !other._placeholder .isLocal ())
172+ if (!_valueHolder .isLocal () && !other._valueHolder .isLocal ())
114173 {
115- std::swap (_placeholder .pHolder , other._placeholder .pHolder );
174+ std::swap (_valueHolder .pHolder , other._valueHolder .pHolder );
116175 }
117176 else
118177 {
119178 Any tmp (*this );
120- if (_placeholder .isLocal ()) this ->~Any ();
179+ if (_valueHolder .isLocal ()) this ->~Any ();
121180 construct (other);
122181 other = tmp;
123182 }
@@ -143,7 +202,7 @@ class Any
143202 if ((this != &rhs) && !rhs.empty ())
144203 construct (rhs);
145204 else if ((this != &rhs) && rhs.empty ())
146- _placeholder .erase ();
205+ _valueHolder .erase ();
147206
148207 return *this ;
149208 }
@@ -152,7 +211,7 @@ class Any
152211 // / Returns true if the Any is empty.
153212 {
154213 char buf[POCO_SMALL_OBJECT_SIZE] = { 0 };
155- return 0 == std::memcmp (_placeholder .holder , buf, POCO_SMALL_OBJECT_SIZE );
214+ return 0 == std::memcmp (_valueHolder .holder , buf, _valueHolder. SIZE );
156215 }
157216
158217 const std::type_info & type () const
@@ -166,20 +225,20 @@ class Any
166225
167226private:
168227
169- class Placeholder
228+ class ValueHolder
170229 {
171230 public:
172231
173- virtual ~Placeholder ()
232+ virtual ~ValueHolder ()
174233 {
175234 }
176235
177236 virtual const std::type_info & type () const = 0;
178- virtual void clone (Any::PH *) const = 0;
237+ virtual void clone (Placeholder<ValueHolder> *) const = 0;
179238 };
180239
181240 template <typename ValueType>
182- class Holder : public Placeholder
241+ class Holder : public ValueHolder
183242 {
184243 public:
185244 Holder (const ValueType & value) : _held(value)
@@ -191,11 +250,11 @@ class Any
191250 return typeid (ValueType);
192251 }
193252
194- virtual void clone (Any::PH * pPlaceholder) const
253+ virtual void clone (Placeholder<ValueHolder> * pPlaceholder) const
195254 {
196- if ((sizeof (Holder<ValueType>) <= POCO_SMALL_OBJECT_SIZE ))
255+ if ((sizeof (Holder<ValueType>) <= pPlaceholder-> SIZE ))
197256 {
198- new ((Placeholder *) pPlaceholder->holder ) Holder (_held);
257+ new ((ValueHolder *) pPlaceholder->holder ) Holder (_held);
199258 pPlaceholder->setLocal (true );
200259 }
201260 else
@@ -211,78 +270,40 @@ class Any
211270 Holder & operator = (const Holder &);
212271 };
213272
214- Placeholder * content () const
273+ ValueHolder * content () const
215274 {
216- return _placeholder .content ();
275+ return _valueHolder .content ();
217276 }
218277
219278 template <typename ValueType>
220279 void construct (const ValueType& value)
221280 {
222- if (sizeof (Holder<ValueType>) <= POCO_SMALL_OBJECT_SIZE )
281+ if (sizeof (Holder<ValueType>) <= _valueHolder. SIZE )
223282 {
224- new (reinterpret_cast <Placeholder *>(_placeholder .holder )) Holder<ValueType>(value);
225- _placeholder .setLocal (true );
283+ new (reinterpret_cast <ValueHolder *>(_valueHolder .holder )) Holder<ValueType>(value);
284+ _valueHolder .setLocal (true );
226285 }
227286 else
228287 {
229- _placeholder .pHolder = new Holder<ValueType>(value);
230- _placeholder .setLocal (false );
288+ _valueHolder .pHolder = new Holder<ValueType>(value);
289+ _valueHolder .setLocal (false );
231290 }
232291 }
233292
234293 void construct (const Any& other)
235294 {
236295 if (!other.empty ())
237- other.content ()->clone (&_placeholder );
296+ other.content ()->clone (&_valueHolder );
238297 else
239- _placeholder .erase ();
298+ _valueHolder .erase ();
240299 }
241-
242- union PH
243- // / Placeholder union. If Holder<Type> fits into POCO_SMALL_OBJECT_SIZE
244- // / bytes of storage, it will be placement-new-allocated into the local buffer
245- // / (i.e. there will be no heap-allocation. The local buffer size is one byte
246- // / larger - [POCO_SMALL_OBJECT_SIZE + 1], additional byte value indicating
247- // / where the object was allocated (0 => heap, 1 => local).
248- {
249- PH ()
250- {
251- erase ();
252- }
253-
254- void erase ()
255- {
256- std::memset (holder, 0 , sizeof (PH));
257- }
258-
259- bool isLocal () const
260- {
261- return holder[POCO_SMALL_OBJECT_SIZE] != 0 ;
262- }
263-
264- void setLocal (bool local) const
265- {
266- holder[POCO_SMALL_OBJECT_SIZE] = local ? 1 : 0 ;
267- }
268-
269- Placeholder* content () const
270- {
271- if (isLocal ())
272- return reinterpret_cast <Placeholder*>(holder);
273- else
274- return pHolder;
275- }
276-
277- Placeholder* pHolder;
278- mutable unsigned char holder[POCO_SMALL_OBJECT_SIZE + 1 ];
279- } _placeholder;
300+
301+ Placeholder<ValueHolder> _valueHolder;
280302
281303
282304#else // if POCO_NO_SOO
283305
284306
285- public:
286307 Any (): _pHolder(0 )
287308 // / Creates an empty any type.
288309 {
@@ -352,19 +373,19 @@ class Any
352373 }
353374
354375private:
355- class Placeholder
376+ class ValueHolder
356377 {
357378 public:
358- virtual ~Placeholder ()
379+ virtual ~ValueHolder ()
359380 {
360381 }
361382
362383 virtual const std::type_info& type () const = 0;
363- virtual Placeholder * clone () const = 0;
384+ virtual ValueHolder * clone () const = 0;
364385 };
365386
366387 template <typename ValueType>
367- class Holder : public Placeholder
388+ class Holder : public ValueHolder
368389 {
369390 public:
370391 Holder (const ValueType& value):
@@ -377,7 +398,7 @@ class Any
377398 return typeid (ValueType);
378399 }
379400
380- virtual Placeholder * clone () const
401+ virtual ValueHolder * clone () const
381402 {
382403 return new Holder (_held);
383404 }
@@ -388,13 +409,13 @@ class Any
388409 Holder & operator =(const Holder &);
389410 };
390411
391- Placeholder * content () const
412+ ValueHolder * content () const
392413 {
393414 return _pHolder;
394415 }
395416
396417private:
397- Placeholder * _pHolder;
418+ ValueHolder * _pHolder;
398419
399420#endif // POCO_NO_SOO
400421
0 commit comments