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 <list> 108#include <boost/any.hpp> 109 110using <functionname>boost::any_cast</functionname>; 111typedef std::list<<classname>boost::any</classname>> many; 112 113void append_int(many & values, int value) 114{ 115 <classname>boost::any</classname> to_append = value; 116 values.push_back(to_append); 117} 118 119void append_string(many & values, const std::string & value) 120{ 121 values.push_back(value); 122} 123 124void append_char_ptr(many & values, const char * value) 125{ 126 values.push_back(value); 127} 128 129void append_any(many & values, const <classname>boost::any</classname> & value) 130{ 131 values.push_back(value); 132} 133 134void append_nothing(many & 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> & operand) 146{ 147 return operand.<methodname>empty</methodname>(); 148} 149 150bool is_int(const <classname>boost::any</classname> & operand) 151{ 152 return operand.<methodname>type</methodname>() == typeid(int); 153} 154 155bool is_char_ptr(const <classname>boost::any</classname> & operand) 156{ 157 try 158 { 159 <functionname>any_cast</functionname><const char *>(operand); 160 return true; 161 } 162 catch(const <classname>boost::bad_any_cast</classname> &) 163 { 164 return false; 165 } 166} 167 168bool is_string(const <classname>boost::any</classname> & operand) 169{ 170 return <functionname>any_cast</functionname><std::string>(&operand); 171} 172 173void count_all(many & values, std::ostream & out) 174{ 175 out << "#empty == " 176 << std::count_if(values.begin(), values.end(), is_empty) << std::endl; 177 out << "#int == " 178 << std::count_if(values.begin(), values.end(), is_int) << std::endl; 179 out << "#const char * == " 180 << std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl; 181 out << "#string == " 182 << std::count_if(values.begin(), values.end(), is_string) << 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 &, const <classname>boost::any</classname> &); 193 194 std::string name; 195 <classname>boost::any</classname> value; 196}; 197 198typedef std::list<property> 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> &) = 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-><methodname>empty</methodname>()</code></simpara></postconditions> 278 </constructor> 279 280 <constructor> 281 <parameter name="other"> 282 <paramtype>const <classname>any</classname> &</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> &&</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-><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 &</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 &&</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> &</type> 357 358 <parameter name="rhs"> 359 <paramtype>const <classname>any</classname> &</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> &</type> 376 377 <parameter name="rhs"> 378 <paramtype><classname>any</classname> &&</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-><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> &</type> 398 399 <parameter name="rhs"> 400 <paramtype>const ValueType &</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> &</type> 420 421 <parameter name="rhs"> 422 <paramtype>ValueType &&</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> &</type> 440 441 <parameter name="rhs"> 442 <paramtype><classname>any</classname> &</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> &</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> &</paramtype> 483 </parameter> 484 <parameter name="rhs"> 485 <paramtype><classname>any</classname> &</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> &</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> &&</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> &</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