Revision: 407 Author: alai04 Date: Mon May 31 02:08:39 2010 Log: 升级至1.43.0,第6批,libs/目录t-z子目录 新增 functional/factory 和 functional/forward 两个子库 http://code.google.com/p/boost-doc-zh/source/detail?r=407 Added: /trunk/libs/functional/factory /trunk/libs/functional/factory/doc /trunk/libs/functional/factory/doc/Jamfile /trunk/libs/functional/factory/doc/factory.qbk /trunk/libs/functional/factory/doc/html /trunk/libs/functional/factory/doc/html/boostbook.css /trunk/libs/functional/factory/doc/html/index.html /trunk/libs/functional/factory/index.html /trunk/libs/functional/factory/test /trunk/libs/functional/factory/test/Jamfile /trunk/libs/functional/factory/test/factory.cpp /trunk/libs/functional/factory/test/factory_with_allocator.cpp /trunk/libs/functional/factory/test/value_factory.cpp /trunk/libs/functional/forward /trunk/libs/functional/forward/doc /trunk/libs/functional/forward/doc/Jamfile /trunk/libs/functional/forward/doc/forward.qbk /trunk/libs/functional/forward/doc/html /trunk/libs/functional/forward/doc/html/boostbook.css /trunk/libs/functional/forward/doc/html/index.html /trunk/libs/functional/forward/index.html /trunk/libs/functional/forward/test /trunk/libs/functional/forward/test/Jamfile /trunk/libs/functional/forward/test/forward_adapter.cpp /trunk/libs/functional/forward/test/lightweight_forward_adapter.cpp /trunk/libs/unordered/doc/diagrams/buckets.svg /trunk/libs/unordered/doc/src_code /trunk/libs/unordered/doc/src_code/dictionary.cpp /trunk/libs/unordered/doc/src_code/intro.cpp /trunk/libs/unordered/doc/src_code/point1.cpp /trunk/libs/unordered/doc/src_code/point2.cpp /trunk/libs/utility/addressof_fn_test.cpp /trunk/libs/utility/addressof_test2.cpp /trunk/libs/utility/binary_test.cpp /trunk/libs/utility/swap /trunk/libs/utility/swap/test /trunk/libs/utility/swap/test/Jamfile.v2 /trunk/libs/utility/swap/test/array_of_array_of_class.cpp /trunk/libs/utility/swap/test/array_of_array_of_int.cpp /trunk/libs/utility/swap/test/array_of_class.cpp /trunk/libs/utility/swap/test/array_of_int.cpp /trunk/libs/utility/swap/test/array_of_template.cpp /trunk/libs/utility/swap/test/lib_header_1.cpp /trunk/libs/utility/swap/test/lib_header_2.cpp /trunk/libs/utility/swap/test/mixed_headers_1.cpp /trunk/libs/utility/swap/test/mixed_headers_2.cpp /trunk/libs/utility/swap/test/no_ambiguity_in_boost.cpp /trunk/libs/utility/swap/test/primitive.cpp /trunk/libs/utility/swap/test/root_header_1.cpp /trunk/libs/utility/swap/test/root_header_2.cpp /trunk/libs/utility/swap/test/specialized_in_boost.cpp /trunk/libs/utility/swap/test/specialized_in_boost_and_other.cpp /trunk/libs/utility/swap/test/specialized_in_global.cpp /trunk/libs/utility/swap/test/specialized_in_other.cpp /trunk/libs/utility/swap/test/specialized_in_std.cpp /trunk/libs/utility/swap/test/std_bitset.cpp /trunk/libs/utility/swap/test/std_dateorder.cpp /trunk/libs/utility/swap/test/std_string.cpp /trunk/libs/utility/swap/test/std_typeinfo_ptr.cpp /trunk/libs/utility/swap/test/std_vector_of_boost.cpp /trunk/libs/utility/swap/test/std_vector_of_global.cpp /trunk/libs/utility/swap/test/std_vector_of_other.cpp /trunk/libs/utility/swap/test/swap_test_class.hpp /trunk/libs/uuid/test/compile_name_generator.cpp /trunk/libs/uuid/test/compile_nil_generator.cpp /trunk/libs/uuid/test/compile_random_generator.cpp /trunk/libs/uuid/test/compile_string_generator.cpp /trunk/libs/uuid/test/compile_uuid.cpp /trunk/libs/uuid/test/compile_uuid_generators.cpp /trunk/libs/uuid/test/compile_uuid_io.cpp /trunk/libs/uuid/test/compile_uuid_serialize.cpp /trunk/libs/uuid/test/lightweight_test_ex.hpp /trunk/libs/uuid/test/test_name_generator.cpp /trunk/libs/uuid/test/test_nil_generator.cpp /trunk/libs/uuid/test/test_random_generator.cpp /trunk/libs/uuid/test/test_string_generator.cpp Deleted: /trunk/libs/uuid/test/compile_uuid_generators_h.cpp /trunk/libs/uuid/test/compile_uuid_h.cpp /trunk/libs/uuid/test/compile_uuid_io_h.cpp /trunk/libs/uuid/test/compile_uuid_serialize_h.cpp Modified: /trunk/libs/libraries.htm /trunk/libs/thread/doc/once.qbk /trunk/libs/type_traits/doc/extent.qbk /trunk/libs/type_traits/doc/rank.qbk /trunk/libs/type_traits/doc/remove_pointer.qbk /trunk/libs/unordered/doc/Jamfile.v2 /trunk/libs/unordered/doc/changes.qbk /trunk/libs/unordered/doc/ref.xml /trunk/libs/utility/base_from_member_test.cpp /trunk/libs/utility/call_traits_test.cpp /trunk/libs/utility/operators_test.cpp /trunk/libs/utility/ref_test.cpp /trunk/libs/utility/value_init_test.cpp /trunk/libs/uuid/test/Jamfile.v2 /trunk/libs/uuid/test/test_include1.cpp /trunk/libs/uuid/test/test_include2.cpp /trunk/libs/uuid/test/test_io.cpp /trunk/libs/uuid/test/test_serialization.cpp /trunk/libs/uuid/test/test_sha1.cpp /trunk/libs/uuid/test/test_tagging.cpp /trunk/libs/uuid/test/test_uuid.cpp /trunk/libs/uuid/test/test_uuid_class.cpp /trunk/libs/uuid/test/test_wserialization.cpp ======================================= --- /dev/null +++ /trunk/libs/functional/factory/doc/Jamfile Mon May 31 02:08:39 2010 @@ -0,0 +1,20 @@ + +# (C) Copyright Tobias Schwinger +#+# Use modification and distribution are subject to the boost Software License,
+# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). + +using quickbook ; + +xml factory : factory.qbk ; +boostbook standalone : factory + : + <xsl:param>boost.root=../../../../.. + <xsl:param>boost.libraries=../../../../libraries.htm + <xsl:param>chunk.section.depth=0 + <xsl:param>chunk.first.sections=0 + <xsl:param>generate.section.toc.level=2 + <xsl:param>toc.max.depth=1 + ; + + ======================================= --- /dev/null +++ /trunk/libs/functional/factory/doc/factory.qbk Mon May 31 02:08:39 2010 @@ -0,0 +1,384 @@ +[library Boost.Functional/Factory + [quickbook 1.3] + [version 1.0] + [authors [Schwinger, Tobias]] + [copyright 2007 2008 Tobias Schwinger] + [license + 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]) + ] + [purpose Function object templates for object creation.] + [category higher-order] + [category generic] + [last-revision $Date: 2008/11/01 21:44:52 $] +] + +[def __boost_bind__ [@http://www.boost.org/libs/bind/bind.html Boost.Bind]]+[def __boost__bind__ [@http://www.boost.org/libs/bind/bind.html `boost::bind`]]
++[def __boost__forward_adapter__ [@http://www.boost.org/libs/functional/forward/doc/index.html `boost::forward_adapter`]] +[def __fusion_functional_adapters__ [@http://www.boost.org/libs/fusion/doc/html/functional.html Fusion Functional Adapters]]
++[def __boost_function__ [@http://www.boost.org/doc/html/function.html Boost.Function]] +[def __boost__function__ [@http://www.boost.org/doc/html/function.html `boost::function`]]
++[def __smart_pointers__ [@http://www.boost.org/libs/smart_ptr/index.html Smart Pointers]] +[def __boost__shared_ptr__ [@http://www.boost.org/libs/smart_ptr/shared_ptr.htm `boost::shared_ptr`]]
+ +[def __std__map__ [@http://www.sgi.com/tech/stl/map.html `std::map`]]+[def __std__string__ [@http://www.sgi.com/tech/stl/string.html `std::string`]] +[def __std_allocator__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocator]] +[def __std_allocators__ [@http://www.sgi.com/tech/stl/concepts/allocator.html Allocators]]
++[def __boost__ptr_map__ [@http://www.boost.org/libs/ptr_container/doc/ptr_map.html `__boost__ptr_map__`]]
+ +[def __boost__factory__ `boost::factory`] +[def __boost__value_factory__ `boost::value_factory`] + +[def __factory__ `factory`] +[def __value_factory__ `value_factory`] + + +[section Brief Description] + +The template __boost__factory__ lets you encapsulate a `new` expression +as a function object, __boost__value_factory__ encapsulates a constructor +invocation without `new`. + + __boost__factory__<T*>()(arg1,arg2,arg3) + // same as new T(arg1,arg2,arg3) + + __boost__value_factory__<T>()(arg1,arg2,arg3) + // same as T(arg1,arg2,arg3) + +For technical reasons the arguments to the function objects have to be +LValues. A factory that also accepts RValues can be composed using the +__boost__forward_adapter__ or __boost__bind__. + +[endsect] + +[section Background] ++In traditional Object Oriented Programming a Factory is an object implementing +an interface of one or more methods that construct objects conforming to known
+interfaces. + + // assuming a_concrete_class and another_concrete_class are derived + // from an_abstract_class + + class a_factory + { + public: + virtual an_abstract_class* create() const = 0; + virtual ~a_factory() { } + }; + + class a_concrete_factory : public a_factory + { + public: + virtual an_abstract_class* create() const + { + return new a_concrete_class(); + } + }; + + class another_concrete_factory : public a_factory + { + public: + virtual an_abstract_class* create() const + { + return new another_concrete_class(); + } + }; + + // [...] + + int main() + { + __boost__ptr_map__<__std__string__,a_factory> factories; + + // [...] + + factories.insert("a_name",std::auto_ptr<a_factory>( + new a_concrete_factory)); + factories.insert("another_name",std::auto_ptr<a_factory>( + new another_concrete_factory)); + + // [...] ++ std::auto_ptr<an_abstract_factory> x = factories[some_name]->create();
+ + // [...] + } + +This approach has several drawbacks. The most obvious one is that there is +lots of boilerplate code. In other words there is too much code to express +a rather simple intention. We could use templates to get rid of some of it +but the approach remains inflexible: + + o We may want a factory that takes some arguments that are forwarded to + the constructor, + o we will probably want to use smart pointers, + o we may want several member functions to create different kinds of + objects, + o we might not necessarily need a polymorphic base class for the objects, + o as we will see, we do not need a factory base class at all, + o we might want to just call the constructor - without `new` to create + an object on the stack, and + o finally we might want to use customized memory management. ++Experience has shown that using function objects and generic Boost components
+for their composition, Design Patterns that describe callback mechasisms +(typically requiring a high percentage of boilerplate code with pure Object+Oriented methodology) become implementable with just few code lines and without
+extra classes. + +Factories are callback mechanisms for constructors, so we provide two class +templates, __boost__value_factory__ and __boost__factory__, that encasulate +object construction via direct application of the constructor and the `new` +operator, respectively. + +We let the function objects forward their arguments to the construction +expressions they encapsulate. Overthis __boost__factory__ optionally allows +the use of smart pointers and __std_allocators__. + +Compile-time polymorphism can be used where appropriate, + + template< class T > + void do_something() + { + // [...] + T x = T(a,b); + + // for conceptually similar objects x we neither need virtual + // functions nor a common base class in this context. + // [...] + } ++Now, to allow inhomogenous signaturs for the constructors of the types passed +in for `T` we can use __value_factory__ and __boost__bind__ to normalize between
+them. + + template< class ValueFactory > + void do_something(ValueFactory make_obj = ValueFactory()) + { + // [...] + typename ValueFactory::result_type x = make_obj(a,b); + + // for conceptually similar objects x we neither need virtual + // functions nor a common base class in this context. + // [...] + } + + int main() + { + // [...] + + do_something(__boost__value_factory__<X>()); + do_something(boost::bind(__boost__value_factory__<Y>(),_1,5,_2)); + // construct X(a,b) and Y(a,5,b), respectively. + + // [...] + } + +Maybe we want our objects to outlive the function's scope, in this case we +have to use dynamic allocation; + + template< class Factory > + whatever do_something(Factory new_obj = Factory()) + { + typename Factory::result_type ptr = new_obj(a,b); + + // again, no common base class or virtual functions needed, + // we could enforce a polymorphic base by writing e.g. + // boost::shared_ptr<base> + // instead of + // typename Factory::result_type + // above. + // Note that we are also free to have the type erasure happen + // somewhere else (e.g. in the constructor of this function's + // result type). + + // [...] + } + + // [... call do_something like above but with __factory__ instead + // of __value_factory__] + +Although we might have created polymorphic objects in the previous example, +we have used compile time polymorphism for the factory. If we want to erase +the type of the factory and thus allow polymorphism at run time, we can +use __boost_function__ to do so. The first example can be rewritten as +follows. + + typedef boost::function< an_abstract_class*() > a_factory; + + // [...] + + int main() + { + __std__map__<__std__string__,a_factory> factories; + + // [...] + + factories["a_name"] = __boost__factory__<a_concrete_class*>(); + factories["another_name"] = + __boost__factory__<another_concrete_class*>(); + + // [...] + } + +Of course we can just as easy create factories that take arguments and/or +return __smart_pointers__. + +[endsect] + + +[section:reference Reference] + + +[section value_factory] + +[heading Description] + +Function object template that invokes the constructor of the type `T`. + +[heading Header] + #include <boost/functional/value_factory.hpp> + +[heading Synopsis] + + namespace boost + { + template< typename T > + class value_factory; + } + +[variablelist Notation+ [[`T`] [an arbitrary type with at least one public constructor]]
+ [[`a0`...`aN`] [argument LValues to a constructor of `T`]] + [[`F`] [the type `value_factory<F>`]] + [[`f`] [an instance object of `F`]] +] + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]] + [[`F()`] [creates an object of type `F`.]] + [[`F(f)`] [creates an object of type `F`.]] + [[`f(a0`...`aN)`] [returns `T(a0`...`aN)`.]] + [[`F::result_type`] [is the type `T`.]] +] + +[heading Limits] ++The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set the
+maximum arity. It defaults to 10. + +[endsect] + + +[section factory] + +[heading Description] + +Function object template that dynamically constructs a pointee object for +the type of pointer given as template argument. Smart pointers may be used+for the template argument, given that `boost::pointee<Pointer>::type` yields
+the pointee type. + +If an __allocator__ is given, it is used for memory allocation and the +placement form of the `new` operator is used to construct the object. +A function object that calls the destructor and deallocates the memory +with a copy of the Allocator is used for the second constructor argument +of `Pointer` (thus it must be a __smart_pointer__ that provides a suitable +constructor, such as __boost__shared_ptr__). + +If a third template argument is `factory_passes_alloc_to_smart_pointer`,+the allocator itself is used for the third constructor argument of `Pointer`
+(__boost__shared_ptr__ then uses the allocator to manage the memory of its +seperately allocated reference counter). + +[heading Header] + #include <boost/functional/factory.hpp> + +[heading Synopsis] + + namespace boost + { + enum factory_alloc_propagation + { + factory_alloc_for_pointee_and_deleter, + factory_passes_alloc_to_smart_pointer + }; + + template< typename Pointer, + class Allocator = boost::none_t, + factory_alloc_propagation AllocProp = + factory_alloc_for_pointee_and_deleter > + class factory; + } + +[variablelist Notation+ [[`T`] [an arbitrary type with at least one public constructor]]
+ [[`P`] [pointer or smart pointer to `T`]] + [[`a0`...`aN`] [argument LValues to a constructor of `T`]] + [[`F`] [the type `factory<P>`]] + [[`f`] [an instance object of `F`]] +] + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]] + [[`F()`] [creates an object of type `F`.]] + [[`F(f)`] [creates an object of type `F`.]] + [[`f(a0`...`aN)`] [dynamically creates an object of type `T` using + `a0`...`aN` as arguments for the constructor invocation.]]+ [[`F::result_type`] [is the type `P` with top-level cv-qualifiers removed.]]
+] + +[heading Limits] + +The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the +maximum arity. It defaults to 10. + +[endsect] + +[endsect] + +[section Acknowledgements] + +Eric Niebler requested a function to invoke a type's constructor (with the+arguments supplied as a Tuple) as a Fusion feature. These Factory utilities are
+a factored-out generalization of this idea. ++Dave Abrahams suggested Smart Pointer support for exception safety, providing
+useful hints for the implementation. + +Joel de Guzman's documentation style was copied from Fusion. + +Further, I want to thank Peter Dimov for sharing his insights on language +details and their evolution. + +[endsect] + +[section References] + +# [@http://en.wikipedia.org/wiki/Design_Patterns Design Patterns], + Gamma et al. - Addison Wesley Publishing, 1995 ++# [@http://www.sgi.com/tech/stl/ Standard Template Library Programmer's Guide],
+ Hewlett-Packard Company, 1994 + +# [@http://www.boost.org/libs/bind/bind.html Boost.Bind], + Peter Dimov, 2001-2005 + +# [@http://www.boost.org/doc/html/function.html Boost.Function], + Douglas Gregor, 2001-2004 + +[endsect] + + ======================================= --- /dev/null+++ /trunk/libs/functional/factory/doc/html/boostbook.css Mon May 31 02:08:39 2010
@@ -0,0 +1,528 @@ +/*============================================================================= + Copyright (c) 2004 Joel de Guzman + http://spirit.sourceforge.net/ + + 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) +=============================================================================*/ + +/*============================================================================= + Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= + Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= + Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 9pt; + } + + pre.synopsis + { + font-size: 90%; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 9pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + /* Program listings in tables don't get borders */ + td .programlisting, + td .screen + { + margin: 0pc 0pc 0pc 0pc; + padding: 0pc 0pc 0pc 0pc; + } + +/*============================================================================= + Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font: 140% } + h2 { font: bold 140% } + h3 { font: bold 130% } + h4 { font: bold 120% } + h5 { font: italic 110% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 120% } + h5 tt.computeroutput { font-size: 110% } + h6 tt.computeroutput { font-size: 100% } + +/*============================================================================= + Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= + Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= + Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= + Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= + Table of contents +=============================================================================*/ + + .toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 80%; + line-height: 1.15; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + font-size: 9pt; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 80%; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + font-size: 9pt; /* A little bit smaller than the main text */ + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.0pc 0.5pc; + } + + div.sidebar img + { + padding: 1pt; + } + +/*============================================================================= + Callouts +=============================================================================*/ + .line_callout_bug img + { + float: left; + position:relative; + left: 4px; + top: -12px; + clear: left; + margin-left:-22px; + } + + .callout_bug img + { + } + +/*============================================================================= + Variable Lists +=============================================================================*/ + + /* Make the terms in definition lists bold */ + div.variablelist dl dt, + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + + div.variablelist dl dt + { + margin-bottom: 0.2em; + } + + div.variablelist dl dd + { + margin: 0em 0em 0.5em 2em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p, + div.variablelist dl dd p + { + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + /* Links */ + a + { + color: #005a9c; + } + + a:visited + { + color: #9c5a9c; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #FFFFFF; } + .dk_grey_bkd { background-color: #999999; } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + border: 1px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #F0F0F0; + border: 1px solid #DCDCDC; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + } + + .programlisting, + .screen + { + border: 1px solid gray; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid gray; + } + + .informaltable table, + .table table + { + border: 1px solid gray; + border-collapse: collapse; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid gray; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid gray; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } ======================================= --- /dev/null+++ /trunk/libs/functional/factory/doc/html/index.html Mon May 31 02:08:39 2010
@@ -0,0 +1,598 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Chapter 1. Boost.Functional/Factory 1.0</title> +<link rel="stylesheet" href="boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">+<link rel="start" href="index.html" title="Chapter 1. Boost.Functional/Factory 1.0">
+</head>+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>+<td align="center"><a href="http://www.boost.org/users/people.html";>People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html";>FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"></div> +<div class="chapter" lang="en"> +<div class="titlepage"><div> +<div><h2 class="title">+<a name="boost_functional_factory"></a>Chapter 1. Boost.Functional/Factory 1.0</h2></div>
+<div><div class="author"><h3 class="author">+<span class="firstname">Tobias</span> <span class="surname">Schwinger</span>
+</h3></div></div> +<div><p class="copyright">Copyright (c) 2007, 2008 Tobias Schwinger</p></div> +<div><div class="legalnotice"> +<a name="id934161"></a><p>+ Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"; target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p> +</div></div> +</div></div> +<div class="toc"> +<p><b>Table of Contents</b></p> +<dl>+<dt><span class="section"><a href="index.html#boost_functional_factory.brief_description">Brief Description</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_factory.background">Background</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_factory.reference"> Reference</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_factory.acknowledgements">Acknowledgements</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_factory.references">References</a></span></dt>
+</dl> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_factory.brief_description"></a><a href="index.html#boost_functional_factory.brief_description" title="Brief Description">Brief Description</a></h2></div></div></div>
+<p>+ The template <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code> lets you encapsulate a <code class="computeroutput"><span class="keyword">new</span></code> expression as a function object, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code> + encapsulates a constructor invocation without <code class="computeroutput"><span class="keyword">new</span></code>.
+ </p>+<pre class="programlisting"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code><span class="special"><</span><span class="identifier">T</span><span class="special">*>()(</span><span class="identifier">arg1</span><span class="special">,</span><span class="identifier">arg2</span><span class="special">,</span><span class="identifier">arg3</span><span class="special">)</span>
+<span class="comment">// same as new T(arg1,arg2,arg3) +</span>+<code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code><span class="special"><</span><span class="identifier">T</span><span class="special">>()(</span><span class="identifier">arg1</span><span class="special">,</span><span class="identifier">arg2</span><span class="special">,</span><span class="identifier">arg3</span><span class="special">)</span>
+<span class="comment">// same as T(arg1,arg2,arg3) +</span></pre> +<p>+ For technical reasons the arguments to the function objects have to be LValues. + A factory that also accepts RValues can be composed using the <a href="http://www.boost.org/libs/functional/forward/doc/index.html"; target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_adapter</span></code></a> + or <a href="http://www.boost.org/libs/bind/bind.html"; target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span></code></a>.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_factory.background"></a><a href="index.html#boost_functional_factory.background" title="Background">Background</a></h2></div></div></div>
+<p>+ In traditional Object Oriented Programming a Factory is an object implementing + an interface of one or more methods that construct objects conforming to known
+ interfaces. + </p>+<pre class="programlisting"><span class="comment">// assuming a_concrete_class and another_concrete_class are derived
+</span><span class="comment">// from an_abstract_class +</span>+<span class="keyword">class</span> <span class="identifier">a_factory</span>
+<span class="special">{</span> + <span class="keyword">public</span><span class="special">:</span>+ <span class="keyword">virtual</span> <span class="identifier">an_abstract_class</span><span class="special">*</span> <span class="identifier">create</span><span class="special">()</span> <span class="keyword">const</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span> + <span class="keyword">virtual</span> <span class="special">~</span><span class="identifier">a_factory</span><span class="special">()</span> <span class="special">{</span> <span class="special">}</span>
+<span class="special">};</span> ++<span class="keyword">class</span> <span class="identifier">a_concrete_factory</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">a_factory</span>
+<span class="special">{</span> + <span class="keyword">public</span><span class="special">:</span>+ <span class="keyword">virtual</span> <span class="identifier">an_abstract_class</span><span class="special">*</span> <span class="identifier">create</span><span class="special">()</span> <span class="keyword">const</span>
+ <span class="special">{</span>+ <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">a_concrete_class</span><span class="special">();</span>
+ <span class="special">}</span> +<span class="special">};</span> ++<span class="keyword">class</span> <span class="identifier">another_concrete_factory</span> <span class="special">:</span> <span class="keyword">public</span> <span class="identifier">a_factory</span>
+<span class="special">{</span> + <span class="keyword">public</span><span class="special">:</span>+ <span class="keyword">virtual</span> <span class="identifier">an_abstract_class</span><span class="special">*</span> <span class="identifier">create</span><span class="special">()</span> <span class="keyword">const</span>
+ <span class="special">{</span>+ <span class="keyword">return</span> <span class="keyword">new</span> <span class="identifier">another_concrete_class</span><span class="special">();</span>
+ <span class="special">}</span> +<span class="special">};</span> + +<span class="comment">// [...] +</span>+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span>+ <a href="http://www.boost.org/libs/ptr_container/doc/ptr_map.html"; target="_top"><code class="computeroutput"><span class="identifier">__boost__ptr_map__</span></code></a><span class="special"><</span><a href="http://www.sgi.com/tech/stl/string.html"; target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code></a><span class="special">,</span><span class="identifier">a_factory</span><span class="special">></span> <span class="identifier">factories</span><span class="special">;</span>
+ + <span class="comment">// [...] +</span>+ <span class="identifier">factories</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="string">"a_name"</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special"><</span><span class="identifier">a_factory</span><span class="special">>(</span> + <span class="keyword">new</span> <span class="identifier">a_concrete_factory</span><span class="special">));</span> + <span class="identifier">factories</span><span class="special">.</span><span class="identifier">insert</span><span class="special">(</span><span class="string">"another_name"</span><span class="special">,</span><span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special"><</span><span class="identifier">a_factory</span><span class="special">>(</span> + <span class="keyword">new</span> <span class="identifier">another_concrete_factory</span><span class="special">));</span>
+ + <span class="comment">// [...] +</span>+ <span class="identifier">std</span><span class="special">::</span><span class="identifier">auto_ptr</span><span class="special"><</span><span class="identifier">an_abstract_factory</span><span class="special">></span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">factories</span><span class="special">[</span><span class="identifier">some_name</span><span class="special">]-></span><span class="identifier">create</span><span class="special">();</span>
+ + <span class="comment">// [...] +</span><span class="special">}</span> +</pre> +<p>+ This approach has several drawbacks. The most obvious one is that there is + lots of boilerplate code. In other words there is too much code to express + a rather simple intention. We could use templates to get rid of some of it
+ but the approach remains inflexible: + </p>+<pre class="programlisting"><span class="identifier">o</span> <span class="identifier">We</span> <span class="identifier">may</span> <span class="identifier">want</span> <span class="identifier">a</span> <span class="identifier">factory</span> <span class="identifier">that</span> <span class="identifier">takes</span> <span class="identifier">some</span> <span class="identifier">arguments</span> <span class="identifier">that</span> <span class="identifier">are</span> <span class="identifier">forwarded</span> <span class="identifier">to</span> + <span class="identifier">the</span> <span class="identifier">constructor</span><span class="special">,</span> +<span class="identifier">o</span> <span class="identifier">we</span> <span class="identifier">will</span> <span class="identifier">probably</span> <span class="identifier">want</span> <span class="identifier">to</span> <span class="identifier">use</span> <span class="identifier">smart</span> <span class="identifier">pointers</span><span class="special">,</span> +<span class="identifier">o</span> <span class="identifier">we</span> <span class="identifier">may</span> <span class="identifier">want</span> <span class="identifier">several</span> <span class="identifier">member</span> <span class="identifier">functions</span> <span class="identifier">to</span> <span class="identifier">create</span> <span class="identifier">different</span> <span class="identifier">kinds</span> <span class="identifier">of</span>
+ <span class="identifier">objects</span><span class="special">,</span>+<span class="identifier">o</span> <span class="identifier">we</span> <span class="identifier">might</span> <span class="keyword">not</span> <span class="identifier">necessarily</span> <span class="identifier">need</span> <span class="identifier">a</span> <span class="identifier">polymorphic</span> <span class="identifier">base</span> <span class="keyword">class</span> <span class="keyword">for</span> <span class="identifier">the</span> <span class="identifier">objects</span><span class="special">,</span> +<span class="identifier">o</span> <span class="identifier">as</span> <span class="identifier">we</span> <span class="identifier">will</span> <span class="identifier">see</span><span class="special">,</span> <span class="identifier">we</span> <span class="keyword">do</span> <span class="keyword">not</span> <span class="identifier">need</span> <span class="identifier">a</span> <span class="identifier">factory</span> <span class="identifier">base</span> <span class="keyword">class</span> <span class="identifier">at</span> <span class="identifier">all</span><span class="special">,</span> +<span class="identifier">o</span> <span class="identifier">we</span> <span class="identifier">might</span> <span class="identifier">want</span> <span class="identifier">to</span> <span class="identifier">just</span> <span class="identifier">call</span> <span class="identifier">the</span> <span class="identifier">constructor</span> <span class="special">-</span> <span class="identifier">without</span> #<span class="keyword">new</span># <span class="identifier">to</span> <span class="identifier">create</span> + <span class="identifier">an</span> <span class="identifier">object</span> <span class="identifier">on</span> <span class="identifier">the</span> <span class="identifier">stack</span><span class="special">,</span> <span class="keyword">and</span> +<span class="identifier">o</span> <span class="identifier">finally</span> <span class="identifier">we</span> <span class="identifier">might</span> <span class="identifier">want</span> <span class="identifier">to</span> <span class="identifier">use</span> <span class="identifier">customized</span> <span class="identifier">memory</span> <span class="identifier">management</span><span class="special">.</span>
+</pre> +<p>+ Experience has shown that using function objects and generic Boost components + for their composition, Design Patterns that describe callback mechasisms (typically + requiring a high percentage of boilerplate code with pure Object Oriented methodology) + become implementable with just few code lines and without extra classes.
+ </p> +<p>+ Factories are callback mechanisms for constructors, so we provide two class + templates, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code> and <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code>, + that encasulate object construction via direct application of the constructor + and the <code class="computeroutput"><span class="keyword">new</span></code> operator, respectively.
+ </p> +<p>+ We let the function objects forward their arguments to the construction expressions + they encapsulate. Overthis <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code> + optionally allows the use of smart pointers and <a href="http://www.sgi.com/tech/stl/concepts/allocator.html"; target="_top">Allocators</a>.
+ </p> +<p> + Compile-time polymorphism can be used where appropriate, + </p>+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">T</span> <span class="special">></span> +<span class="keyword">void</span> <span class="identifier">do_something</span><span class="special">()</span>
+<span class="special">{</span> + <span class="comment">// [...]+</span> <span class="identifier">T</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">T</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">);</span>
++ <span class="comment">// for conceptually similar objects x we neither need virtual +</span> <span class="comment">// functions nor a common base class in this context.
+</span> <span class="comment">// [...] +</span><span class="special">}</span> +</pre> +<p>+ Now, to allow inhomogenous signaturs for the constructors of the types passed + in for <code class="computeroutput"><span class="identifier">T</span></code> we can use <code class="computeroutput"><span class="identifier">value_factory</span></code> and <a href="http://www.boost.org/libs/bind/bind.html"; target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span></code></a>
+ to normalize between them. + </p>+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">ValueFactory</span> <span class="special">></span> +<span class="keyword">void</span> <span class="identifier">do_something</span><span class="special">(</span><span class="identifier">ValueFactory</span> <span class="identifier">make_obj</span> <span class="special">=</span> <span class="identifier">ValueFactory</span><span class="special">())</span>
+<span class="special">{</span> + <span class="comment">// [...]+</span> <span class="keyword">typename</span> <span class="identifier">ValueFactory</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">x</span> <span class="special">=</span> <span class="identifier">make_obj</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">);</span>
++ <span class="comment">// for conceptually similar objects x we neither need virtual +</span> <span class="comment">// functions nor a common base class in this context.
+</span> <span class="comment">// [...] +</span><span class="special">}</span> ++<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span> + <span class="comment">// [...] +</span>+ <span class="identifier">do_something</span><span class="special">(</span><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code><span class="special"><</span><span class="identifier">X</span><span class="special">>());</span> + <span class="identifier">do_something</span><span class="special">(</span><span class="identifier">boost</span><span class="special">::</span><span class="identifier">bind</span><span class="special">(</span><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">value_factory</span></code><span class="special"><</span><span class="identifier">Y</span><span class="special">>(),</span><span class="identifier">_1</span><span class="special">,</span><span class="number">5</span><span class="special">,</span><span class="identifier">_2</span><span class="special">));</span>
+ <span class="comment">// construct X(a,b) and Y(a,5,b), respectively. +</span> + <span class="comment">// [...] +</span><span class="special">}</span> +</pre> +<p>+ Maybe we want our objects to outlive the function's scope, in this case we
+ have to use dynamic allocation; + </p>+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Factory</span> <span class="special">></span> +<span class="identifier">whatever</span> <span class="identifier">do_something</span><span class="special">(</span><span class="identifier">Factory</span> <span class="identifier">new_obj</span> <span class="special">=</span> <span class="identifier">Factory</span><span class="special">())</span>
+<span class="special">{</span>+ <span class="keyword">typename</span> <span class="identifier">Factory</span><span class="special">::</span><span class="identifier">result_type</span> <span class="identifier">ptr</span> <span class="special">=</span> <span class="identifier">new_obj</span><span class="special">(</span><span class="identifier">a</span><span class="special">,</span><span class="identifier">b</span><span class="special">);</span>
++ <span class="comment">// again, no common base class or virtual functions needed, +</span> <span class="comment">// we could enforce a polymorphic base by writing e.g.
+</span> <span class="comment">// boost::shared_ptr<base> +</span> <span class="comment">// instead of +</span> <span class="comment">// typename Factory::result_type +</span> <span class="comment">// above.+</span> <span class="comment">// Note that we are also free to have the type erasure happen +</span> <span class="comment">// somewhere else (e.g. in the constructor of this function's
+</span> <span class="comment">// result type). +</span> + <span class="comment">// [...] +</span><span class="special">}</span> ++<span class="comment">// [... call do_something like above but with __factory__ instead
+</span><span class="comment">// of __value_factory__] +</span></pre> +<p>+ Although we might have created polymorphic objects in the previous example, + we have used compile time polymorphism for the factory. If we want to erase + the type of the factory and thus allow polymorphism at run time, we can use + <a href="http://www.boost.org/doc/html/function.html"; target="_top">Boost.Function</a>
+ to do so. The first example can be rewritten as follows. + </p>+<pre class="programlisting"><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">function</span><span class="special"><</span> <span class="identifier">an_abstract_class</span><span class="special">*()</span> <span class="special">></span> <span class="identifier">a_factory</span><span class="special">;</span>
+ +<span class="comment">// [...] +</span>+<span class="keyword">int</span> <span class="identifier">main</span><span class="special">()</span>
+<span class="special">{</span>+ <a href="http://www.sgi.com/tech/stl/map.html"; target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">map</span></code></a><span class="special"><</span><a href="http://www.sgi.com/tech/stl/string.html"; target="_top"><code class="computeroutput"><span class="identifier">std</span><span class="special">::</span><span class="identifier">string</span></code></a><span class="special">,</span><span class="identifier">a_factory</span><span class="special">></span> <span class="identifier">factories</span><span class="special">;</span>
+ + <span class="comment">// [...] +</span>+ <span class="identifier">factories</span><span class="special">[</span><span class="string">"a_name"</span><span class="special">]</span> <span class="special">=</span> <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code><span class="special"><</span><span class="identifier">a_concrete_class</span><span class="special">*>();</span> + <span class="identifier">factories</span><span class="special">[</span><span class="string">"another_name"</span><span class="special">]</span> <span class="special">=</span> + <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">factory</span></code><span class="special"><</span><span class="identifier">another_concrete_class</span><span class="special">*>();</span>
+ + <span class="comment">// [...] +</span><span class="special">}</span> +</pre> +<p>+ Of course we can just as easy create factories that take arguments and/or return + <a href="http://www.boost.org/libs/smart_ptr/index.html"; target="_top">Smart Pointers</a>.
+ </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_factory.reference"></a><a href="index.html#boost_functional_factory.reference" title=" Reference"> Reference</a></h2></div></div></div>
+<div class="toc"><dl>+<dt><span class="section"><a href="index.html#boost_functional_factory.reference.value_factory">value_factory</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_factory.reference.factory">factory</a></span></dt>
+</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_functional_factory.reference.value_factory"></a><a href="index.html#boost_functional_factory.reference.value_factory" title="value_factory">value_factory</a></h3></div></div></div> +<a name="boost_functional_factory.reference.value_factory.description"></a><h4>
+<a name="id936876"></a>+ <a href="index.html#boost_functional_factory.reference.value_factory.description">Description</a>
+ </h4> +<p>+ Function object template that invokes the constructor of the type <code class="computeroutput"><span class="identifier">T</span></code>.
+ </p> +<a name="boost_functional_factory.reference.value_factory.header"></a><h4> +<a name="id936914"></a>+ <a href="index.html#boost_functional_factory.reference.value_factory.header">Header</a>
+ </h4>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">value_factory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>+<a name="boost_functional_factory.reference.value_factory.synopsis"></a><h4>
+<a name="id936989"></a>+ <a href="index.html#boost_functional_factory.reference.value_factory.synopsis">Synopsis</a>
+ </h4>+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span>+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> + <span class="keyword">class</span> <span class="identifier">value_factory</span><span class="special">;</span>
+<span class="special">}</span> +</pre> +<div class="variablelist"> +<p class="title"><b>Notation</b></p> +<dl>+<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span></code></span></dt>
+<dd><p> + an arbitrary type with at least one public constructor + </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
+<dd><p>+ argument LValues to a constructor of <code class="computeroutput"><span class="identifier">T</span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
+<dd><p>+ the type <code class="computeroutput"><span class="identifier">value_factory</span><span class="special"><</span><span class="identifier">F</span><span class="special">></span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
+<dd><p>+ an instance object of <code class="computeroutput"><span class="identifier">F</span></code>
+ </p></dd> +</dl> +</div>+<a name="boost_functional_factory.reference.value_factory.expression_semantics"></a><h4>
+<a name="id937226"></a>+ <a href="index.html#boost_functional_factory.reference.value_factory.expression_semantics">Expression
+ Semantics</a> + </h4> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Semantics + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">F</span><span class="special">()</span></code>
+ </p> + </td> +<td> + <p>+ creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">F</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
+ </p> + </td> +<td> + <p>+ creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
+ </p> + </td> +<td> + <p>+ returns <code class="computeroutput"><span class="identifier">T</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">result_type</span></code>
+ </p> + </td> +<td> + <p>+ is the type <code class="computeroutput"><span class="identifier">T</span></code>.
+ </p> + </td> +</tr> +</tbody> +</table></div> +<a name="boost_functional_factory.reference.value_factory.limits"></a><h4> +<a name="id937498"></a>+ <a href="index.html#boost_functional_factory.reference.value_factory.limits">Limits</a>
+ </h4> +<p>+ The macro BOOST_FUNCTIONAL_VALUE_FACTORY_MAX_ARITY can be defined to set
+ the maximum arity. It defaults to 10. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_functional_factory.reference.factory"></a><a href="index.html#boost_functional_factory.reference.factory" title="factory">factory</a></h3></div></div></div>
+<a name="boost_functional_factory.reference.factory.description"></a><h4> +<a name="id937545"></a>+ <a href="index.html#boost_functional_factory.reference.factory.description">Description</a>
+ </h4> +<p>+ Function object template that dynamically constructs a pointee object for + the type of pointer given as template argument. Smart pointers may be used + for the template argument, given that <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">pointee</span><span class="special"><</span><span class="identifier">Pointer</span><span class="special">>::</span><span class="identifier">type</span></code>
+ yields the pointee type. + </p> +<p>+ If an <span class="underline">_allocator</span>_ is given, it is used + for memory allocation and the placement form of the <code class="computeroutput"><span class="keyword">new</span></code> + operator is used to construct the object. A function object that calls the + destructor and deallocates the memory with a copy of the Allocator is used + for the second constructor argument of <code class="computeroutput"><span class="identifier">Pointer</span></code>
+ (thus it must be a __smart<span class="underline">pointer</span>_+ that provides a suitable constructor, such as <a href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm"; target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span></code></a>).
+ </p> +<p>+ If a third template argument is <code class="computeroutput"><span class="identifier">factory_passes_alloc_to_smart_pointer</span></code>, + the allocator itself is used for the third constructor argument of <code class="computeroutput"><span class="identifier">Pointer</span></code> (<a href="http://www.boost.org/libs/smart_ptr/shared_ptr.htm"; target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">shared_ptr</span></code></a> then uses the allocator + to manage the memory of its seperately allocated reference counter).
+ </p> +<a name="boost_functional_factory.reference.factory.header"></a><h4> +<a name="id937729"></a>+ <a href="index.html#boost_functional_factory.reference.factory.header">Header</a>
+ </h4>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">factory</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre> +<a name="boost_functional_factory.reference.factory.synopsis"></a><h4> +<a name="id937804"></a>+ <a href="index.html#boost_functional_factory.reference.factory.synopsis">Synopsis</a>
+ </h4>+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span>+ <span class="keyword">enum</span> <span class="identifier">factory_alloc_propagation</span>
+ <span class="special">{</span>+ <span class="identifier">factory_alloc_for_pointee_and_deleter</span><span class="special">,</span> + <span class="identifier">factory_passes_alloc_to_smart_pointer</span>
+ <span class="special">};</span> ++ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">Pointer</span><span class="special">,</span> + <span class="keyword">class</span> <span class="identifier">Allocator</span> <span class="special">=</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">none_t</span><span class="special">,</span> + <span class="identifier">factory_alloc_propagation</span> <span class="identifier">AllocProp</span> <span class="special">=</span> + <span class="identifier">factory_alloc_for_pointee_and_deleter</span> <span class="special">></span> + <span class="keyword">class</span> <span class="identifier">factory</span><span class="special">;</span>
+<span class="special">}</span> +</pre> +<div class="variablelist"> +<p class="title"><b>Notation</b></p> +<dl>+<dt><span class="term"><code class="computeroutput"><span class="identifier">T</span></code></span></dt>
+<dd><p> + an arbitrary type with at least one public constructor + </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">P</span></code></span></dt>
+<dd><p>+ pointer or smart pointer to <code class="computeroutput"><span class="identifier">T</span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
+<dd><p>+ argument LValues to a constructor of <code class="computeroutput"><span class="identifier">T</span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
+<dd><p>+ the type <code class="computeroutput"><span class="identifier">factory</span><span class="special"><</span><span class="identifier">P</span><span class="special">></span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
+<dd><p>+ an instance object of <code class="computeroutput"><span class="identifier">F</span></code>
+ </p></dd> +</dl> +</div>+<a name="boost_functional_factory.reference.factory.expression_semantics"></a><h4>
+<a name="id938169"></a>+ <a href="index.html#boost_functional_factory.reference.factory.expression_semantics">Expression
+ Semantics</a> + </h4> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Semantics + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">F</span><span class="special">()</span></code>
+ </p> + </td> +<td> + <p>+ creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">F</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
+ </p> + </td> +<td> + <p>+ creates an object of type <code class="computeroutput"><span class="identifier">F</span></code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">f</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
+ </p> + </td> +<td> + <p>+ dynamically creates an object of type <code class="computeroutput"><span class="identifier">T</span></code> + using <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code> as arguments for the constructor
+ invocation. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">F</span><span class="special">::</span><span class="identifier">result_type</span></code>
+ </p> + </td> +<td> + <p>+ is the type <code class="computeroutput"><span class="identifier">P</span></code> with
+ top-level cv-qualifiers removed. + </p> + </td> +</tr> +</tbody> +</table></div> +<a name="boost_functional_factory.reference.factory.limits"></a><h4> +<a name="id938440"></a>+ <a href="index.html#boost_functional_factory.reference.factory.limits">Limits</a>
+ </h4> +<p>+ The macro BOOST_FUNCTIONAL_FACTORY_MAX_ARITY can be defined to set the maximum
+ arity. It defaults to 10. + </p> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_factory.acknowledgements"></a><a href="index.html#boost_functional_factory.acknowledgements" title="Acknowledgements">Acknowledgements</a></h2></div></div></div>
+<p>+ Eric Niebler requested a function to invoke a type's constructor (with the + arguments supplied as a Tuple) as a Fusion feature. These Factory utilities
+ are a factored-out generalization of this idea. + </p> +<p>+ Dave Abrahams suggested Smart Pointer support for exception safety, providing
+ useful hints for the implementation. + </p> +<p> + Joel de Guzman's documentation style was copied from Fusion. + </p> +<p>+ Further, I want to thank Peter Dimov for sharing his insights on language details
+ and their evolution. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_factory.references"></a><a href="index.html#boost_functional_factory.references" title="References">References</a></h2></div></div></div>
+<div class="orderedlist"><ol type="1"> +<li>+<a href="http://en.wikipedia.org/wiki/Design_Patterns"; target="_top">Design Patterns</a>,
+ Gamma et al. - Addison Wesley Publishing, 1995 + </li> +<li>+<a href="http://www.sgi.com/tech/stl/"; target="_top">Standard Template Library Programmer's
+ Guide</a>, Hewlett-Packard Company, 1994 + </li> +<li>+<a href="http://www.boost.org/libs/bind/bind.html"; target="_top">Boost.Bind</a>,
+ Peter Dimov, 2001-2005 + </li> +<li>+<a href="http://www.boost.org/doc/html/function.html"; target="_top">Boost.Function</a>,
+ Douglas Gregor, 2001-2004 + </li> +</ol></div> +</div> +</div>+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision"; width="100%"><tr> +<td align="left"><p><small>Last revised: November 01, 2008 at 21:44:52 GMT</small></p></td>
+<td align="right"><div class="copyright-footer"></div></td> +</tr></table> +<hr> +<div class="spirit-nav"></div> +</body> +</html> ======================================= --- /dev/null +++ /trunk/libs/functional/factory/index.html Mon May 31 02:08:39 2010 @@ -0,0 +1,15 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <meta http-equiv="refresh" content="0; URL=doc/html/index.html"> + </head> + <body> + Automatic redirection failed, click this + <a href="doc/html/index.html">link</a> <hr> + <p>(c) Copyright Tobias Schwinger, 2009</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> ======================================= --- /dev/null +++ /trunk/libs/functional/factory/test/Jamfile Mon May 31 02:08:39 2010 @@ -0,0 +1,18 @@ + +# (C) Copyright Tobias Schwinger +#+# Use modification and distribution are subject to the boost Software License,
+# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). + +import testing ; + +project factory-tests + ; + +test-suite functional/factory + : + [ run value_factory.cpp ] + [ run factory.cpp ] + [ run factory_with_allocator.cpp ] + ; + ======================================= --- /dev/null +++ /trunk/libs/functional/factory/test/factory.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,36 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are 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). +==============================================================================*/ + +#include <boost/functional/factory.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <memory> + +class sum +{ + int val_sum; + public: + sum(int a, int b) : val_sum(a + b) { } + + operator int() const { return this->val_sum; } +}; + +int main() +{ + int one = 1, two = 2; + { + sum* instance( boost::factory< sum* >()(one,two) ); + BOOST_TEST(*instance == 3); + } + {+ std::auto_ptr<sum> instance( boost::factory< std::auto_ptr<sum>
()(one,two) );
+ BOOST_TEST(*instance == 3); + } + return boost::report_errors(); +} + ======================================= --- /dev/null+++ /trunk/libs/functional/factory/test/factory_with_allocator.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,79 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are 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). +==============================================================================*/ + +#include <boost/functional/factory.hpp> +#include <boost/detail/lightweight_test.hpp> + +#include <cstddef> +#include <memory> +#include <boost/shared_ptr.hpp> + +using std::size_t; + +class sum +{ + int val_sum; + public: + sum(int a, int b) : val_sum(a + b) { } + + operator int() const { return this->val_sum; } +}; + +template< typename T > +class counting_allocator : public std::allocator<T> +{ + public: + counting_allocator() + { } + + template< typename OtherT > + struct rebind { typedef counting_allocator<OtherT> other; }; + + template< typename OtherT > + counting_allocator(counting_allocator<OtherT> const& that) + { } + + static size_t n_allocated; + T* allocate(size_t n, void const* hint = 0l) + { + n_allocated += 1; + return std::allocator<T>::allocate(n,hint); + } + + static size_t n_deallocated; + void deallocate(T* ptr, size_t n) + { + n_deallocated += 1; + return std::allocator<T>::deallocate(ptr,n); + } +}; +template< typename T > size_t counting_allocator<T>::n_allocated = 0; +template< typename T > size_t counting_allocator<T>::n_deallocated = 0; + +int main() +{ + int one = 1, two = 2; + { + boost::shared_ptr<sum> instance( + boost::factory< boost::shared_ptr<sum>, counting_allocator<void>, + boost::factory_alloc_for_pointee_and_deleter >()(one,two) ); + BOOST_TEST(*instance == 3); + } + BOOST_TEST(counting_allocator<sum>::n_allocated == 1); + BOOST_TEST(counting_allocator<sum>::n_deallocated == 1); + { + boost::shared_ptr<sum> instance( + boost::factory< boost::shared_ptr<sum>, counting_allocator<void>, + boost::factory_passes_alloc_to_smart_pointer >()(one,two) ); + BOOST_TEST(*instance == 3); + } + BOOST_TEST(counting_allocator<sum>::n_allocated == 2); + BOOST_TEST(counting_allocator<sum>::n_deallocated == 2); + return boost::report_errors(); +} + ======================================= --- /dev/null+++ /trunk/libs/functional/factory/test/value_factory.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,29 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are 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). +==============================================================================*/ + +#include <boost/functional/value_factory.hpp> +#include <boost/detail/lightweight_test.hpp> + +class sum +{ + int val_sum; + public: + sum(int a, int b) : val_sum(a + b) { } + operator int() const { return this->val_sum; } +}; + +int main() +{ + int one = 1, two = 2; + { + sum instance( boost::value_factory< sum >()(one,two) ); + BOOST_TEST(instance == 3); + } + return boost::report_errors(); +} + ======================================= --- /dev/null +++ /trunk/libs/functional/forward/doc/Jamfile Mon May 31 02:08:39 2010 @@ -0,0 +1,19 @@ + +# (C) Copyright Tobias Schwinger +#+# Use modification and distribution are subject to the boost Software License,
+# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). + +using quickbook ; + +xml forward : forward.qbk ; +boostbook standalone : forward + : + <xsl:param>boost.root=../../../../.. + <xsl:param>boost.libraries=../../../../libraries.htm + <xsl:param>chunk.section.depth=0 + <xsl:param>chunk.first.sections=0 + <xsl:param>generate.section.toc.level=2 + <xsl:param>toc.max.depth=1 + ; + ======================================= --- /dev/null +++ /trunk/libs/functional/forward/doc/forward.qbk Mon May 31 02:08:39 2010 @@ -0,0 +1,316 @@ +[library Boost.Functional/Forward + [quickbook 1.3] + [version 1.0] + [authors [Schwinger, Tobias]] + [copyright 2007 2008 Tobias Schwinger] + [license + 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]) + ] + [purpose Function object adapters for generic argument forwarding.] + [category higher-order] + [category generic] + [last-revision $Date: 2008/11/01 19:58:50 $] +] + +[def __unspecified__ /unspecified/]+[def __boost_ref__ [@http://www.boost.org/doc/html/ref.html Boost.Ref]] +[def __boost_result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf]] +[def __boost__result_of__ [@http://www.boost.org/libs/utility/utility.htm#result_of `boost::result_of`]] +[def __the_forwarding_problem__ [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem]] +[def __boost_fusion__ [@http://www.boost.org/libs/fusion/doc/html/index.html Boost.Fusion]]
+ +[section Brief Description] + +`boost::forward_adapter` provides a reusable adapter template for function +objects. It forwards RValues as references to const, while leaving LValues +as-is. + + struct g // function object that only accept LValues + { + template< typename T0, typename T1, typename T2 > + void operator()(T0 & t0, T1 & t1, T2 & t2) const; + + typedef void result_type; + }; + + // Adapted version also accepts RValues and forwards + // them as references to const, LValues as-is + typedef boost::forward_adapter<g> f; + +Another adapter, `boost::lighweight_forward_adapter` allows forwarding with +some help from the user accepting and unwrapping reference wrappers (see+__boost_ref__) for reference arguments, const qualifying all other arguments.
++The target functions must be compatible with __boost_result_of__, and so are
+the adapters. + +[endsect] + +[section Background] + +Let's suppose we have some function `f` that we can call like this: + + f(123,a_variable); + +Now we want to write another, generic function `g` that can be called the +same way and returns some object that calls `f` with the same arguments. + + f(123,a_variable) == g(f,123,a_variable).call_f() + +[heading Why would we want to do it, anyway?] + +Maybe we want to run `f` several times. Or maybe we want to run it within+another thread. Maybe we just want to encapsulate the call expression for now, +and then use it with other code that allows to compose more complex expressions +in order to decompose it with C++ templates and have the compiler generate some
+machinery that eventually calls `f` at runtime (in other words; apply a +technique that is commonly referred to as Expression Templates). + +[heading Now, how do we do it?] + +The bad news is: It's impossible. + +That is so because there is a slight difference between a variable and an +expression that evaluates to its value: Given + + int y; + int const z = 0; + +and + + template< typename T > void func1(T & x); + +we can call + + func1(y); // x is a reference to a non-const object + func1(z); // x is a reference to a const object + +where + + func1(1); // fails to compile. + +This way we can safely have `func1` store its reference argument and the+compiler keeps us from storing a reference to an object with temporary lifetime.
++It is important to realize that non-constness and whether an object binds to a +non-const reference parameter are two different properties. The latter is the +distinction between LValues and RValues. The names stem from the left hand side +and the right hand side of assignment expressions, thus LValues are typically +the ones you can assign to, and RValues the temporary results from the right
+hand side expression. ++ y = 1+2; // a is LValue, 1+2 is the expression producing the RValue,
+ // 1+2 = a; // usually makes no sense. + + func1(y); // works, because y is an LValue + // func1(1+2); // fails to compile, because we only got an RValue. + +If we add const qualification on the parameter, our function also accepts +RValues: + + template< typename T > void func2(T const & x); + + // [...] function scope: + func2(1); // x is a reference to a const temporary, object,+ func2(y); // x is a reference to a const object, while y is not const, and
+ func2(z); // x is a reference to a const object, just like z. + +In all cases, the argument `x` in `func2` is a const-qualified LValue. +We can use function overloading to identify non-const LValues: + + template< typename T > void func3(T const & x); // #1 + template< typename T > void func3(T & x); // #2 + + // [...] function scope: + func3(1); // x is a reference to a const, temporary object in #1, + func3(y); // x is a reference to a non-const object in #2, and + func3(z); // x is a reference to a const object in #1. + +Note that all arguments `x` in the overloaded function `func3` are LValues.+In fact, there is no way to transport RValues into a function as-is in C++98. +Also note that we can't distinguish between what used to be a const qualified
+LValue and an RValue. + +That's as close as we can get to a generic forwarding function `g` as+described above by the means of C++ 98. See __the_forwarding_problem__ for a
+very detailed discussion including solutions that require language changes. + +Now, for actually implementing it, we need 2^N overloads for N parameters +(each with and without const qualifier) for each number of arguments+(that is 2^(Nmax+1) - 2^Nmin). Right, that means the compile-time complexity +is O(2^N), however the factor is low so it works quite well for a reasonable
+number (< 10) of arguments. + +[endsect] + +[section:reference Reference] + +[section forward_adapter] + +[heading Description] ++Function object adapter template whose instances are callable with LValue and +RValue arguments. RValue arguments are forwarded as reference-to-const typed
+LValues. ++An arity can be given as second, numeric non-type template argument to restrict
+forwarding to a specific arity.+If a third, numeric non-type template argument is present, the second and third
+template argument are treated as minimum and maximum arity, respectively. +Specifying an arity can be helpful to improve the readability of diagnostic +messages and compile time performance. ++__boost_result_of__ can be used to determine the result types of specific call
+expressions. + +[heading Header] + #include <boost/functional/forward_adapter.hpp> + +[heading Synopsis] + + namespace boost + { + template< class Function,+ int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ >
+ class forward_adapter; + } + +[variablelist Notation+ [[`F`] [a possibly const qualified function object type or reference type thereof]]
+ [[`f`] [an object convertible to `F`]] + [[`FA`] [the type `forward_adapter<F>`]] + [[`fa`] [an instance object of `FA`, initialized with `f`]] + [[`a0`...`aN`] [arguments to `fa`]] +] + +The result type of a target function invocation must be + + __boost__result_of__<F*(TA0 [const]&...TAN [const]&])>::type + +where `TA0`...`TAN` denote the argument types of `a0`...`aN`. + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]]+ [[`FA(f)`] [creates an adapter, initializes the target function with `f`.]] + [[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]]
+ [[`fa(a0`...`aN)`] [calls `f` with with arguments `a0`...`aN`.]] +] + +[heading Limits] ++The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set the
+maximum call arity. It defaults to 6. + +[heading Complexity] + +Preprocessing time: O(2^N), where N is the arity limit. +Compile time: O(2^N), where N depends on the arity range. +Run time: O(0) if the compiler inlines, O(1) otherwise. + +[endsect] + + +[section lightweight_forward_adapter] + +[heading Description] ++Function object adapter template whose instances are callable with LValue and
+RValue arguments. All arguments are forwarded as reference-to-const typed +LValues, except for reference wrappers which are unwrapped and may yield +non-const LValues. ++An arity can be given as second, numeric non-type template argument to restrict
+forwarding to a specific arity.+If a third, numeric non-type template argument is present, the second and third
+template argument are treated as minimum and maximum arity, respectively. +Specifying an arity can be helpful to improve the readability of diagnostic +messages and compile time performance. ++__boost_result_of__ can be used to determine the result types of specific call
+expressions. + +[heading Header] + #include <boost/functional/lightweight_forward_adapter.hpp> + +[heading Synopsis] + + namespace boost + { + template< class Function,+ int Arity_Or_MinArity = __unspecified__, int MaxArity = __unspecified__ >
+ struct lightweight_forward_adapter; + } + +[variablelist Notation+ [[`F`] [a possibly const qualified function object type or reference type thereof]]
+ [[`f`] [an object convertible to `F`]] + [[`FA`] [the type `lightweight_forward_adapter<F>`]] + [[`fa`] [an instance of `FA`, initialized with `f`]] + [[`a0`...`aN`] [arguments to `fa`]] +] + +The result type of a target function invocation must be + + __boost__result_of__<F*(TA0 [const]&...TAN [const]&])>::type + +where `TA0`...`TAN` denote the argument types of `a0`...`aN`. + +[heading Expression Semantics] + +[table + [[Expression] [Semantics]]+ [[`FA(f)`] [creates an adapter, initializes the target function with `f`.]] + [[`FA()`] [creates an adapter, attempts to use `F`'s default constructor.]] + [[`fa(a0`...`aN)`] [calls `f` with with const arguments `a0`...`aN`. If `aI` is a
+ reference wrapper it is unwrapped.]] +] + +[heading Limits] ++The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined
+to set the maximum call arity. It defaults to 10. + +[heading Complexity] + +Preprocessing time: O(N), where N is the arity limit. +Compile time: O(N), where N is the effective arity of a call. +Run time: O(0) if the compiler inlines, O(1) otherwise. + +[endsect] + +[endsect] + + +[section Acknowledgements] ++As these utilities are factored out of the __boost_fusion__ functional module, +I want to thank Dan Marsden and Joel de Guzman for letting me participate in the
+development of that great library in the first place. + +Further, I want to credit the authors of the references below, for their +in-depth investigation of the problem and the solution implemented here. ++Last but not least I want to thank Vesa Karnoven and Paul Mensonides for the +Boost Preprocessor library. Without it, I would have ended up with an external
+code generator for this one. + +[endsect] + + +[section References] ++# [@http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm The Forwarding Problem],
+ Peter Dimov, Howard E. Hinnant, David Abrahams, 2002 ++# [@http://www.boost.org/libs/utility/utility.htm#result_of Boost.ResultOf],
+ Douglas Gregor, 2004 + +# [@http://www.boost.org/doc/html/ref.html Boost.Ref], + Jaakko Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002 + +[endsect] + ======================================= --- /dev/null+++ /trunk/libs/functional/forward/doc/html/boostbook.css Mon May 31 02:08:39 2010
@@ -0,0 +1,528 @@ +/*============================================================================= + Copyright (c) 2004 Joel de Guzman + http://spirit.sourceforge.net/ + + 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) +=============================================================================*/ + +/*============================================================================= + Body defaults +=============================================================================*/ + + body + { + margin: 1em; + font-family: sans-serif; + } + +/*============================================================================= + Paragraphs +=============================================================================*/ + + p + { + text-align: left; + font-size: 10pt; + line-height: 1.15; + } + +/*============================================================================= + Program listings +=============================================================================*/ + + /* Code on paragraphs */ + p tt.computeroutput + { + font-size: 9pt; + } + + pre.synopsis + { + font-size: 90%; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + .programlisting, + .screen + { + font-size: 9pt; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.5pc 0.5pc; + } + + /* Program listings in tables don't get borders */ + td .programlisting, + td .screen + { + margin: 0pc 0pc 0pc 0pc; + padding: 0pc 0pc 0pc 0pc; + } + +/*============================================================================= + Headings +=============================================================================*/ + + h1, h2, h3, h4, h5, h6 + { + text-align: left; + margin: 1em 0em 0.5em 0em; + font-weight: bold; + } + + h1 { font: 140% } + h2 { font: bold 140% } + h3 { font: bold 130% } + h4 { font: bold 120% } + h5 { font: italic 110% } + h6 { font: italic 100% } + + /* Top page titles */ + title, + h1.title, + h2.title + h3.title, + h4.title, + h5.title, + h6.title, + .refentrytitle + { + font-weight: bold; + margin-bottom: 1pc; + } + + h1.title { font-size: 140% } + h2.title { font-size: 140% } + h3.title { font-size: 130% } + h4.title { font-size: 120% } + h5.title { font-size: 110% } + h6.title { font-size: 100% } + + .section h1 + { + margin: 0em 0em 0.5em 0em; + font-size: 140%; + } + + .section h2 { font-size: 140% } + .section h3 { font-size: 130% } + .section h4 { font-size: 120% } + .section h5 { font-size: 110% } + .section h6 { font-size: 100% } + + /* Code on titles */ + h1 tt.computeroutput { font-size: 140% } + h2 tt.computeroutput { font-size: 140% } + h3 tt.computeroutput { font-size: 130% } + h4 tt.computeroutput { font-size: 120% } + h5 tt.computeroutput { font-size: 110% } + h6 tt.computeroutput { font-size: 100% } + +/*============================================================================= + Author +=============================================================================*/ + + h3.author + { + font-size: 100% + } + +/*============================================================================= + Lists +=============================================================================*/ + + li + { + font-size: 10pt; + line-height: 1.3; + } + + /* Unordered lists */ + ul + { + text-align: left; + } + + /* Ordered lists */ + ol + { + text-align: left; + } + +/*============================================================================= + Links +=============================================================================*/ + + a + { + text-decoration: none; /* no underline */ + } + + a:hover + { + text-decoration: underline; + } + +/*============================================================================= + Spirit style navigation +=============================================================================*/ + + .spirit-nav + { + text-align: right; + } + + .spirit-nav a + { + color: white; + padding-left: 0.5em; + } + + .spirit-nav img + { + border-width: 0px; + } + +/*============================================================================= + Table of contents +=============================================================================*/ + + .toc + { + margin: 1pc 4% 0pc 4%; + padding: 0.1pc 1pc 0.1pc 1pc; + font-size: 80%; + line-height: 1.15; + } + + .boost-toc + { + float: right; + padding: 0.5pc; + } + +/*============================================================================= + Tables +=============================================================================*/ + + .table-title, + div.table p.title + { + margin-left: 4%; + padding-right: 0.5em; + padding-left: 0.5em; + } + + .informaltable table, + .table table + { + width: 92%; + margin-left: 4%; + margin-right: 4%; + } + + div.informaltable table, + div.table table + { + padding: 4px; + } + + /* Table Cells */ + div.informaltable table tr td, + div.table table tr td + { + padding: 0.5em; + text-align: left; + font-size: 9pt; + } + + div.informaltable table tr th, + div.table table tr th + { + padding: 0.5em 0.5em 0.5em 0.5em; + border: 1pt solid white; + font-size: 80%; + } + +/*============================================================================= + Blurbs +=============================================================================*/ + + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + font-size: 9pt; /* A little bit smaller than the main text */ + line-height: 1.2; + display: block; + margin: 1pc 4% 0pc 4%; + padding: 0.5pc 0.5pc 0.0pc 0.5pc; + } + + div.sidebar img + { + padding: 1pt; + } + +/*============================================================================= + Callouts +=============================================================================*/ + .line_callout_bug img + { + float: left; + position:relative; + left: 4px; + top: -12px; + clear: left; + margin-left:-22px; + } + + .callout_bug img + { + } + +/*============================================================================= + Variable Lists +=============================================================================*/ + + /* Make the terms in definition lists bold */ + div.variablelist dl dt, + span.term + { + font-weight: bold; + font-size: 10pt; + } + + div.variablelist table tbody tr td + { + text-align: left; + vertical-align: top; + padding: 0em 2em 0em 0em; + font-size: 10pt; + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + + div.variablelist dl dt + { + margin-bottom: 0.2em; + } + + div.variablelist dl dd + { + margin: 0em 0em 0.5em 2em; + font-size: 10pt; + } + + div.variablelist table tbody tr td p, + div.variablelist dl dd p + { + margin: 0em 0em 0.5em 0em; + line-height: 1; + } + +/*============================================================================= + Misc +=============================================================================*/ + + /* Title of books and articles in bibliographies */ + span.title + { + font-style: italic; + } + + span.underline + { + text-decoration: underline; + } + + span.strikethrough + { + text-decoration: line-through; + } + + /* Copyright, Legal Notice */ + div div.legalnotice p + { + text-align: left + } + +/*============================================================================= + Colors +=============================================================================*/ + + @media screen + { + /* Links */ + a + { + color: #005a9c; + } + + a:visited + { + color: #9c5a9c; + } + + h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, + h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ { + text-decoration: none; /* no underline */ + color: #000000; + } + + /* Syntax Highlighting */ + .keyword { color: #0000AA; } + .identifier { color: #000000; } + .special { color: #707070; } + .preprocessor { color: #402080; } + .char { color: teal; } + .comment { color: #800000; } + .string { color: teal; } + .number { color: teal; } + .white_bkd { background-color: #FFFFFF; } + .dk_grey_bkd { background-color: #999999; } + + /* Copyright, Legal Notice */ + .copyright + { + color: #666666; + font-size: small; + } + + div div.legalnotice p + { + color: #666666; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid #DCDCDC; + } + + .programlisting, + .screen + { + border: 1px solid #DCDCDC; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Blurbs */ + div.note, + div.tip, + div.important, + div.caution, + div.warning, + div.sidebar + { + border: 1px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid #DCDCDC; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid #DCDCDC; + } + + div.informaltable table tr th, + div.table table tr th + { + background-color: #F0F0F0; + border: 1px solid #DCDCDC; + } + + /* Misc */ + span.highlight + { + color: #00A000; + } + } + + @media print + { + /* Links */ + a + { + color: black; + } + + a:visited + { + color: black; + } + + .spirit-nav + { + display: none; + } + + /* Program listing */ + pre.synopsis + { + border: 1px solid gray; + } + + .programlisting, + .screen + { + border: 1px solid gray; + } + + td .programlisting, + td .screen + { + border: 0px solid #DCDCDC; + } + + /* Table of contents */ + .toc + { + border: 1px solid gray; + } + + .informaltable table, + .table table + { + border: 1px solid gray; + border-collapse: collapse; + } + + /* Tables */ + div.informaltable table tr td, + div.table table tr td + { + border: 1px solid gray; + } + + div.informaltable table tr th, + div.table table tr th + { + border: 1px solid gray; + } + + /* Misc */ + span.highlight + { + font-weight: bold; + } + } ======================================= --- /dev/null+++ /trunk/libs/functional/forward/doc/html/index.html Mon May 31 02:08:39 2010
@@ -0,0 +1,564 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> +<title>Chapter 1. Boost.Functional/Forward 1.0</title> +<link rel="stylesheet" href="boostbook.css" type="text/css"> +<meta name="generator" content="DocBook XSL Stylesheets V1.68.1">+<link rel="start" href="index.html" title="Chapter 1. Boost.Functional/Forward 1.0">
+</head>+<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
+<table cellpadding="2" width="100%"><tr>+<td valign="top"><img alt="Boost C++ Libraries" width="277" height="86" src="../../../../../boost.png"></td>
+<td align="center"><a href="../../../../../index.html">Home</a></td> +<td align="center"><a href="../../../../libraries.htm">Libraries</a></td>+<td align="center"><a href="http://www.boost.org/users/people.html";>People</a></td> +<td align="center"><a href="http://www.boost.org/users/faq.html";>FAQ</a></td>
+<td align="center"><a href="../../../../../more/index.htm">More</a></td> +</tr></table> +<hr> +<div class="spirit-nav"></div> +<div class="chapter" lang="en"> +<div class="titlepage"><div> +<div><h2 class="title">+<a name="boost_functional_forward"></a>Chapter 1. Boost.Functional/Forward 1.0</h2></div>
+<div><div class="author"><h3 class="author">+<span class="firstname">Tobias</span> <span class="surname">Schwinger</span>
+</h3></div></div> +<div><p class="copyright">Copyright (c) 2007, 2008 Tobias Schwinger</p></div> +<div><div class="legalnotice"> +<a name="id934161"></a><p>+ Distributed under the Boost Software License, Version 1.0. (See accompanying + file LICENSE_1_0.txt or copy at <a href="http://www.boost.org/LICENSE_1_0.txt"; target="_top">http://www.boost.org/LICENSE_1_0.txt</a>)
+ </p> +</div></div> +</div></div> +<div class="toc"> +<p><b>Table of Contents</b></p> +<dl>+<dt><span class="section"><a href="index.html#boost_functional_forward.brief_description">Brief Description</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_forward.background">Background</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_forward.reference"> Reference</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_forward.acknowledgements">Acknowledgements</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_forward.references">References</a></span></dt>
+</dl> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_forward.brief_description"></a><a href="index.html#boost_functional_forward.brief_description" title="Brief Description">Brief Description</a></h2></div></div></div>
+<p>+ <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_adapter</span></code> provides a reusable adapter + template for function objects. It forwards RValues as references to const,
+ while leaving LValues as-is. + </p>+<pre class="programlisting"><span class="keyword">struct</span> <span class="identifier">g</span> <span class="comment">// function object that only accept LValues
+</span><span class="special">{</span>+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T0</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T1</span><span class="special">,</span> <span class="keyword">typename</span> <span class="identifier">T2</span> <span class="special">></span> + <span class="keyword">void</span> <span class="keyword">operator</span><span class="special">()(</span><span class="identifier">T0</span> <span class="special">&</span> <span class="identifier">t0</span><span class="special">,</span> <span class="identifier">T1</span> <span class="special">&</span> <span class="identifier">t1</span><span class="special">,</span> <span class="identifier">T2</span> <span class="special">&</span> <span class="identifier">t2</span><span class="special">)</span> <span class="keyword">const</span><span class="special">;</span>
++ <span class="keyword">typedef</span> <span class="keyword">void</span> <span class="identifier">result_type</span><span class="special">;</span>
+<span class="special">};</span> + +<span class="comment">// Adapted version also accepts RValues and forwards +</span><span class="comment">// them as references to const, LValues as-is+</span><span class="keyword">typedef</span> <span class="identifier">boost</span><span class="special">::</span><span class="identifier">forward_adapter</span><span class="special"><</span><span class="identifier">g</span><span class="special">></span> <span class="identifier">f</span><span class="special">;</span>
+</pre> +<p>+ Another adapter, <code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">lighweight_forward_adapter</span></code> allows forwarding + with some help from the user accepting and unwrapping reference wrappers (see + <a href="http://www.boost.org/doc/html/ref.html"; target="_top">Boost.Ref</a>) for
+ reference arguments, const qualifying all other arguments. + </p> +<p>+ The target functions must be compatible with <a href="http://www.boost.org/libs/utility/utility.htm#result_of"; target="_top">Boost.ResultOf</a>,
+ and so are the adapters. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_forward.background"></a><a href="index.html#boost_functional_forward.background" title="Background">Background</a></h2></div></div></div>
+<p>+ Let's suppose we have some function <code class="computeroutput"><span class="identifier">f</span></code>
+ that we can call like this: + </p>+<pre class="programlisting"><span class="identifier">f</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">);</span>
+</pre> +<p>+ Now we want to write another, generic function <code class="computeroutput"><span class="identifier">g</span></code> + that can be called the same way and returns some object that calls <code class="computeroutput"><span class="identifier">f</span></code> with the same arguments.
+ </p>+<pre class="programlisting"><span class="identifier">f</span><span class="special">(</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">)</span> <span class="special">==</span> <span class="identifier">g</span><span class="special">(</span><span class="identifier">f</span><span class="special">,</span><span class="number">123</span><span class="special">,</span><span class="identifier">a_variable</span><span class="special">).</span><span class="identifier">call_f</span><span class="special">()</span>
+</pre>+<a name="boost_functional_forward.background.why_would_we_want_to_do_it__anyway_"></a><h3>
+<a name="id934701"></a>+ <a href="index.html#boost_functional_forward.background.why_would_we_want_to_do_it__anyway_">Why
+ would we want to do it, anyway?</a> + </h3> +<p>+ Maybe we want to run <code class="computeroutput"><span class="identifier">f</span></code> several + times. Or maybe we want to run it within another thread. Maybe we just want + to encapsulate the call expression for now, and then use it with other code + that allows to compose more complex expressions in order to decompose it with + C++ templates and have the compiler generate some machinery that eventually + calls <code class="computeroutput"><span class="identifier">f</span></code> at runtime (in other + words; apply a technique that is commonly referred to as Expression Templates).
+ </p>+<a name="boost_functional_forward.background.now__how_do_we_do_it_"></a><h3>
+<a name="id934755"></a>+ <a href="index.html#boost_functional_forward.background.now__how_do_we_do_it_">Now,
+ how do we do it?</a> + </h3> +<p> + The bad news is: It's impossible. + </p> +<p>+ That is so because there is a slight difference between a variable and an expression
+ that evaluates to its value: Given + </p>+<pre class="programlisting"><span class="keyword">int</span> <span class="identifier">y</span><span class="special">;</span> +<span class="keyword">int</span> <span class="keyword">const</span> <span class="identifier">z</span> <span class="special">=</span> <span class="number">0</span><span class="special">;</span>
+</pre> +<p> + and + </p>+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func1</span><span class="special">(</span><span class="identifier">T</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span>
+</pre> +<p> + we can call + </p>+<pre class="programlisting"><span class="identifier">func1</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a non-const object +</span><span class="identifier">func1</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object
+</span></pre> +<p> + where + </p>+<pre class="programlisting"><span class="identifier">func1</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// fails to compile.
+</span></pre> +<p>+ This way we can safely have <code class="computeroutput"><span class="identifier">func1</span></code> + store its reference argument and the compiler keeps us from storing a reference
+ to an object with temporary lifetime. + </p> +<p>+ It is important to realize that non-constness and whether an object binds to + a non-const reference parameter are two different properties. The latter is + the distinction between LValues and RValues. The names stem from the left hand + side and the right hand side of assignment expressions, thus LValues are typically + the ones you can assign to, and RValues the temporary results from the right
+ hand side expression. + </p>+<pre class="programlisting"><span class="identifier">y</span> <span class="special">=</span> <span class="number">1</span><span class="special">+</span><span class="number">2</span><span class="special">;</span> <span class="comment">// a is LValue, 1+2 is the expression producing the RValue,
+</span><span class="comment">// 1+2 = a; // usually makes no sense. +</span>+<span class="identifier">func1</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// works, because y is an LValue +</span><span class="comment">// func1(1+2); // fails to compile, because we only got an RValue.
+</span></pre> +<p>+ If we add const qualification on the parameter, our function also accepts RValues:
+ </p>+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func2</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span>
+ +<span class="comment">// [...] function scope:+</span><span class="identifier">func2</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// x is a reference to a const temporary, object, +</span><span class="identifier">func2</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a const object, while y is not const, and +</span><span class="identifier">func2</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object, just like z.
+</span></pre> +<p>+ In all cases, the argument <code class="computeroutput"><span class="identifier">x</span></code> + in <code class="computeroutput"><span class="identifier">func2</span></code> is a const-qualified + LValue. We can use function overloading to identify non-const LValues:
+ </p>+<pre class="programlisting"><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func3</span><span class="special">(</span><span class="identifier">T</span> <span class="keyword">const</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span> <span class="comment">// #1 +</span><span class="keyword">template</span><span class="special"><</span> <span class="keyword">typename</span> <span class="identifier">T</span> <span class="special">></span> <span class="keyword">void</span> <span class="identifier">func3</span><span class="special">(</span><span class="identifier">T</span> <span class="special">&</span> <span class="identifier">x</span><span class="special">);</span> <span class="comment">// #2
+</span> +<span class="comment">// [...] function scope:+</span><span class="identifier">func3</span><span class="special">(</span><span class="number">1</span><span class="special">);</span> <span class="comment">// x is a reference to a const, temporary object in #1, +</span><span class="identifier">func3</span><span class="special">(</span><span class="identifier">y</span><span class="special">);</span> <span class="comment">// x is a reference to a non-const object in #2, and +</span><span class="identifier">func3</span><span class="special">(</span><span class="identifier">z</span><span class="special">);</span> <span class="comment">// x is a reference to a const object in #1.
+</span></pre> +<p>+ Note that all arguments <code class="computeroutput"><span class="identifier">x</span></code> in + the overloaded function <code class="computeroutput"><span class="identifier">func3</span></code> + are LValues. In fact, there is no way to transport RValues into a function + as-is in C++98. Also note that we can't distinguish between what used to be
+ a const qualified LValue and an RValue. + </p> +<p>+ That's as close as we can get to a generic forwarding function <code class="computeroutput"><span class="identifier">g</span></code> as described above by the means of C++ + 98. See <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm"; target="_top">The + Forwarding Problem</a> for a very detailed discussion including solutions
+ that require language changes. + </p> +<p>+ Now, for actually implementing it, we need 2^N overloads for N parameters (each + with and without const qualifier) for each number of arguments (that is 2^(Nmax+1) + - 2^Nmin). Right, that means the compile-time complexity is O(2^N), however + the factor is low so it works quite well for a reasonable number (< 10)
+ of arguments. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_forward.reference"></a><a href="index.html#boost_functional_forward.reference" title=" Reference"> Reference</a></h2></div></div></div>
+<div class="toc"><dl>+<dt><span class="section"><a href="index.html#boost_functional_forward.reference.forward_adapter">forward_adapter</a></span></dt> +<dt><span class="section"><a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter">lightweight_forward_adapter</a></span></dt>
+</dl></div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_functional_forward.reference.forward_adapter"></a><a href="index.html#boost_functional_forward.reference.forward_adapter" title="forward_adapter">forward_adapter</a></h3></div></div></div> +<a name="boost_functional_forward.reference.forward_adapter.description"></a><h4>
+<a name="id935594"></a>+ <a href="index.html#boost_functional_forward.reference.forward_adapter.description">Description</a>
+ </h4> +<p>+ Function object adapter template whose instances are callable with LValue + and RValue arguments. RValue arguments are forwarded as reference-to-const
+ typed LValues. + </p> +<p>+ An arity can be given as second, numeric non-type template argument to restrict + forwarding to a specific arity. If a third, numeric non-type template argument + is present, the second and third template argument are treated as minimum + and maximum arity, respectively. Specifying an arity can be helpful to improve + the readability of diagnostic messages and compile time performance.
+ </p> +<p>+ <a href="http://www.boost.org/libs/utility/utility.htm#result_of"; target="_top">Boost.ResultOf</a> + can be used to determine the result types of specific call expressions.
+ </p>+<a name="boost_functional_forward.reference.forward_adapter.header"></a><h4>
+<a name="id935646"></a>+ <a href="index.html#boost_functional_forward.reference.forward_adapter.header">Header</a>
+ </h4>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">forward_adapter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>+<a name="boost_functional_forward.reference.forward_adapter.synopsis"></a><h4>
+<a name="id935721"></a>+ <a href="index.html#boost_functional_forward.reference.forward_adapter.synopsis">Synopsis</a>
+ </h4>+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span>+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Function</span><span class="special">,</span> + <span class="keyword">int</span> <span class="identifier">Arity_Or_MinArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">MaxArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span> <span class="special">></span> + <span class="keyword">class</span> <span class="identifier">forward_adapter</span><span class="special">;</span>
+<span class="special">}</span> +</pre> +<div class="variablelist"> +<p class="title"><b>Notation</b></p> +<dl>+<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
+<dd><p>+ a possibly const qualified function object type or reference type thereof
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
+<dd><p>+ an object convertible to <code class="computeroutput"><span class="identifier">F</span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">FA</span></code></span></dt>
+<dd><p>+ the type <code class="computeroutput"><span class="identifier">forward_adapter</span><span class="special"><</span><span class="identifier">F</span><span class="special">></span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">fa</span></code></span></dt>
+<dd><p>+ an instance object of <code class="computeroutput"><span class="identifier">FA</span></code>, + initialized with <code class="computeroutput"><span class="identifier">f</span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
+<dd><p>+ arguments to <code class="computeroutput"><span class="identifier">fa</span></code>
+ </p></dd> +</dl> +</div> +<p> + The result type of a target function invocation must be + </p>+<pre class="programlisting"><a href="http://www.boost.org/libs/utility/utility.htm#result_of"; target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span></code></a><span class="special"><</span><span class="identifier">F</span><span class="special">*(</span><span class="identifier">TA0</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&...</span><span class="identifier">TAN</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&])>::</span><span class="identifier">type</span>
+</pre> +<p>+ where <code class="computeroutput"><span class="identifier">TA0</span></code>...<code class="computeroutput"><span class="identifier">TAN</span></code> denote the argument types of <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
+ </p>+<a name="boost_functional_forward.reference.forward_adapter.expression_semantics"></a><h4>
+<a name="id936177"></a>+ <a href="index.html#boost_functional_forward.reference.forward_adapter.expression_semantics">Expression
+ Semantics</a> + </h4> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Semantics + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">FA</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
+ </p> + </td> +<td> + <p>+ creates an adapter, initializes the target function with <code class="computeroutput"><span class="identifier">f</span></code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">FA</span><span class="special">()</span></code>
+ </p> + </td> +<td> + <p>+ creates an adapter, attempts to use <code class="computeroutput"><span class="identifier">F</span></code>'s
+ default constructor. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">fa</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
+ </p> + </td> +<td> + <p>+ calls <code class="computeroutput"><span class="identifier">f</span></code> with with + arguments <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
+ </p> + </td> +</tr> +</tbody> +</table></div>+<a name="boost_functional_forward.reference.forward_adapter.limits"></a><h4>
+<a name="id936405"></a>+ <a href="index.html#boost_functional_forward.reference.forward_adapter.limits">Limits</a>
+ </h4> +<p>+ The macro BOOST_FUNCTIONAL_FORWARD_ADAPTER_MAX_ARITY can be defined to set
+ the maximum call arity. It defaults to 6. + </p>+<a name="boost_functional_forward.reference.forward_adapter.complexity"></a><h4>
+<a name="id936434"></a>+ <a href="index.html#boost_functional_forward.reference.forward_adapter.complexity">Complexity</a>
+ </h4> +<p>+ Preprocessing time: O(2^N), where N is the arity limit. Compile time: O(2^N), + where N depends on the arity range. Run time: O(0) if the compiler inlines,
+ O(1) otherwise. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h3 class="title">+<a name="boost_functional_forward.reference.lightweight_forward_adapter"></a><a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter" title="lightweight_forward_adapter">lightweight_forward_adapter</a></h3></div></div></div> +<a name="boost_functional_forward.reference.lightweight_forward_adapter.description"></a><h4>
+<a name="id936485"></a>+ <a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.description">Description</a>
+ </h4> +<p>+ Function object adapter template whose instances are callable with LValue + and RValue arguments. All arguments are forwarded as reference-to-const typed + LValues, except for reference wrappers which are unwrapped and may yield
+ non-const LValues. + </p> +<p>+ An arity can be given as second, numeric non-type template argument to restrict + forwarding to a specific arity. If a third, numeric non-type template argument + is present, the second and third template argument are treated as minimum + and maximum arity, respectively. Specifying an arity can be helpful to improve + the readability of diagnostic messages and compile time performance.
+ </p> +<p>+ <a href="http://www.boost.org/libs/utility/utility.htm#result_of"; target="_top">Boost.ResultOf</a> + can be used to determine the result types of specific call expressions.
+ </p>+<a name="boost_functional_forward.reference.lightweight_forward_adapter.header"></a><h4>
+<a name="id936540"></a>+ <a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.header">Header</a>
+ </h4>+<pre class="programlisting"><span class="preprocessor">#include</span> <span class="special"><</span><span class="identifier">boost</span><span class="special">/</span><span class="identifier">functional</span><span class="special">/</span><span class="identifier">lightweight_forward_adapter</span><span class="special">.</span><span class="identifier">hpp</span><span class="special">></span>
+</pre>+<a name="boost_functional_forward.reference.lightweight_forward_adapter.synopsis"></a><h4>
+<a name="id936616"></a>+ <a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.synopsis">Synopsis</a>
+ </h4>+<pre class="programlisting"><span class="keyword">namespace</span> <span class="identifier">boost</span>
+<span class="special">{</span>+ <span class="keyword">template</span><span class="special"><</span> <span class="keyword">class</span> <span class="identifier">Function</span><span class="special">,</span> + <span class="keyword">int</span> <span class="identifier">Arity_Or_MinArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span><span class="special">,</span> <span class="keyword">int</span> <span class="identifier">MaxArity</span> <span class="special">=</span> <span class="emphasis"><em>unspecified</em></span> <span class="special">></span> + <span class="keyword">struct</span> <span class="identifier">lightweight_forward_adapter</span><span class="special">;</span>
+<span class="special">}</span> +</pre> +<div class="variablelist"> +<p class="title"><b>Notation</b></p> +<dl>+<dt><span class="term"><code class="computeroutput"><span class="identifier">F</span></code></span></dt>
+<dd><p>+ a possibly const qualified function object type or reference type thereof
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">f</span></code></span></dt>
+<dd><p>+ an object convertible to <code class="computeroutput"><span class="identifier">F</span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">FA</span></code></span></dt>
+<dd><p>+ the type <code class="computeroutput"><span class="identifier">lightweight_forward_adapter</span><span class="special"><</span><span class="identifier">F</span><span class="special">></span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">fa</span></code></span></dt>
+<dd><p>+ an instance of <code class="computeroutput"><span class="identifier">FA</span></code>, initialized + with <code class="computeroutput"><span class="identifier">f</span></code>
+ </p></dd>+<dt><span class="term"><code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code></span></dt>
+<dd><p>+ arguments to <code class="computeroutput"><span class="identifier">fa</span></code>
+ </p></dd> +</dl> +</div> +<p> + The result type of a target function invocation must be + </p>+<pre class="programlisting"><a href="http://www.boost.org/libs/utility/utility.htm#result_of"; target="_top"><code class="computeroutput"><span class="identifier">boost</span><span class="special">::</span><span class="identifier">result_of</span></code></a><span class="special"><</span><span class="identifier">F</span><span class="special">*(</span><span class="identifier">TA0</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&...</span><span class="identifier">TAN</span> <span class="special">[</span><span class="keyword">const</span><span class="special">]&])>::</span><span class="identifier">type</span>
+</pre> +<p>+ where <code class="computeroutput"><span class="identifier">TA0</span></code>...<code class="computeroutput"><span class="identifier">TAN</span></code> denote the argument types of <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>.
+ </p>+<a name="boost_functional_forward.reference.lightweight_forward_adapter.expression_semantics"></a><h4>
+<a name="id937073"></a>+ <a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.expression_semantics">Expression
+ Semantics</a> + </h4> +<div class="informaltable"><table class="table"> +<colgroup> +<col> +<col> +</colgroup> +<thead><tr> +<th> + <p> + Expression + </p> + </th> +<th> + <p> + Semantics + </p> + </th> +</tr></thead> +<tbody> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">FA</span><span class="special">(</span><span class="identifier">f</span><span class="special">)</span></code>
+ </p> + </td> +<td> + <p>+ creates an adapter, initializes the target function with <code class="computeroutput"><span class="identifier">f</span></code>.
+ </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">FA</span><span class="special">()</span></code>
+ </p> + </td> +<td> + <p>+ creates an adapter, attempts to use <code class="computeroutput"><span class="identifier">F</span></code>'s
+ default constructor. + </p> + </td> +</tr> +<tr> +<td> + <p>+ <code class="computeroutput"><span class="identifier">fa</span><span class="special">(</span><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span><span class="special">)</span></code>
+ </p> + </td> +<td> + <p>+ calls <code class="computeroutput"><span class="identifier">f</span></code> with with + const arguments <code class="computeroutput"><span class="identifier">a0</span></code>...<code class="computeroutput"><span class="identifier">aN</span></code>. If <code class="computeroutput"><span class="identifier">aI</span></code>
+ is a reference wrapper it is unwrapped. + </p> + </td> +</tr> +</tbody> +</table></div>+<a name="boost_functional_forward.reference.lightweight_forward_adapter.limits"></a><h4>
+<a name="id937311"></a>+ <a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.limits">Limits</a>
+ </h4> +<p>+ The macro BOOST_FUNCTIONAL_LIGHTWEIGHT_FORWARD_ADAPTER_MAX_ARITY can be defined
+ to set the maximum call arity. It defaults to 10. + </p>+<a name="boost_functional_forward.reference.lightweight_forward_adapter.complexity"></a><h4>
+<a name="id937342"></a>+ <a href="index.html#boost_functional_forward.reference.lightweight_forward_adapter.complexity">Complexity</a>
+ </h4> +<p>+ Preprocessing time: O(N), where N is the arity limit. Compile time: O(N), + where N is the effective arity of a call. Run time: O(0) if the compiler
+ inlines, O(1) otherwise. + </p> +</div> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_forward.acknowledgements"></a><a href="index.html#boost_functional_forward.acknowledgements" title="Acknowledgements">Acknowledgements</a></h2></div></div></div>
+<p>+ As these utilities are factored out of the <a href="http://www.boost.org/libs/fusion/doc/html/index.html"; target="_top">Boost.Fusion</a> + functional module, I want to thank Dan Marsden and Joel de Guzman for letting + me participate in the development of that great library in the first place.
+ </p> +<p>+ Further, I want to credit the authors of the references below, for their in-depth
+ investigation of the problem and the solution implemented here. + </p> +<p>+ Last but not least I want to thank Vesa Karnoven and Paul Mensonides for the + Boost Preprocessor library. Without it, I would have ended up with an external
+ code generator for this one. + </p> +</div> +<div class="section" lang="en"> +<div class="titlepage"><div><div><h2 class="title" style="clear: both">+<a name="boost_functional_forward.references"></a><a href="index.html#boost_functional_forward.references" title="References">References</a></h2></div></div></div>
+<div class="orderedlist"><ol type="1"> +<li>+<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm"; target="_top">The + Forwarding Problem</a>, Peter Dimov, Howard E. Hinnant, David Abrahams,
+ 2002 + </li> +<li>+<a href="http://www.boost.org/libs/utility/utility.htm#result_of"; target="_top">Boost.ResultOf</a>,
+ Douglas Gregor, 2004 + </li> +<li>+<a href="http://www.boost.org/doc/html/ref.html"; target="_top">Boost.Ref</a>, Jaakko
+ Jarvi, Peter Dimov, Douglas Gregor, David Abrahams, 1999-2002 + </li> +</ol></div> +</div> +</div>+<table xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision"; width="100%"><tr> +<td align="left"><p><small>Last revised: November 01, 2008 at 19:58:50 GMT</small></p></td>
+<td align="right"><div class="copyright-footer"></div></td> +</tr></table> +<hr> +<div class="spirit-nav"></div> +</body> +</html> ======================================= --- /dev/null +++ /trunk/libs/functional/forward/index.html Mon May 31 02:08:39 2010 @@ -0,0 +1,15 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> +<html> + <head> + <meta http-equiv="refresh" content="0; URL=doc/html/index.html"> + </head> + <body> + Automatic redirection failed, click this + <a href="doc/html/index.html">link</a> <hr> + <p>(c) Copyright Tobias Schwinger, 2009</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> ======================================= --- /dev/null +++ /trunk/libs/functional/forward/test/Jamfile Mon May 31 02:08:39 2010 @@ -0,0 +1,17 @@ + +# (C) Copyright Tobias Schwinger +#+# Use modification and distribution are subject to the boost Software License,
+# Version 1.0. (See http:/\/www.boost.org/LICENSE_1_0.txt). + +import testing ; + +project forward-tests + ; + +test-suite functional/forward + : + [ run forward_adapter.cpp ] + [ run lightweight_forward_adapter.cpp ] + ; + ======================================= --- /dev/null+++ /trunk/libs/functional/forward/test/forward_adapter.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,128 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are 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). +==============================================================================*/ + +#include <boost/config.hpp> + +#ifdef BOOST_MSVC +# pragma warning(disable: 4244) // no conversion warnings, please +#endif + +#include <boost/detail/lightweight_test.hpp> +#include <boost/functional/forward_adapter.hpp> + +#include <boost/type_traits/is_same.hpp> + +#include <boost/blank.hpp> +#include <boost/noncopyable.hpp> + +#include <memory> + +template <class Base = boost::blank> +class test_func : public Base +{ + int val; +public: + test_func(int v) : val(v) { } + + template<class B> + test_func(test_func<B> const & that) + : val(that.val) + { } + + template<class B> friend class test_func; + + int operator()(int & l, int const & r) const + { + return l=r+val; + } + long operator()(int & l, int const & r) + { + return -(l=r+val); + } + + template <typename Sig> + struct result + { + typedef void type; + }; + + // ensure result_of argument types are what's expected + // note: this is *not* how client code should look like + template <class Self> + struct result< Self const(int&,int const&) > { typedef int type; }; + + template <class Self> + struct result< Self(int&,int const&) > { typedef long type; }; + + template <class Self> + struct result< Self(int&,int&) > { typedef char type; }; +}; + +enum { int_, long_, char_ }; + +int type_of(int) { return int_; } +int type_of(long) { return long_; } +int type_of(char) { return char_; } + +int main() +{ + { + using boost::is_same; + using boost::result_of; + typedef boost::forward_adapter< test_func<> > f; + + // lvalue,rvalue + BOOST_TEST(( is_same< + result_of< f(int&, int) >::type, long >::value )); + BOOST_TEST(( is_same< + result_of< f const (int&, int) >::type, int >::value )); + // lvalue,const lvalue + BOOST_TEST(( is_same< + result_of< f(int&, int const &) >::type, long >::value )); + BOOST_TEST(( is_same<+ result_of< f const (int&, int const &) >::type, int >::value ));
+ // lvalue,lvalue + BOOST_TEST(( is_same< + result_of< f(int&, int&) >::type, char >::value )); + BOOST_TEST(( is_same< + result_of< f const (int&, int&) >::type, char >::value )); + } + + { + using boost::noncopyable; + using boost::forward_adapter; + + int x = 0; + test_func<noncopyable> f(7); + forward_adapter< test_func<> > func(f); + forward_adapter< test_func<noncopyable> & > func_ref(f); + forward_adapter< test_func<noncopyable> & > const func_ref_c(f); + forward_adapter< test_func<> const > func_c(f); + forward_adapter< test_func<> > const func_c2(f); + forward_adapter< test_func<noncopyable> const & > func_c_ref(f); + + BOOST_TEST( type_of( func(x,1) ) == long_ ); + BOOST_TEST( type_of( func_ref(x,1) ) == long_ ); + BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ ); + BOOST_TEST( type_of( func_c(x,1) ) == int_ ); + BOOST_TEST( type_of( func_c2(x,1) ) == int_ ); + BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ ); + BOOST_TEST( type_of( func(x,x) ) == char_ ); + + BOOST_TEST( func(x,1) == -8 ); + BOOST_TEST( func_ref(x,1) == -8 ); + BOOST_TEST( func_ref_c(x,1) == -8 ); + BOOST_TEST( func_c(x,1) == 8 ); + BOOST_TEST( func_c2(x,1) == 8 ); + BOOST_TEST( func_c_ref(x,1) == 8 ); + } + + return boost::report_errors(); +} + + ======================================= --- /dev/null+++ /trunk/libs/functional/forward/test/lightweight_forward_adapter.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,128 @@ +/*============================================================================= + Copyright (c) 2007 Tobias Schwinger + + Use modification and distribution are 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). +==============================================================================*/ + +#include <boost/config.hpp> + +#ifdef BOOST_MSVC +# pragma warning(disable: 4244) // no conversion warnings, please +#endif + +#include <boost/detail/lightweight_test.hpp> +#include <boost/functional/lightweight_forward_adapter.hpp> + +#include <boost/type_traits/is_same.hpp> + +#include <boost/blank.hpp> +#include <boost/noncopyable.hpp> + +#include <memory> + +template <class Base = boost::blank> +class test_func : public Base +{ + int val; +public: + test_func(int v) : val(v) { } + + template<class B> + test_func(test_func<B> const & that) + : val(that.val) + { } + + template<class B> friend class test_func; + + int operator()(int & l, int const & r) const + { + return l=r+val; + } + long operator()(int & l, int const & r) + { + return -(l=r+val); + } + + template <typename Sig> + struct result + { + typedef void type; + }; + + // ensure result_of argument types are what's expected + // note: this is *not* how client code should look like + template <class Self> + struct result< Self const(int&,int const&) > { typedef int type; }; + + template <class Self> + struct result< Self(int&,int const&) > { typedef long type; }; + + template <class Self> + struct result< Self(int&,int&) > { typedef char type; }; +}; + +enum { int_, long_, char_ }; + +int type_of(int) { return int_; } +int type_of(long) { return long_; } +int type_of(char) { return char_; } + +int main() +{ + { + using boost::is_same; + using boost::result_of; + typedef boost::lightweight_forward_adapter< test_func<> > f; + typedef boost::reference_wrapper<int> ref; + typedef boost::reference_wrapper<int const> cref; + + // lvalue,rvalue + BOOST_TEST(( is_same< + result_of< f(ref, int) >::type, long >::value )); + BOOST_TEST(( is_same< + result_of< f const (ref, int) >::type, int >::value )); + // lvalue,const lvalue + BOOST_TEST(( is_same< + result_of< f(ref, cref) >::type, long >::value )); + BOOST_TEST(( is_same< + result_of< f const (ref, cref) >::type, int >::value )); + // lvalue,lvalue + BOOST_TEST(( is_same< + result_of< f(ref, ref) >::type, char >::value )); + BOOST_TEST(( is_same< + result_of< f const (ref, ref) >::type, char >::value )); + } + { + using boost::noncopyable; + using boost::lightweight_forward_adapter; + + int v = 0; boost::reference_wrapper<int> x(v); + test_func<noncopyable> f(7); + lightweight_forward_adapter< test_func<> > func(f);+ lightweight_forward_adapter< test_func<noncopyable> & > func_ref(f); + lightweight_forward_adapter< test_func<noncopyable> & > const func_ref_c(f);
+ lightweight_forward_adapter< test_func<> const > func_c(f); + lightweight_forward_adapter< test_func<> > const func_c2(f);+ lightweight_forward_adapter< test_func<noncopyable> const & > func_c_ref(f);
+ + BOOST_TEST( type_of( func(x,1) ) == long_ ); + BOOST_TEST( type_of( func_ref(x,1) ) == long_ ); + BOOST_TEST( type_of( func_ref_c(x,1) ) == long_ ); + BOOST_TEST( type_of( func_c(x,1) ) == int_ ); + BOOST_TEST( type_of( func_c2(x,1) ) == int_ ); + BOOST_TEST( type_of( func_c_ref(x,1) ) == int_ ); + BOOST_TEST( type_of( func(x,x) ) == char_ ); + + BOOST_TEST( func(x,1) == -8 ); + BOOST_TEST( func_ref(x,1) == -8 ); + BOOST_TEST( func_ref_c(x,1) == -8 ); + BOOST_TEST( func_c(x,1) == 8 ); + BOOST_TEST( func_c2(x,1) == 8 ); + BOOST_TEST( func_c_ref(x,1) == 8 ); + } + + return boost::report_errors(); +} + ======================================= --- /dev/null +++ /trunk/libs/unordered/doc/diagrams/buckets.svg Mon May 31 02:08:39 2010 @@ -0,0 +1,313 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:svg="http://www.w3.org/2000/svg"; + xmlns="http://www.w3.org/2000/svg"; + version="1.0" + width="507.85925" + height="400.45422" + viewBox="1.33 0.95 6.01 4.09" + id="svg2"> + <defs + id="defs95" /> + <rect + width="6.0023117" + height="4.0815721" + x="1.3310578" + y="0.95080346" + id="rect4" + style="fill:#e5e5e5;stroke:none;stroke-width:0" /> + <rect + width="6.0023117" + height="4.0815721" + x="1.3310578" + y="0.95080346" + id="rect6" + style="opacity:1;fill:none;stroke:#000000;stroke-width:0.02400924" /> + <rect + width="1.2004625" + height="1.6806473" + x="1.5711501" + y="1.1908962" + id="rect8" + style="fill:#ffffff;stroke:none;stroke-width:0" /> + <rect + width="1.2004625" + height="1.6806473" + x="1.5711501" + y="1.1908962" + id="rect10" + style="fill:none;stroke:#000000;stroke-width:0.02400924" /> + <text + x="1.7289008" + y="1.4950322" + id="text12"+ style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 1</text>
+ <line + x1="1.5711501" + y1="1.6710808" + x2="2.7716124" + y2="1.6710808" + id="line14" + style="stroke:#000000;stroke-width:0.02400924" /> + <rect + width="1.2004625" + height="1.6806473" + x="3.0117054" + y="1.1908962" + id="rect16" + style="fill:#ffffff;stroke:none;stroke-width:0" /> + <rect + width="1.2004625" + height="1.6806473" + x="3.0117054" + y="1.1908962" + id="rect18" + style="fill:none;stroke:#000000;stroke-width:0.02400924" /> + <text + x="3.1603069" + y="1.4950322" + id="text20"+ style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 2</text>
+ <line + x1="3.0117054" + y1="1.6710808" + x2="4.2121677" + y2="1.6710808" + id="line22" + style="stroke:#000000;stroke-width:0.02400924" /> + <rect + width="1.2004625" + height="1.6806473" + x="4.4522605" + y="1.1908962" + id="rect24" + style="fill:#ffffff;stroke:none;stroke-width:0" /> + <rect + width="1.2004625" + height="1.6806473" + x="4.4522605" + y="1.1908962" + id="rect26" + style="fill:none;stroke:#000000;stroke-width:0.02400924" /> + <text + x="4.5917125" + y="1.4950322" + id="text28"+ style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 3</text>
+ <line + x1="4.4522605" + y1="1.6710808" + x2="5.6527228" + y2="1.6710808" + id="line30" + style="stroke:#000000;stroke-width:0.02400924" /> + <rect + width="1.2004625" + height="1.6806473" + x="5.8928151" + y="1.1908962" + id="rect32" + style="fill:#ffffff;stroke:none;stroke-width:0" /> + <rect + width="1.2004625" + height="1.6806473" + x="5.8928151" + y="1.1908962" + id="rect34" + style="fill:none;stroke:#000000;stroke-width:0.02400924" /> + <text + x="6.0688629" + y="1.4858831" + id="text36"+ style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 4</text>
+ <line + x1="5.8928151" + y1="1.6710808" + x2="7.093277" + y2="1.6710808" + id="line38" + style="stroke:#000000;stroke-width:0.02400924" /> + <rect + width="1.2004625" + height="1.6806473" + x="2.2941716" + y="3.1054616" + id="rect40" + style="fill:#ffffff;stroke:none;stroke-width:0" /> + <rect + width="1.2004625" + height="1.6806473" + x="2.2941716" + y="3.1054616" + id="rect42" + style="fill:none;stroke:#000000;stroke-width:0.02400924" /> + <text + x="2.4427731" + y="3.4187472" + id="text44"+ style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 5</text>
+ <line + x1="2.2941716" + y1="3.5856469" + x2="3.4946339" + y2="3.5856469" + id="line46" + style="stroke:#000000;stroke-width:0.02400924" /> + <rect + width="1.2004625" + height="1.6806473" + x="3.7347264" + y="3.1054616" + id="rect48" + style="fill:#ffffff;stroke:none;stroke-width:0" /> + <rect + width="1.2004625" + height="1.6806473" + x="3.7347264" + y="3.1054616" + id="rect50" + style="fill:none;stroke:#000000;stroke-width:0.02400924" /> + <text + x="3.8833277" + y="3.4187472" + id="text52"+ style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 6</text>
+ <line + x1="3.7347264" + y1="3.5856469" + x2="4.9351892" + y2="3.5856469" + id="line54" + style="stroke:#000000;stroke-width:0.02400924" /> + <rect + width="1.2004625" + height="1.6806473" + x="5.175281" + y="3.1054616" + id="rect56" + style="fill:#ffffff;stroke:none;stroke-width:0" /> + <rect + width="1.2004625" + height="1.6806473" + x="5.175281" + y="3.1054616" + id="rect58" + style="fill:none;stroke:#000000;stroke-width:0.02400924" /> + <text + x="5.3330317" + y="3.4187472" + id="text60"+ style="font-size:0.19207397px;font-style:normal;font-weight:400;text-anchor:start;fill:#000000;font-family:sans">Bucket 7</text>
+ <line + x1="5.175281" + y1="3.5856469" + x2="6.3757439" + y2="3.5856469" + id="line62" + style="stroke:#000000;stroke-width:0.02400924" /> + <ellipse + cx="7.1999998" + cy="4.0110002" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse64" + style="fill:#ffffff;stroke:none" /> + <ellipse + cx="7.1999998" + cy="4.0110002" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse66" + style="fill:none;stroke:#000000;stroke-width:0.035" /> + <text + x="6.1443377" + y="2.1364057" + id="text68"+ style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">A</text>
+ <ellipse + cx="3.007" + cy="4.0300002" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse70" + style="fill:#ffffff;stroke:none" /> + <ellipse + cx="3.007" + cy="4.0300002" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse72" + style="fill:none;stroke:#000000;stroke-width:0.035" /> + <text + x="3.2742035" + y="2.1540098" + id="text74"+ style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">B</text>
+ <ellipse + cx="4.0599999" + cy="6.7820001" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse76" + style="fill:#ffffff;stroke:none" /> + <ellipse + cx="4.0599999" + cy="6.7820001" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse78" + style="fill:none;stroke:#000000;stroke-width:0.035" /> + <text + x="3.976877" + y="4.0473108" + id="text80"+ style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">C</text>
+ <ellipse + cx="7.8449998" + cy="4.6550002" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse82" + style="fill:#ffffff;stroke:none" /> + <ellipse + cx="7.8449998" + cy="4.6550002" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse84" + style="fill:none;stroke:#000000;stroke-width:0.035" /> + <text + x="6.5808516" + y="2.5937216" + id="text86"+ style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">D</text>
+ <ellipse + cx="0.87" + cy="4.0079999" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse88" + style="fill:#ffffff;stroke:none" /> + <ellipse + cx="0.87" + cy="4.0079999" + rx="0.308" + ry="0.308" + transform="matrix(0.6859785,0,0,0.6859785,1.3310577,-0.7298436)" + id="ellipse90" + style="fill:none;stroke:#000000;stroke-width:0.035" /> + <text + x="1.7991183" + y="2.1403852" + id="text92"+ style="font-size:0.34038281px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#000000;font-family:Sans;-inkscape-font-specification:Sans">E</text>
+</svg> ======================================= --- /dev/null+++ /trunk/libs/unordered/doc/src_code/dictionary.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,103 @@ + +// Copyright 2006-2007 Daniel James.+// 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/unordered_map.hpp> +#include <boost/detail/lightweight_test.hpp> +#include <boost/algorithm/string/predicate.hpp> +#include "../../examples/fnv1.hpp" + +//[case_insensitive_functions + struct iequal_to + : std::binary_function<std::string, std::string, bool> + { + bool operator()(std::string const& x, + std::string const& y) const + { + return boost::algorithm::iequals(x, y, std::locale()); + } + }; + + struct ihash + : std::unary_function<std::string, std::size_t> + { + std::size_t operator()(std::string const& x) const + { + std::size_t seed = 0; + std::locale locale; + + for(std::string::const_iterator it = x.begin(); + it != x.end(); ++it) + { + boost::hash_combine(seed, std::toupper(*it, locale)); + } + + return seed; + } + }; +//] + +int main() { +//[case_sensitive_dictionary_fnv + boost::unordered_map<std::string, int, hash::fnv_1> + dictionary; +//] + + BOOST_TEST(dictionary.empty()); + + dictionary["one"] = 1; + BOOST_TEST(dictionary.size() == 1); + BOOST_TEST(dictionary.find("ONE") == dictionary.end()); + + dictionary.insert(std::make_pair("ONE", 2)); + BOOST_TEST(dictionary.size() == 2); + BOOST_TEST(dictionary.find("ONE") != dictionary.end() && + dictionary.find("ONE")->first == "ONE" && + dictionary.find("ONE")->second == 2); + + dictionary["One"] = 3; + BOOST_TEST(dictionary.size() == 3); + BOOST_TEST(dictionary.find("One") != dictionary.end() && + dictionary.find("One")->first == "One" && + dictionary.find("One")->second == 3); + + dictionary["two"] = 4; + BOOST_TEST(dictionary.size() == 4); + BOOST_TEST(dictionary.find("Two") == dictionary.end() && + dictionary.find("two") != dictionary.end() && + dictionary.find("two")->second == 4); + + +//[case_insensitive_dictionary + boost::unordered_map<std::string, int, ihash, iequal_to> + idictionary; +//] + + BOOST_TEST(idictionary.empty()); + + idictionary["one"] = 1; + BOOST_TEST(idictionary.size() == 1); + BOOST_TEST(idictionary.find("ONE") != idictionary.end() && + idictionary.find("ONE") == idictionary.find("one")); + + idictionary.insert(std::make_pair("ONE", 2)); + BOOST_TEST(idictionary.size() == 1); + BOOST_TEST(idictionary.find("ONE") != idictionary.end() && + idictionary.find("ONE")->first == "one" && + idictionary.find("ONE")->second == 1); + + idictionary["One"] = 3; + BOOST_TEST(idictionary.size() == 1); + BOOST_TEST(idictionary.find("ONE") != idictionary.end() && + idictionary.find("ONE")->first == "one" && + idictionary.find("ONE")->second == 3); + + idictionary["two"] = 4; + BOOST_TEST(idictionary.size() == 2); + BOOST_TEST(idictionary.find("two") != idictionary.end() && + idictionary.find("TWO")->first == "two" && + idictionary.find("Two")->second == 4); + + return boost::report_errors(); +} ======================================= --- /dev/null +++ /trunk/libs/unordered/doc/src_code/intro.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,30 @@ + +// Copyright 2006-2009 Daniel James.+// 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) + +//[intro_example1_1 +#include <boost/unordered_map.hpp> +#include <boost/foreach.hpp> +#include <cassert> +#include <iostream> +//] + +int main() { +//[intro_example1_2 + typedef boost::unordered_map<std::string, int> map; + map x; + x["one"] = 1; + x["two"] = 2; + x["three"] = 3; + + assert(x.at("one") == 1); + assert(x.find("missing") == x.end()); +//] + +//[intro_example1_3 + BOOST_FOREACH(map::value_type i, x) { + std::cout<<i.first<<","<<i.second<<"\n"; + } +//] +} ======================================= --- /dev/null +++ /trunk/libs/unordered/doc/src_code/point1.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,45 @@ + +// Copyright 2006-2009 Daniel James.+// 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/unordered_set.hpp> +#include <boost/detail/lightweight_test.hpp> + +//[point_example1 + struct point { + int x; + int y; + }; + + bool operator==(point const& p1, point const& p2) + { + return p1.x == p2.x && p1.y == p2.y; + } + + struct point_hash + : std::unary_function<point, std::size_t> + { + std::size_t operator()(point const& p) const + { + std::size_t seed = 0; + boost::hash_combine(seed, p.x); + boost::hash_combine(seed, p.y); + return seed; + } + }; + + boost::unordered_multiset<point, point_hash> points; +//] + +int main() { + point x[] = {{1,2}, {3,4}, {1,5}, {1,2}}; + for(int i = 0; i < sizeof(x) / sizeof(point); ++i) + points.insert(x[i]); + BOOST_TEST(points.count(x[0]) == 2); + BOOST_TEST(points.count(x[1]) == 1); + point y = {10, 2}; + BOOST_TEST(points.count(y) == 0); + + return boost::report_errors(); +} ======================================= --- /dev/null +++ /trunk/libs/unordered/doc/src_code/point2.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,43 @@ + +// Copyright 2006-2009 Daniel James.+// 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/unordered_set.hpp> +#include <boost/functional/hash.hpp> +#include <boost/detail/lightweight_test.hpp> + +//[point_example2 + struct point { + int x; + int y; + }; + + bool operator==(point const& p1, point const& p2) + { + return p1.x == p2.x && p1.y == p2.y; + } + + std::size_t hash_value(point const& p) { + std::size_t seed = 0; + boost::hash_combine(seed, p.x); + boost::hash_combine(seed, p.y); + return seed; + } + + // Now the default function objects work. + boost::unordered_multiset<point> points; +//] + +int main() { + point x[] = {{1,2}, {3,4}, {1,5}, {1,2}}; + for(int i = 0; i < sizeof(x) / sizeof(point); ++i) + points.insert(x[i]); + BOOST_TEST(points.count(x[0]) == 2); + BOOST_TEST(points.count(x[1]) == 1); + point y = {10, 2}; + BOOST_TEST(points.count(y) == 0); + + return boost::report_errors(); +} + ======================================= --- /dev/null +++ /trunk/libs/utility/addressof_fn_test.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,76 @@ +#include <boost/config.hpp> + +#if defined(BOOST_MSVC) +#pragma warning(disable: 4786) // identifier truncated in debug info +#pragma warning(disable: 4710) // function not inlined+#pragma warning(disable: 4711) // function selected for automatic inline expansion
+#pragma warning(disable: 4514) // unreferenced inline removed +#endif + +// addressof_fn_test.cpp: addressof( f ) +// +// Copyright (c) 2008, 2009 Peter Dimov +// +// 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/utility/addressof.hpp> +#include <boost/detail/lightweight_test.hpp> + + +void f0() +{ +} + +void f1(int) +{ +} + +void f2(int, int) +{ +} + +void f3(int, int, int) +{ +} + +void f4(int, int, int, int) +{ +} + +void f5(int, int, int, int, int) +{ +} + +void f6(int, int, int, int, int, int) +{ +} + +void f7(int, int, int, int, int, int, int) +{ +} + +void f8(int, int, int, int, int, int, int, int) +{ +} + +void f9(int, int, int, int, int, int, int, int, int) +{ +} + +int main() +{ + BOOST_TEST( boost::addressof( f0 ) == &f0 ); + BOOST_TEST( boost::addressof( f1 ) == &f1 ); + BOOST_TEST( boost::addressof( f2 ) == &f2 ); + BOOST_TEST( boost::addressof( f3 ) == &f3 ); + BOOST_TEST( boost::addressof( f4 ) == &f4 ); + BOOST_TEST( boost::addressof( f5 ) == &f5 ); + BOOST_TEST( boost::addressof( f6 ) == &f6 ); + BOOST_TEST( boost::addressof( f7 ) == &f7 ); + BOOST_TEST( boost::addressof( f8 ) == &f8 ); + BOOST_TEST( boost::addressof( f9 ) == &f9 ); + + return boost::report_errors(); +} ======================================= --- /dev/null +++ /trunk/libs/utility/addressof_test2.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,95 @@ +// Copyright (C) 2002 Brad King (brad.king@xxxxxxxxxxx) +// Douglas Gregor (gregod@xxxxxxxxxx) +// +// Copyright 2009 Peter Dimov +// +// 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) + +// For more information, see http://www.boost.org + + +#include <boost/utility/addressof.hpp> + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(push, 3) +#endif + +#include <iostream> + +#if defined(BOOST_MSVC) && (BOOST_MSVC < 1300) +#pragma warning(pop) +#endif + +#include <boost/detail/lightweight_test.hpp> + +template<class T> void scalar_test( T * = 0 ) +{ + T* px = new T(); + + T& x = *px; + BOOST_TEST( boost::addressof(x) == px ); + + const T& cx = *px; + const T* pcx = boost::addressof(cx); + BOOST_TEST( pcx == px ); + + volatile T& vx = *px; + volatile T* pvx = boost::addressof(vx); + BOOST_TEST( pvx == px ); + + const volatile T& cvx = *px; + const volatile T* pcvx = boost::addressof(cvx); + BOOST_TEST( pcvx == px ); + + delete px; +} + +template<class T> void array_test( T * = 0 ) +{ + T nrg[3] = {1,2,3}; + T (*pnrg)[3] = &nrg; + BOOST_TEST( boost::addressof(nrg) == pnrg ); + + T const cnrg[3] = {1,2,3}; + T const (*pcnrg)[3] = &cnrg; + BOOST_TEST( boost::addressof(cnrg) == pcnrg ); +} + +class convertible { +public: + + convertible( int = 0 ) + { + } + + template<class U> operator U () const + { + return U(); + } +}; + +class convertible2 { +public: + + convertible2( int = 0 ) + { + } + + operator convertible2* () const + { + return 0; + } +}; + +int main() +{ + scalar_test<convertible>(); + scalar_test<convertible2>(); + + array_test<convertible>(); + array_test<convertible2>(); + + return boost::report_errors(); +} ======================================= --- /dev/null +++ /trunk/libs/utility/binary_test.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,647 @@ +/*============================================================================= + Copyright (c) 2006, 2007 Matthew Calabrese + + 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) +==============================================================================*/ + +#include <boost/test/minimal.hpp> +#include <boost/utility/binary.hpp> +#include <algorithm> +#include <cstddef> + +#ifdef BOOST_MSVC+#pragma warning(disable:4996) // warning C4996: 'std::equal': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
+#endif + +/* +Note: This file tests every single valid bit-grouping on its own, and some + random combinations of bit-groupings. +*/ + +std::size_t const num_random_test_values = 32; + +// Note: These hex values should all correspond with the binary array below +unsigned int const random_unsigned_ints_hex[num_random_test_values]+ = { 0x0103u, 0x77ebu, 0x5f36u, 0x1f18u, 0xc530u, 0xa73au, 0xd6f8u, 0x0919u
+ , 0xfbb0u, 0x3e7cu, 0xd0e9u, 0x22c8u, 0x724eu, 0x14fau, 0xd98eu, 0x40b5+ , 0xeba0u, 0xfe50u, 0x688au, 0x1b05u, 0x5f9cu, 0xe4fcu, 0xa7b8u, 0xd3acu
+ , 0x1dddu, 0xbf04u, 0x8352u, 0xe89cu, 0x7506u, 0xe767u, 0xf489u, 0xe167 + }; + +unsigned int const random_unsigned_ints_binary[num_random_test_values] + = { BOOST_BINARY( 0 00010000 0011 ), BOOST_BINARY( 0 11101 1111 101011 )+ , BOOST_BINARY( 010111 1100110 1 1 0 ), BOOST_BINARY( 000 1 11110 00 11000 ) + , BOOST_BINARY( 110 001010 0110 000 ), BOOST_BINARY( 1010 01110011 1010 ) + , BOOST_BINARY( 11 010 1 101111 1000 ), BOOST_BINARY( 0000 100100 0110 01 ) + , BOOST_BINARY( 1111 101110 11 0000 ), BOOST_BINARY( 00111110 01111100 ) + , BOOST_BINARY( 11 010 000111 01001 ), BOOST_BINARY( 00100 010110 01000 )
+ , BOOST_BINARY( 01 11001001 001110 ), BOOST_BINARY( 0010 1001111 1010 )+ , BOOST_BINARY( 1101 1 00110 0 01110 ), BOOST_BINARY( 100 000 01011010 1 ) + , BOOST_BINARY( 11 1010 1110 1000 00 ), BOOST_BINARY( 11111 110010 10000 ) + , BOOST_BINARY( 01101 00010 001010 ), BOOST_BINARY( 000 11011 000001 01 ) + , BOOST_BINARY( 01 01111 1100111 00 ), BOOST_BINARY( 1 110010 0111111 00 ) + , BOOST_BINARY( 101 0011 11 01110 00 ), BOOST_BINARY( 110100 1 110101 100 ) + , BOOST_BINARY( 00 1110111 011 101 ), BOOST_BINARY( 1011 1111 00000 100 ) + , BOOST_BINARY( 1000 00110 101 0010 ), BOOST_BINARY( 1110 10001 001110 0 ) + , BOOST_BINARY( 011 1010100 000 110 ), BOOST_BINARY( 1110 0111 01100 111 ) + , BOOST_BINARY( 11110 10010 001001 ), BOOST_BINARY( 11 1000010 1100 111 )
+ }; + +unsigned int const unsigned_ints_1_bit[2] = +{ BOOST_BINARY( 0 ) +, BOOST_BINARY( 1 ) +}; + +unsigned int const unsigned_ints_2_bits[4] = +{ BOOST_BINARY( 00 ) +, BOOST_BINARY( 01 ) +, BOOST_BINARY( 10 ) +, BOOST_BINARY( 11 ) +}; + +unsigned int const unsigned_ints_3_bits[8] = +{ BOOST_BINARY( 000 ) +, BOOST_BINARY( 001 ) +, BOOST_BINARY( 010 ) +, BOOST_BINARY( 011 ) +, BOOST_BINARY( 100 ) +, BOOST_BINARY( 101 ) +, BOOST_BINARY( 110 ) +, BOOST_BINARY( 111 ) +}; + +unsigned int const unsigned_ints_4_bits[16] = +{ BOOST_BINARY( 0000 ) +, BOOST_BINARY( 0001 ) +, BOOST_BINARY( 0010 ) +, BOOST_BINARY( 0011 ) +, BOOST_BINARY( 0100 ) +, BOOST_BINARY( 0101 ) +, BOOST_BINARY( 0110 ) +, BOOST_BINARY( 0111 ) +, BOOST_BINARY( 1000 ) +, BOOST_BINARY( 1001 ) +, BOOST_BINARY( 1010 ) +, BOOST_BINARY( 1011 ) +, BOOST_BINARY( 1100 ) +, BOOST_BINARY( 1101 ) +, BOOST_BINARY( 1110 ) +, BOOST_BINARY( 1111 ) +}; + +unsigned int const unsigned_ints_5_bits[32] = +{ BOOST_BINARY( 00000 ) +, BOOST_BINARY( 00001 ) +, BOOST_BINARY( 00010 ) +, BOOST_BINARY( 00011 ) +, BOOST_BINARY( 00100 ) +, BOOST_BINARY( 00101 ) +, BOOST_BINARY( 00110 ) +, BOOST_BINARY( 00111 ) +, BOOST_BINARY( 01000 ) +, BOOST_BINARY( 01001 ) +, BOOST_BINARY( 01010 ) +, BOOST_BINARY( 01011 ) +, BOOST_BINARY( 01100 ) +, BOOST_BINARY( 01101 ) +, BOOST_BINARY( 01110 ) +, BOOST_BINARY( 01111 ) +, BOOST_BINARY( 10000 ) +, BOOST_BINARY( 10001 ) +, BOOST_BINARY( 10010 ) +, BOOST_BINARY( 10011 ) +, BOOST_BINARY( 10100 ) +, BOOST_BINARY( 10101 ) +, BOOST_BINARY( 10110 ) +, BOOST_BINARY( 10111 ) +, BOOST_BINARY( 11000 ) +, BOOST_BINARY( 11001 ) +, BOOST_BINARY( 11010 ) +, BOOST_BINARY( 11011 ) +, BOOST_BINARY( 11100 ) +, BOOST_BINARY( 11101 ) +, BOOST_BINARY( 11110 ) +, BOOST_BINARY( 11111 ) +}; + +unsigned int const unsigned_ints_6_bits[64] = +{ BOOST_BINARY( 000000 ) +, BOOST_BINARY( 000001 ) +, BOOST_BINARY( 000010 ) +, BOOST_BINARY( 000011 ) +, BOOST_BINARY( 000100 ) +, BOOST_BINARY( 000101 ) +, BOOST_BINARY( 000110 ) +, BOOST_BINARY( 000111 ) +, BOOST_BINARY( 001000 ) +, BOOST_BINARY( 001001 ) +, BOOST_BINARY( 001010 ) +, BOOST_BINARY( 001011 ) +, BOOST_BINARY( 001100 ) +, BOOST_BINARY( 001101 ) +, BOOST_BINARY( 001110 ) +, BOOST_BINARY( 001111 ) +, BOOST_BINARY( 010000 ) +, BOOST_BINARY( 010001 ) +, BOOST_BINARY( 010010 ) +, BOOST_BINARY( 010011 ) +, BOOST_BINARY( 010100 ) +, BOOST_BINARY( 010101 ) +, BOOST_BINARY( 010110 ) +, BOOST_BINARY( 010111 ) +, BOOST_BINARY( 011000 ) +, BOOST_BINARY( 011001 ) +, BOOST_BINARY( 011010 ) +, BOOST_BINARY( 011011 ) +, BOOST_BINARY( 011100 ) +, BOOST_BINARY( 011101 ) +, BOOST_BINARY( 011110 ) +, BOOST_BINARY( 011111 ) +, BOOST_BINARY( 100000 ) +, BOOST_BINARY( 100001 ) +, BOOST_BINARY( 100010 ) +, BOOST_BINARY( 100011 ) +, BOOST_BINARY( 100100 ) +, BOOST_BINARY( 100101 ) +, BOOST_BINARY( 100110 ) +, BOOST_BINARY( 100111 ) +, BOOST_BINARY( 101000 ) +, BOOST_BINARY( 101001 ) +, BOOST_BINARY( 101010 ) +, BOOST_BINARY( 101011 ) +, BOOST_BINARY( 101100 ) +, BOOST_BINARY( 101101 ) +, BOOST_BINARY( 101110 ) +, BOOST_BINARY( 101111 ) +, BOOST_BINARY( 110000 ) +, BOOST_BINARY( 110001 ) +, BOOST_BINARY( 110010 ) +, BOOST_BINARY( 110011 ) +, BOOST_BINARY( 110100 ) +, BOOST_BINARY( 110101 ) +, BOOST_BINARY( 110110 ) +, BOOST_BINARY( 110111 ) +, BOOST_BINARY( 111000 ) +, BOOST_BINARY( 111001 ) +, BOOST_BINARY( 111010 ) +, BOOST_BINARY( 111011 ) +, BOOST_BINARY( 111100 ) +, BOOST_BINARY( 111101 ) +, BOOST_BINARY( 111110 ) +, BOOST_BINARY( 111111 ) +}; + +unsigned int const unsigned_ints_7_bits[128] = +{ BOOST_BINARY( 0000000 ) +, BOOST_BINARY( 0000001 ) +, BOOST_BINARY( 0000010 ) +, BOOST_BINARY( 0000011 ) +, BOOST_BINARY( 0000100 ) +, BOOST_BINARY( 0000101 ) +, BOOST_BINARY( 0000110 ) +, BOOST_BINARY( 0000111 ) +, BOOST_BINARY( 0001000 ) +, BOOST_BINARY( 0001001 ) +, BOOST_BINARY( 0001010 ) +, BOOST_BINARY( 0001011 ) +, BOOST_BINARY( 0001100 ) +, BOOST_BINARY( 0001101 ) +, BOOST_BINARY( 0001110 ) +, BOOST_BINARY( 0001111 ) +, BOOST_BINARY( 0010000 ) +, BOOST_BINARY( 0010001 ) +, BOOST_BINARY( 0010010 ) +, BOOST_BINARY( 0010011 ) +, BOOST_BINARY( 0010100 ) +, BOOST_BINARY( 0010101 ) +, BOOST_BINARY( 0010110 ) +, BOOST_BINARY( 0010111 ) +, BOOST_BINARY( 0011000 ) +, BOOST_BINARY( 0011001 ) +, BOOST_BINARY( 0011010 ) +, BOOST_BINARY( 0011011 ) +, BOOST_BINARY( 0011100 ) +, BOOST_BINARY( 0011101 ) +, BOOST_BINARY( 0011110 ) +, BOOST_BINARY( 0011111 ) +, BOOST_BINARY( 0100000 ) +, BOOST_BINARY( 0100001 ) +, BOOST_BINARY( 0100010 ) +, BOOST_BINARY( 0100011 ) +, BOOST_BINARY( 0100100 ) +, BOOST_BINARY( 0100101 ) +, BOOST_BINARY( 0100110 ) +, BOOST_BINARY( 0100111 ) +, BOOST_BINARY( 0101000 ) +, BOOST_BINARY( 0101001 ) +, BOOST_BINARY( 0101010 ) +, BOOST_BINARY( 0101011 ) +, BOOST_BINARY( 0101100 ) +, BOOST_BINARY( 0101101 ) +, BOOST_BINARY( 0101110 ) +, BOOST_BINARY( 0101111 ) +, BOOST_BINARY( 0110000 ) +, BOOST_BINARY( 0110001 ) +, BOOST_BINARY( 0110010 ) +, BOOST_BINARY( 0110011 ) +, BOOST_BINARY( 0110100 ) +, BOOST_BINARY( 0110101 ) +, BOOST_BINARY( 0110110 ) +, BOOST_BINARY( 0110111 ) +, BOOST_BINARY( 0111000 ) +, BOOST_BINARY( 0111001 ) +, BOOST_BINARY( 0111010 ) +, BOOST_BINARY( 0111011 ) +, BOOST_BINARY( 0111100 ) +, BOOST_BINARY( 0111101 ) +, BOOST_BINARY( 0111110 ) +, BOOST_BINARY( 0111111 ) +, BOOST_BINARY( 1000000 ) +, BOOST_BINARY( 1000001 ) +, BOOST_BINARY( 1000010 ) +, BOOST_BINARY( 1000011 ) +, BOOST_BINARY( 1000100 ) +, BOOST_BINARY( 1000101 ) +, BOOST_BINARY( 1000110 ) +, BOOST_BINARY( 1000111 ) +, BOOST_BINARY( 1001000 ) +, BOOST_BINARY( 1001001 ) +, BOOST_BINARY( 1001010 ) +, BOOST_BINARY( 1001011 ) +, BOOST_BINARY( 1001100 ) +, BOOST_BINARY( 1001101 ) +, BOOST_BINARY( 1001110 ) +, BOOST_BINARY( 1001111 ) +, BOOST_BINARY( 1010000 ) +, BOOST_BINARY( 1010001 ) +, BOOST_BINARY( 1010010 ) +, BOOST_BINARY( 1010011 ) +, BOOST_BINARY( 1010100 ) +, BOOST_BINARY( 1010101 ) +, BOOST_BINARY( 1010110 ) +, BOOST_BINARY( 1010111 ) +, BOOST_BINARY( 1011000 ) +, BOOST_BINARY( 1011001 ) +, BOOST_BINARY( 1011010 ) +, BOOST_BINARY( 1011011 ) +, BOOST_BINARY( 1011100 ) +, BOOST_BINARY( 1011101 ) +, BOOST_BINARY( 1011110 ) +, BOOST_BINARY( 1011111 ) +, BOOST_BINARY( 1100000 ) +, BOOST_BINARY( 1100001 ) +, BOOST_BINARY( 1100010 ) +, BOOST_BINARY( 1100011 ) +, BOOST_BINARY( 1100100 ) +, BOOST_BINARY( 1100101 ) +, BOOST_BINARY( 1100110 ) +, BOOST_BINARY( 1100111 ) +, BOOST_BINARY( 1101000 ) +, BOOST_BINARY( 1101001 ) +, BOOST_BINARY( 1101010 ) +, BOOST_BINARY( 1101011 ) +, BOOST_BINARY( 1101100 ) +, BOOST_BINARY( 1101101 ) +, BOOST_BINARY( 1101110 ) +, BOOST_BINARY( 1101111 ) +, BOOST_BINARY( 1110000 ) +, BOOST_BINARY( 1110001 ) +, BOOST_BINARY( 1110010 ) +, BOOST_BINARY( 1110011 ) +, BOOST_BINARY( 1110100 ) +, BOOST_BINARY( 1110101 ) +, BOOST_BINARY( 1110110 ) +, BOOST_BINARY( 1110111 ) +, BOOST_BINARY( 1111000 ) +, BOOST_BINARY( 1111001 ) +, BOOST_BINARY( 1111010 ) +, BOOST_BINARY( 1111011 ) +, BOOST_BINARY( 1111100 ) +, BOOST_BINARY( 1111101 ) +, BOOST_BINARY( 1111110 ) +, BOOST_BINARY( 1111111 ) +}; +unsigned int const unsigned_ints_8_bits[256] = +{ BOOST_BINARY( 00000000 ) +, BOOST_BINARY( 00000001 ) +, BOOST_BINARY( 00000010 ) +, BOOST_BINARY( 00000011 ) +, BOOST_BINARY( 00000100 ) +, BOOST_BINARY( 00000101 ) +, BOOST_BINARY( 00000110 ) +, BOOST_BINARY( 00000111 ) +, BOOST_BINARY( 00001000 ) +, BOOST_BINARY( 00001001 ) +, BOOST_BINARY( 00001010 ) +, BOOST_BINARY( 00001011 ) +, BOOST_BINARY( 00001100 ) +, BOOST_BINARY( 00001101 ) +, BOOST_BINARY( 00001110 ) +, BOOST_BINARY( 00001111 ) +, BOOST_BINARY( 00010000 ) +, BOOST_BINARY( 00010001 ) +, BOOST_BINARY( 00010010 ) +, BOOST_BINARY( 00010011 ) +, BOOST_BINARY( 00010100 ) +, BOOST_BINARY( 00010101 ) +, BOOST_BINARY( 00010110 ) +, BOOST_BINARY( 00010111 ) +, BOOST_BINARY( 00011000 ) +, BOOST_BINARY( 00011001 ) +, BOOST_BINARY( 00011010 ) +, BOOST_BINARY( 00011011 ) +, BOOST_BINARY( 00011100 ) +, BOOST_BINARY( 00011101 ) +, BOOST_BINARY( 00011110 ) +, BOOST_BINARY( 00011111 ) +, BOOST_BINARY( 00100000 ) +, BOOST_BINARY( 00100001 ) +, BOOST_BINARY( 00100010 ) +, BOOST_BINARY( 00100011 ) +, BOOST_BINARY( 00100100 ) +, BOOST_BINARY( 00100101 ) +, BOOST_BINARY( 00100110 ) +, BOOST_BINARY( 00100111 ) +, BOOST_BINARY( 00101000 ) +, BOOST_BINARY( 00101001 ) +, BOOST_BINARY( 00101010 ) +, BOOST_BINARY( 00101011 ) +, BOOST_BINARY( 00101100 ) +, BOOST_BINARY( 00101101 ) +, BOOST_BINARY( 00101110 ) +, BOOST_BINARY( 00101111 ) +, BOOST_BINARY( 00110000 ) +, BOOST_BINARY( 00110001 ) +, BOOST_BINARY( 00110010 ) +, BOOST_BINARY( 00110011 ) +, BOOST_BINARY( 00110100 ) +, BOOST_BINARY( 00110101 ) +, BOOST_BINARY( 00110110 ) +, BOOST_BINARY( 00110111 ) +, BOOST_BINARY( 00111000 ) +, BOOST_BINARY( 00111001 ) +, BOOST_BINARY( 00111010 ) +, BOOST_BINARY( 00111011 ) +, BOOST_BINARY( 00111100 ) +, BOOST_BINARY( 00111101 ) +, BOOST_BINARY( 00111110 ) +, BOOST_BINARY( 00111111 ) +, BOOST_BINARY( 01000000 ) +, BOOST_BINARY( 01000001 ) +, BOOST_BINARY( 01000010 ) +, BOOST_BINARY( 01000011 ) +, BOOST_BINARY( 01000100 ) +, BOOST_BINARY( 01000101 ) +, BOOST_BINARY( 01000110 ) +, BOOST_BINARY( 01000111 ) +, BOOST_BINARY( 01001000 ) +, BOOST_BINARY( 01001001 ) +, BOOST_BINARY( 01001010 ) +, BOOST_BINARY( 01001011 ) +, BOOST_BINARY( 01001100 ) +, BOOST_BINARY( 01001101 ) +, BOOST_BINARY( 01001110 ) +, BOOST_BINARY( 01001111 ) +, BOOST_BINARY( 01010000 ) +, BOOST_BINARY( 01010001 ) +, BOOST_BINARY( 01010010 ) +, BOOST_BINARY( 01010011 ) +, BOOST_BINARY( 01010100 ) +, BOOST_BINARY( 01010101 ) +, BOOST_BINARY( 01010110 ) +, BOOST_BINARY( 01010111 ) +, BOOST_BINARY( 01011000 ) +, BOOST_BINARY( 01011001 ) +, BOOST_BINARY( 01011010 ) +, BOOST_BINARY( 01011011 ) +, BOOST_BINARY( 01011100 ) +, BOOST_BINARY( 01011101 ) +, BOOST_BINARY( 01011110 ) +, BOOST_BINARY( 01011111 ) +, BOOST_BINARY( 01100000 ) +, BOOST_BINARY( 01100001 ) +, BOOST_BINARY( 01100010 ) +, BOOST_BINARY( 01100011 ) +, BOOST_BINARY( 01100100 ) +, BOOST_BINARY( 01100101 ) +, BOOST_BINARY( 01100110 ) +, BOOST_BINARY( 01100111 ) +, BOOST_BINARY( 01101000 ) +, BOOST_BINARY( 01101001 ) +, BOOST_BINARY( 01101010 ) +, BOOST_BINARY( 01101011 ) +, BOOST_BINARY( 01101100 ) +, BOOST_BINARY( 01101101 ) +, BOOST_BINARY( 01101110 ) +, BOOST_BINARY( 01101111 ) +, BOOST_BINARY( 01110000 ) +, BOOST_BINARY( 01110001 ) +, BOOST_BINARY( 01110010 ) +, BOOST_BINARY( 01110011 ) +, BOOST_BINARY( 01110100 ) +, BOOST_BINARY( 01110101 ) +, BOOST_BINARY( 01110110 ) +, BOOST_BINARY( 01110111 ) +, BOOST_BINARY( 01111000 ) +, BOOST_BINARY( 01111001 ) +, BOOST_BINARY( 01111010 ) +, BOOST_BINARY( 01111011 ) +, BOOST_BINARY( 01111100 ) +, BOOST_BINARY( 01111101 ) +, BOOST_BINARY( 01111110 ) +, BOOST_BINARY( 01111111 ) +, BOOST_BINARY( 10000000 ) +, BOOST_BINARY( 10000001 ) +, BOOST_BINARY( 10000010 ) +, BOOST_BINARY( 10000011 ) +, BOOST_BINARY( 10000100 ) +, BOOST_BINARY( 10000101 ) +, BOOST_BINARY( 10000110 ) +, BOOST_BINARY( 10000111 ) +, BOOST_BINARY( 10001000 ) +, BOOST_BINARY( 10001001 ) +, BOOST_BINARY( 10001010 ) +, BOOST_BINARY( 10001011 ) +, BOOST_BINARY( 10001100 ) +, BOOST_BINARY( 10001101 ) +, BOOST_BINARY( 10001110 ) +, BOOST_BINARY( 10001111 ) +, BOOST_BINARY( 10010000 ) +, BOOST_BINARY( 10010001 ) +, BOOST_BINARY( 10010010 ) +, BOOST_BINARY( 10010011 ) +, BOOST_BINARY( 10010100 ) +, BOOST_BINARY( 10010101 ) +, BOOST_BINARY( 10010110 ) +, BOOST_BINARY( 10010111 ) +, BOOST_BINARY( 10011000 ) +, BOOST_BINARY( 10011001 ) +, BOOST_BINARY( 10011010 ) +, BOOST_BINARY( 10011011 ) +, BOOST_BINARY( 10011100 ) +, BOOST_BINARY( 10011101 ) +, BOOST_BINARY( 10011110 ) +, BOOST_BINARY( 10011111 ) +, BOOST_BINARY( 10100000 ) +, BOOST_BINARY( 10100001 ) +, BOOST_BINARY( 10100010 ) +, BOOST_BINARY( 10100011 ) +, BOOST_BINARY( 10100100 ) +, BOOST_BINARY( 10100101 ) +, BOOST_BINARY( 10100110 ) +, BOOST_BINARY( 10100111 ) +, BOOST_BINARY( 10101000 ) +, BOOST_BINARY( 10101001 ) +, BOOST_BINARY( 10101010 ) +, BOOST_BINARY( 10101011 ) +, BOOST_BINARY( 10101100 ) +, BOOST_BINARY( 10101101 ) +, BOOST_BINARY( 10101110 ) +, BOOST_BINARY( 10101111 ) +, BOOST_BINARY( 10110000 ) +, BOOST_BINARY( 10110001 ) +, BOOST_BINARY( 10110010 ) +, BOOST_BINARY( 10110011 ) +, BOOST_BINARY( 10110100 ) +, BOOST_BINARY( 10110101 ) +, BOOST_BINARY( 10110110 ) +, BOOST_BINARY( 10110111 ) +, BOOST_BINARY( 10111000 ) +, BOOST_BINARY( 10111001 ) +, BOOST_BINARY( 10111010 ) +, BOOST_BINARY( 10111011 ) +, BOOST_BINARY( 10111100 ) +, BOOST_BINARY( 10111101 ) +, BOOST_BINARY( 10111110 ) +, BOOST_BINARY( 10111111 ) +, BOOST_BINARY( 11000000 ) +, BOOST_BINARY( 11000001 ) +, BOOST_BINARY( 11000010 ) +, BOOST_BINARY( 11000011 ) +, BOOST_BINARY( 11000100 ) +, BOOST_BINARY( 11000101 ) +, BOOST_BINARY( 11000110 ) +, BOOST_BINARY( 11000111 ) +, BOOST_BINARY( 11001000 ) +, BOOST_BINARY( 11001001 ) +, BOOST_BINARY( 11001010 ) +, BOOST_BINARY( 11001011 ) +, BOOST_BINARY( 11001100 ) +, BOOST_BINARY( 11001101 ) +, BOOST_BINARY( 11001110 ) +, BOOST_BINARY( 11001111 ) +, BOOST_BINARY( 11010000 ) +, BOOST_BINARY( 11010001 ) +, BOOST_BINARY( 11010010 ) +, BOOST_BINARY( 11010011 ) +, BOOST_BINARY( 11010100 ) +, BOOST_BINARY( 11010101 ) +, BOOST_BINARY( 11010110 ) +, BOOST_BINARY( 11010111 ) +, BOOST_BINARY( 11011000 ) +, BOOST_BINARY( 11011001 ) +, BOOST_BINARY( 11011010 ) +, BOOST_BINARY( 11011011 ) +, BOOST_BINARY( 11011100 ) +, BOOST_BINARY( 11011101 ) +, BOOST_BINARY( 11011110 ) +, BOOST_BINARY( 11011111 ) +, BOOST_BINARY( 11100000 ) +, BOOST_BINARY( 11100001 ) +, BOOST_BINARY( 11100010 ) +, BOOST_BINARY( 11100011 ) +, BOOST_BINARY( 11100100 ) +, BOOST_BINARY( 11100101 ) +, BOOST_BINARY( 11100110 ) +, BOOST_BINARY( 11100111 ) +, BOOST_BINARY( 11101000 ) +, BOOST_BINARY( 11101001 ) +, BOOST_BINARY( 11101010 ) +, BOOST_BINARY( 11101011 ) +, BOOST_BINARY( 11101100 ) +, BOOST_BINARY( 11101101 ) +, BOOST_BINARY( 11101110 ) +, BOOST_BINARY( 11101111 ) +, BOOST_BINARY( 11110000 ) +, BOOST_BINARY( 11110001 ) +, BOOST_BINARY( 11110010 ) +, BOOST_BINARY( 11110011 ) +, BOOST_BINARY( 11110100 ) +, BOOST_BINARY( 11110101 ) +, BOOST_BINARY( 11110110 ) +, BOOST_BINARY( 11110111 ) +, BOOST_BINARY( 11111000 ) +, BOOST_BINARY( 11111001 ) +, BOOST_BINARY( 11111010 ) +, BOOST_BINARY( 11111011 ) +, BOOST_BINARY( 11111100 ) +, BOOST_BINARY( 11111101 ) +, BOOST_BINARY( 11111110 ) +, BOOST_BINARY( 11111111 ) +}; + +struct left_is_not_one_less_than_right +{ + bool operator ()( unsigned int left, unsigned int right ) const + { + return right != left + 1; + } +}; + +template< std::size_t Size > +bool is_ascending_from_0_array( unsigned int const (&array)[Size] ) +{ + unsigned int const* const curr = array, + * const end = array + Size; + + return ( *curr == 0 ) + && ( std::adjacent_find( curr, end + , left_is_not_one_less_than_right() + ) + == end + ); +} + +std::size_t const unsigned_int_id = 1, + unsigned_long_int_id = 2; + +typedef char (&unsigned_int_id_type)[unsigned_int_id]; +typedef char (&unsigned_long_int_id_type)[unsigned_long_int_id]; + +// Note: Functions only used for type checking +unsigned_int_id_type binary_type_checker( unsigned int ); +unsigned_long_int_id_type binary_type_checker( unsigned long int ); + +int test_main( int, char *[] ) +{ + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_1_bit ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_2_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_3_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_4_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_5_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_6_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_7_bits ) ); + BOOST_CHECK( is_ascending_from_0_array( unsigned_ints_8_bits ) ); + + BOOST_CHECK( std::equal( &random_unsigned_ints_hex[0]+ , random_unsigned_ints_hex + num_random_test_values
+ , &random_unsigned_ints_binary[0] + ) + ); ++ BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_U( 110100 1010 ) ) )
+ == unsigned_int_id + ); + + BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_UL( 11110 ) ) ) + == unsigned_long_int_id + ); ++ BOOST_CHECK( sizeof( binary_type_checker( BOOST_BINARY_LU( 10 0001 ) ) )
+ == unsigned_long_int_id + ); + + return 0; +} ======================================= --- /dev/null +++ /trunk/libs/utility/swap/test/Jamfile.v2 Mon May 31 02:08:39 2010 @@ -0,0 +1,37 @@ +# Copyright (c) 2007, 2008 Joseph Gauterin +# +# 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) + +# bring in rules for testing +import testing ; + +test-suite utility/swap + : + [ compile root_header_1.cpp ] + [ compile root_header_2.cpp ] + [ compile lib_header_1.cpp ] + [ compile lib_header_2.cpp ] + [ compile mixed_headers_1.cpp ] + [ compile mixed_headers_2.cpp ]+ [ run primitive.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run specialized_in_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run specialized_in_global.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run specialized_in_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run specialized_in_std.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run specialized_in_boost_and_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run std_bitset.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run std_dateorder.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run std_string.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run std_typeinfo_ptr.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run std_vector_of_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run std_vector_of_global.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run std_vector_of_other.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run no_ambiguity_in_boost.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run array_of_array_of_class.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run array_of_array_of_int.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run array_of_class.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run array_of_int.cpp ../../../test/build//boost_test_exec_monitor/<link>static ] + [ run array_of_template.cpp ../../../test/build//boost_test_exec_monitor/<link>static ]
+ ; ======================================= --- /dev/null+++ /trunk/libs/utility/swap/test/array_of_array_of_class.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,69 @@ +// Copyright (c) 2008 Joseph Gauterin, Niels Dekker +// +// 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) ++// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
+ +#include <boost/utility/swap.hpp> +#define BOOST_INCLUDE_MAIN +#include <boost/test/test_tools.hpp> + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + +#include <algorithm> //for std::copy and std::equal +#include <cstddef> //for std::size_t + +//Provide swap function in both the namespace of swap_test_class +//(which is the global namespace), and the std namespace. +//It's common to provide a swap function for a class in both +//namespaces. Scott Meyers recommends doing so: Effective C++, +//Third Edition, item 25, "Consider support for a non-throwing swap". +void swap(swap_test_class& left, swap_test_class& right) +{ + left.swap(right); +} + +namespace std +{ + template <> + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + + +int test_main(int, char*[]) +{ + const std::size_t first_dimension = 3; + const std::size_t second_dimension = 4;+ const std::size_t number_of_elements = first_dimension * second_dimension;
+ + swap_test_class array1[first_dimension][second_dimension]; + swap_test_class array2[first_dimension][second_dimension]; + + swap_test_class* const ptr1 = array1[0]; + swap_test_class* const ptr2 = array2[0]; + + for (std::size_t i = 0; i < number_of_elements; ++i) + { + ptr1[i].set_data( static_cast<int>(i) ); + ptr2[i].set_data( static_cast<int>(i + number_of_elements) ); + } + + boost::swap(array1, array2); + + for (std::size_t i = 0; i < number_of_elements; ++i) + {+ BOOST_CHECK_EQUAL(ptr1[i].get_data(), static_cast<int>(i + number_of_elements) );
+ BOOST_CHECK_EQUAL(ptr2[i].get_data(), static_cast<int>(i) ); + } + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(), number_of_elements); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/utility/swap/test/array_of_array_of_int.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,42 @@ +// Copyright (c) 2008 Joseph Gauterin, Niels Dekker +// +// 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) + +// Tests swapping an array of arrays of integers by means of boost::swap. + +#include <boost/utility/swap.hpp> +#define BOOST_INCLUDE_MAIN +#include <boost/test/test_tools.hpp> + +#include <algorithm> //for std::copy and std::equal +#include <cstddef> //for std::size_t + +int test_main(int, char*[]) +{ + const std::size_t first_dimension = 3; + const std::size_t second_dimension = 4;+ const std::size_t number_of_elements = first_dimension * second_dimension;
+ + int array1[first_dimension][second_dimension]; + int array2[first_dimension][second_dimension]; + + int* const ptr1 = array1[0]; + int* const ptr2 = array2[0]; + + for (std::size_t i = 0; i < number_of_elements; ++i) + { + ptr1[i] = static_cast<int>(i); + ptr2[i] = static_cast<int>(i + number_of_elements); + } + + boost::swap(array1, array2); + + for (std::size_t i = 0; i < number_of_elements; ++i) + { + BOOST_CHECK_EQUAL(ptr1[i], static_cast<int>(i + number_of_elements) ); + BOOST_CHECK_EQUAL(ptr2[i], static_cast<int>(i) ); + } + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/utility/swap/test/array_of_class.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,61 @@ +// Copyright (c) 2008 Joseph Gauterin, Niels Dekker +// +// 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) ++// Tests swapping an array of arrays of swap_test_class objects by means of boost::swap.
+ +#include <boost/utility/swap.hpp> +#define BOOST_INCLUDE_MAIN +#include <boost/test/test_tools.hpp> + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + +#include <algorithm> //for std::copy and std::equal +#include <cstddef> //for std::size_t + +//Provide swap function in both the namespace of swap_test_class +//(which is the global namespace), and the std namespace. +//It's common to provide a swap function for a class in both +//namespaces. Scott Meyers recommends doing so: Effective C++, +//Third Edition, item 25, "Consider support for a non-throwing swap". +void swap(swap_test_class& left, swap_test_class& right) +{ + left.swap(right); +} + +namespace std +{ + template <> + void swap(swap_test_class& left, swap_test_class& right) + { + left.swap(right); + } +} + + +int test_main(int, char*[]) +{ + const std::size_t array_size = 2;+ const swap_test_class initial_array1[array_size] = { swap_test_class(1), swap_test_class(2) }; + const swap_test_class initial_array2[array_size] = { swap_test_class(3), swap_test_class(4) };
+ + swap_test_class array1[array_size]; + swap_test_class array2[array_size]; + + std::copy(initial_array1, initial_array1 + array_size, array1); + std::copy(initial_array2, initial_array2 + array_size, array2); + + swap_test_class::reset(); + boost::swap(array1, array2); + + BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2)); + BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(), array_size); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); + + return 0; +} ======================================= --- /dev/null +++ /trunk/libs/utility/swap/test/array_of_int.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,35 @@ +// Copyright (c) 2008 Joseph Gauterin, Niels Dekker +// +// 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) + +// Tests swapping an array of integers by means of boost::swap. + +#include <boost/utility/swap.hpp> +#define BOOST_INCLUDE_MAIN +#include <boost/test/test_tools.hpp> + +#include <algorithm> //for std::copy and std::equal +#include <cstddef> //for std::size_t + + +int test_main(int, char*[]) +{ + const std::size_t array_size = 3; + const int initial_array1[array_size] = { 1, 2, 3 }; + const int initial_array2[array_size] = { 4, 5, 6 }; + + int array1[array_size]; + int array2[array_size]; + + std::copy(initial_array1, initial_array1 + array_size, array1); + std::copy(initial_array2, initial_array2 + array_size, array2); + + boost::swap(array1, array2); + + BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2)); + BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); + + return 0; +} ======================================= --- /dev/null+++ /trunk/libs/utility/swap/test/array_of_template.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,71 @@ +// Copyright (c) 2008 Joseph Gauterin, Niels Dekker +// +// 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) ++// Tests swapping an array of swap_test_template<int> objects by means of boost::swap.
+ +#include <boost/utility/swap.hpp> +#define BOOST_INCLUDE_MAIN +#include <boost/test/test_tools.hpp> + +//Put test class in the global namespace +#include "./swap_test_class.hpp" + +#include <algorithm> //for std::copy and std::equal +#include <cstddef> //for std::size_t + +template <class T> +class swap_test_template +{ +public: + typedef T template_argument; + swap_test_class swap_test_object; +}; + +template <class T>+inline bool operator==(const swap_test_template<T> & lhs, const swap_test_template<T> & rhs)
+{ + return lhs.swap_test_object == rhs.swap_test_object; +} + +template <class T>+inline bool operator!=(const swap_test_template<T> & lhs, const swap_test_template<T> & rhs)
+{ + return !(lhs == rhs); +} + +//Provide swap function in the namespace of swap_test_template +//(which is the global namespace). Note that it isn't allowed to put +//an overload of this function within the std namespace. +template <class T> +void swap(swap_test_template<T>& left, swap_test_template<T>& right) +{ + left.swap_test_object.swap(right.swap_test_object); +} + + +int test_main(int, char*[]) +{ + const std::size_t array_size = 2;+ const swap_test_template<int> initial_array1[array_size] = { swap_test_class(1), swap_test_class(2) }; + const swap_test_template<int> initial_array2[array_size] = { swap_test_class(3), swap_test_class(4) };
+ + swap_test_template<int> array1[array_size]; + swap_test_template<int> array2[array_size]; + + std::copy(initial_array1, initial_array1 + array_size, array1); + std::copy(initial_array2, initial_array2 + array_size, array2); + + swap_test_class::reset(); + boost::swap(array1, array2); + + BOOST_CHECK(std::equal(array1, array1 + array_size, initial_array2)); + BOOST_CHECK(std::equal(array2, array2 + array_size, initial_array1)); + + BOOST_CHECK_EQUAL(swap_test_class::swap_count(), array_size); + BOOST_CHECK_EQUAL(swap_test_class::copy_count(), 0); + + return 0; +} ======================================= --- /dev/null +++ /trunk/libs/utility/swap/test/lib_header_1.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,10 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap header compiles as a standalone translation unit + +#include <boost/utility/swap.hpp> + ======================================= --- /dev/null +++ /trunk/libs/utility/swap/test/lib_header_2.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,11 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap header include guards work correctly + +#include <boost/utility/swap.hpp> +#include <boost/utility/swap.hpp> + ======================================= --- /dev/null+++ /trunk/libs/utility/swap/test/mixed_headers_1.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,11 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap headers work when both are included + +#include <boost/swap.hpp> +#include <boost/utility/swap.hpp> + ======================================= --- /dev/null+++ /trunk/libs/utility/swap/test/mixed_headers_2.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,12 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap headers work when both are included + +#include <boost/utility/swap.hpp> +#include <boost/swap.hpp> + + ======================================= --- /dev/null+++ /trunk/libs/utility/swap/test/no_ambiguity_in_boost.cpp Mon May 31 02:08:39 2010
@@ -0,0 +1,44 @@ +// Copyright (c) 2008 Joseph Gauterin, Niels Dekker +// +// 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) + +// boost::swap internally does an unqualified function call to swap. +// This could have led to ambiguity or infinite recursion, when the +// objects to be swapped would themselves be from the boost namespace. +// If so, boost::swap itself might be found by argument dependent lookup. +// The implementation of boost::swap resolves this issue by giving +// boost::swap two template argumetns, thereby making it less specialized +// than std::swap. + +#include <boost/utility/swap.hpp> +#define BOOST_INCLUDE_MAIN +#include <boost/test/test_tools.hpp> + +//Put test class in namespace boost +namespace boost +{ + #include "./swap_test_class.hpp" +} + + +int test_main(int, char*[]) +{ + const boost::swap_test_class initial_value1(1); + const boost::swap_test_class initial_value2(2); + + boost::swap_test_class object1 = initial_value1; + boost::swap_test_class object2 = initial_value2; + + boost::swap_test_class::reset(); + boost::swap(object1,object2); + + BOOST_CHECK(object1 == initial_value2); + BOOST_CHECK(object2 == initial_value1); + BOOST_CHECK_EQUAL(boost::swap_test_class::swap_count(),0); + BOOST_CHECK_EQUAL(boost::swap_test_class::copy_count(),3); + + return 0; +} + ======================================= --- /dev/null +++ /trunk/libs/utility/swap/test/primitive.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,23 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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/utility/swap.hpp> +#define BOOST_INCLUDE_MAIN +#include <boost/test/test_tools.hpp> + +int test_main(int, char*[]) +{ + int object1 = 1; + int object2 = 2; + + boost::swap(object1,object2); + + BOOST_CHECK_EQUAL(object1,2); + BOOST_CHECK_EQUAL(object2,1); + + return 0; +} + ======================================= --- /dev/null +++ /trunk/libs/utility/swap/test/root_header_1.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,10 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap header compiles as a standalone translation unit + +#include <boost/swap.hpp> + ======================================= --- /dev/null +++ /trunk/libs/utility/swap/test/root_header_2.cpp Mon May 31 02:08:39 2010 @@ -0,0 +1,11 @@ +// Copyright (c) 2007 Joseph Gauterin +// +// 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) + +// Tests that the swap header include guards work correctly + +#include <boost/swap.hpp> +#include <boost/swap.hpp> + ======================================= ***Additional files exist in this changeset.***