Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_34_1/libs/any/doc/any.xml @ 69

Last change on this file since 69 was 29, checked in by landauf, 17 years ago

updated boost from 1_33_1 to 1_34_1

File size: 16.8 KB
RevLine 
[29]1<?xml version="1.0" encoding="utf-8"?>
2<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN"
3  "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
4<library name="Any" dirname="any" xmlns:xi="http://www.w3.org/2001/XInclude" 
5         id="any" last-revision="$Date: 2005/11/04 09:34:36 $">
6  <libraryinfo>
7    <author>
8      <firstname>Kevlin</firstname>
9      <surname>Henney</surname>
10    </author>
11
12    <copyright>
13      <year>2001</year>
14      <holder>Kevlin Henney</holder>
15    </copyright>
16
17    <librarypurpose>
18      Safe, generic container for single values of different value types
19    </librarypurpose> 
20    <librarycategory name="category:data-structures"/>
21  </libraryinfo>
22
23  <title>Boost.Any</title>
24
25  <section>
26    <title>Introduction</title>
27
28    <para>There are times when a generic (in the sense of
29    <emphasis>general</emphasis> as opposed to
30    <emphasis>template-based programming</emphasis>) type is needed:
31    variables that are truly variable, accommodating values of many
32    other more specific types rather than C++'s normal strict and
33    static types. We can distinguish three basic kinds of generic
34    type:</para>
35
36    <itemizedlist>
37      <listitem>
38        <para>Converting types that can hold one of a number of
39        possible value types, e.g. <code>int</code> and
40        <code>string</code>, and freely convert between them, for
41        instance interpreting <code>5</code> as <code>"5"</code> or
42        vice-versa.  Such types are common in scripting and other
43        interpreted
44        languages.
45        <code><functionname>boost::lexical_cast</functionname></code>
46        supports such conversion functionality.</para>
47      </listitem>
48      <listitem>
49        <para>
50        Discriminated types that contain values of different types but
51        do not attempt conversion between them, i.e. <code>5</code> is
52        held strictly as an <code>int</code> and is not implicitly
53        convertible either to <code>"5"</code> or to
54        <code>5.0</code>. Their indifference to interpretation but
55        awareness of type effectively makes them safe, generic
56        containers of single values, with no scope for surprises from
57        ambiguous conversions.</para>
58      </listitem>
59      <listitem>
60        <para>
61        Indiscriminate types that can refer to anything but are
62        oblivious to the actual underlying type, entrusting all forms
63        of access and interpretation to the programmer. This niche is
64        dominated by <code>void *</code>, which offers plenty of scope
65        for surprising, undefined behavior.</para>
66      </listitem>
67    </itemizedlist>
68
69    <para>The <code><classname>boost::any</classname></code> class
70    (based on the class of the same name described in <ulink
71    url="http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf">"Valued
72    Conversions"</ulink> by Kevlin Henney, <emphasis>C++
73    Report</emphasis> 12(7), July/August 2000) is a variant value type
74    based on the second category. It supports copying of any value
75    type and safe checked extraction of that value strictly against
76    its type. A similar design, offering more appropriate operators,
77    can be used for a generalized function adaptor,
78    <code>any_function</code>, a generalized iterator adaptor,
79    <code>any_iterator</code>, and other object types that need
80    uniform runtime treatment but support only compile-time template
81    parameter conformance.</para>
82  </section>
83
84  <section>
85    <title>Examples</title>
86
87    <using-namespace name="boost"/>
88    <using-class name="boost::any"/>
89
90    <para>The following code demonstrates the syntax for using
91    implicit conversions to and copying of any objects:</para>
92
93<programlisting name="any.example.first">
94#include &lt;list&gt;
95#include &lt;boost/any.hpp&gt;
96
97using <functionname>boost::any_cast</functionname>;
98typedef std::list&lt;<classname>boost::any</classname>&gt; many;
99
100void append_int(many &amp; values, int value)
101{
102    <classname>boost::any</classname> to_append = value;
103    values.push_back(to_append);
104}
105
106void append_string(many &amp; values, const std::string &amp; value)
107{
108    values.push_back(value);
109}
110
111void append_char_ptr(many &amp; values, const char * value)
112{
113    values.push_back(value);
114}
115
116void append_any(many &amp; values, const <classname>boost::any</classname> &amp; value)
117{
118    values.push_back(value);
119}
120
121void append_nothing(many &amp; values)
122{
123    values.push_back(<classname>boost::any</classname>());
124}
125</programlisting>
126
127    <para>The following predicates follow on from the previous
128    definitions and demonstrate the use of queries on any
129    objects:</para>
130
131<programlisting name="any.example.second">
132bool is_empty(const <classname>boost::any</classname> &amp; operand)
133{
134    return operand.<methodname>empty</methodname>();
135}
136
137bool is_int(const <classname>boost::any</classname> &amp; operand)
138{
139    return operand.<methodname>type</methodname>() == typeid(int);
140}
141
142bool is_char_ptr(const <classname>boost::any</classname> &amp; operand)
143{
144    try
145    {
146        <functionname>any_cast</functionname>&lt;const char *&gt;(operand);
147        return true;
148    }
149    catch(const <classname>boost::bad_any_cast</classname> &amp;)
150    {
151        return false;
152    }
153}
154
155bool is_string(const <classname>boost::any</classname> &amp; operand)
156{
157    return <functionname>any_cast</functionname>&lt;std::string&gt;(&amp;operand);
158}
159
160void count_all(many &amp; values, std::ostream &amp; out)
161{
162    out &lt;&lt; "#empty == "
163        &lt;&lt; std::count_if(values.begin(), values.end(), is_empty) &lt;&lt; std::endl;
164    out &lt;&lt; "#int == "
165        &lt;&lt; std::count_if(values.begin(), values.end(), is_int) &lt;&lt; std::endl;
166    out &lt;&lt; "#const char * == "
167        &lt;&lt; std::count_if(values.begin(), values.end(), is_char_ptr) &lt;&lt; std::endl;
168    out &lt;&lt; "#string == "
169        &lt;&lt; std::count_if(values.begin(), values.end(), is_string) &lt;&lt; std::endl;
170}
171</programlisting>
172
173    <para>The following type, patterned after the OMG's Property Service, defines name-value pairs for arbitrary value types:</para>
174
175<programlisting>
176struct property
177{
178    property();
179    property(const std::string &amp;, const <classname>boost::any</classname> &amp;);
180
181    std::string name;
182    <classname>boost::any</classname> value;
183};
184
185typedef std::list&lt;property&gt; properties;
186</programlisting>
187
188    <para>The following base class demonstrates one approach to
189    runtime polymorphism based callbacks that also require arbitrary
190    argument types. The absence of virtual member templates requires
191    that different solutions have different trade-offs in terms of
192    efficiency, safety, and generality. Using a checked variant type
193    offers one approach:</para>
194
195<programlisting>
196class consumer
197{
198public:
199    virtual void notify(const <classname>any</classname> &amp;) = 0;
200    ...
201};
202</programlisting>
203  </section>
204
205  <library-reference>
206    <section id="any.ValueType">
207      <title><emphasis>ValueType</emphasis> requirements</title>
208
209      <para>Values are strongly informational objects for which
210      identity is not significant, i.e. the focus is principally on
211      their state content and any behavior organized around
212      that. Another distinguishing feature of values is their
213      granularity: normally fine-grained objects representing simple
214      concepts in the system such as quantities.</para>
215
216      <para>As the emphasis of a value lies in its state not its
217      identity, values can be copied and typically assigned one to
218      another, requiring the explicit or implicit definition of a
219      public copy constructor and public assignment operator. Values
220      typically live within other scopes, i.e. within objects or
221      blocks, rather than on the heap. Values are therefore normally
222      passed around and manipulated directly as variables or through
223      references, but not as pointers that emphasize identity and
224      indirection.</para>
225
226      <para>The specific requirements on value types to be used in an
227      <code><classname alt="boost::any">any</classname></code>
228      are:</para>
229
230      <itemizedlist spacing="compact">
231        <listitem><simpara>A <emphasis>ValueType</emphasis> is
232          <emphasis>CopyConstructible</emphasis> [20.1.3].</simpara>
233        </listitem>
234       
235        <listitem><simpara>A <emphasis>ValueType</emphasis> is
236        optionally <emphasis>Assignable</emphasis> [23.1]. The strong
237        exception-safety guarantee is required for all forms of
238        assignment.</simpara>
239        </listitem>
240       
241        <listitem><simpara>The destructor for a
242        <emphasis>ValueType</emphasis> upholds the no-throw
243        exception-safety guarantee.</simpara>
244        </listitem>
245      </itemizedlist>
246    </section>
247
248    <header name="boost/any.hpp">
249      <namespace name="boost">
250        <class name="bad_any_cast">
251          <inherit access="public">
252            <classname>std::bad_cast</classname>
253          </inherit>
254          <purpose>The exception thrown in the event of a failed
255          <code><functionname>any_cast</functionname></code> of an
256          <code><classname>any</classname></code> value.</purpose>
257
258          <method name="what" specifiers="virtual" cv="const">
259            <type>const char *</type>
260          </method>
261        </class>
262
263        <class name="any">
264          <purpose>A class whose instances can hold instances of any
265          type that satisfies <link
266          linkend="any.ValueType">ValueType</link>
267          requirements.</purpose>
268
269          <constructor>
270            <postconditions><simpara><code>this-&gt;<methodname>empty</methodname>()</code></simpara></postconditions>
271          </constructor>
272
273          <constructor>
274            <parameter name="other">
275              <paramtype>const <classname>any</classname> &amp;</paramtype>
276            </parameter>
277
278            <effects><simpara> Copy constructor that copies content of
279            <code>other</code> into new instance, so that any content
280            is equivalent in both type and value to the content of
281            <code>other</code>, or empty if <code>other</code> is
282            empty. </simpara></effects>
283
284            <throws><simpara>May fail with a
285            <code><classname>std::bad_alloc</classname></code>
286            exception or any exceptions arising from the copy
287            constructor of the contained type.</simpara></throws>
288          </constructor>
289
290          <constructor>
291            <template>
292              <template-type-parameter name="ValueType"/>
293            </template>
294
295            <parameter name="value">
296              <paramtype>const ValueType &amp;</paramtype>
297            </parameter>
298
299            <effects><simpara>Makes a copy of <code>value</code>, so
300            that the initial content of the new instance is equivalent
301            in both type and value to
302            <code>value</code>.</simpara></effects>
303
304            <throws><simpara><code><classname>std::bad_alloc</classname></code>
305            or any exceptions arising from the copy constructor of the
306            contained type.</simpara></throws>
307          </constructor>
308
309          <destructor>
310            <effects><simpara>Releases any and all resources used in
311            management of instance.</simpara></effects>
312            <throws><simpara>Nothing.</simpara></throws>
313          </destructor>
314
315          <copy-assignment>
316            <type><classname>any</classname> &amp;</type>
317
318            <parameter name="rhs">
319              <paramtype>const <classname>any</classname> &amp;</paramtype>
320            </parameter>
321
322            <effects><simpara>Copies content of <code>rhs</code> into
323            current instance, discarding previous content, so that the
324            new content is equivalent in both type and value to the
325            content of <code>rhs</code>, or empty if
326            <code>rhs.<methodname>empty</methodname>()</code>.</simpara></effects>
327
328            <throws><simpara><code><classname>std::bad_alloc</classname></code>
329            or any exceptions arising from the copy constructor of the
330            contained type. Assignment satisfies the strong guarantee
331            of exception safety.</simpara></throws>
332          </copy-assignment>
333
334          <copy-assignment>
335             <template>
336              <template-type-parameter name="ValueType"/>
337            </template>
338
339            <type><classname>any</classname> &amp;</type>
340
341            <parameter name="rhs">
342              <paramtype>const ValueType &amp;</paramtype>
343            </parameter>
344
345            <effects><simpara>Makes a copy of <code>rhs</code>,
346            discarding previous content, so that the new content of is
347            equivalent in both type and value to
348            <code>rhs</code>.</simpara></effects>
349
350            <throws><simpara><code><classname>std::bad_alloc</classname></code>
351            or any exceptions arising from the copy constructor of the
352            contained type. Assignment satisfies the strong guarantee
353            of exception safety.</simpara></throws>
354          </copy-assignment>
355
356          <method-group name="modifiers">
357            <method name="swap">
358              <type><classname>any</classname> &amp;</type>
359
360              <parameter name="rhs">
361                <paramtype><classname>any</classname> &amp;</paramtype>
362              </parameter>
363
364              <effects><simpara>Exchange of the contents of
365              <code>*this</code> and
366              <code>rhs</code>.</simpara></effects>
367
368              <returns><simpara><code>*this</code></simpara></returns>
369
370              <throws><simpara>Nothing.</simpara></throws>
371            </method>
372          </method-group>
373
374          <method-group name="queries">
375            <method name="empty" cv="const">
376              <type>bool</type>
377
378              <returns><simpara><code>true</code> if instance is
379              empty, otherwise <code>false</code>.</simpara></returns>
380             
381              <throws><simpara>Will not throw.</simpara></throws>
382            </method>
383
384            <method name="type" cv="const">
385              <type>const <classname>std::type_info</classname> &amp;</type>
386             
387              <returns><simpara>the <code>typeid</code> of the
388              contained value if instance is non-empty, otherwise
389              <code>typeid(void)</code>.</simpara></returns>
390
391              <notes><simpara>Useful for querying against types known
392              either at compile time or only at
393              runtime.</simpara></notes>
394            </method>
395          </method-group>
396        </class>
397
398        <overloaded-function name="any_cast">
399          <signature>
400            <template>
401              <template-type-parameter name="T"/>
402            </template>
403           
404            <type>T</type>
405           
406            <parameter name="operand">
407              <paramtype><classname>any</classname> &amp;</paramtype>
408            </parameter>
409          </signature>
410         
411          <signature>
412            <template>
413              <template-type-parameter name="T"/>
414            </template>
415           
416            <type>T</type>
417           
418            <parameter name="operand">
419              <paramtype>const <classname>any</classname> &amp;</paramtype>
420            </parameter>
421          </signature>
422         
423          <signature>
424            <template>
425              <template-type-parameter name="ValueType"/>
426            </template>
427           
428            <type>const ValueType *</type>
429           
430            <parameter name="operand">
431              <paramtype>const <classname>any</classname> *</paramtype>
432            </parameter>
433          </signature>
434         
435          <signature>
436            <template>
437              <template-type-parameter name="ValueType"/>
438            </template>
439           
440            <type>ValueType *</type>
441           
442            <parameter name="operand">
443              <paramtype><classname>any</classname> *</paramtype>
444            </parameter>
445          </signature>
446         
447          <purpose><simpara>Custom keyword cast for extracting a value
448          of a given type from an
449          <code><classname>any</classname></code>.</simpara></purpose>
450
451          <returns><simpara> If passed a pointer, it returns a
452          similarly qualified pointer to the value content if
453          successful, otherwise null is returned.
454          If T is ValueType, it returns a copy of the held value, otherwise, if T is a reference
455          to (possibly const qualified) ValueType, it returns a reference to the held
456          value.</simpara></returns>
457
458          <throws><simpara>Overloads taking an
459          <code><classname>any</classname></code> pointer do not
460          throw; overloads taking an
461          <code><classname>any</classname></code> value or reference
462          throws <code><classname>bad_any_cast</classname></code> if
463          unsuccessful.</simpara></throws>
464
465        </overloaded-function>
466      </namespace>
467    </header>
468  </library-reference>
469
470  <section>
471    <title>Acknowledgements</title>
472
473    <para>Doug Gregor ported the documentation to the BoostBook format.</para>
474  </section>
475</library>
Note: See TracBrowser for help on using the repository browser.