diff options
author | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2012-10-30 12:57:26 -0700 |
commit | 1a78a62555be32868418fe52f8e330c9d0f95d5a (patch) | |
tree | d3765a80e7d3b9640ec2e930743630cd6b9fce2b /libs/any | |
download | boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.gz boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.tar.bz2 boost-1a78a62555be32868418fe52f8e330c9d0f95d5a.zip |
Imported Upstream version 1.49.0upstream/1.49.0
Diffstat (limited to 'libs/any')
-rw-r--r-- | libs/any/any_test.cpp | 233 | ||||
-rw-r--r-- | libs/any/doc/any.xml | 483 | ||||
-rw-r--r-- | libs/any/index.html | 14 | ||||
-rw-r--r-- | libs/any/test.hpp | 321 | ||||
-rw-r--r-- | libs/any/test/Jamfile.v2 | 14 | ||||
-rw-r--r-- | libs/any/test/any_cast_cv_failed.cpp | 14 |
6 files changed, 1079 insertions, 0 deletions
diff --git a/libs/any/any_test.cpp b/libs/any/any_test.cpp new file mode 100644 index 0000000000..f3c5e7fef9 --- /dev/null +++ b/libs/any/any_test.cpp @@ -0,0 +1,233 @@ +// what: unit tests for variant type boost::any +// who: contributed by Kevlin Henney +// when: July 2001 +// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.95 + +#include <cstdlib> +#include <string> +#include <utility> + +#include "boost/any.hpp" +#include "test.hpp" + +namespace any_tests +{ + typedef test<const char *, void (*)()> test_case; + typedef const test_case * test_case_iterator; + + extern const test_case_iterator begin, end; +} + +int main() +{ + using namespace any_tests; + tester<test_case_iterator> test_suite(begin, end); + return test_suite() ? EXIT_SUCCESS : EXIT_FAILURE; +} + +namespace any_tests // test suite +{ + void test_default_ctor(); + void test_converting_ctor(); + void test_copy_ctor(); + void test_copy_assign(); + void test_converting_assign(); + void test_bad_cast(); + void test_swap(); + void test_null_copying(); + void test_cast_to_reference(); + + const test_case test_cases[] = + { + { "default construction", test_default_ctor }, + { "single argument construction", test_converting_ctor }, + { "copy construction", test_copy_ctor }, + { "copy assignment operator", test_copy_assign }, + { "converting assignment operator", test_converting_assign }, + { "failed custom keyword cast", test_bad_cast }, + { "swap member function", test_swap }, + { "copying operations on a null", test_null_copying }, + { "cast to reference types", test_cast_to_reference } + }; + + const test_case_iterator begin = test_cases; + const test_case_iterator end = + test_cases + (sizeof test_cases / sizeof *test_cases); +} + +namespace any_tests // test definitions +{ + using namespace boost; + + void test_default_ctor() + { + const any value; + + check_true(value.empty(), "empty"); + check_null(any_cast<int>(&value), "any_cast<int>"); + check_equal(value.type(), typeid(void), "type"); + } + + void test_converting_ctor() + { + std::string text = "test message"; + any value = text; + + check_false(value.empty(), "empty"); + check_equal(value.type(), typeid(std::string), "type"); + check_null(any_cast<int>(&value), "any_cast<int>"); + check_non_null(any_cast<std::string>(&value), "any_cast<std::string>"); + check_equal( + any_cast<std::string>(value), text, + "comparing cast copy against original text"); + check_unequal( + any_cast<std::string>(&value), &text, + "comparing address in copy against original text"); + } + + void test_copy_ctor() + { + std::string text = "test message"; + any original = text, copy = original; + + check_false(copy.empty(), "empty"); + check_equal(original.type(), copy.type(), "type"); + check_equal( + any_cast<std::string>(original), any_cast<std::string>(copy), + "comparing cast copy against original"); + check_equal( + text, any_cast<std::string>(copy), + "comparing cast copy against original text"); + check_unequal( + any_cast<std::string>(&original), + any_cast<std::string>(©), + "comparing address in copy against original"); + } + + void test_copy_assign() + { + std::string text = "test message"; + any original = text, copy; + any * assign_result = &(copy = original); + + check_false(copy.empty(), "empty"); + check_equal(original.type(), copy.type(), "type"); + check_equal( + any_cast<std::string>(original), any_cast<std::string>(copy), + "comparing cast copy against cast original"); + check_equal( + text, any_cast<std::string>(copy), + "comparing cast copy against original text"); + check_unequal( + any_cast<std::string>(&original), + any_cast<std::string>(©), + "comparing address in copy against original"); + check_equal(assign_result, ©, "address of assignment result"); + } + + void test_converting_assign() + { + std::string text = "test message"; + any value; + any * assign_result = &(value = text); + + check_false(value.empty(), "type"); + check_equal(value.type(), typeid(std::string), "type"); + check_null(any_cast<int>(&value), "any_cast<int>"); + check_non_null(any_cast<std::string>(&value), "any_cast<std::string>"); + check_equal( + any_cast<std::string>(value), text, + "comparing cast copy against original text"); + check_unequal( + any_cast<std::string>(&value), + &text, + "comparing address in copy against original text"); + check_equal(assign_result, &value, "address of assignment result"); + } + + void test_bad_cast() + { + std::string text = "test message"; + any value = text; + + TEST_CHECK_THROW( + any_cast<const char *>(value), + bad_any_cast, + "any_cast to incorrect type"); + } + + void test_swap() + { + std::string text = "test message"; + any original = text, swapped; + std::string * original_ptr = any_cast<std::string>(&original); + any * swap_result = &original.swap(swapped); + + check_true(original.empty(), "empty on original"); + check_false(swapped.empty(), "empty on swapped"); + check_equal(swapped.type(), typeid(std::string), "type"); + check_equal( + text, any_cast<std::string>(swapped), + "comparing swapped copy against original text"); + check_non_null(original_ptr, "address in pre-swapped original"); + check_equal( + original_ptr, + any_cast<std::string>(&swapped), + "comparing address in swapped against original"); + check_equal(swap_result, &original, "address of swap result"); + } + + void test_null_copying() + { + const any null; + any copied = null, assigned; + assigned = null; + + check_true(null.empty(), "empty on null"); + check_true(copied.empty(), "empty on copied"); + check_true(assigned.empty(), "empty on copied"); + } + + void test_cast_to_reference() + { + any a(137); + const any b(a); + + int & ra = any_cast<int &>(a); + int const & ra_c = any_cast<int const &>(a); + int volatile & ra_v = any_cast<int volatile &>(a); + int const volatile & ra_cv = any_cast<int const volatile&>(a); + + check_true( + &ra == &ra_c && &ra == &ra_v && &ra == &ra_cv, + "cv references to same obj"); + + int const & rb_c = any_cast<int const &>(b); + int const volatile & rb_cv = any_cast<int const volatile &>(b); + + check_true(&rb_c == &rb_cv, "cv references to copied const obj"); + check_true(&ra != &rb_c, "copies hold different objects"); + + ++ra; + int incremented = any_cast<int>(a); + check_true(incremented == 138, "increment by reference changes value"); + + TEST_CHECK_THROW( + any_cast<char &>(a), + bad_any_cast, + "any_cast to incorrect reference type"); + + TEST_CHECK_THROW( + any_cast<const char &>(b), + bad_any_cast, + "any_cast to incorrect const reference type"); + } + +} + +// Copyright Kevlin Henney, 2000, 2001. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// diff --git a/libs/any/doc/any.xml b/libs/any/doc/any.xml new file mode 100644 index 0000000000..6bf9475cac --- /dev/null +++ b/libs/any/doc/any.xml @@ -0,0 +1,483 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.0//EN" + "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd"> +<library name="Any" dirname="any" xmlns:xi="http://www.w3.org/2001/XInclude" + id="any" last-revision="$Date: 2009-07-26 16:11:03 -0400 (Sun, 26 Jul 2009) $"> + <libraryinfo> + <author> + <firstname>Kevlin</firstname> + <surname>Henney</surname> + </author> + + <copyright> + <year>2001</year> + <holder>Kevlin Henney</holder> + </copyright> + + <librarypurpose> + Safe, generic container for single values of different value types + </librarypurpose> + <librarycategory name="category:data-structures"/> + + <legalnotice> + <para>Distributed under the Boost Software License, Version 1.0. + (See accompanying file <filename>LICENSE_1_0.txt</filename> or copy at + <ulink + url="http://www.boost.org/LICENSE_1_0.txt">http://www.boost.org/LICENSE_1_0.txt</ulink>) + </para> + </legalnotice> + </libraryinfo> + + <title>Boost.Any</title> + + <section> + <title>Introduction</title> + + <para>There are times when a generic (in the sense of + <emphasis>general</emphasis> as opposed to + <emphasis>template-based programming</emphasis>) 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:</para> + + <itemizedlist> + <listitem> + <para>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. + <code><functionname>boost::lexical_cast</functionname></code> + supports such conversion functionality.</para> + </listitem> + <listitem> + <para> + 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.</para> + </listitem> + <listitem> + <para> + 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.</para> + </listitem> + </itemizedlist> + + <para>The <code><classname>boost::any</classname></code> class + (based on the class of the same name described in <ulink + url="http://www.two-sdg.demon.co.uk/curbralan/papers/ValuedConversions.pdf">"Valued + Conversions"</ulink> by Kevlin Henney, <emphasis>C++ + Report</emphasis> 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.</para> + </section> + + <section> + <title>Examples</title> + + <using-namespace name="boost"/> + <using-class name="boost::any"/> + + <para>The following code demonstrates the syntax for using + implicit conversions to and copying of any objects:</para> + +<programlisting name="any.example.first"> +#include <list> +#include <boost/any.hpp> + +using <functionname>boost::any_cast</functionname>; +typedef std::list<<classname>boost::any</classname>> many; + +void append_int(many & values, int value) +{ + <classname>boost::any</classname> 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 <classname>boost::any</classname> & value) +{ + values.push_back(value); +} + +void append_nothing(many & values) +{ + values.push_back(<classname>boost::any</classname>()); +} +</programlisting> + + <para>The following predicates follow on from the previous + definitions and demonstrate the use of queries on any + objects:</para> + +<programlisting name="any.example.second"> +bool is_empty(const <classname>boost::any</classname> & operand) +{ + return operand.<methodname>empty</methodname>(); +} + +bool is_int(const <classname>boost::any</classname> & operand) +{ + return operand.<methodname>type</methodname>() == typeid(int); +} + +bool is_char_ptr(const <classname>boost::any</classname> & operand) +{ + try + { + <functionname>any_cast</functionname><const char *>(operand); + return true; + } + catch(const <classname>boost::bad_any_cast</classname> &) + { + return false; + } +} + +bool is_string(const <classname>boost::any</classname> & operand) +{ + return <functionname>any_cast</functionname><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; +} +</programlisting> + + <para>The following type, patterned after the OMG's Property Service, defines name-value pairs for arbitrary value types:</para> + +<programlisting> +struct property +{ + property(); + property(const std::string &, const <classname>boost::any</classname> &); + + std::string name; + <classname>boost::any</classname> value; +}; + +typedef std::list<property> properties; +</programlisting> + + <para>The following base class demonstrates one approach to + runtime polymorphism based callbacks that also require arbitrary + argument types. The absence of virtual 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:</para> + +<programlisting> +class consumer +{ +public: + virtual void notify(const <classname>any</classname> &) = 0; + ... +}; +</programlisting> + </section> + + <library-reference> + <section id="any.ValueType"> + <title><emphasis>ValueType</emphasis> requirements</title> + + <para>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.</para> + + <para>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.</para> + + <para>The specific requirements on value types to be used in an + <code><classname alt="boost::any">any</classname></code> + are:</para> + + <itemizedlist spacing="compact"> + <listitem><simpara>A <emphasis>ValueType</emphasis> is + <emphasis>CopyConstructible</emphasis> [20.1.3].</simpara> + </listitem> + + <listitem><simpara>A <emphasis>ValueType</emphasis> is + optionally <emphasis>Assignable</emphasis> [23.1]. The strong + exception-safety guarantee is required for all forms of + assignment.</simpara> + </listitem> + + <listitem><simpara>The destructor for a + <emphasis>ValueType</emphasis> upholds the no-throw + exception-safety guarantee.</simpara> + </listitem> + </itemizedlist> + </section> + + <header name="boost/any.hpp"> + <namespace name="boost"> + <class name="bad_any_cast"> + <inherit access="public"> + <classname>std::bad_cast</classname> + </inherit> + <purpose>The exception thrown in the event of a failed + <code><functionname>any_cast</functionname></code> of an + <code><classname>any</classname></code> value.</purpose> + + <method name="what" specifiers="virtual" cv="const"> + <type>const char *</type> + </method> + </class> + + <class name="any"> + <purpose>A class whose instances can hold instances of any + type that satisfies <link + linkend="any.ValueType">ValueType</link> + requirements.</purpose> + + <constructor> + <postconditions><simpara><code>this-><methodname>empty</methodname>()</code></simpara></postconditions> + </constructor> + + <constructor> + <parameter name="other"> + <paramtype>const <classname>any</classname> &</paramtype> + </parameter> + + <effects><simpara> 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. </simpara></effects> + + <throws><simpara>May fail with a + <code><classname>std::bad_alloc</classname></code> + exception or any exceptions arising from the copy + constructor of the contained type.</simpara></throws> + </constructor> + + <constructor> + <template> + <template-type-parameter name="ValueType"/> + </template> + + <parameter name="value"> + <paramtype>const ValueType &</paramtype> + </parameter> + + <effects><simpara>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>.</simpara></effects> + + <throws><simpara><code><classname>std::bad_alloc</classname></code> + or any exceptions arising from the copy constructor of the + contained type.</simpara></throws> + </constructor> + + <destructor> + <effects><simpara>Releases any and all resources used in + management of instance.</simpara></effects> + <throws><simpara>Nothing.</simpara></throws> + </destructor> + + <copy-assignment> + <type><classname>any</classname> &</type> + + <parameter name="rhs"> + <paramtype>const <classname>any</classname> &</paramtype> + </parameter> + + <effects><simpara>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.<methodname>empty</methodname>()</code>.</simpara></effects> + + <throws><simpara><code><classname>std::bad_alloc</classname></code> + or any exceptions arising from the copy constructor of the + contained type. Assignment satisfies the strong guarantee + of exception safety.</simpara></throws> + </copy-assignment> + + <copy-assignment> + <template> + <template-type-parameter name="ValueType"/> + </template> + + <type><classname>any</classname> &</type> + + <parameter name="rhs"> + <paramtype>const ValueType &</paramtype> + </parameter> + + <effects><simpara>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>.</simpara></effects> + + <throws><simpara><code><classname>std::bad_alloc</classname></code> + or any exceptions arising from the copy constructor of the + contained type. Assignment satisfies the strong guarantee + of exception safety.</simpara></throws> + </copy-assignment> + + <method-group name="modifiers"> + <method name="swap"> + <type><classname>any</classname> &</type> + + <parameter name="rhs"> + <paramtype><classname>any</classname> &</paramtype> + </parameter> + + <effects><simpara>Exchange of the contents of + <code>*this</code> and + <code>rhs</code>.</simpara></effects> + + <returns><simpara><code>*this</code></simpara></returns> + + <throws><simpara>Nothing.</simpara></throws> + </method> + </method-group> + + <method-group name="queries"> + <method name="empty" cv="const"> + <type>bool</type> + + <returns><simpara><code>true</code> if instance is + empty, otherwise <code>false</code>.</simpara></returns> + + <throws><simpara>Will not throw.</simpara></throws> + </method> + + <method name="type" cv="const"> + <type>const <classname>std::type_info</classname> &</type> + + <returns><simpara>the <code>typeid</code> of the + contained value if instance is non-empty, otherwise + <code>typeid(void)</code>.</simpara></returns> + + <notes><simpara>Useful for querying against types known + either at compile time or only at + runtime.</simpara></notes> + </method> + </method-group> + </class> + + <overloaded-function name="any_cast"> + <signature> + <template> + <template-type-parameter name="T"/> + </template> + + <type>T</type> + + <parameter name="operand"> + <paramtype><classname>any</classname> &</paramtype> + </parameter> + </signature> + + <signature> + <template> + <template-type-parameter name="T"/> + </template> + + <type>T</type> + + <parameter name="operand"> + <paramtype>const <classname>any</classname> &</paramtype> + </parameter> + </signature> + + <signature> + <template> + <template-type-parameter name="ValueType"/> + </template> + + <type>const ValueType *</type> + + <parameter name="operand"> + <paramtype>const <classname>any</classname> *</paramtype> + </parameter> + </signature> + + <signature> + <template> + <template-type-parameter name="ValueType"/> + </template> + + <type>ValueType *</type> + + <parameter name="operand"> + <paramtype><classname>any</classname> *</paramtype> + </parameter> + </signature> + + <purpose><simpara>Custom keyword cast for extracting a value + of a given type from an + <code><classname>any</classname></code>.</simpara></purpose> + + <returns><simpara> If passed a pointer, it returns a + similarly qualified pointer to the value content if + successful, otherwise null is returned. + If T is ValueType, it returns a copy of the held value, otherwise, if T is a reference + to (possibly const qualified) ValueType, it returns a reference to the held + value.</simpara></returns> + + <throws><simpara>Overloads taking an + <code><classname>any</classname></code> pointer do not + throw; overloads taking an + <code><classname>any</classname></code> value or reference + throws <code><classname>bad_any_cast</classname></code> if + unsuccessful.</simpara></throws> + + </overloaded-function> + </namespace> + </header> + </library-reference> + + <section> + <title>Acknowledgements</title> + + <para>Doug Gregor ported the documentation to the BoostBook format.</para> + </section> +</library> diff --git a/libs/any/index.html b/libs/any/index.html new file mode 100644 index 0000000000..18d07f16b7 --- /dev/null +++ b/libs/any/index.html @@ -0,0 +1,14 @@ +<html> +<head> +<meta http-equiv="refresh" content="0; URL=../../doc/html/any.html"> +</head> +<body> +Automatic redirection failed, please go to +<a href="../../doc/html/any.html">../../doc/html/any.html</a> +<hr> +<p>© Copyright Beman Dawes, 2001</p> +<p> Distributed under the Boost Software +License, Version 1.0. (See accompanying file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"> +www.boost.org/LICENSE_1_0.txt</a>)</p> +</body> +</html>
\ No newline at end of file diff --git a/libs/any/test.hpp b/libs/any/test.hpp new file mode 100644 index 0000000000..f75f9ebd84 --- /dev/null +++ b/libs/any/test.hpp @@ -0,0 +1,321 @@ +// what: simple unit test framework +// who: developed by Kevlin Henney +// when: November 2000 +// where: tested with BCC 5.5, MSVC 6.0, and g++ 2.91 + +#ifndef TEST_INCLUDED +#define TEST_INCLUDED + +#include <boost/config.hpp> +#include <exception> +#include <iostream> +#ifdef BOOST_NO_STRINGSTREAM +#include <strstream> // for out-of-the-box g++ pre-2.95.3 +#else +#include <sstream> +#endif +#include <string> + +namespace any_tests // test tuple comprises name and nullary function (object) +{ + template<typename string_type, typename function_type> + struct test + { + string_type name; + function_type action; + + static test make(string_type name, function_type action) + { + test result; // MSVC aggreggate initializer bugs + result.name = name; + result.action = action; + return result; + } + }; +} + +namespace any_tests // failure exception used to indicate checked test failures +{ + class failure : public std::exception + { + public: // struction (default cases are OK) + + failure(const std::string & why) throw() + : reason(why) + { + } + + ~failure() throw() {} + + public: // usage + + virtual const char * what() const throw() + { + return reason.c_str(); + } + + private: // representation + + std::string reason; + + }; +} + +namespace any_tests // not_implemented exception used to mark unimplemented tests +{ + class not_implemented : public std::exception + { + public: // usage (default ctor and dtor are OK) + + virtual const char * what() const throw() + { + return "not implemented"; + } + + }; +} + +namespace any_tests // test utilities +{ + inline void check(bool condition, const std::string & description) + { + if(!condition) + { + throw failure(description); + } + } + + inline void check_true(bool value, const std::string & description) + { + check(value, "expected true: " + description); + } + + inline void check_false(bool value, const std::string & description) + { + check(!value, "expected false: " + description); + } + + template<typename lhs_type, typename rhs_type> + void check_equal( + const lhs_type & lhs, const rhs_type & rhs, + const std::string & description) + { + check(lhs == rhs, "expected equal values: " + description); + } + + template<typename lhs_type, typename rhs_type> + void check_unequal( + const lhs_type & lhs, const rhs_type & rhs, + const std::string & description) + { + check(lhs != rhs, "expected unequal values: " + description); + } + + inline void check_null(const void * ptr, const std::string & description) + { + check(!ptr, "expected null pointer: " + description); + } + + inline void check_non_null(const void * ptr, const std::string & description) + { + check(ptr, "expected non-null pointer: " + description); + } +} + +#define TEST_CHECK_THROW(expression, exception, description) \ + try \ + { \ + expression; \ + throw ::any_tests::failure(description); \ + } \ + catch(exception &) \ + { \ + } + +namespace any_tests // memory tracking (enabled if test new and delete linked in) +{ + class allocations + { + public: // singleton access + + static allocations & instance() + { + static allocations singleton; + return singleton; + } + + public: // logging + + void clear() + { + alloc_count = dealloc_count = 0; + } + + void allocation() + { + ++alloc_count; + } + + void deallocation() + { + ++dealloc_count; + } + + public: // reporting + + unsigned long allocated() const + { + return alloc_count; + } + + unsigned long deallocated() const + { + return dealloc_count; + } + + bool balanced() const + { + return alloc_count == dealloc_count; + } + + private: // structors (default dtor is fine) + + allocations() + : alloc_count(0), dealloc_count(0) + { + } + + private: // prevention + + allocations(const allocations &); + allocations & operator=(const allocations &); + + private: // state + + unsigned long alloc_count, dealloc_count; + + }; +} + +namespace any_tests // tester is the driver class for a sequence of tests +{ + template<typename test_iterator> + class tester + { + public: // structors (default destructor is OK) + + tester(test_iterator first_test, test_iterator after_last_test) + : begin(first_test), end(after_last_test) + { + } + + public: // usage + + bool operator()(); // returns true if all tests passed + + private: // representation + + test_iterator begin, end; + + private: // prevention + + tester(const tester &); + tester &operator=(const tester &); + + }; + +#if defined(__GNUC__) && defined(__SGI_STL_PORT) && (__GNUC__ < 3) + // function scope using declarations don't work: + using namespace std; +#endif + + template<typename test_iterator> + bool tester<test_iterator>::operator()() + { + using std::cerr; + using std::endl; + using std::ends; + using std::exception; + using std::flush; + using std::string; + + unsigned long passed = 0, failed = 0, unimplemented = 0; + + for(test_iterator current = begin; current != end; ++current) + { + cerr << "[" << current->name << "] " << flush; + string result = "passed"; // optimistic + + try + { + allocations::instance().clear(); + current->action(); + + if(!allocations::instance().balanced()) + { + unsigned long allocated = allocations::instance().allocated(); + unsigned long deallocated = allocations::instance().deallocated(); +#ifdef BOOST_NO_STRINGSTREAM + std::ostrstream report; +#else + std::ostringstream report; +#endif + report << "new/delete (" + << allocated << " allocated, " + << deallocated << " deallocated)" + << ends; + const string text = report.str(); +#ifdef BOOST_NO_STRINGSTREAM + report.freeze(false); +#endif + throw failure(text); + } + + ++passed; + } + catch(const failure & caught) + { + (result = "failed: ") += caught.what(); + ++failed; + } + catch(const not_implemented &) + { + result = "not implemented"; + ++unimplemented; + } + catch(const exception & caught) + { + (result = "exception: ") += caught.what(); + ++failed; + } + catch(...) + { + result = "failed with unknown exception"; + ++failed; + } + + cerr << result << endl; + } + + cerr << (passed + failed) << " tests: " + << passed << " passed, " + << failed << " failed"; + + if(unimplemented) + { + cerr << " (" << unimplemented << " not implemented)"; + } + + cerr << endl; + + return failed == 0; + } +} + +#endif + +// Copyright Kevlin Henney, 2000. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) diff --git a/libs/any/test/Jamfile.v2 b/libs/any/test/Jamfile.v2 new file mode 100644 index 0000000000..86a808b7fe --- /dev/null +++ b/libs/any/test/Jamfile.v2 @@ -0,0 +1,14 @@ +# Copyright Vladimur Prus 2005. Use, modification and +# distribution is subject to the Boost Software License, Version +# 1.0. (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) +# +# For more information, see http://www.boost.org/libs/any +# + +test-suite any : + [ run ../any_test.cpp ] + [ compile-fail any_cast_cv_failed.cpp ] + ; + + diff --git a/libs/any/test/any_cast_cv_failed.cpp b/libs/any/test/any_cast_cv_failed.cpp new file mode 100644 index 0000000000..860240f177 --- /dev/null +++ b/libs/any/test/any_cast_cv_failed.cpp @@ -0,0 +1,14 @@ +// Copyright 2006 Alexander Nasonov. +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include <boost/any.hpp> + +int main() +{ + boost::any const a; + boost::any_cast<int&>(a); +} + |