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