mirror of
https://github.com/boostorg/any.git
synced 2026-02-01 08:02:07 +00:00
432 lines
14 KiB
HTML
432 lines
14 KiB
HTML
<!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
<html>
|
|
<head>
|
|
<title>any</title>
|
|
<meta name="author" content="Kevlin Henney, mailto:kevlin@curbralan.com">
|
|
<meta name="generator" content="Microsoft FrontPage 4.0">
|
|
</head>
|
|
|
|
<body bgcolor="#FFFFFF" text="#000000">
|
|
|
|
<h1><img border="0" src="../../c++boost.gif" align="center" width="277" height="86">Header <<a href="../../boost/any.hpp">boost/any.hpp</a>></h1>
|
|
|
|
<ul>
|
|
<li><a href="#motivation">Motivation</li>
|
|
<li><a href="#examples">Examples</li>
|
|
<li><a href="#synopsis">Synopsis</li>
|
|
<li><a href="#ValueType"><i>ValueType</i> requirements</li>
|
|
<li><a href="#any"><code>any</code></li>
|
|
<li><a href="#bad_any_cast"><code>bad_any_cast</code></li>
|
|
<li><a href="#any_cast"><code>any_cast</code></li>
|
|
<li><a href="#portability">Portability</li>
|
|
</ul>
|
|
|
|
<hr>
|
|
<h2><a name="motivation">Motivation</a></h2>
|
|
|
|
There are times when a generic (in the sense of <i>general</i> as opposed to
|
|
<i>template-based programming</i>) type is needed: variables that are truly variable,
|
|
accommodating values of many other more specific types rather than C++'s normal strict
|
|
and static types. We can distinguish three basic kinds of generic type:
|
|
|
|
<ol>
|
|
<li>
|
|
Converting types that can hold one of a number of possible value types,
|
|
e.g. <code>int</code> and <code>string</code>, and freely convert between them,
|
|
for instance interpreting <code>5</code> as <code>"5"</code> or vice-versa.
|
|
Such types are common in scripting and other interpreted languages.
|
|
<a href="../conversion/lexical_cast.htm">
|
|
<code>boost::lexical_cast</code></a> supports such conversion functionality.
|
|
</li>
|
|
<li>
|
|
Discriminated types that contain values of different types but do not attempt conversion between
|
|
them, i.e. <code>5</code> is held strictly as an <code>int</code> and is not implicitly
|
|
convertible either to <code>"5"</code> or to <code>5.0</code>. Their indifference to
|
|
interpretation but awareness of type effectively makes them safe, generic containers of single
|
|
values, with no scope for surprises from ambiguous conversions.
|
|
</li>
|
|
<li>
|
|
Indiscriminate types that can refer to anything but are oblivious to the actual underlying type,
|
|
entrusting all forms of access and interpretation to the programmer. This niche is dominated by
|
|
<code>void *</code>, which offers plenty of scope for surprising, undefined behavior.
|
|
</li>
|
|
</ol>
|
|
|
|
The <code>any</code> class (based on the class of the same name described in
|
|
<a href="http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf">"Valued Conversions"</a>
|
|
by Kevlin Henney, <i>C++ Report</i> 12(7), July/August 2000) is a variant value type based on the second
|
|
category. It supports copying of any value type and safe checked extraction of that value strictly
|
|
against its type. A similar design, offering more appropriate operators, can be used for a generalized
|
|
function adaptor, <code>any_function</code>, a generalized iterator adaptor, <code>any_iterator</code>,
|
|
and other object types that need uniform runtime treatment but support only compile-time template
|
|
parameter conformance.
|
|
<p>
|
|
|
|
<hr>
|
|
<h2><a name="examples">Examples</a></h2>
|
|
|
|
The following code demonstrates the syntax for using implicit conversions to and copying of
|
|
<code>any</code> objects:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
#include <list>
|
|
#include <boost/any.hpp>
|
|
|
|
typedef std::list<boost::any> many;
|
|
|
|
void append_int(many & values, int value)
|
|
{
|
|
boost::any to_append = value;
|
|
values.push_back(to_append);
|
|
}
|
|
|
|
void append_string(many & values, const std::string & value)
|
|
{
|
|
values.push_back(value);
|
|
}
|
|
|
|
void append_char_ptr(many & values, const char * value)
|
|
{
|
|
values.push_back(value);
|
|
}
|
|
|
|
void append_any(many & values, const boost::any & value)
|
|
{
|
|
values.push_back(value);
|
|
}
|
|
|
|
void append_nothing(many & values)
|
|
{
|
|
values.push_back(boost::any());
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The following predicates follow on from the previous definitions and demonstrate
|
|
the use of queries on <code>any</code> objects:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
bool is_empty(const boost::any & operand)
|
|
{
|
|
return operand.empty();
|
|
}
|
|
|
|
bool is_int(const boost::any & operand)
|
|
{
|
|
return operand.type() == typeid(int);
|
|
}
|
|
|
|
bool is_char_ptr(const boost::any & operand)
|
|
{
|
|
try
|
|
{
|
|
any_ptr<const char *>(operand);
|
|
return true;
|
|
}
|
|
catch(const boost::bad_any_cast &)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool is_string(const boost::any & operand)
|
|
{
|
|
return any_ptr<std::string>(&operand);
|
|
}
|
|
|
|
void count_all(many & values, std::ostream & out)
|
|
{
|
|
out << "#empty == "
|
|
<< std::count_if(values.begin(), values.end(), is_empty) << std::endl;
|
|
out << "#int == "
|
|
<< std::count_if(values.begin(), values.end(), is_int) << std::endl;
|
|
out << "#const char * == "
|
|
<< std::count_if(values.begin(), values.end(), is_char_ptr) << std::endl;
|
|
out << "#string == "
|
|
<< std::count_if(values.begin(), values.end(), is_string) << std::endl;
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The following type, patterned after the OMG's Property Service, defines name–value
|
|
pairs for arbitrary value types:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
struct property
|
|
{
|
|
property();
|
|
property(const std::string &, const boost::any &);
|
|
|
|
std::string name;
|
|
boost::any value;
|
|
};
|
|
|
|
typedef std::list<property> properties;
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The following base class demonstrates one approach to runtime polymorphism based callbacks that also
|
|
require arbitrary argument types. The absence of <code>virtual</code> member templates requires that
|
|
different solutions have different trade-offs in terms of efficiency, safety, and generality. Using
|
|
a checked variant type offers one approach:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
class consumer
|
|
{
|
|
public:
|
|
virtual void notify(const any &) = 0;
|
|
...
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
<hr>
|
|
<h2><a name="synopsis">Synopsis</a></h2>
|
|
|
|
Dependencies and library features defined in <a href="../../boost/any.hpp"><code>"boost/any.hpp"</code></a>:
|
|
|
|
<blockquote>
|
|
<pre>
|
|
#include <typeinfo>
|
|
|
|
namespace boost
|
|
{
|
|
class <a href="#any">any</a>;
|
|
class <a href="#bad_any_cast">bad_any_cast</a>;
|
|
template<typename <a href="#ValueType">ValueType</a>>
|
|
<a href="#ValueType">ValueType</a> <a href="#any_cast">any_cast</a>(const <a href="#any">any</a> &);
|
|
}
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Test harness defined in <a href="any_test.cpp"><code>"any_test.cpp"</code></a>.
|
|
<p>
|
|
|
|
<hr>
|
|
<h2><a name="ValueType"><i>ValueType</i> requirements</a></h2>
|
|
|
|
Values are strongly informational objects for which identity is not significant,
|
|
i.e. the focus is principally on their state content and any behavior organized around that.
|
|
Another distinguishing feature of values is their granularity: normally fine-grained
|
|
objects representing simple concepts in the system such as quantities.
|
|
<p>
|
|
As the emphasis of a value lies in its state not its identity, values can be copied and
|
|
typically assigned one to another, requiring the explicit or implicit definition of a
|
|
public copy constructor and public assignment operator. Values typically live within
|
|
other scopes, i.e. within objects or blocks, rather than on the heap. Values are therefore
|
|
normally passed around and manipulated directly as variables or through references, but not
|
|
as pointers that emphasize identity and indirection.
|
|
<p>
|
|
The specific requirements on value types to be used in an <a href="#any"><code>any</code></a> are:
|
|
<ul>
|
|
<li>
|
|
A <i>ValueType</i> is <i>CopyConstructible</i> [20.1.3].
|
|
</li>
|
|
<li>
|
|
A <i>ValueType</i> is optionally <i>Assignable</i> [23.1]. The strong exception-safety
|
|
guarantee is required for all forms of assignment.
|
|
</li>
|
|
<li>
|
|
The destructor for a <i>ValueType</i> upholds the no-throw exception-safety guarantee.
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
|
|
<hr>
|
|
<h2><a name="any"><code>any</code></a></h2>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
class any
|
|
{
|
|
public: // <a href="#structors"><i>structors</i></a>
|
|
|
|
<a href="#default-ctor">any</a>();
|
|
<a href="#copy-ctor">any</a>(const any &);
|
|
template<typename <a href="#ValueType">ValueType</a>>
|
|
<a href="#template-ctor">any</a>(const <a href="#ValueType">ValueType</a> &);
|
|
<a href="#dtor">~any</a>();
|
|
|
|
public: // <a href="#modifiers"><i>modifiers</i></a>
|
|
|
|
any & <a href="#swap">swap</a>(any &);
|
|
any & <a href="#copy-assign">operator=</a>(const any &);
|
|
template<typename <a href="#ValueType">ValueType</a>>
|
|
any & <a href="#template-assign">operator=</a>(const <a href="#ValueType">ValueType</a> &);
|
|
|
|
public: // <a href="#queries"><i>queries</i></a>
|
|
|
|
bool <a href="#empty">empty</a>() const;
|
|
const std::type_info & <a href="#type">type</a>() const;
|
|
|
|
private: // <i>representation</i>
|
|
...
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
A class whose instances can hold instances of any type that satisfies
|
|
<a href="#ValueType"><i>ValueType</i></a> requirements: effectively an unbounded <code>union</code> type.
|
|
Note that <code>any</code> itself satisfies <a href="#ValueType"><i>ValueType</i></a> requirements with
|
|
assignment.
|
|
<p>
|
|
|
|
<ul>
|
|
<hr>
|
|
<h3><a name="structors">Structors</a></h3>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="default-ctor">any::any();</a>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Default constructor that sets new instance to empty.
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="copy-ctor">any::any(const any & other);</a>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Copy constructor that copies content of <code>other</code> into new instance, so that
|
|
any content is equivalent in both type and value to the content of <code>other</code>,
|
|
or empty if <code>other</code> is empty. May fail with a <code>std::bad_alloc</code> exception
|
|
or any exceptions arising from the copy constructor of the contained type.
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="template-ctor">template<typename </a><a href="#ValueType">ValueType</a>>
|
|
any::any(const <a href="#ValueType">ValueType</a> & value);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Templated converting constructor makes a copy of <code>value</code>, so that the initial
|
|
content of the new instance is equivalent in both type and value to <code>value</code>.
|
|
May fail with a <code>std::bad_alloc</code> exception or any exceptions arising from the
|
|
copy constructor of
|
|
the contained type.
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="dtor">any::~any();</a>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Non-throwing destructor that releases any and all resources used in management of instance.
|
|
<p>
|
|
|
|
<hr>
|
|
<h3><a name="modifiers">Modifiers</a></h3>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="swap">any & swap(any & rhs);</a>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Non-throwing exchange of the contents of <code>*this</code> and <code>rhs</code>.
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="copy-assign">any & operator=(const any & rhs);</a>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Copy assignment operator that copies content of <code>rhs</code> into current instance, discarding
|
|
previous content, so that the new content is equivalent in both type and value to the content of
|
|
<code>rhs</code>, or empty if <code>rhs.empty()</code>. May fail with a <code>std::bad_alloc</code>
|
|
exception or any exceptions arising from the copy constructor of the contained type.
|
|
Assignment satisfies the strong guarantee of exception safety.
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="template-assign">template<typename </a><a href="#ValueType">ValueType</a>>
|
|
any & operator=(const <a href="#ValueType">ValueType</a> & rhs);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Templated assignment operator makes a copy of <code>rhs</code>, discarding previous content,
|
|
so that the new content of is equivalent in both type and value to <code>rhs</code>. May fail with a
|
|
<code>std::bad_alloc</code> exception or any exceptions arising from the copy constructor of
|
|
the contained type. Assignment satisfies the strong guarantee of exception safety.
|
|
<p>
|
|
|
|
<hr>
|
|
<h3><a name="queries">Queries</a></h3>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="empty">bool empty() const;</a>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Test for emptiness, returning <code>true</code> if instance is empty, otherwise <code>false</code>.
|
|
|
|
<blockquote>
|
|
<pre>
|
|
<a name="type">const std::type_info & type() const;</a>
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Returns the <code>typeid</code> of the contained value if instance is non-empty, otherwise
|
|
<code>typeid(void)</code> returned. Useful for querying against types known either at
|
|
compile time or only at runtime.
|
|
</ul>
|
|
|
|
<hr>
|
|
<h2><a name="bad_any_cast"><code>bad_any_cast</code></a></h2>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
class bad_any_cast : public std::bad_cast
|
|
{
|
|
public:
|
|
virtual const char * what() const;
|
|
};
|
|
</pre>
|
|
</blockquote>
|
|
|
|
The exception thrown in the event of a failed <a href="#any_cast"><code>any_cast</code></a> of
|
|
an <a href="#any"><code>any</code></a> value.
|
|
<p>
|
|
|
|
<hr>
|
|
<h2><a name="any_cast"><code>any_cast</code></a></h2>
|
|
|
|
<blockquote>
|
|
<pre>
|
|
template<typename <a href="#ValueType">ValueType</a>>
|
|
<a href="#ValueType">ValueType</a> any_cast(const <a href="#any">any</a> & operand);
|
|
template<typename <a href="#ValueType">ValueType</a>>
|
|
const <a href="#ValueType">ValueType</a> * any_cast(const <a href="#any">any</a> * operand);
|
|
template<typename <a href="#ValueType">ValueType</a>>
|
|
<a href="#ValueType">ValueType</a> * any_cast(<a href="#any">any</a> * operand);
|
|
</pre>
|
|
</blockquote>
|
|
|
|
Custom keyword cast for extracting a value of a given type from an
|
|
<a href="#any"><code>any</code></a>. If passed a pointer, it returns a similarly qualified
|
|
pointer to the value content if successful, otherwise null is returned. If passed a value or
|
|
reference, it returns a copy of the value content if successful, otherwise a
|
|
<a href="#bad_any_cast"><code>bad_any_cast</code></a> exception is thrown.
|
|
<p>
|
|
|
|
<hr>
|
|
<h2><a name="portability">Portability</a></h2>
|
|
|
|
To date the code and test harness have been compiled and tested successfully using Borland C++ 5.5,
|
|
Microsoft Visual C++ 6.0, and GNU g++ 2.95.
|
|
<p>
|
|
|
|
<hr>
|
|
|
|
<div align="right"><small><i>© Copyright Kevlin Henney, 2001</i></small></div>
|
|
|
|
</body>
|
|
</html>
|