[boost-doc-zh] r380 committed - 升级至1.42.0,第六批,libs/目录下s子目录

  • From: boost-doc-zh@xxxxxxxxxxxxxx
  • To: boost-doc-zh-notify@xxxxxxxxxxxxx
  • Date: Tue, 09 Feb 2010 03:42:45 +0000

Revision: 380
Author: alai04
Date: Mon Feb  8 19:41:53 2010
Log: 升级至1.42.0,第六批,libs/目录下s子目录
http://code.google.com/p/boost-doc-zh/source/detail?r=380

Added:
 /trunk/libs/serialization/example/Jamfile.v2
 /trunk/libs/serialization/src/archive_exception.cpp
 /trunk/libs/serialization/src/shared_ptr_helper.cpp
 /trunk/libs/serialization/src/xml_archive_exception.cpp
 /trunk/libs/serialization/test/Jamfile.v2
 /trunk/libs/serialization/test/polymorphic_base.cpp
 /trunk/libs/serialization/test/polymorphic_base.hpp
 /trunk/libs/serialization/test/polymorphic_derived1.cpp
 /trunk/libs/serialization/test/polymorphic_derived1.hpp
 /trunk/libs/serialization/test/polymorphic_derived2.cpp
 /trunk/libs/serialization/test/polymorphic_derived2.hpp
 /trunk/libs/serialization/test/test_bitset.cpp
 /trunk/libs/serialization/test/test_check.cpp
 /trunk/libs/serialization/test/test_multiple_inheritance.cpp
 /trunk/libs/serialization/test/test_new_operator.cpp
 /trunk/libs/serialization/test/test_polymorphic2.cpp
 /trunk/libs/serialization/test/test_polymorphic2.hpp
 /trunk/libs/serialization/test/test_polymorphic2imp.cpp
 /trunk/libs/serialization/test/test_private_base.cpp
 /trunk/libs/serialization/test/test_shared_ptr_multi_base.cpp
 /trunk/libs/smart_ptr/test/Jamfile.v2
 /trunk/libs/smart_ptr/test/allocate_shared_esft_test.cpp
 /trunk/libs/smart_ptr/test/atomic_count_test2.cpp
 /trunk/libs/smart_ptr/test/auto_ptr_lv_fail.cpp
 /trunk/libs/smart_ptr/test/esft_constructor_test.cpp
 /trunk/libs/smart_ptr/test/esft_second_ptr_test.cpp
 /trunk/libs/smart_ptr/test/esft_void_test.cpp
 /trunk/libs/smart_ptr/test/intrusive_ptr_move_test.cpp
 /trunk/libs/smart_ptr/test/make_shared_esft_test.cpp
 /trunk/libs/smart_ptr/test/make_shared_perfect_forwarding_test.cpp
 /trunk/libs/smart_ptr/test/sp_recursive_assign2_rv_test.cpp
 /trunk/libs/smart_ptr/test/sp_recursive_assign2_test.cpp
 /trunk/libs/smart_ptr/test/sp_recursive_assign_rv_test.cpp
 /trunk/libs/smart_ptr/test/sp_recursive_assign_test.cpp
 /trunk/libs/smart_ptr/test/sp_typeinfo_test.cpp
 /trunk/libs/smart_ptr/test/weak_ptr_move_test.cpp
 /trunk/libs/spirit/doc/Jamfile
 /trunk/libs/spirit/doc/abstracts
 /trunk/libs/spirit/doc/abstracts/attributes.qbk
 /trunk/libs/spirit/doc/abstracts/peg.qbk
 /trunk/libs/spirit/doc/abstracts/syntax_diagram.qbk
 /trunk/libs/spirit/doc/abstracts.qbk
 /trunk/libs/spirit/doc/acknowledgments.qbk
 /trunk/libs/spirit/doc/advanced
 /trunk/libs/spirit/doc/advanced/customization_points.qbk
 /trunk/libs/spirit/doc/advanced/indepth.qbk
 /trunk/libs/spirit/doc/advanced.qbk
 /trunk/libs/spirit/doc/concepts_template.qbk
 /trunk/libs/spirit/doc/customization_point_template.qbk
 /trunk/libs/spirit/doc/faq.qbk
 /trunk/libs/spirit/doc/introduction.qbk
 /trunk/libs/spirit/doc/karma
 /trunk/libs/spirit/doc/karma/action.qbk
 /trunk/libs/spirit/doc/karma/actions.qbk
 /trunk/libs/spirit/doc/karma/auto.qbk
 /trunk/libs/spirit/doc/karma/auxiliary.qbk
 /trunk/libs/spirit/doc/karma/basics.qbk
 /trunk/libs/spirit/doc/karma/binary.qbk
 /trunk/libs/spirit/doc/karma/char.qbk
 /trunk/libs/spirit/doc/karma/complex.qbk
 /trunk/libs/spirit/doc/karma/concepts.qbk
 /trunk/libs/spirit/doc/karma/directive.qbk
 /trunk/libs/spirit/doc/karma/generate_api.qbk
 /trunk/libs/spirit/doc/karma/nonterminal.qbk
 /trunk/libs/spirit/doc/karma/num_list.qbk
 /trunk/libs/spirit/doc/karma/numeric.qbk
 /trunk/libs/spirit/doc/karma/numeric_performance.qbk
 /trunk/libs/spirit/doc/karma/operator.qbk
 /trunk/libs/spirit/doc/karma/quick_reference.qbk
 /trunk/libs/spirit/doc/karma/stream.qbk
 /trunk/libs/spirit/doc/karma/string.qbk
 /trunk/libs/spirit/doc/karma/tutorial_intro.qbk
 /trunk/libs/spirit/doc/karma/warming_up.qbk
 /trunk/libs/spirit/doc/karma.qbk
 /trunk/libs/spirit/doc/lex
 /trunk/libs/spirit/doc/lex/basics.qbk
 /trunk/libs/spirit/doc/lex/concepts.qbk
 /trunk/libs/spirit/doc/lex/introduction.qbk
 /trunk/libs/spirit/doc/lex/lexer.qbk
 /trunk/libs/spirit/doc/lex/lexer_api.qbk
 /trunk/libs/spirit/doc/lex/lexer_attributes.qbk
 /trunk/libs/spirit/doc/lex/lexer_class.qbk
 /trunk/libs/spirit/doc/lex/lexer_primitives.qbk
 /trunk/libs/spirit/doc/lex/lexer_quickstart1.qbk
 /trunk/libs/spirit/doc/lex/lexer_quickstart2.qbk
 /trunk/libs/spirit/doc/lex/lexer_quickstart3.qbk
 /trunk/libs/spirit/doc/lex/lexer_semantic_actions.qbk
 /trunk/libs/spirit/doc/lex/lexer_states.qbk
 /trunk/libs/spirit/doc/lex/lexer_static_model.qbk
 /trunk/libs/spirit/doc/lex/lexer_tutorials.qbk
 /trunk/libs/spirit/doc/lex/parsing_using_a_lexer.qbk
 /trunk/libs/spirit/doc/lex/quick_reference.qbk
 /trunk/libs/spirit/doc/lex/token.qbk
 /trunk/libs/spirit/doc/lex/token_class.qbk
 /trunk/libs/spirit/doc/lex/token_definition.qbk
 /trunk/libs/spirit/doc/lex/token_primitives.qbk
 /trunk/libs/spirit/doc/lex/tokendef.qbk
 /trunk/libs/spirit/doc/lex/tokendef_class.qbk
 /trunk/libs/spirit/doc/lex/tokenizing.qbk
 /trunk/libs/spirit/doc/lex/tokens_values.qbk
 /trunk/libs/spirit/doc/lex.qbk
 /trunk/libs/spirit/doc/notes
 /trunk/libs/spirit/doc/notes/porting_from_1_8.qbk
 /trunk/libs/spirit/doc/notes/style_guide.qbk
 /trunk/libs/spirit/doc/notes.qbk
 /trunk/libs/spirit/doc/operator_template.qbk
 /trunk/libs/spirit/doc/preface.qbk
 /trunk/libs/spirit/doc/qi
 /trunk/libs/spirit/doc/qi/action.qbk
 /trunk/libs/spirit/doc/qi/actions.qbk
 /trunk/libs/spirit/doc/qi/auto.qbk
 /trunk/libs/spirit/doc/qi/auxiliary.qbk
 /trunk/libs/spirit/doc/qi/basics.qbk
 /trunk/libs/spirit/doc/qi/binary.qbk
 /trunk/libs/spirit/doc/qi/char.qbk
 /trunk/libs/spirit/doc/qi/complex.qbk
 /trunk/libs/spirit/doc/qi/concepts.qbk
 /trunk/libs/spirit/doc/qi/directive.qbk
 /trunk/libs/spirit/doc/qi/employee.qbk
 /trunk/libs/spirit/doc/qi/error_handling.qbk
 /trunk/libs/spirit/doc/qi/mini_xml.qbk
 /trunk/libs/spirit/doc/qi/nonterminal.qbk
 /trunk/libs/spirit/doc/qi/num_list2.qbk
 /trunk/libs/spirit/doc/qi/num_list3.qbk
 /trunk/libs/spirit/doc/qi/num_list4.qbk
 /trunk/libs/spirit/doc/qi/numeric.qbk
 /trunk/libs/spirit/doc/qi/operator.qbk
 /trunk/libs/spirit/doc/qi/parse_api.qbk
 /trunk/libs/spirit/doc/qi/quick_reference.qbk
 /trunk/libs/spirit/doc/qi/roman.qbk
 /trunk/libs/spirit/doc/qi/stream.qbk
 /trunk/libs/spirit/doc/qi/string.qbk
 /trunk/libs/spirit/doc/qi/sum_tutorial.qbk
 /trunk/libs/spirit/doc/qi/tutorial_intro.qbk
 /trunk/libs/spirit/doc/qi/warming_up.qbk
 /trunk/libs/spirit/doc/qi.qbk
 /trunk/libs/spirit/doc/rationale.qbk
 /trunk/libs/spirit/doc/reference_template.qbk
 /trunk/libs/spirit/doc/references.qbk
 /trunk/libs/spirit/doc/repository.qbk
 /trunk/libs/spirit/doc/spirit2.qbk
 /trunk/libs/spirit/doc/structure.qbk
 /trunk/libs/spirit/doc/support
 /trunk/libs/spirit/doc/support/multi_pass.qbk
 /trunk/libs/spirit/doc/support.qbk
 /trunk/libs/spirit/doc/what_s_new.qbk
 /trunk/libs/spirit/phoenix/doc/Jamfile.v2
 /trunk/libs/spirit/phoenix/doc/users_manual.qbk
 /trunk/libs/spirit/repository/doc/Jamfile
 /trunk/libs/spirit/repository/doc/karma
 /trunk/libs/spirit/repository/doc/karma/compound_generators.qbk
 /trunk/libs/spirit/repository/doc/karma/confix.qbk
 /trunk/libs/spirit/repository/doc/karma/directives.qbk
 /trunk/libs/spirit/repository/doc/karma/nonterminals.qbk
 /trunk/libs/spirit/repository/doc/karma/primitive_generators.qbk
 /trunk/libs/spirit/repository/doc/karma/subrule.qbk
 /trunk/libs/spirit/repository/doc/karma.qbk
 /trunk/libs/spirit/repository/doc/preface.qbk
 /trunk/libs/spirit/repository/doc/qi
 /trunk/libs/spirit/repository/doc/qi/compound_parsers.qbk
 /trunk/libs/spirit/repository/doc/qi/confix.qbk
 /trunk/libs/spirit/repository/doc/qi/directives.qbk
 /trunk/libs/spirit/repository/doc/qi/distinct.qbk
 /trunk/libs/spirit/repository/doc/qi/flush_multi_pass.qbk
 /trunk/libs/spirit/repository/doc/qi/nonterminals.qbk
 /trunk/libs/spirit/repository/doc/qi/primitive_parsers.qbk
 /trunk/libs/spirit/repository/doc/qi/subrule.qbk
 /trunk/libs/spirit/repository/doc/qi.qbk
 /trunk/libs/spirit/repository/doc/repository_template.qbk
 /trunk/libs/spirit/repository/doc/spirit2_repository.qbk
 /trunk/libs/statechart/test/TriggeringEventTest.cpp
Modified:
 /trunk/libs/serialization/doc/contents.html
 /trunk/libs/serialization/doc/release.html
 /trunk/libs/serialization/example/demo_fast_archive.cpp
 /trunk/libs/serialization/example/demo_gps.hpp
 /trunk/libs/serialization/example/demo_polymorphic_A.cpp
 /trunk/libs/serialization/example/demo_polymorphic_A.hpp
 /trunk/libs/serialization/example/portable_binary_archive.hpp
 /trunk/libs/serialization/example/portable_binary_iarchive.cpp
 /trunk/libs/serialization/example/portable_binary_iarchive.hpp
 /trunk/libs/serialization/example/portable_binary_oarchive.cpp
 /trunk/libs/serialization/src/basic_archive.cpp
 /trunk/libs/serialization/src/basic_iarchive.cpp
 /trunk/libs/serialization/src/basic_iserializer.cpp
 /trunk/libs/serialization/src/basic_oarchive.cpp
 /trunk/libs/serialization/src/basic_oserializer.cpp
 /trunk/libs/serialization/src/basic_serializer_map.cpp
 /trunk/libs/serialization/src/basic_xml_archive.cpp
 /trunk/libs/serialization/src/basic_xml_grammar.ipp
 /trunk/libs/serialization/src/binary_iarchive.cpp
 /trunk/libs/serialization/src/binary_oarchive.cpp
 /trunk/libs/serialization/src/binary_wiarchive.cpp
 /trunk/libs/serialization/src/binary_woarchive.cpp
 /trunk/libs/serialization/src/codecvt_null.cpp
 /trunk/libs/serialization/src/extended_type_info.cpp
 /trunk/libs/serialization/src/extended_type_info_no_rtti.cpp
 /trunk/libs/serialization/src/extended_type_info_typeid.cpp
 /trunk/libs/serialization/src/polymorphic_iarchive.cpp
 /trunk/libs/serialization/src/polymorphic_oarchive.cpp
 /trunk/libs/serialization/src/stl_port.cpp
 /trunk/libs/serialization/src/text_iarchive.cpp
 /trunk/libs/serialization/src/text_oarchive.cpp
 /trunk/libs/serialization/src/text_wiarchive.cpp
 /trunk/libs/serialization/src/text_woarchive.cpp
 /trunk/libs/serialization/src/void_cast.cpp
 /trunk/libs/serialization/src/xml_grammar.cpp
 /trunk/libs/serialization/src/xml_iarchive.cpp
 /trunk/libs/serialization/src/xml_oarchive.cpp
 /trunk/libs/serialization/src/xml_wgrammar.cpp
 /trunk/libs/serialization/src/xml_wiarchive.cpp
 /trunk/libs/serialization/src/xml_woarchive.cpp
 /trunk/libs/serialization/test/A.cpp
 /trunk/libs/serialization/test/A.hpp
 /trunk/libs/serialization/test/A.ipp
 /trunk/libs/serialization/test/B.hpp
 /trunk/libs/serialization/test/D.hpp
 /trunk/libs/serialization/test/base.hpp
 /trunk/libs/serialization/test/derived2.hpp
 /trunk/libs/serialization/test/dll_a.cpp
 /trunk/libs/serialization/test/dll_base.cpp
 /trunk/libs/serialization/test/dll_derived2.cpp
 /trunk/libs/serialization/test/polymorphic_text_warchive.hpp
 /trunk/libs/serialization/test/test_binary.cpp
 /trunk/libs/serialization/test/test_class_info_save.cpp
 /trunk/libs/serialization/test/test_complex.cpp
 /trunk/libs/serialization/test/test_contained_class.cpp
 /trunk/libs/serialization/test/test_cyclic_ptrs.cpp
 /trunk/libs/serialization/test/test_decl.hpp
 /trunk/libs/serialization/test/test_delete_pointer.cpp
 /trunk/libs/serialization/test/test_deque.cpp
 /trunk/libs/serialization/test/test_derived.cpp
 /trunk/libs/serialization/test/test_derived_class.cpp
 /trunk/libs/serialization/test/test_derived_class_ptr.cpp
 /trunk/libs/serialization/test/test_diamond.cpp
 /trunk/libs/serialization/test/test_dll_exported.cpp
 /trunk/libs/serialization/test/test_dll_plugin.cpp
 /trunk/libs/serialization/test/test_dll_simple.cpp
 /trunk/libs/serialization/test/test_exported.cpp
 /trunk/libs/serialization/test/test_inclusion.cpp
 /trunk/libs/serialization/test/test_iterators.cpp
 /trunk/libs/serialization/test/test_iterators_base64.cpp
 /trunk/libs/serialization/test/test_list.cpp
 /trunk/libs/serialization/test/test_list_ptrs.cpp
 /trunk/libs/serialization/test/test_map.cpp
 /trunk/libs/serialization/test/test_mi.cpp
 /trunk/libs/serialization/test/test_mult_archive_types.cpp
 /trunk/libs/serialization/test/test_multiple_ptrs.cpp
 /trunk/libs/serialization/test/test_no_rtti.cpp
 /trunk/libs/serialization/test/test_non_default_ctor.cpp
 /trunk/libs/serialization/test/test_non_default_ctor2.cpp
 /trunk/libs/serialization/test/test_non_intrusive.cpp
 /trunk/libs/serialization/test/test_null_ptr.cpp
 /trunk/libs/serialization/test/test_nvp.cpp
 /trunk/libs/serialization/test/test_object.cpp
 /trunk/libs/serialization/test/test_optional.cpp
 /trunk/libs/serialization/test/test_polymorphic.cpp
 /trunk/libs/serialization/test/test_primitive.cpp
 /trunk/libs/serialization/test/test_private_ctor.cpp
 /trunk/libs/serialization/test/test_recursion.cpp
 /trunk/libs/serialization/test/test_registered.cpp
 /trunk/libs/serialization/test/test_reset_object_address.cpp
 /trunk/libs/serialization/test/test_shared_ptr.cpp
 /trunk/libs/serialization/test/test_shared_ptr_132.cpp
 /trunk/libs/serialization/test/test_simple_class.cpp
 /trunk/libs/serialization/test/test_simple_class_ptr.cpp
 /trunk/libs/serialization/test/test_smart_cast.cpp
 /trunk/libs/serialization/test/test_split.cpp
 /trunk/libs/serialization/test/test_static_warning.cpp
 /trunk/libs/serialization/test/test_tools.hpp
 /trunk/libs/serialization/test/test_tracking.cpp
 /trunk/libs/serialization/test/test_unregistered.cpp
 /trunk/libs/serialization/test/test_utf8_codecvt.cpp
 /trunk/libs/serialization/test/test_valarray.cpp
 /trunk/libs/serialization/test/test_variant.cpp
 /trunk/libs/serialization/test/test_vector.cpp
 /trunk/libs/serialization/test/test_void_cast.cpp
 /trunk/libs/smart_ptr/enable_shared_from_this.html
 /trunk/libs/smart_ptr/src/sp_collector.cpp
 /trunk/libs/smart_ptr/test/allocate_shared_test.cpp
 /trunk/libs/smart_ptr/test/make_shared_test.cpp
 /trunk/libs/smart_ptr/test/pointer_cast_test.cpp
 /trunk/libs/smart_ptr/test/shared_from_this_test.cpp
 /trunk/libs/smart_ptr/test/shared_ptr_basic_test.cpp
 /trunk/libs/smart_ptr/test/shared_ptr_move_test.cpp
 /trunk/libs/smart_ptr/test/shared_ptr_test.cpp
 /trunk/libs/smart_ptr/test/spinlock_pool_test.cpp
 /trunk/libs/smart_ptr/test/spinlock_test.cpp
 /trunk/libs/smart_ptr/test/spinlock_try_test.cpp
 /trunk/libs/smart_ptr/test/yield_k_test.cpp
 /trunk/libs/static_assert/static_assert_example_2.cpp
 /trunk/libs/static_assert/static_assert_example_3.cpp

=======================================
--- /dev/null
+++ /trunk/libs/serialization/example/Jamfile.v2        Mon Feb  8 19:41:53 2010
@@ -0,0 +1,55 @@
+# Boost serialization Library Build Jamfile
+#  (C) Copyright Robert Ramey 2002-2004.
+#  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)
+#
+#  See http://www.boost.org/libs/serialization for the library home page.
+
+project libs/serialization/example
+    : id serialization_test
+    : requirements <library>../build//boost_serialization
+    ;
+
+rule demo_bsl_run ( demo-name : othersources * : requirements * )
+{
+    return [ run
+        # sources
+            $(demo-name).cpp
+            $(othersources).cpp
+        : # command
+        : # input files
+        : # requirements
+            # toolset suppress-warnings
+ <toolset>gcc:<cxxflags>"-Wno-non-virtual-dtor -Wno-ctor-dtor-privacy"
+            <toolset>msvc-8.0:<cxxflags>"-wd4996"
+ <toolset>borland:<cxxflags>"-w-8080 -w-8071 -w-8057 -w-8062 -w-8008 -w-0018 -w-8066"
+            # toolset optimizations
+            <toolset>gcc:<cxxflags>"-ftemplate-depth-255"
+            <toolset>msvc:<cxxflags>"-Gy"
+            # toolset shared library support
+            <toolset>como,<runtime-link>shared:<build>no
+            <toolset>msvc,<stdlib>stlport,<runtime-link>shared:<build>no
+            <toolset>cw,<runtime-link>static:<build>no
+            $(requirements)
+         : # test name
+            $(demo-name)
+       ]
+    ;
+}
+
+test-suite "demo-suite" :
+    # demos
+    [ demo_bsl_run demo ]
+    [ demo_bsl_run demo_auto_ptr ]
+    [ demo_bsl_run demo_exception ]
+    [ demo_bsl_run demo_fast_archive ]
+    [ demo_bsl_run demo_pimpl : demo_pimpl_A ]
+    [ demo_bsl_run demo_polymorphic : demo_polymorphic_A ]
+ [ demo_bsl_run demo_portable_archive : portable_binary_iarchive portable_binary_oarchive ]
+    [ demo_bsl_run demo_shared_ptr ]
+    [ demo_bsl_run demo_xml ]
+    [ demo_bsl_run demo_xml_save ]
+    [ demo_bsl_run demo_xml_load : : <dependency>demo_xml_save ]
+;
+
=======================================
--- /dev/null
+++ /trunk/libs/serialization/src/archive_exception.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,110 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// archive_exception.cpp:
+
+// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#if (defined _MSC_VER) && (_MSC_VER == 1200)
+#  pragma warning (disable : 4786) // too long name, harmless warning
+#endif
+
+#include <exception>
+#include <cassert>
+#include <string>
+
+#define BOOST_ARCHIVE_SOURCE
+#include <boost/archive/archive_exception.hpp>
+
+namespace boost {
+namespace archive {
+
+BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+archive_exception::archive_exception(
+    exception_code c,
+    const char * e1,
+    const char * e2
+) :
+    code(c)
+{
+    m_msg = "programming error";
+    switch(code){
+    case no_exception:
+        m_msg = "uninitialized exception";
+        break;
+    case unregistered_class:
+        m_msg = "unregistered class";
+        if(NULL != e1){
+            m_msg += " - ";
+            m_msg += e1;
+        }
+        break;
+    case invalid_signature:
+        m_msg = "invalid signature";
+        break;
+    case unsupported_version:
+        m_msg = "unsupported version";
+        break;
+    case pointer_conflict:
+        m_msg = "pointer conflict";
+        break;
+    case incompatible_native_format:
+        m_msg = "incompatible native format";
+        if(NULL != e1){
+            m_msg += " - ";
+            m_msg += e1;
+        }
+        break;
+    case array_size_too_short:
+        m_msg = "array size too short";
+        break;
+    case stream_error:
+        m_msg = "stream error";
+        break;
+    case invalid_class_name:
+        m_msg = "class name too long";
+        break;
+    case unregistered_cast:
+        m_msg = "unregistered void cast ";
+        m_msg += (NULL != e1) ? e1 : "?";
+        m_msg += "<-";
+        m_msg += (NULL != e2) ? e2 : "?";
+        break;
+    case unsupported_class_version:
+        m_msg = "class version";
+        break;
+    case other_exception:
+        // if get here - it indicates a derived exception
+        // was sliced by passing by value in catch
+        m_msg = "unknown derived exception";
+        break;
+    case multiple_code_instantiation:
+        m_msg = "code instantiated in more than one module";
+        if(NULL != e1){
+            m_msg += " - ";
+            m_msg += e1;
+        }
+        break;
+    default:
+        assert(false);
+        break;
+    }
+}
+BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+archive_exception::~archive_exception() throw () {}
+
+BOOST_ARCHIVE_DECL(const char *)
+archive_exception::what( ) const throw()
+{
+    return m_msg.c_str();
+}
+BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+archive_exception::archive_exception() :
+        code(no_exception)
+{}
+
+} // archive
+} // boost
=======================================
--- /dev/null
+++ /trunk/libs/serialization/src/shared_ptr_helper.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,123 @@
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// shared_ptr_helper.hpp: serialization for boost shared pointer
+
+// (C) Copyright 2004-2009 Robert Ramey, Martin Ecker and Takatoshi Kondo
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <map>
+#include <list>
+#include <utility>
+#include <cstddef> // NULL
+
+#define BOOST_ARCHIVE_SOURCE
+
+#include <boost/serialization/throw_exception.hpp>
+#include <boost/serialization/void_cast.hpp>
+#include <boost/serialization/extended_type_info.hpp>
+#include <boost/archive/shared_ptr_helper.hpp>
+#include <boost/archive/archive_exception.hpp>
+
+namespace boost {
+namespace archive{
+namespace detail {
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// a common class for holding various types of shared pointers
+
+// returns pointer to object and an indicator whether this is a
+// new entry (true) or a previous one (false)
+BOOST_ARCHIVE_DECL(shared_ptr<void>)
+shared_ptr_helper::get_od(
+        const void * t,
+        const boost::serialization::extended_type_info * true_type,
+        const boost::serialization::extended_type_info * this_type
+){
+    // get void pointer to the most derived type
+    // this uniquely identifies the object referred to
+    const void * od = void_downcast(
+        *true_type,
+        *this_type,
+        t
+    );
+    if(NULL == od)
+        boost::serialization::throw_exception(
+            archive_exception(
+                archive_exception::unregistered_cast,
+                true_type->get_debug_info(),
+                this_type->get_debug_info()
+            )
+        );
+
+    // make tracking array if necessary
+    if(NULL == m_pointers)
+        m_pointers = new collection_type;
+
+    //shared_ptr<const void> sp(od, null_deleter());
+    shared_ptr<const void> sp(od, null_deleter());
+    collection_type::iterator i = m_pointers->find(sp);
+
+    if(i == m_pointers->end()){
+        std::pair<collection_type::iterator, bool> result;
+ shared_ptr<const void> sp(const_cast<void * >(od), void_deleter(true_type));
+        result = m_pointers->insert(sp);
+        assert(result.second);
+        i = result.first;
+    }
+    od = void_upcast(
+        *true_type,
+        *this_type,
+        i->get()
+    );
+    if(NULL == od)
+        boost::serialization::throw_exception(
+            archive_exception(
+                archive_exception::unregistered_cast,
+                true_type->get_debug_info(),
+                this_type->get_debug_info()
+            )
+        );
+
+    return shared_ptr<void>(
+        const_pointer_cast<void>(*i),
+        const_cast<void *>(od)
+    );
+}
+
+//  #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
+BOOST_ARCHIVE_DECL(void)
+shared_ptr_helper::append(const boost_132::shared_ptr<void> & t){
+    if(NULL == m_pointers_132)
+        m_pointers_132 = new std::list<boost_132::shared_ptr<void> >;
+    m_pointers_132->push_back(t);
+}
+//  #endif
+BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+shared_ptr_helper::shared_ptr_helper() :
+    m_pointers(NULL)
+    #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
+        , m_pointers_132(NULL)
+    #endif
+{}
+BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+shared_ptr_helper::~shared_ptr_helper(){
+    if(NULL != m_pointers)
+        delete m_pointers;
+    #ifdef BOOST_SERIALIZATION_SHARED_PTR_132_HPP
+    if(NULL != m_pointers_132)
+        delete m_pointers_132;
+    #endif
+}
+
+} // namespace detail
+} // namespace serialization
+} // namespace boost
+
=======================================
--- /dev/null
+++ /trunk/libs/serialization/src/xml_archive_exception.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,56 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// xml_archive_exception.cpp:
+
+// (C) Copyright 2009 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#if (defined _MSC_VER) && (_MSC_VER == 1200)
+#  pragma warning (disable : 4786) // too long name, harmless warning
+#endif
+
+#define BOOST_ARCHIVE_SOURCE
+
+#include <exception>
+#include <cassert>
+#include <string>
+
+#include <boost/archive/xml_archive_exception.hpp>
+
+namespace boost {
+namespace archive {
+
+BOOST_ARCHIVE_DECL(BOOST_PP_EMPTY())
+xml_archive_exception::xml_archive_exception(
+        exception_code c,
+        const char * e1,
+        const char * e2
+    ) :
+        archive_exception(other_exception, e1, e2)
+    {
+        m_msg = "programming error";
+        switch(c){
+        case xml_archive_parsing_error:
+            m_msg = "unrecognized XML syntax";
+            break;
+        case xml_archive_tag_mismatch:
+            m_msg = "XML start/end tag mismatch";
+            if(NULL != e1){
+                m_msg += " - ";
+                m_msg += e1;
+            }
+            break;
+        case xml_archive_tag_name_error:
+            m_msg = "Invalid XML tag name";
+            break;
+        default:
+            assert(false);
+            break;
+        }
+    }
+
+} // archive
+} // boost
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/Jamfile.v2   Mon Feb  8 19:41:53 2010
@@ -0,0 +1,162 @@
+# Boost serialization Library test Jamfile
+
+#  (C) Copyright Robert Ramey 2002-2004.
+#  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)
+#
+
+project libs/serialization/test
+    : id serialization_test
+    ;
+
+# import rules from the boost serialization test
+# import ../util/test : test-bsl-run-no-lib ;
+import ../util/test :
+    run-template
+    run-invoke
+    run-winvoke
+    test-bsl-run-no-lib
+    test-bsl-run
+    test-bsl-run_archive
+    test-bsl-run_files
+    test-bsl-run_polymorphic_archive
+;
+
+BOOST_ARCHIVE_LIST = [ modules.peek : BOOST_ARCHIVE_LIST ] ;
+
+lib dll_a_lib
+    :
+        dll_a.cpp
+        ../build//boost_serialization
+    :
+        <link>shared
+    ;
+
+lib dll_base_lib
+    :
+        dll_base.cpp
+        ../build//boost_serialization
+    :
+        <link>shared
+    ;
+
+lib dll_derived2_lib
+    :
+        dll_derived2.cpp
+        dll_base_lib
+        ../build//boost_serialization
+    :
+        <link>shared
+    ;
+
+lib dll_polymorphic_derived2_lib
+    :
+        polymorphic_derived2.cpp
+        polymorphic_base.cpp
+        ../build//boost_serialization
+    :
+        <link>shared
+    ;
+
+test-suite "serialization" :
+     [ test-bsl-run_files test_array : A ]
+     [ test-bsl-run_files test_binary ]
+     [ test-bsl-run_files test_bitset ]
+     [ test-bsl-run_files test_complex ]
+     [ test-bsl-run_files test_contained_class : A ]
+     [ test-bsl-run_files test_cyclic_ptrs : A ]
+     [ test-bsl-run_files test_delete_pointer ]
+     [ test-bsl-run_files test_deque : A ]
+     [ test-bsl-run_files test_derived ]
+     [ test-bsl-run_files test_derived_class : A ]
+     [ test-bsl-run_files test_derived_class_ptr : A ]
+     [ test-bsl-run_files test_diamond ]
+     [ test-bsl-run_files test_exported : polymorphic_base ]
+     [ test-bsl-run_files test_class_info_load ]
+     [ test-bsl-run_files test_class_info_save ]
+     [ test-bsl-run_files test_object ]
+     [ test-bsl-run_files test_primitive ]
+     [ test-bsl-run_files test_list : A ]
+     [ test-bsl-run_files test_list_ptrs : A ]
+     [ test-bsl-run_files test_map : A ]
+     [ test-bsl-run_files test_mi ]
+     [ test-bsl-run_files test_multiple_ptrs : A ]
+     [ test-bsl-run_files test_multiple_inheritance ]
+ [ test-bsl-run_files test_no_rtti : polymorphic_base polymorphic_derived1 ]
+     [ test-bsl-run_files test_non_intrusive ]
+     [ test-bsl-run_files test_non_default_ctor ]
+     [ test-bsl-run_files test_non_default_ctor2 ]
+     [ test-bsl-run_files test_null_ptr ]
+     [ test-bsl-run_files test_nvp : A ]
+     [ test-bsl-run_files test_recursion : A ]
+     [ test-bsl-run_files test_registered ]
+     [ test-bsl-run_files test_set : A ]
+     [ test-bsl-run_files test_simple_class : A ]
+     [ test-bsl-run_files test_simple_class_ptr : A ]
+     [ test-bsl-run_files test_split ]
+     [ test-bsl-run_files test_tracking ]
+     [ test-bsl-run_files test_unregistered ]
+     [ test-bsl-run_files test_valarray ]
+     [ test-bsl-run_files test_variant : A ]
+     [ test-bsl-run_files test_vector : A ]
+     [ test-bsl-run_files test_new_operator : A ]
+     [ test-bsl-run_files test_optional ]
+     [ test-bsl-run_files test_shared_ptr ]
+     [ test-bsl-run_files test_shared_ptr_multi_base ]
+     [ test-bsl-run_files test_shared_ptr_132 ]
+ [ test-bsl-run_polymorphic_archive test_polymorphic : test_polymorphic_A A ] + [ test-bsl-run_polymorphic_archive test_polymorphic2 : test_polymorphic2imp ]
+    ;
+
+if ! $(BOOST_ARCHIVE_LIST) {
+    test-suite "serialization2" :
+ [ test-bsl-run test_dll_exported : polymorphic_base : dll_polymorphic_derived2_lib : <runtime-link>shared ] +# [ test-bsl-run test_dll_plugin : : dll_base_lib dll_derived2_lib : <runtime-link>shared ] + [ test-bsl-run test_dll_simple : : dll_a_lib : <runtime-link>shared ]
+
+        [ test-bsl-run test_private_ctor ]
+        [ test-bsl-run test_reset_object_address : A ]
+        [ test-bsl-run test_void_cast ]
+        [ test-bsl-run test_mult_archive_types ]
+
+        [ test-bsl-run-no-lib test_iterators ]
+        [ test-bsl-run-no-lib test_iterators_base64 ]
+           [ test-bsl-run-no-lib test_inclusion ]
+        [ test-bsl-run-no-lib test_smart_cast ]
+
+        [ test-bsl-run-no-lib test_utf8_codecvt
+            : ../src/utf8_codecvt_facet
+            : <dependency>../../config/test/all//BOOST_NO_STD_WSTREAMBUF
+        ]
+        [ test-bsl-run-no-lib test_codecvt_null
+            : ../src/codecvt_null
+            : <dependency>../../config/test/all//BOOST_NO_STD_WSTREAMBUF
+        ]
+
+        # should fail compilation
+        [ compile-fail test_not_serializable.cpp ]
+        [ compile-fail test_traits_fail.cpp ]
+        [ compile-fail test_const_load_fail1.cpp ]
+        [ compile-fail test_const_load_fail2.cpp ]
+        [ compile-fail test_const_load_fail3.cpp ]
+        [ compile-fail test_const_load_fail1_nvp.cpp ]
+        [ compile-fail test_const_load_fail2_nvp.cpp ]
+        [ compile-fail test_const_load_fail3_nvp.cpp ]
+        [ compile-fail test_check.cpp ]
+
+        # should compile with a warning message
+        [ compile test_static_warning.cpp ]
+        [ compile test_const_save_warn1.cpp ]
+        [ compile test_const_save_warn2.cpp ]
+        [ compile test_const_save_warn3.cpp ]
+        # note - library unable to detect these errors for now
+        #[ compile test_const_save_warn1_nvp.cpp ]
+        #[ compile test_const_save_warn2_nvp.cpp ]
+        #[ compile test_const_save_warn3_nvp.cpp ]
+
+        # should compile
+        [ compile test_traits_pass.cpp ]
+        [ compile test_const_pass.cpp ]
+    ;
+}
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/polymorphic_base.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,21 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// polymorphic_base.cpp
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/serialization/export.hpp>
+#include "polymorphic_base.hpp"
+
+BOOST_CLASS_EXPORT_IMPLEMENT(polymorphic_base)
+
+const char * polymorphic_base::get_key() const{
+    return
+        boost::serialization::type_info_implementation<
+            polymorphic_base
+        >::type::get_const_instance().get_key();
+}
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/polymorphic_base.hpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,51 @@
+#ifndef POLYMORPHIC_BASE_HPP
+#define POLYMORPHIC_BASE_HPP
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// polymorphic_base.hpp    simple class test
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/assume_abstract.hpp>
+#include <boost/serialization/export.hpp>
+#include <boost/serialization/type_info_implementation.hpp>
+#include <boost/serialization/extended_type_info_no_rtti.hpp>
+
+class polymorphic_base
+{
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(
+        Archive & /* ar */,
+        const unsigned int /* file_version */
+    ){}
+public:
+    // note that since this class uses the "no_rtti"
+    // extended_type_info implementation, it MUST
+    // implement this function
+    virtual const char * get_key() const;
+    virtual ~polymorphic_base(){};
+};
+
+BOOST_SERIALIZATION_ASSUME_ABSTRACT(polymorphic_base)
+
+// the no_rtti system requires this !!!
+BOOST_CLASS_EXPORT_KEY(polymorphic_base)
+
+BOOST_CLASS_TYPE_INFO(
+    polymorphic_base,
+    boost::serialization::extended_type_info_no_rtti<polymorphic_base>
+)
+
+#endif // POLYMORPHIC_BASE_HPP
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/polymorphic_derived1.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,23 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// polymorphic_derived1.cpp
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/serialization/type_info_implementation.hpp>
+#include <boost/serialization/export.hpp>
+
+#include "polymorphic_derived1.hpp"
+
+const char * polymorphic_derived1::get_key() const {
+    return
+        boost::serialization::type_info_implementation<
+            polymorphic_derived1
+        >::type::get_const_instance().get_key();
+}
+
+BOOST_CLASS_EXPORT_IMPLEMENT(polymorphic_derived1)
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/polymorphic_derived1.hpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,45 @@
+#ifndef POLYMORPHIC_DERIVED1_HPP
+#define POLYMORPHIC_DERIVED1_HPP
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// polymorphic_derived1.hpp    simple class test
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/type_info_implementation.hpp>
+#include <boost/serialization/extended_type_info_no_rtti.hpp>
+
+#include "polymorphic_base.hpp"
+
+class polymorphic_derived1 : public polymorphic_base
+{
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int  /* file_version */){
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(polymorphic_base);
+    }
+public:
+    virtual const char * get_key() const ;
+};
+
+BOOST_CLASS_EXPORT_KEY(polymorphic_derived1)
+
+BOOST_CLASS_TYPE_INFO(
+    polymorphic_derived1,
+    extended_type_info_no_rtti<polymorphic_derived1>
+)
+
+#endif // POLYMORPHIC_DERIVED1_HPP
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/polymorphic_derived2.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,58 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// polymorphic_derived2.cpp
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/serialization/type_info_implementation.hpp>
+#include <boost/serialization/extended_type_info_no_rtti.hpp>
+#include <boost/serialization/export.hpp>
+
+#define POLYMORPHIC_DERIVED2_EXPORT
+#include "polymorphic_derived2.hpp"
+
+// instantiate code for text archives
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+template EXPORT_DECL(void) polymorphic_derived2::serialize(
+    boost::archive::text_oarchive & ar,
+    const unsigned int version
+);
+template EXPORT_DECL(void) polymorphic_derived2::serialize(
+    boost::archive::text_iarchive & ar,
+    const unsigned int version
+);
+
+// instantiate code for polymorphic archives
+#include <boost/archive/polymorphic_iarchive.hpp>
+#include <boost/archive/polymorphic_oarchive.hpp>
+
+template EXPORT_DECL(void) polymorphic_derived2::serialize(
+    boost::archive::polymorphic_oarchive & ar,
+    const unsigned int version
+);
+template EXPORT_DECL(void) polymorphic_derived2::serialize(
+    boost::archive::polymorphic_iarchive & ar,
+    const unsigned int version
+);
+
+// MWerks users can do this to make their code work
+BOOST_SERIALIZATION_MWERKS_BASE_AND_DERIVED(polymorphic_base, polymorphic_derived2)
+
+// note: export has to be AFTER #includes for all archive classes
+BOOST_CLASS_EXPORT_IMPLEMENT(polymorphic_derived2)
+
+// export plug-in not yet working !!!
+#if 0
+#include <boost/serialization/factory.hpp>
+BOOST_SERIALIZATION_FACTORY_0(polymorphic_derived2)
+
+template
+EXPORT_DECL(polymorphic_derived2 *)
+boost::serialization::factory<polymorphic_derived2, 0>(std::va_list ap);
+#endif
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/polymorphic_derived2.hpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,70 @@
+#ifndef POLYMORPHIC_DERIVED2_HPP
+#define POLYMORPHIC_DERIVED2_HPP
+
+// MS compatible compilers support #pragma once
+#if defined(_MSC_VER) && (_MSC_VER >= 1020)
+# pragma once
+#endif
+
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// derived1.hpp    simple class test
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/type_info_implementation.hpp>
+#include <boost/serialization/extended_type_info_typeid.hpp>
+#include <boost/preprocessor/empty.hpp>
+
+#include "polymorphic_base.hpp"
+
+#include "test_decl.hpp"
+
+#if defined(POLYMORPHIC_DERIVED2_IMPORT)
+    #define DLL_DECL IMPORT_DECL
+#elif defined(POLYMORPHIC_DERIVED2_EXPORT)
+    #define DLL_DECL EXPORT_DECL
+#else
+    #define DLL_DECL(x)
+#endif
+
+class DLL_DECL(BOOST_PP_EMPTY()) polymorphic_derived2 :
+    public polymorphic_base
+{
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(
+        Archive &ar,
+        const unsigned int /* file_version */
+    ){
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(polymorphic_base);
+    }
+    virtual const char * get_key() const {
+        return "polymorphic_derived2";
+    }
+};
+
+// we use this because we want to assign a key to this type
+// but we don't want to explicitly instantiate code every time
+// we do so!!!.  If we don't do this, we end up with the same
+// code in BOTH the DLL which implements polymorphic_derived2
+// as well as the main program.
+BOOST_CLASS_EXPORT_KEY(polymorphic_derived2)
+
+// note the mixing of type_info systems is supported.
+BOOST_CLASS_TYPE_INFO(
+    polymorphic_derived2,
+    boost::serialization::extended_type_info_typeid<polymorphic_derived2>
+)
+
+#undef DLL_DECL
+
+#endif // POLYMORPHIC_DERIVED2_HPP
+
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_bitset.cpp      Mon Feb  8 19:41:53 2010
@@ -0,0 +1,64 @@
+//  (C) Copyright 2009 Brian Ravnsgaard and Kenneth Riddile
+//  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)
+
+// See http://www.boost.org for most recent version including documentation.
+
+// Test that serialization of std::bitset works.
+// Should pass compilation and execution
+// 16.09.2004, updated 04.03.2009
+
+#include <cstddef> // NULL
+#include <cstdio> // remove
+#include <fstream>
+
+#include <boost/config.hpp>
+
+#if defined( BOOST_NO_STDC_NAMESPACE )
+namespace std
+{
+    using ::remove;
+}
+#endif
+
+#include "test_tools.hpp"
+
+#include <boost/serialization/bitset.hpp>
+#include <boost/serialization/nvp.hpp>
+
+int test_main( int /* argc */, char* /* argv */[] )
+{
+    const char* testfile = boost::archive::tmpnam( NULL );
+    BOOST_REQUIRE( NULL != testfile );
+
+    std::bitset<8> bitsetA;
+    bitsetA.set( 0, false );
+    bitsetA.set( 1, true  );
+    bitsetA.set( 2, false );
+    bitsetA.set( 3, true  );
+    bitsetA.set( 4, false );
+    bitsetA.set( 5, false );
+    bitsetA.set( 6, true  );
+    bitsetA.set( 7, true  );
+
+    {
+        test_ostream os( testfile, TEST_STREAM_FLAGS );
+        test_oarchive oa( os );
+        oa << boost::serialization::make_nvp( "bitset", bitsetA );
+    }
+
+    std::bitset<8> bitsetB;
+    {
+        test_istream is( testfile, TEST_STREAM_FLAGS );
+        test_iarchive ia( is );
+        ia >> boost::serialization::make_nvp( "bitset", bitsetB );
+    }
+
+    BOOST_CHECK( bitsetA == bitsetB );
+
+    std::remove( testfile );
+    return EXIT_SUCCESS;
+}
+
+// EOF
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_check.cpp       Mon Feb  8 19:41:53 2010
@@ -0,0 +1,142 @@
+//  (C) Copyright 2009 Robert Ramey
+//  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)
+
+// See http://www.boost.org for most recent version including documentation.
+
+// note: this is a compile only test.
+#include <sstream>
+#include <boost/config.hpp> // BOOST_STATIC_CONST
+
+#include <boost/serialization/static_warning.hpp>
+#include <boost/serialization/tracking.hpp>
+#include <boost/serialization/level.hpp>
+#include <boost/serialization/version.hpp>
+#include <boost/serialization/nvp.hpp>
+
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/text_oarchive.hpp>
+
+// track_selectivly with class information in the archive
+// is unsafe when used with a pointer and should trigger a warning
+struct check1 {
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int version);
+};
+
+BOOST_CLASS_IMPLEMENTATION(check1, boost::serialization::object_serializable)
+BOOST_CLASS_TRACKING(check1, boost::serialization::track_selectively)
+
+// the combination of versioning + no class information
+// should trigger a warning
+struct check2 {
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int version);
+};
+
+BOOST_CLASS_IMPLEMENTATION(check2, boost::serialization::object_serializable)
+BOOST_CLASS_VERSION(check2, 1)
+// use track always to turn off warning tested above
+BOOST_CLASS_TRACKING(check2, boost::serialization::track_always)
+
+// serializing a type marked as "track_never" through a pointer
+// is likely an error
+struct check3 {
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int version);
+};
+
+BOOST_CLASS_TRACKING(check3, boost::serialization::track_never)
+
+template<class T>
+int f(){
+    BOOST_STATIC_WARNING(T::value);
+    BOOST_STATIC_ASSERT(T::value);
+    return 0;
+}
+
+/////////////////////////////////////////////////////////////////////////
+// compilation of this program should show a total of 10 warning messages
+int main(int /* argc */, char * /* argv */[]){
+    std::stringstream s;
+    {
+        boost::archive::text_oarchive oa(s);
+
+        check1 const c1_out;
+        oa << c1_out;
+
+        check1 c1_non_const_out;
+        oa << c1_non_const_out; // warn check_object_tracking
+
+        check1 * const c1_ptr_out = 0;
+        oa << c1_ptr_out; // warn check_pointer_level
+
+        check2 const * c2_ptr_out;
+        oa << c2_ptr_out; // error check_object_versioning
+
+        check3 * const c3_ptr_out = 0;
+        oa << c3_ptr_out; // warning check_pointer_tracking
+
+        check2 const c2_out;
+        oa << c2_out; // error check_object_versioning
+    }
+    {
+        boost::archive::text_iarchive ia(s);
+
+        check1 const c1_in;
+        ia >> c1_in; // check_const_loading
+
+        check1 * c1_ptr_in = 0;
+        ia >> c1_ptr_in; // warn check_pointer_level
+
+        check2 * c2_ptr_in;
+        ia >> c2_ptr_in; // error check_object_versioning
+
+        check3 * c3_ptr_in = 0;
+        ia >> c3_ptr_in; // warning check_pointer_tracking
+
+        check2 c2_in;
+        ia >> c2_in; // error check_object_versioning
+    }
+    {
+        boost::archive::text_oarchive oa(s);
+
+        check1 const c1_out;
+        oa << BOOST_SERIALIZATION_NVP(c1_out);
+
+        check1 c1_non_const_out;
+ oa << BOOST_SERIALIZATION_NVP(c1_non_const_out; // warn check_object_tracking
+
+        check1 * const c1_ptr_out = 0;
+ oa << BOOST_SERIALIZATION_NVP(c1_ptr_out); // warn check_pointer_level
+
+        check2 const * c2_ptr_out;
+ oa << BOOST_SERIALIZATION_NVP(c2_ptr_out); // error check_object_versioning
+
+        check3 * const c3_ptr_out = 0;
+ oa << BOOST_SERIALIZATION_NVP(c3_ptr_out); // warning check_pointer_tracking
+
+        check2 const c2_out;
+ oa << BOOST_SERIALIZATION_NVP(c2_out); // error check_object_versioning
+    }
+    {
+        boost::archive::text_iarchive ia(s);
+
+        check1 const c1_in;
+        ia >> BOOST_SERIALIZATION_NVP(c1_in); // check_const_loading
+
+        check1 * c1_ptr_in = 0;
+ ia >> BOOST_SERIALIZATION_NVP(c1_ptr_in); // warn check_pointer_level
+
+        check2 * c2_ptr_in;
+ ia >> BOOST_SERIALIZATION_NVP(c2_ptr_in); // error check_object_versioning
+
+        check3 * c3_ptr_in = 0;
+ ia >> BOOST_SERIALIZATION_NVP(c3_ptr_in); // warning check_pointer_tracking
+
+        check2 c2_in;
+ ia >> BOOST_SERIALIZATION_NVP(c2_in); // error check_object_versioning
+    }
+    return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_multiple_inheritance.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,125 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// test_multiple_inheritance.cpp
+
+// (C) Copyright 2009 Robert Ramey.
+// 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)
+
+// test of serialization library for multiple inheritence situations
+
+#include <cassert>
+#include <fstream>
+
+#include <boost/config.hpp>
+#include <cstdio> // remove
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+    using ::remove;
+}
+#endif
+
+#include "test_tools.hpp"
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/export.hpp>
+
+struct Base1 {
+    int m_x;
+    Base1(){}
+    Base1(int x) : m_x(1 + x) {}
+    virtual ~Base1() {}
+    bool operator==(Base1 & rhs) const {
+        return m_x == rhs.m_x;
+    }
+    // serialize
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int /* file_version */) {
+        ar & BOOST_SERIALIZATION_NVP(m_x);
+    }
+};
+
+//BOOST_CLASS_EXPORT(Base1)
+
+struct Base2 {
+    int m_x;
+    Base2(){}
+    Base2(int x) : m_x(2 + x) {}
+    virtual ~Base2() {}
+    bool operator==(Base2 & rhs) const {
+        return m_x == rhs.m_x;
+    }
+    // serialize
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int /* file_version */) {
+        ar & BOOST_SERIALIZATION_NVP(m_x);
+    }
+};
+
+//BOOST_CLASS_EXPORT(Base2)
+
+struct Sub :
+    public Base1,
+    public Base2
+{
+    int m_x;
+    Sub(){}
+    Sub(int x) :
+        Base1(x),
+        Base2(x),
+        m_x(x)
+    {}
+    bool operator==(Sub & rhs) const {
+        if(! Base2::operator==(rhs))
+            return false;
+        if(! Base1::operator==(rhs))
+            return false;
+        return m_x == rhs.m_x;
+    }
+    virtual ~Sub() {}
+
+    // serialize
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int /* file_version */)
+    {
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base1);
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base2);
+        ar & BOOST_SERIALIZATION_NVP(m_x);
+    }
+};
+
+BOOST_CLASS_EXPORT(Sub)
+
+int
+test_main( int /* argc */, char* /* argv */[] )
+{
+    const char * testfile = boost::archive::tmpnam(NULL);
+    BOOST_REQUIRE(NULL != testfile);
+    Base2 * pb2;
+    {
+        // serialize
+        pb2 = new Sub(2);
+
+        test_ostream ofs(testfile);
+        test_oarchive oa(ofs);
+        oa << boost::serialization::make_nvp("Base2", pb2);
+    }
+    Base2 * pb2_1;
+    {
+        // de-serialize
+        test_istream ifs(testfile);
+        test_iarchive ia(ifs);
+        ia >> boost::serialization::make_nvp("Base2", pb2_1);
+    }
+    Sub *s1 = dynamic_cast<Sub *>(pb2);
+    BOOST_CHECK(0 != s1);
+    Sub *s2 = dynamic_cast<Sub *>(pb2_1);
+    BOOST_CHECK(0 != s2);
+    BOOST_CHECK(*s1 == *s2);
+    return EXIT_SUCCESS;
+}
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_new_operator.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,95 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// test_new_operator.cpp
+
+// (C) Copyright 2002 Robert Ramey - http://www.rrsd.com .
+// 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)
+
+// should pass compilation and execution
+
+#include <cstddef> // NULL
+#include <cstdio> // remove
+#include <fstream>
+#include <new>
+
+#include <boost/config.hpp>
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+    using ::remove;
+}
+#endif
+
+#include <boost/serialization/access.hpp>
+
+#include "test_tools.hpp"
+
+#include "A.hpp"
+#include "A.ipp"
+
+class ANew : public A {
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned /*file_version*/){
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
+    }
+public:
+    static unsigned int m_new_calls;
+    static unsigned int m_delete_calls;
+    // implement class specific new/delete in terms standard
+    // implementation - we're testing serialization
+    // not "new" here.
+    static void * operator new(size_t s){
+        ++m_new_calls;
+        return  ::operator new(s);
+    }
+    static void operator delete(void *p, std::size_t /*s*/){
+        ++m_delete_calls;
+        ::operator delete(p);
+    }
+};
+
+unsigned int ANew::m_new_calls = 0;
+unsigned int ANew::m_delete_calls = 0;
+
+int test_main( int /* argc */, char* /* argv */[] )
+{
+    const char * testfile = boost::archive::tmpnam(NULL);
+
+    BOOST_REQUIRE(NULL != testfile);
+
+    ANew *ta = new ANew();
+
+    BOOST_CHECK(1 == ANew::m_new_calls);
+    BOOST_CHECK(0 == ANew::m_delete_calls);
+
+    ANew *ta1 = NULL;
+
+    {
+        test_ostream os(testfile, TEST_STREAM_FLAGS);
+        test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
+        oa << boost::serialization::make_nvp("ta", ta);
+    }
+    {
+        test_istream is(testfile, TEST_STREAM_FLAGS);
+        test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
+        ia >> boost::serialization::make_nvp("ta", ta1);
+    }
+    BOOST_CHECK(ta != ta1);
+    BOOST_CHECK(*ta == *ta1);
+
+    BOOST_CHECK(2 == ANew::m_new_calls);
+    BOOST_CHECK(0 == ANew::m_delete_calls);
+
+    std::remove(testfile);
+
+    delete ta;
+    delete ta1;
+
+    BOOST_CHECK(2 == ANew::m_new_calls);
+    BOOST_CHECK(2 == ANew::m_delete_calls);
+
+    return EXIT_SUCCESS;
+}
+
+// EOF
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_polymorphic2.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,31 @@
+#include <fstream>
+
+#include "test_tools.hpp"
+
+#include "test_polymorphic2.hpp"
+
+int test_main(int /*argc*/, char* /*argv*/[])
+{
+    A *a = new B();
+    a->i = 3;
+
+    const char * testfile = boost::archive::tmpnam(NULL);
+    BOOST_REQUIRE(NULL != testfile);
+    {
+        test_ostream os(testfile, TEST_STREAM_FLAGS);
+        test_oarchive oa_implementation(os, TEST_ARCHIVE_FLAGS);
+        boost::archive::polymorphic_oarchive & opa = oa_implementation;
+        opa << BOOST_SERIALIZATION_NVP(a);
+    }
+    A *loaded = 0;
+    {
+        test_istream is(testfile, TEST_STREAM_FLAGS);
+        test_iarchive ia_implementation(is, TEST_ARCHIVE_FLAGS);
+        boost::archive::polymorphic_iarchive & ipa = ia_implementation;
+        ipa >> BOOST_SERIALIZATION_NVP(loaded);
+    }
+    BOOST_CHECK(a->i == loaded->i);
+    delete a;
+    delete loaded;
+    return EXIT_SUCCESS;
+}
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_polymorphic2.hpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,34 @@
+namespace boost {
+namespace archive {
+    class polymorphic_oarchive;
+    class polymorphic_iarchive;
+}
+}
+
+struct A {
+public:
+    A() {}
+    virtual ~A() {}
+
+    void serialize(
+        boost::archive::polymorphic_oarchive &ar,
+        const unsigned int /*version*/
+    );
+    void serialize(
+        boost::archive::polymorphic_iarchive &ar,
+        const unsigned int /*version*/
+    );
+
+    int i;
+};
+
+struct B : A {
+    void serialize(
+        boost::archive::polymorphic_oarchive &ar,
+        const unsigned int /*version*/
+    );
+    void serialize(
+        boost::archive::polymorphic_iarchive &ar,
+        const unsigned int /*version*/
+    );
+};
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_polymorphic2imp.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,35 @@
+
+#include <boost/serialization/export.hpp>
+#include <boost/archive/polymorphic_oarchive.hpp>
+#include <boost/archive/polymorphic_iarchive.hpp>
+
+#include "test_polymorphic2.hpp"
+
+void A::serialize(
+    boost::archive::polymorphic_oarchive &ar,
+    const unsigned int /*version*/
+){
+    ar & BOOST_SERIALIZATION_NVP(i);
+}
+void A::serialize(
+    boost::archive::polymorphic_iarchive &ar,
+    const unsigned int /*version*/
+){
+    ar & BOOST_SERIALIZATION_NVP(i);
+}
+// note: only the most derived classes need be exported
+// BOOST_CLASS_EXPORT(A)
+
+void B::serialize(
+    boost::archive::polymorphic_oarchive &ar,
+    const unsigned int /*version*/
+){
+    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
+}
+void B::serialize(
+    boost::archive::polymorphic_iarchive &ar,
+    const unsigned int /*version*/
+){
+    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(A);
+}
+BOOST_CLASS_EXPORT(B)
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_private_base.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,99 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// test_private_base.cpp
+
+// (C) Copyright 2009 Eric Moyer - http://www.rrsd.com .
+// 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)
+
+// should pass compilation and execution
+
+// invoke header for a custom archive test.
+
+#include <fstream>
+#include <boost/config.hpp>
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+    using ::remove;
+}
+#endif
+
+#include <boost/serialization/access.hpp>
+#include <boost/serialization/base_object.hpp>
+#include <boost/serialization/export.hpp>
+
+#include "test_tools.hpp"
+
+class Base {
+    friend class boost::serialization::access;
+    int m_i;
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int version){
+        ar & m_i;
+    }
+protected:
+    bool operator==(const Base &rhs) const {
+        return m_i == rhs.m_i;
+    }
+    Base(int i = 0) :
+        m_i(i)
+    {}
+    virtual ~Base();
+};
+
+class Derived :  public Base {
+    friend class boost::serialization::access;
+private:
+    template<class Archive>
+    void serialize(Archive & ar, const unsigned int version){
+        ar & boost::serialization::base_object<Base>(*this);
+    }
+public:
+    bool operator==(const Derived &rhs) const {
+        return Base::operator==(rhs);
+    }
+    Derived(int i = 0) :
+        Base(i)
+    {}
+};
+
+BOOST_CLASS_EXPORT(Derived)
+
+int
+test_main( int /* argc */, char* /* argv */[] )
+{
+    const char * testfile = boost::archive::tmpnam(NULL);
+    BOOST_REQUIRE(NULL != testfile);
+
+    Derived a(1), a1(2);
+    {
+        test_ostream os(testfile, TEST_STREAM_FLAGS);
+        test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
+        oa << boost::serialization::make_nvp("a", a);
+    }
+    {
+        test_istream is(testfile, TEST_STREAM_FLAGS);
+        test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
+        ia >> boost::serialization::make_nvp("a", a1);
+    }
+    BOOST_CHECK_EQUAL(a, a1);
+    std::remove(testfile);
+
+    Base *ta = new Derived(1);
+    Base *ta1 = NULL;
+
+    {
+        test_ostream os(testfile, TEST_STREAM_FLAGS);
+        test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
+        oa << boost::serialization::make_nvp("ta", ta);
+    }
+    {
+        test_istream is(testfile, TEST_STREAM_FLAGS);
+        test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
+        ia >> boost::serialization::make_nvp("ta", ta1);
+    }
+    BOOST_CHECK(ta != ta1);
+ BOOST_CHECK(*static_cast<Derived *>(ta) == *static_cast<Derived *>(ta1));
+    std::remove(testfile);
+    return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/serialization/test/test_shared_ptr_multi_base.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,271 @@
+/////////1/////////2/////////3/////////4/////////5/////////6/////////7/////////8
+// test_shared_ptr_multi_base.cpp
+
+// (C) Copyright 2002 Robert Ramey- http://www.rrsd.com and Takatoshi Kondo.
+// 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)
+//
+// See http://www.boost.org for updates, documentation, and revision history.
+
+#include <cstddef> // NULL
+#include <cstdio> // remove
+#include <fstream>
+
+#include <boost/config.hpp>
+#if defined(BOOST_NO_STDC_NAMESPACE)
+namespace std{
+    using ::remove;
+}
+#endif
+#include <boost/type_traits/broken_compiler_spec.hpp>
+
+#include <boost/serialization/shared_ptr.hpp>
+#include <boost/serialization/weak_ptr.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/serialization/export.hpp>
+
+#include "test_tools.hpp"
+
+struct Base1 {
+    Base1() {}
+    Base1(int x) : m_x(1 + x) {}
+    virtual ~Base1(){
+    }
+    int m_x;
+    // serialize
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int /* file_version */)
+    {
+        ar & BOOST_SERIALIZATION_NVP(m_x);
+    }
+};
+
+struct Base2 {
+    Base2() {}
+    Base2(int x) : m_x(2 + x) {}
+    int m_x;
+    virtual ~Base2(){
+    }
+    // serialize
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int /* file_version */)
+    {
+        ar & BOOST_SERIALIZATION_NVP(m_x);
+    }
+};
+
+struct Base3 {
+    Base3() {}
+    Base3(int x) : m_x(3 + x) {}
+    virtual ~Base3(){
+    }
+    int m_x;
+    // serialize
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int /* file_version */)
+    {
+        ar & BOOST_SERIALIZATION_NVP(m_x);
+    }
+};
+
+// Sub is a subclass of Base1, Base1 and Base3.
+struct Sub:public Base1, public Base2, public Base3 {
+    static int count;
+    Sub() {
+        ++count;
+    }
+    Sub(int x) :
+        Base1(x),
+        Base2(x),
+        m_x(x)
+    {
+        ++count;
+    }
+    Sub(const Sub & rhs) :
+        m_x(rhs.m_x)
+    {
+        ++count;
+    }
+    virtual ~Sub() {
+        assert(0 < count);
+        --count;
+    }
+    int m_x;
+    // serialize
+    friend class boost::serialization::access;
+    template<class Archive>
+    void serialize(Archive &ar, const unsigned int /* file_version */)
+    {
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base1);
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base2);
+        ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Base3);
+        ar & BOOST_SERIALIZATION_NVP(m_x);
+    }
+};
+
+// Sub needs to be exported because its serialized via a base class pointer
+BOOST_CLASS_EXPORT(Sub)
+BOOST_SERIALIZATION_SHARED_PTR(Sub)
+
+int Sub::count = 0;
+
+template <class FIRST, class SECOND>
+void save2(
+    const char * testfile,
+    const FIRST& first,
+    const SECOND& second
+){
+    test_ostream os(testfile, TEST_STREAM_FLAGS);
+    test_oarchive oa(os, TEST_ARCHIVE_FLAGS);
+    oa << BOOST_SERIALIZATION_NVP(first);
+    oa << BOOST_SERIALIZATION_NVP(second);
+}
+
+template <class FIRST, class SECOND>
+void load2(
+    const char * testfile,
+    FIRST& first,
+    SECOND& second)
+{
+    test_istream is(testfile, TEST_STREAM_FLAGS);
+    test_iarchive ia(is, TEST_ARCHIVE_FLAGS);
+    ia >> BOOST_SERIALIZATION_NVP(first);
+    ia >> BOOST_SERIALIZATION_NVP(second);
+}
+
+// Run tests by serializing two shared_ptrs into an archive,
+// clearing them (deleting the objects) and then reloading the
+// objects back from an archive.
+
+// Serialization sequence
+// First,  shared_ptr
+// Second, weak_ptr
+template <class FIRST, class SECOND>
+void shared_weak(
+    boost::shared_ptr<FIRST>& first,
+    boost::weak_ptr<SECOND>& second
+){
+    const char * testfile = boost::archive::tmpnam(NULL);
+    BOOST_REQUIRE(NULL != testfile);
+    int firstm = first->m_x;
+    int secondm = second.lock()->m_x;
+    save2(testfile, first, second);
+
+    // Clear the pointers, thereby destroying the objects they contain
+    second.reset();
+    first.reset();
+
+    load2(testfile, first, second);
+
+    // Check data member
+    BOOST_CHECK(firstm == first->m_x);
+    BOOST_CHECK(secondm == second.lock()->m_x);
+    // Check pointer to vtable
+    BOOST_CHECK(boost::dynamic_pointer_cast<Sub>(first));
+    BOOST_CHECK(boost::dynamic_pointer_cast<Sub>(second.lock()));
+
+    std::remove(testfile);
+}
+
+// Serialization sequence
+// First,  weak_ptr
+// Second, shared_ptr
+template <class FIRST, class SECOND>
+void weak_shared(
+    boost::weak_ptr<FIRST>& first,
+    boost::shared_ptr<SECOND>& second
+){
+    const char * testfile = boost::archive::tmpnam(NULL);
+    BOOST_REQUIRE(NULL != testfile);
+    int firstm = first.lock()->m_x;
+    int secondm = second->m_x;
+    save2(testfile, first, second);
+
+    // Clear the pointers, thereby destroying the objects they contain
+    first.reset();
+    second.reset();
+
+    load2(testfile, first, second);
+
+    // Check data member
+    BOOST_CHECK(firstm == first.lock()->m_x);
+    BOOST_CHECK(secondm == second->m_x);
+    // Check pointer to vtable
+    BOOST_CHECK(boost::dynamic_pointer_cast<Sub>(first.lock()));
+    BOOST_CHECK(boost::dynamic_pointer_cast<Sub>(second));
+
+    std::remove(testfile);
+}
+
+// This does the tests
+int test_main(int /* argc */, char * /* argv */[])
+{
+
+    // Both Sub
+    boost::shared_ptr<Sub> tc1_sp(new Sub(10));
+    boost::weak_ptr<Sub> tc1_wp(tc1_sp);
+    shared_weak(tc1_sp, tc1_wp);
+    weak_shared(tc1_wp, tc1_sp);
+    tc1_sp.reset();
+    BOOST_CHECK(0 == Sub::count);
+
+    // Sub and Base1
+    boost::shared_ptr<Sub> tc2_sp(new Sub(10));
+    boost::weak_ptr<Base1> tc2_wp(tc2_sp);
+    shared_weak(tc2_sp, tc2_wp);
+    weak_shared(tc2_wp, tc2_sp);
+    tc2_sp.reset();
+    BOOST_CHECK(0 == Sub::count);
+
+    // Sub and Base2
+    boost::shared_ptr<Sub> tc3_sp(new Sub(10));
+    boost::weak_ptr<Base2> tc3_wp(tc3_sp);
+    shared_weak(tc3_sp, tc3_wp);
+    weak_shared(tc3_wp, tc3_sp);
+    tc3_sp.reset();
+    BOOST_CHECK(0 == Sub::count);
+
+    // Sub and Base3
+    boost::shared_ptr<Sub> tc4_sp(new Sub(10));
+    boost::weak_ptr<Base3> tc4_wp(tc4_sp);
+    shared_weak(tc4_sp, tc4_wp);
+    weak_shared(tc4_wp, tc4_sp);
+    tc4_sp.reset();
+    BOOST_CHECK(0 == Sub::count);
+
+    // Base1 and Base2
+    boost::shared_ptr<Sub> tc5_sp_tmp(new Sub(10));
+    boost::shared_ptr<Base1> tc5_sp(tc5_sp_tmp);
+    boost::weak_ptr<Base2> tc5_wp(tc5_sp_tmp);
+    tc5_sp_tmp.reset();
+    shared_weak(tc5_sp, tc5_wp);
+    weak_shared(tc5_wp, tc5_sp);
+    tc5_sp.reset();
+    BOOST_CHECK(0 == Sub::count);
+
+    // Base2 and Base3
+    boost::shared_ptr<Sub> tc6_sp_tmp(new Sub(10));
+    boost::shared_ptr<Base2> tc6_sp(tc6_sp_tmp);
+    boost::weak_ptr<Base3> tc6_wp(tc6_sp_tmp);
+    tc6_sp_tmp.reset();
+    shared_weak(tc6_sp, tc6_wp);
+    weak_shared(tc6_wp, tc6_sp);
+    tc6_sp.reset();
+    BOOST_CHECK(0 == Sub::count);
+
+    // Base3 and Base1
+    boost::shared_ptr<Sub> tc7_sp_tmp(new Sub(10));
+    boost::shared_ptr<Base3> tc7_sp(tc7_sp_tmp);
+    boost::weak_ptr<Base1> tc7_wp(tc7_sp_tmp);
+    tc7_sp_tmp.reset();
+    shared_weak(tc7_sp, tc7_wp);
+    weak_shared(tc7_wp, tc7_sp);
+    tc7_sp.reset();
+    BOOST_CHECK(0 == Sub::count);
+
+    return EXIT_SUCCESS;
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/Jamfile.v2       Mon Feb  8 19:41:53 2010
@@ -0,0 +1,67 @@
+#  Boost.SmartPtr Library test Jamfile
+#
+#  Copyright (c) 2003-2007 Peter Dimov
+#  Copyright (c) 2003 Dave Abrahams
+#
+#  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 "smart_ptr"
+        : [ run smart_ptr_test.cpp ]
+ [ run shared_ptr_basic_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ] + [ run shared_ptr_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ]
+          [ run weak_ptr_test.cpp ]
+          [ run weak_ptr_move_test.cpp ]
+ [ run shared_from_this_test.cpp : : : <toolset>gcc:<cxxflags>-Wno-non-virtual-dtor ]
+          [ run get_deleter_test.cpp ]
+          [ run intrusive_ptr_test.cpp ]
+          [ run intrusive_ptr_move_test.cpp ]
+          [ run atomic_count_test.cpp ]
+          [ run lw_mutex_test.cpp ]
+          [ compile-fail shared_ptr_assign_fail.cpp ]
+          [ compile-fail shared_ptr_delete_fail.cpp ]
+          [ compile-fail shared_ptr_compare_fail.cpp ]
+          [ run shared_ptr_alloc2_test.cpp ]
+          [ run pointer_cast_test.cpp ]
+          [ compile pointer_to_other_test.cpp ]
+          [ run auto_ptr_rv_test.cpp ]
+          [ run shared_ptr_alias_test.cpp ]
+          [ run shared_ptr_rv_test.cpp ]
+          [ run shared_ptr_move_test.cpp ]
+          [ compile-fail shared_ptr_pv_fail.cpp ]
+          [ run sp_unary_addr_test.cpp ]
+          [ compile-fail scoped_ptr_eq_fail.cpp ]
+          [ compile-fail scoped_array_eq_fail.cpp ]
+          [ run esft_regtest.cpp ]
+          [ run yield_k_test.cpp ]
+          [ run yield_k_test.cpp : : : <threading>multi : yield_k_test.mt ]
+          [ run spinlock_test.cpp ]
+          [ run spinlock_try_test.cpp ]
+ [ run spinlock_try_test.cpp : : : <threading>multi : spinlock_try_test.mt ]
+          [ run spinlock_pool_test.cpp ]
+          [ run make_shared_test.cpp ]
+          [ run make_shared_perfect_forwarding_test.cpp ]
+          [ run sp_convertible_test.cpp ]
+          [ run wp_convertible_test.cpp ]
+          [ run ip_convertible_test.cpp ]
+          [ run allocate_shared_test.cpp ]
+          [ run sp_atomic_test.cpp ]
+          [ run esft_void_test.cpp ]
+          [ run esft_second_ptr_test.cpp ]
+          [ run make_shared_esft_test.cpp ]
+          [ run allocate_shared_esft_test.cpp ]
+          [ run sp_recursive_assign_test.cpp ]
+          [ run sp_recursive_assign2_test.cpp ]
+          [ run sp_recursive_assign_rv_test.cpp ]
+          [ run sp_recursive_assign2_rv_test.cpp ]
+          [ run esft_constructor_test.cpp ]
+          [ compile-fail auto_ptr_lv_fail.cpp ]
+          [ run atomic_count_test2.cpp ]
+          [ run sp_typeinfo_test.cpp ]
+        ;
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/allocate_shared_esft_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,264 @@
+//  allocate_shared_esft_test.cpp
+//
+//  Copyright 2007-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/detail/lightweight_test.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <memory>
+
+class X: public boost::enable_shared_from_this<X>
+{
+private:
+
+    X( X const & );
+    X & operator=( X const & );
+
+public:
+
+    static int instances;
+
+ explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 )
+    {
+        ++instances;
+    }
+
+    ~X()
+    {
+        --instances;
+    }
+};
+
+int X::instances = 0;
+
+int main()
+{
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>() );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::allocate_shared< X >( std::allocator<void>(), 1, 2, 3, 4, 5, 6, 7, 8, 9 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/atomic_count_test2.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,55 @@
+//
+// atomic_count_test2.cpp
+//
+// 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
+//
+
+#include <boost/detail/atomic_count.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+int main()
+{
+    boost::detail::atomic_count n( 4 );
+
+    BOOST_TEST( n == 4 );
+
+    BOOST_TEST( ++n == 5 );
+    BOOST_TEST( ++n == 6 );
+
+    BOOST_TEST( n == 6 );
+
+    BOOST_TEST( --n == 5 );
+    BOOST_TEST( --n == 4 );
+
+    BOOST_TEST( n == 4 );
+
+    boost::detail::atomic_count m( 0 );
+
+    BOOST_TEST( m == 0 );
+
+    BOOST_TEST( ++m == 1 );
+    BOOST_TEST( ++m == 2 );
+
+    BOOST_TEST( m == 2 );
+
+    BOOST_TEST( --m == 1 );
+    BOOST_TEST( --m == 0 );
+
+    BOOST_TEST( m == 0 );
+
+    BOOST_TEST( --m == -1 );
+    BOOST_TEST( --m == -2 );
+
+    BOOST_TEST( m == -2 );
+
+    BOOST_TEST( ++m == -1 );
+    BOOST_TEST( ++m == 0 );
+
+    BOOST_TEST( m == 0 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/auto_ptr_lv_fail.cpp     Mon Feb  8 19:41:53 2010
@@ -0,0 +1,32 @@
+#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
+
+//
+// auto_ptr_lv_fail.cpp - a negative test for converting an auto_ptr to shared_ptr
+//
+//  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
+//
+
+#include <boost/shared_ptr.hpp>
+#include <memory>
+
+void f( boost::shared_ptr<int> )
+{
+}
+
+int main()
+{
+    std::auto_ptr<int> p;
+    f( p ); // must fail
+    return 0;
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/esft_constructor_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,169 @@
+//
+//  esft_constructor_test.cpp
+//
+//  A test for the new enable_shared_from_this support for calling
+//  shared_from_this from constructors (that is, prior to the
+//  object's ownership being passed to an external shared_ptr).
+//
+//  Copyright (c) 2008 Frank Mori Hess
+//  Copyright (c) 2008 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/smart_ptr/enable_shared_from_this2.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <memory>
+
+class X: public boost::enable_shared_from_this2< X >
+{
+private:
+
+    int destroyed_;
+    int deleted_;
+    int expected_;
+
+private:
+
+    X( X const& );
+    X& operator=( X const& );
+
+public:
+
+    static int instances;
+
+public:
+
+ explicit X( int expected, boost::shared_ptr<X> *early_px = 0 ): destroyed_( 0 ), deleted_( 0 ), expected_( expected )
+    {
+        ++instances;
+        if( early_px ) *early_px = shared_from_this();
+    }
+
+    ~X()
+    {
+        BOOST_TEST( deleted_ == expected_ );
+        BOOST_TEST( destroyed_ == 0 );
+        ++destroyed_;
+        --instances;
+    }
+
+    typedef void (*deleter_type)( X* );
+
+    static void deleter( X * px )
+    {
+        ++px->deleted_;
+    }
+
+    static void deleter2( X * px )
+    {
+        ++px->deleted_;
+        delete px;
+    }
+};
+
+int X::instances = 0;
+
+template<typename T, typename U>
+bool are_shared_owners(const boost::shared_ptr<T> &a, const boost::shared_ptr<U> &b)
+{
+    return !(a < b) && !(b < a);
+}
+
+struct Y: public boost::enable_shared_from_this2<Y>
+{};
+
+int main()
+{
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr<X> early_px;
+        X* x = new X( 1, &early_px );
+        BOOST_TEST( early_px.use_count() > 0 );
+        BOOST_TEST( boost::get_deleter<X::deleter_type>(early_px) == 0 );
+        boost::shared_ptr<X> px( x, &X::deleter2 );
+        BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 );
+        BOOST_TEST(are_shared_owners(early_px, px));
+        px.reset();
+        BOOST_TEST( early_px.use_count() == 1 );
+        BOOST_TEST( X::instances == 1 );
+ // X::deleter_type *pd = boost::get_deleter<X::deleter_type>(early_px);
+        // BOOST_TEST(pd && *pd == &X::deleter2 );
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr<X> early_px;
+        X* x = new X( 1, &early_px );
+        boost::weak_ptr<X> early_weak_px = early_px;
+        early_px.reset();
+        BOOST_TEST( !early_weak_px.expired() );
+        boost::shared_ptr<X> px( x, &X::deleter2 );
+        BOOST_TEST( px.use_count() == 1 );
+        BOOST_TEST( X::instances == 1 );
+        BOOST_TEST(are_shared_owners(early_weak_px.lock(), px));
+        px.reset();
+        BOOST_TEST( early_weak_px.expired() );
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr<X> early_px;
+        X x( 1, &early_px );
+        BOOST_TEST( early_px.use_count() > 0 );
+        boost::shared_ptr<X> px( &x, &X::deleter );
+        BOOST_TEST( early_px.use_count() == 2 && px.use_count() == 2 );
+        early_px.reset();
+        BOOST_TEST( px.use_count() == 1 );
+        BOOST_TEST( X::instances == 1 );
+        px.reset();
+        try
+        {
+            x.shared_from_this();
+            BOOST_ERROR("x did not throw bad_weak_ptr");
+        }
+        catch( const boost::bad_weak_ptr & )
+        {}
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::weak_ptr<X> early_weak_px;
+        {
+            boost::shared_ptr<X> early_px;
+            X x( 0, &early_px );
+            early_weak_px = early_px;
+            early_px.reset();
+            BOOST_TEST( !early_weak_px.expired() );
+            BOOST_TEST( X::instances == 1 );
+        }
+        BOOST_TEST( early_weak_px.expired() );
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr<Y> px(new Y());
+        Y y(*px);
+        px.reset();
+        try
+        {
+            y.shared_from_this();
+        }
+        catch( const boost::bad_weak_ptr & )
+        {
+            BOOST_ERROR("y threw bad_weak_ptr");
+        }
+    }
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/esft_second_ptr_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,51 @@
+//
+//  esft_second_ptr_test.cpp
+//
+//  This test has been extracted from a real
+//  scenario that occurs in Boost.Python
+//
+//  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
+//
+
+
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+//
+
+class X: public boost::enable_shared_from_this<X>
+{
+};
+
+void null_deleter( void const* )
+{
+}
+
+int main()
+{
+    boost::shared_ptr<X> px( new X );
+
+    {
+        boost::shared_ptr<X> px2( px.get(), null_deleter );
+        BOOST_TEST( px == px2 );
+    }
+
+    try
+    {
+        boost::shared_ptr< X > qx = px->shared_from_this();
+
+        BOOST_TEST( px == qx );
+        BOOST_TEST( !( px < qx ) && !( qx < px ) );
+    }
+    catch( boost::bad_weak_ptr const& )
+    {
+        BOOST_ERROR( "px->shared_from_this() failed" );
+    }
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/esft_void_test.cpp       Mon Feb  8 19:41:53 2010
@@ -0,0 +1,41 @@
+//
+//  esft_void_test.cpp
+//
+//  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
+//
+
+
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+//
+
+class X: public boost::enable_shared_from_this<X>
+{
+};
+
+int main()
+{
+    boost::shared_ptr< void const volatile > pv( new X );
+ boost::shared_ptr< void > pv2 = boost::const_pointer_cast< void >( pv );
+    boost::shared_ptr< X > px = boost::static_pointer_cast< X >( pv2 );
+
+    try
+    {
+        boost::shared_ptr< X > qx = px->shared_from_this();
+
+        BOOST_TEST( px == qx );
+        BOOST_TEST( !( px < qx ) && !( qx < px ) );
+    }
+    catch( boost::bad_weak_ptr const& )
+    {
+        BOOST_ERROR( "px->shared_from_this() failed" );
+    }
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/intrusive_ptr_move_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,184 @@
+#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
+#pragma warning(disable: 4355) // 'this' : used in base member initializer list
+#pragma warning(disable: 4511)  // copy constructor could not be generated
+#pragma warning(disable: 4512) // assignment operator could not be generated
+
+#if (BOOST_MSVC >= 1310)
+#pragma warning(disable: 4675) // resolved overload found with Koenig lookup
+#endif
+
+#endif
+
+//
+//  intrusive_ptr_move_test.cpp
+//
+//  Copyright (c) 2002-2005 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/detail/lightweight_test.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/detail/atomic_count.hpp>
+#include <boost/config.hpp>
+#include <algorithm>
+#include <functional>
+
+#if defined( BOOST_HAS_RVALUE_REFS )
+
+namespace N
+{
+
+class base
+{
+private:
+
+    boost::detail::atomic_count use_count_;
+
+    base(base const &);
+    base & operator=(base const &);
+
+protected:
+
+    base(): use_count_(0)
+    {
+        ++instances;
+    }
+
+    virtual ~base()
+    {
+        --instances;
+    }
+
+public:
+
+    static long instances;
+
+    long use_count() const
+    {
+        return use_count_;
+    }
+
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+
+    inline friend void intrusive_ptr_add_ref(base * p)
+    {
+        ++p->use_count_;
+    }
+
+    inline friend void intrusive_ptr_release(base * p)
+    {
+        if(--p->use_count_ == 0) delete p;
+    }
+
+#else
+
+    void add_ref()
+    {
+        ++use_count_;
+    }
+
+    void release()
+    {
+        if(--use_count_ == 0) delete this;
+    }
+
+#endif
+};
+
+long base::instances = 0;
+
+} // namespace N
+
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+
+namespace boost
+{
+
+inline void intrusive_ptr_add_ref(N::base * p)
+{
+    p->add_ref();
+}
+
+inline void intrusive_ptr_release(N::base * p)
+{
+    p->release();
+}
+
+} // namespace boost
+
+#endif
+
+//
+
+struct X: public virtual N::base
+{
+};
+
+struct Y: public X
+{
+};
+
+int main()
+{
+    BOOST_TEST( N::base::instances == 0 );
+
+    {
+        boost::intrusive_ptr<X> p( new X );
+        BOOST_TEST( N::base::instances == 1 );
+
+        boost::intrusive_ptr<X> p2( std::move( p ) );
+        BOOST_TEST( N::base::instances == 1 );
+        BOOST_TEST( p.get() == 0 );
+
+        p2.reset();
+        BOOST_TEST( N::base::instances == 0 );
+    }
+
+    {
+        boost::intrusive_ptr<X> p( new X );
+        BOOST_TEST( N::base::instances == 1 );
+
+        boost::intrusive_ptr<X> p2;
+        p2 = std::move( p );
+        BOOST_TEST( N::base::instances == 1 );
+        BOOST_TEST( p.get() == 0 );
+
+        p2.reset();
+        BOOST_TEST( N::base::instances == 0 );
+    }
+
+    {
+        boost::intrusive_ptr<X> p( new X );
+        BOOST_TEST( N::base::instances == 1 );
+
+        boost::intrusive_ptr<X> p2( new X );
+        BOOST_TEST( N::base::instances == 2 );
+        p2 = std::move( p );
+        BOOST_TEST( N::base::instances == 1 );
+        BOOST_TEST( p.get() == 0 );
+
+        p2.reset();
+        BOOST_TEST( N::base::instances == 0 );
+    }
+
+    return boost::report_errors();
+}
+
+#else // !defined( BOOST_HAS_RVALUE_REFS )
+
+int main()
+{
+    return 0;
+}
+
+#endif
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/make_shared_esft_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,263 @@
+//  make_shared_esft_test.cpp
+//
+//  Copyright 2007-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/detail/lightweight_test.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+
+class X: public boost::enable_shared_from_this<X>
+{
+private:
+
+    X( X const & );
+    X & operator=( X const & );
+
+public:
+
+    static int instances;
+
+ explicit X( int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0, int = 0 )
+    {
+        ++instances;
+    }
+
+    ~X()
+    {
+        --instances;
+    }
+};
+
+int X::instances = 0;
+
+int main()
+{
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr< X > px = boost::make_shared< X >();
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr< X > px = boost::make_shared< X >( 1 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    {
+ boost::shared_ptr< X > px = boost::make_shared< X >( 1, 2, 3, 4, 5, 6, 7, 8, 9 );
+        BOOST_TEST( X::instances == 1 );
+
+        try
+        {
+            boost::shared_ptr< X > qx = px->shared_from_this();
+
+            BOOST_TEST( px == qx );
+            BOOST_TEST( !( px < qx ) && !( qx < px ) );
+
+            px.reset();
+            BOOST_TEST( X::instances == 1 );
+        }
+        catch( boost::bad_weak_ptr const& )
+        {
+            BOOST_ERROR( "px->shared_from_this() failed" );
+        }
+    }
+
+    BOOST_TEST( X::instances == 0 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/make_shared_perfect_forwarding_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,98 @@
+// make_shared_perfect_forwarding_test.cpp - a test of make_shared
+//   perfect forwarding of constructor arguments when using a C++0x
+//   compiler.
+//
+// Copyright 2009 Frank Mori Hess
+//
+// 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/detail/lightweight_test.hpp>
+#include <boost/make_shared.hpp>
+#include <boost/shared_ptr.hpp>
+
+#ifndef BOOST_HAS_RVALUE_REFS
+
+int main()
+{
+    return 0;
+}
+
+#else // BOOST_HAS_RVALUE_REFS
+
+class myarg
+{
+public:
+    myarg()
+    {}
+private:
+    myarg(myarg && other)
+    {}
+    myarg& operator=(myarg && other)
+    {
+        return *this;
+    }
+    myarg(const myarg & other)
+    {}
+    myarg& operator=(const myarg & other)
+    {
+        return *this;
+    }
+};
+
+class X
+{
+public:
+    enum constructor_id
+    {
+        move_constructor,
+        const_ref_constructor,
+        ref_constructor
+    };
+
+    X(myarg &&arg): constructed_by_(move_constructor)
+    {}
+    X(const myarg &arg): constructed_by_(const_ref_constructor)
+    {}
+    X(myarg &arg): constructed_by_(ref_constructor)
+    {}
+
+    constructor_id constructed_by_;
+};
+
+struct Y
+{
+    Y(int &value): ref(value)
+    {}
+    int &ref;
+};
+
+int main()
+{
+    {
+        myarg a;
+        boost::shared_ptr< X > x = boost::make_shared< X >(a);
+        BOOST_TEST( x->constructed_by_ == X::ref_constructor);
+    }
+    {
+        const myarg ca;
+        boost::shared_ptr< X > x = boost::make_shared< X >(ca);
+        BOOST_TEST( x->constructed_by_ == X::const_ref_constructor);
+    }
+    {
+        boost::shared_ptr< X > x = boost::make_shared< X >(myarg());
+        BOOST_TEST( x->constructed_by_ == X::move_constructor);
+    }
+    {
+        int value = 1;
+        boost::shared_ptr< Y > y = boost::make_shared< Y >(value);
+        BOOST_TEST( y->ref == 1 && value == y->ref );
+        ++y->ref;
+        BOOST_TEST( value == y->ref );
+    }
+
+    return boost::report_errors();
+}
+
+#endif // BOOST_HAS_RVALUE_REFS
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/sp_recursive_assign2_rv_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,114 @@
+//
+//  sp_recursive_assign2_rv_test.cpp
+//
+//  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
+//
+
+
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+//
+
+class X
+{
+public:
+
+    static int instances;
+
+    X()
+    {
+        ++instances;
+    }
+
+    ~X()
+    {
+        --instances;
+    }
+
+private:
+
+    X( X const& );
+};
+
+int X::instances = 0;
+
+class Y
+{
+public:
+
+    static int instances;
+
+    Y()
+    {
+        ++instances;
+    }
+
+    ~Y()
+    {
+        --instances;
+    }
+
+private:
+
+    Y( Y const& );
+};
+
+int Y::instances = 0;
+
+static boost::shared_ptr<void> s_pv;
+
+class Z
+{
+public:
+
+    static int instances;
+
+    Z()
+    {
+        ++instances;
+    }
+
+    ~Z()
+    {
+        --instances;
+        s_pv = boost::shared_ptr<Y>( new Y );
+    }
+
+private:
+
+    Z( Z const& );
+};
+
+int Z::instances = 0;
+
+int main()
+{
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 0 );
+
+    s_pv = boost::shared_ptr<Z>( new Z );
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 1 );
+
+    s_pv = boost::shared_ptr<X>( new X );
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 1 );
+    BOOST_TEST( Z::instances == 0 );
+
+    s_pv = boost::shared_ptr<Y>();
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 0 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/sp_recursive_assign2_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,122 @@
+//
+//  sp_recursive_assign2_test.cpp
+//
+//  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
+//
+
+
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+//
+
+class X
+{
+public:
+
+    static int instances;
+
+    X()
+    {
+        ++instances;
+    }
+
+    ~X()
+    {
+        --instances;
+    }
+
+private:
+
+    X( X const& );
+};
+
+int X::instances = 0;
+
+class Y
+{
+public:
+
+    static int instances;
+
+    Y()
+    {
+        ++instances;
+    }
+
+    ~Y()
+    {
+        --instances;
+    }
+
+private:
+
+    Y( Y const& );
+};
+
+int Y::instances = 0;
+
+static boost::shared_ptr<void> s_pv;
+
+class Z
+{
+public:
+
+    static int instances;
+
+    Z()
+    {
+        ++instances;
+    }
+
+    ~Z()
+    {
+        --instances;
+
+        boost::shared_ptr<Y> pv( new Y );
+        s_pv = pv;
+    }
+
+private:
+
+    Z( Z const& );
+};
+
+int Z::instances = 0;
+
+int main()
+{
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 0 );
+
+    {
+        boost::shared_ptr<Z> pv( new Z );
+        s_pv = pv;
+    }
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 1 );
+
+    {
+        boost::shared_ptr<X> pv( new X );
+        s_pv = pv;
+    }
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 1 );
+    BOOST_TEST( Z::instances == 0 );
+
+    s_pv.reset();
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 0 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/sp_recursive_assign_rv_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,114 @@
+//
+//  sp_recursive_assign_rv_test.cpp
+//
+//  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
+//
+
+
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+//
+
+class X
+{
+public:
+
+    static int instances;
+
+    X()
+    {
+        ++instances;
+    }
+
+    ~X()
+    {
+        --instances;
+    }
+
+private:
+
+    X( X const& );
+};
+
+int X::instances = 0;
+
+class Y
+{
+public:
+
+    static int instances;
+
+    Y()
+    {
+        ++instances;
+    }
+
+    ~Y()
+    {
+        --instances;
+    }
+
+private:
+
+    Y( Y const& );
+};
+
+int Y::instances = 0;
+
+static boost::shared_ptr<void> s_pv;
+
+class Z
+{
+public:
+
+    static int instances;
+
+    Z()
+    {
+        ++instances;
+    }
+
+    ~Z()
+    {
+        --instances;
+        s_pv = boost::shared_ptr<void>( new Y );
+    }
+
+private:
+
+    Z( Z const& );
+};
+
+int Z::instances = 0;
+
+int main()
+{
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 0 );
+
+    s_pv = boost::shared_ptr<void>( new Z );
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 1 );
+
+    s_pv = boost::shared_ptr<void>( new X );
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 1 );
+    BOOST_TEST( Z::instances == 0 );
+
+    s_pv = boost::shared_ptr<void>();
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 0 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/sp_recursive_assign_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,122 @@
+//
+//  sp_recursive_assign_test.cpp
+//
+//  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
+//
+
+
+#include <boost/shared_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+//
+
+class X
+{
+public:
+
+    static int instances;
+
+    X()
+    {
+        ++instances;
+    }
+
+    ~X()
+    {
+        --instances;
+    }
+
+private:
+
+    X( X const& );
+};
+
+int X::instances = 0;
+
+class Y
+{
+public:
+
+    static int instances;
+
+    Y()
+    {
+        ++instances;
+    }
+
+    ~Y()
+    {
+        --instances;
+    }
+
+private:
+
+    Y( Y const& );
+};
+
+int Y::instances = 0;
+
+static boost::shared_ptr<void> s_pv;
+
+class Z
+{
+public:
+
+    static int instances;
+
+    Z()
+    {
+        ++instances;
+    }
+
+    ~Z()
+    {
+        --instances;
+
+        boost::shared_ptr<void> pv( new Y );
+        s_pv = pv;
+    }
+
+private:
+
+    Z( Z const& );
+};
+
+int Z::instances = 0;
+
+int main()
+{
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 0 );
+
+    {
+        boost::shared_ptr<void> pv( new Z );
+        s_pv = pv;
+    }
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 1 );
+
+    {
+        boost::shared_ptr<void> pv( new X );
+        s_pv = pv;
+    }
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 1 );
+    BOOST_TEST( Z::instances == 0 );
+
+    s_pv.reset();
+
+    BOOST_TEST( X::instances == 0 );
+    BOOST_TEST( Y::instances == 0 );
+    BOOST_TEST( Z::instances == 0 );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/sp_typeinfo_test.cpp     Mon Feb  8 19:41:53 2010
@@ -0,0 +1,51 @@
+//
+// sp_typeinfo_test.cpp
+//
+// Copyright (c) 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/detail/sp_typeinfo.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <iostream>
+
+int main()
+{
+    BOOST_TEST( BOOST_SP_TYPEID( int ) == BOOST_SP_TYPEID( int ) );
+    BOOST_TEST( BOOST_SP_TYPEID( int ) != BOOST_SP_TYPEID( long ) );
+    BOOST_TEST( BOOST_SP_TYPEID( int ) != BOOST_SP_TYPEID( void ) );
+
+    boost::detail::sp_typeinfo const & ti = BOOST_SP_TYPEID( int );
+
+    boost::detail::sp_typeinfo const * pti = &BOOST_SP_TYPEID( int );
+    BOOST_TEST( *pti == ti );
+
+    BOOST_TEST( ti == ti );
+    BOOST_TEST( !( ti != ti ) );
+    BOOST_TEST( !ti.before( ti ) );
+
+    char const * nti = ti.name();
+    std::cout << nti << std::endl;
+
+    boost::detail::sp_typeinfo const & tv = BOOST_SP_TYPEID( void );
+
+    boost::detail::sp_typeinfo const * ptv = &BOOST_SP_TYPEID( void );
+    BOOST_TEST( *ptv == tv );
+
+    BOOST_TEST( tv == tv );
+    BOOST_TEST( !( tv != tv ) );
+    BOOST_TEST( !tv.before( tv ) );
+
+    char const * ntv = tv.name();
+    std::cout << ntv << std::endl;
+
+    BOOST_TEST( ti != tv );
+    BOOST_TEST( !( ti == tv ) );
+
+    BOOST_TEST( ti.before( tv ) != tv.before( ti ) );
+
+    return boost::report_errors();
+}
=======================================
--- /dev/null
+++ /trunk/libs/smart_ptr/test/weak_ptr_move_test.cpp Mon Feb 8 19:41:53 2010
@@ -0,0 +1,121 @@
+//
+//  weak_ptr_move_test.cpp
+//
+//  Copyright (c) 2007 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/weak_ptr.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+#if defined( BOOST_HAS_RVALUE_REFS )
+
+struct X
+{
+    static long instances;
+
+    X()
+    {
+        ++instances;
+    }
+
+    ~X()
+    {
+        --instances;
+    }
+
+private:
+
+    X( X const & );
+    X & operator=( X const & );
+};
+
+long X::instances = 0;
+
+int main()
+{
+    BOOST_TEST( X::instances == 0 );
+
+    {
+        boost::shared_ptr<X> p_( new X );
+        boost::weak_ptr<X> p( p_ );
+        BOOST_TEST( X::instances == 1 );
+        BOOST_TEST( p.use_count() == 1 );
+
+        boost::weak_ptr<X> p2( std::move( p ) );
+        BOOST_TEST( X::instances == 1 );
+        BOOST_TEST( p2.use_count() == 1 );
+        BOOST_TEST( p.expired() );
+
+        boost::weak_ptr<void> p3( std::move( p2 ) );
+        BOOST_TEST( X::instances == 1 );
+        BOOST_TEST( p3.use_count() == 1 );
+        BOOST_TEST( p2.expired() );
+
+        p_.reset();
+        BOOST_TEST( X::instances == 0 );
+        BOOST_TEST( p3.expired() );
+    }
+
+    {
+        boost::shared_ptr<X> p_( new X );
+        boost::weak_ptr<X> p( p_ );
+        BOOST_TEST( X::instances == 1 );
+        BOOST_TEST( p.use_count() == 1 );
+
+        boost::weak_ptr<X> p2;
+        p2 = static_cast< boost::weak_ptr<X> && >( p );
+        BOOST_TEST( X::instances == 1 );
+        BOOST_TEST( p2.use_count() == 1 );
+        BOOST_TEST( p.expired() );
+
+        boost::weak_ptr<void> p3;
+        p3 = std::move( p2 );
+        BOOST_TEST( X::instances == 1 );
+        BOOST_TEST( p3.use_count() == 1 );
+        BOOST_TEST( p2.expired() );
+
+        p_.reset();
+        BOOST_TEST( X::instances == 0 );
+        BOOST_TEST( p3.expired() );
+    }
+
+    {
+        boost::shared_ptr<X> p_( new X );
+        boost::weak_ptr<X> p( p_ );
+        BOOST_TEST( X::instances == 1 );
+        BOOST_TEST( p.use_count() == 1 );
+
+        boost::shared_ptr<X> p_2( new X );
+        boost::weak_ptr<X> p2( p_2 );
+        BOOST_TEST( X::instances == 2 );
+        p2 = std::move( p );
+        BOOST_TEST( X::instances == 2 );
+        BOOST_TEST( p2.use_count() == 1 );
+        BOOST_TEST( p.expired() );
+        BOOST_TEST( p2.lock() != p_2 );
+
+        boost::shared_ptr<void> p_3( new X );
+        boost::weak_ptr<void> p3( p_3 );
+        BOOST_TEST( X::instances == 3 );
+        p3 = std::move( p2 );
+        BOOST_TEST( X::instances == 3 );
+        BOOST_TEST( p3.use_count() == 1 );
+        BOOST_TEST( p2.expired() );
+        BOOST_TEST( p3.lock() != p_3 );
+    }
+
+    return boost::report_errors();
+}
+
+#else // !defined( BOOST_HAS_RVALUE_REFS )
+
+int main()
+{
+    return 0;
+}
+
+#endif
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/Jamfile      Mon Feb  8 19:41:53 2010
@@ -0,0 +1,35 @@
+#==============================================================================
+#   Copyright (c) 2001-2009 Joel de Guzman
+#   Copyright (c) 2001-2009 Hartmut Kaiser
+#
+#   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)
+#==============================================================================
+
+project spirit/doc ;
+
+import boostbook ;
+import quickbook ;
+
+path-constant images_location : html ;
+
+boostbook spirit2
+    :
+        spirit2.qbk
+    :
+        <xsl:param>boost.root=../../../..
+        <xsl:param>boost.libraries=../../../libraries.htm
+        <xsl:param>html.stylesheet=../../../../doc/html/boostbook.css
+        <xsl:param>chunk.section.depth=4
+        <xsl:param>chunk.first.sections=1
+        <xsl:param>toc.section.depth=3
+        <xsl:param>toc.max.depth=3
+        <xsl:param>generate.section.toc.level=4
+        <format>html:<xsl:param>admon.graphics.path=images/
+
+        <include>.
+        <format>pdf:<xsl:param>img.src.path=$(images_location)/
+        <format>pdf:<xsl:param>draft.mode="no"
+ <format>pdf:<xsl:param>boost.url.prefix=http://www.boost.org/doc/libs/release/libs/spirit/doc/html
+    ;
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/abstracts/attributes.qbk     Mon Feb  8 19:41:53 2010
@@ -0,0 +1,310 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Hartmut Kaiser
+    Copyright (C) 2001-2010 Joel de Guzman
+
+ 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)
+===============================================================================/]
+
+[section:attributes Attributes]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:primitive_attributes Attributes of Primitive Components]
+
+Parsers and generators in __spirit__ are fully attributed. __qi__ parsers always
+/expose/ an attribute specific to their type. This is called /synthesized
+attribute/ as it is returned from a successful match representing the matched
+input sequence. For instance, numeric parsers, such as `int_` or `double_`,
+return the `int` or `double` value converted from the matched input sequence. +Other primitive parser components have other intuitive attribute types, such as for instance `int_` which has `int`, or `ascii::char_` which has `char`. Forprimitive parsers apply the normal C++ convertibility rules: you can use any Other primitive parser components have other intuitive attribute types, e.g.
+the parser `ascii::char_` has `char` as attribute type. For
+primitive parsers the normal C++ convertibility rules apply: you can use any
+C++ type to receive the parsed value as long as the attribute type of the
+parser is convertible to the type provided. The following example shows how a
+synthesized parser attribute (the `int` value) is extracted by calling the
+API function `qi::parse`:
+
+    int value = 0;
+    std::string str("123");
+    std::string::iterator strbegin = str.begin();
+    qi::parse(strbegin, str.end(), int_, value);   // value == 123
+
+The attribute type of a generator defines what data types this generator is
+able to consume in order to produce its output. __karma__ generators always
+/expect/ an attribute specific to their type. This is called /consumed
+attribute/ and is expected to be passed to the generator. The consumed
+attribute is most of the time the value the generator is designed to emit
+output for. For primitive generators the normal C++ convertibility rules apply. +Any data type convertible to the attribute type of a primitive generator can be +used to provide the data to generate. We present a similar example as above,
+this time the consumed attribute of the `int_` generator (the `int` value)
+is passed to the API function `karma::generate`:
+
+    int value = 123;
+    std::string str;
+    std::back_insert_iterator<std::string> out(str);
+    karma::generate(out, int_, value);                // str == "123"
+
+Other primitive generator components have other intuitive attribute types, very
+similar to the corresponding parser components.  For instance, the
+`ascii::char_` generator has `char` as consumed attribute. For a full list of +available parser and generator primitives and their attribute types please see
+the sections __sec_qi_primitive__ and __sec_karma_primitive__.
+
+[endsect]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:compound_attributes Attributes of Compound Components]
+
+__qi__ and __karma__ implement well defined attribute type propagation rules
+for all compound parsers and generators, such as sequences, alternatives,
+Kleene star, etc. The main attribute propagation rule for a sequences is for
+instance:
+
+[table
+    [[Library]      [Sequence attribute propagation rule]]
+    [[Qi]           [`a: A, b: B --> (a >> b): tuple<A, B>`]]
+    [[Karma]        [`a: A, b: B --> (a << b): tuple<A, B>`]]
+]
+
+which reads as:
+
+[:Given `a` and `b` are parsers (generators), and `A` is the attribute type of
+  `a`, and `B` is the attribute type of `b`, then the attribute type of
+  `a >> b` (`a << b`) will be `tuple<A, B>`.]
+
+[note The notation `tuple<A, B>` is used as a placeholder expression for any
+      fusion sequence holding the types A and B, such as
+ `boost::fusion::tuple<A, B>` or `std::pair<A, B>` (for more information
+      see __fusion__).]
+
+As you can see, in order for a type to be compatible with the attribute type
+of a compound expression it has to
+
+* either be convertible to the attribute type,
+* or it has to expose certain functionalities, i.e. it needs to conform to a
+  concept compatible with the component.
+
+Each compound component implements its own set of attribute propagation rules.
+For a full list of how the different compound generators consume attributes
+see the sections __sec_qi_compound__ and __sec_karma_compound__.
+
+[heading The Attribute of Sequence Parsers and Generators]
+
+Sequences require an attribute type to expose the concept of a fusion sequence,
+where all elements of that fusion sequence have to be compatible with the
+corresponding element of the component sequence. For example, the expression:
+
+[table
+    [[Library]      [Sequence expression]]
+    [[Qi]           [`double_ >> double_`]]
+    [[Karma]        [`double_ << double_`]]
+]
+
+is compatible with any fusion sequence holding two types, where both types have +to be compatible with `double`. The first element of the fusion sequence has to +be compatible with the attribute of the first `double_`, and the second element +of the fusion sequence has to be compatible with the attribute of the second +`double_`. If we assume to have an instance of a `std::pair<double, double>`, +we can directly use the expressions above to do both, parse input to fill the
+attribute:
+
+    // the following parses "1.0 2.0" into a pair of double
+    std::string input("1.0 2.0");
+    std::string::iterator strbegin = input.begin();
+    std::pair<double, double> p;
+    qi::phrase_parse(strbegin, input.end(),
+        qi::double_ >> qi::double_,       // parser grammar
+        qi::space,                        // delimiter grammar
+ p); // attribute to fill while parsing
+
+and generate output for it:
+
+    // the following generates: "1.0 2.0" from the pair filled above
+    std::string str;
+    std::back_insert_iterator<std::string> out(str);
+    karma::generate_delimited(out,
+ karma::double_ << karma::double_, // generator grammar (format description)
+        karma::space,                     // delimiter grammar
+        p);                               // data to use as the attribute
+
+(where the `karma::space` generator is used as the delimiter, allowing to
+automatically skip/insert delimiting spaces in between all primitives).
+
+[tip *For sequences only:* __qi__ and __karma__ expose a set of API functions + usable mainly with sequences. Very much like the functions of the `scanf` + and `printf` families these functions allow to pass the attributes for + each of the elements of the sequence separately. Using the corresponding + overload of /Qi's/ parse or /Karma's/ `generate()` the expression above
+      could be rewritten as:
+      ``
+          double d1 = 0.0, d2 = 0.0;
+ qi::phrase_parse(begin, end, qi::double_ >> qi::double_, qi::space, d1, d2); + karma::generate_delimited(out, karma::double_ << karma::double_, karma::space, d1, d2);
+      ``
+      where the first attribute is used for the first `double_`, and
+      the second attribute is used for the second `double_`.
+]
+
+[heading The Attribute of Alternative Parsers and Generators]
+
+Alternative parsers and generators are all about - well - alternatives. In
+order to store possibly different result (attribute) types from the different
+alternatives we use the data type __boost_variant__. The main attribute
+propagation rule of these components is:
+
+    a: A, b: B --> (a | b): variant<A, B>
+
+Alternatives have a second very important attribute propagation rule:
+
+    a: A, b: A --> (a | b): A
+
+often allowing to simplify things significantly. If all sub expressions of
+an alternative expose the same attribute type, the overall alternative
+will expose exactly the same attribute type as well.
+
+[endsect]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:more_compound_attributes More About Attributes of Compound Components]
+
+While parsing input or generating output it is often desirable to combine some +constant elements with variable parts. For instance, let us look at the example +of parsing or formatting a complex number, which is written as `(real, imag)`, +where `real` and `imag ` are the variables representing the real and imaginary
+parts of our complex number. This can be achieved by writing:
+
+[table
+    [[Library]      [Sequence expression]]
+    [[Qi]           [`'(' >> double_ >> ", " >> double_ >> ')'`]]
+    [[Karma]        [`'(' << double_ << ", " << double_ << ')'`]]
+]
+
+Fortunately, literals (such as `'('` and `", "`) do /not/ expose any attribute
+(well actually, they do expose the special type `unused_type`, but in this
+context `unused_type` is interpreted as if the component does not expose any +attribute at all). It is very important to understand that the literals don't
+consume any of the elements of a fusion sequence passed to this component
+sequence. As said, they just don't expose any attribute and don't produce
+(consume) any data. The following example shows this:
+
+    // the following parses "(1.0, 2.0)" into a pair of double
+    std::string input("(1.0, 2.0)");
+    std::string::iterator strbegin = input.begin();
+    std::pair<double, double> p;
+    qi::parse(strbegin, input.end(),
+        '(' >> qi::double_ >> ", " >> qi::double_ >> ')', // parser grammar
+ p); // attribute to fill while parsing
+
+and here is the equivalent __karma__ code snippet:
+
+    // the following generates: (1.0, 2.0)
+    std::string str;
+    std::back_insert_iterator<std::string> out(str);
+    generate(out,
+ '(' << karma::double_ << ", " << karma::double_ << ')', // generator grammar (format description) + p); // data to use as the attribute
+
+where the first element of the pair passed in as the data to generate is still +associated with the first `double_`, and the second element is associated with
+the second `double_` generator.
+
+This behavior should be familiar as it conforms to the way other input and
+output formatting libraries such as `scanf`, `printf` or `boost::format` are
+handling their variable parts. In this context you can think about __qi__'s
+and __karma__'s primitive components (such as the `double_` above) as of being
+typesafe placeholders for the attribute values.
+
+[tip  Similarly to the tip provided above, this example could be rewritten
+      using /Spirit's/ multi-attribute API function:
+      ``
+          double d1 = 0.0, d2 = 0.0;
+ qi::parse(begin, end, '(' >> qi::double_ >> ", " >> qi::double_ << ')', d1, d2); + karma::generate(out, '(' << karma::double_ << ", " << karma::double_ << ')', d1, d2);
+      ``
+      which provides a clear and comfortable syntax, more similar to the
+      placeholder based syntax as exposed by `printf` or `boost::format`.
+]
+
+Let's take a look at this from a more formal perspective. The sequence attribute +propagation rules define a special behavior if generators exposing `unused_type`
+as their attribute are involved (see __sec_karma_compound__):
+
+[table
+    [[Library]      [Sequence attribute propagation rule]]
+    [[Qi]           [`a: A, b: Unused --> (a >> b): A`]]
+    [[Karma]        [`a: A, b: Unused --> (a << b): A`]]
+]
+
+which reads as:
+
+[:Given `a` and `b` are parsers (generators), and `A` is the attribute type of + `a`, and `unused_type` is the attribute type of `b`, then the attribute type + of `a >> b` (`a << b`) will be `A` as well. This rule applies regardless of
+  the position the element exposing the `unused_type` is at.]
+
+This rule is the key to the understanding of the attribute handling in
+sequences as soon as literals are involved. It is as if elements with
+`unused_type` attributes 'disappeared' during attribute propagation. Notably,
+this is not only true for sequences but for any compound components. For
+instance, for alternative componets the corresponding rule is:
+
+    a: A, b: Unused --> (a | b): A
+
+again, allowing to simplify the overall attribute type of an expression.
+
+[endsect]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:nonterminal_attributes Attributes of Rules and Grammars]
+
+Nonterminals are well known from parsers where they are used as the main means +of constructing more complex parsers out of simpler ones. The nonterminals in
+the parser world are very similar to functions in an imperative programming
+language. They can be used to encapsulate parser expressions for a particular +input sequence. After being defined, the nonterminals can be used as 'normal' +parsers in more complex expressions whenever the encapsulated input needs to be +recognized. Parser nonterminals in __qi__ may accept /parameters/ (inherited
+attributes) and usually return a value (the synthesized attribute).
+
+Both, the types of the inherited and the synthesized attributes have to be
+explicitely specified while defining the particular `grammar` or the `rule`
+(the Spirit __repo__ additionally has `subrules` which conform to a similar
+interface). As an example, the following code declares a __qi__ `rule`
+exposing an `int` as its synthesized attribute, while expecting a single
+`double` as its inherited attribute (see the section about the __qi__ __rule__
+for more information):
+
+    qi::rule<Iterator, int(double)> r;
+
+In the world of generators, nonterminals are just as useful as in the parser +world. Generator nonterminals encapsulate a format description for a particular
+data type, and, whenever we need to emit output for this data type, the
+corresponding nonterminal is invoked in a similar way as the predefined
+__karma__ generator primitives. The __karma__ [karma_nonterminal nonterminals] +are very similar to the __qi__ nonterminals. Generator nonterminals may accept
+/parameters/ as well, and we call those inherited attributes too. The main
+difference is that they do not expose a synthesized attribute (as parsers do), +but they require a special /consumed attribute/. Usually the consumed attribute
+is the value the generator creates its output from. Even if the consumed
+attribute is not 'returned' from the generator we chose to use the same
+function style declaration syntax as used in __qi__. The example below declares
+a __karma__ `rule` consuming a `double` while not expecting any additional
+inherited attributes.
+
+    karma::rule<OutputIterator, double()> r;
+
+The inherited attributes of nonterminal parsers and generators are normally
+passed to the component during its invocation. These are the /parameters/ the
+parser or generator may accept and they can be used to parameterize the
+component depending on the context they are invoked from.
+
+
+[/
+* attribute propagation
+  * explicit and operator%=
+]
+
+[endsect]
+
+[endsect]  [/ Attributes]
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/abstracts/peg.qbk    Mon Feb  8 19:41:53 2010
@@ -0,0 +1,113 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Joel de Guzman
+    Copyright (C) 2001-2010 Hartmut Kaiser
+
+ 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)
+===============================================================================/]
+[section Parsing Expression Grammar]
+
+Parsing Expression Grammars (PEG) [footnote Bryan Ford: Parsing Expression
+Grammars: A Recognition-Based Syntactic Foundation,
+[@http://pdos.csail.mit.edu/~baford/packrat/popl04/]] are a derivative of
+Extended Backus-Naur Form (EBNF) [footnote Richard E. Pattis: EBNF: A Notation
+to Describe Syntax, [@http://www.cs.cmu.edu/~pattis/misc/ebnf.pdf]]
+with a different interpretation, designed to represent a recursive descent
+parser. A PEG can be directly represented as a recursive-descent parser.
+
+Like EBNF, PEG is a formal grammar for describing a formal language in
+terms of a set of rules used to recognize strings of this language.
+Unlike EBNF, PEGs have an exact interpretation. There is only one valid
+parse tree (see __ast__) for each PEG grammar.
+
+[heading Sequences]
+
+Sequences are represented by juxtaposition like in EBNF:
+
+    a b
+
+The PEG expression above states that, in order for this to succeed,
+`b` must follow `a`. Here's the syntax diagram:
+
+[:__sd_sequence__]
+
+Here's a trivial example:
+
+    'x' digit
+
+which means the character `x` must be followed by a digit.
+
+[note In __qi__, we use the `>>` for sequences since C++ does not
+allow juxtaposition, while in __karma__ we use the `<<` instead.]
+
+[heading Alternatives]
+
+Alternatives are represented in PEG using the slash:
+
+    a / b
+
+[note In __qi__ and __karma__, we use the `|` for alternatives just as in EBNF.]
+
+Alternatives allow for choices. The expression above reads: try to match
+`a`. If `a` succeeds, success, if not try to match `b`. This is a bit of
+a deviation from the usual EBNF interpretation where you simply match
+`a` *or* `b`. Here's the syntax diagram:
+
+[:__sd_choice__]
+
+PEGs allow for ambiguity in the alternatives. In the expression above,
+both `a` or `b` can both match an input string. However, only the first
+matching alternative is valid. As noted, there can only be one valid
+parse tree. [/FIXME: $$$ explain more about this $$$]
+
+[heading Loops]
+
+Again, like EBNF, PEG uses the regular-expression Kleene star and the
+plus loops:
+
+    a*
+    a+
+
+[note __qi__ and __karma__ use the prefix star and plus since there is no
+postfix star or plus in C++.]
+
+Here are the syntax diagrams:
+
+[:__sd_kleene__]
+[:__sd_plus__]
+
+The first, called the Kleene star, matches zero or more of its subject
+`a`. The second, plus, matches one ore more of its subject `a`.
+
+Unlike EBNF, PEGs have greedy loops. It will match as much as it can
+until its subject fails to match without regard to what follows. The
+following is a classic example of a fairly common EBNF/regex expression
+failing to match in PEG:
+
+    alnum* digit
+
+In PEG, alnum will eat as much alpha-numeric characters as it can
+leaving nothing more left behind. Thus, the trailing digit will get
+nothing. Loops are simply implemented in recursive descent code as
+for/while loops making them extremely efficient. That is a definite
+advantage. On the other hand, those who are familiar with EBNF and regex
+behavior might find the behavior a major gotcha. PEG provides a couple
+of other mechanisms to circumvent this. We will see more of these other
+mechanisms shortly.
+
+[heading Difference]
+
+In some cases, you may want to restrict a certain expression. You can
+think of a PEG expression as a match for a potentially infinite set of
+strings. The difference operator allows you to restrict this set:
+
+    a - b
+
+The expression reads: match `a` but not `b`.
+
+[note There is no difference operator in __karma__, as the concept does not
+make sense in the context of output generation.]
+
+[endsect]
+
+
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/abstracts/syntax_diagram.qbk Mon Feb 8 19:41:53 2010
@@ -0,0 +1,104 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Joel de Guzman
+    Copyright (C) 2001-2010 Hartmut Kaiser
+
+ 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)
+===============================================================================/]
+[section Syntax Diagram]
+
+In the next section, we will deal with Parsing Expression Grammars
+(PEG) [footnote Bryan Ford: Parsing Expression Grammars: A Recognition-Based +Syntactic Foundation, [@http://pdos.csail.mit.edu/~baford/packrat/popl04/]], +a variant of Extended Backus-Naur Form (EBNF) [footnote Richard E. Pattis: EBNF: +A Notation to Describe Syntax, [@http://www.cs.cmu.edu/~pattis/misc/ebnf.pdf]] +with a different interpretation. It is easier to understand PEG using Syntax +Diagrams. Syntax diagrams represent a grammar graphically. It was used extensibly
+by Niklaus Wirth [footnote Niklaus Wirth: The Programming Language
+Pascal. (July 1973)] in the "Pascal User Manual". Syntax Diagrams are
+easily understandable by programmers due to their similarity to flow
+charts. The isomorphism of the diagrams and functions make them ideal for
+representing __rd__ parsers which are essentially mutually recursive
+functions.
+
+Historically, Parsing Expression Grammars have been used for describing grammars +for parsers only (hence the name). In __spirit__ we use a very similar notation
+for output generation as well. Almost all the concepts described here are
+equally applicable both to __qi__ parsers and to __karma__ generators.
+
+[heading Elements]
+
+All diagrams have one entry and one exit point. Arrows connect all possible
+paths through the grammar from the entry point to the exit point.
+
+[:__sd_start_stop__]
+
+Terminals are represented by round boxes. Terminals are atomic and
+usually represent plain characters, strings or tokens.
+
+[:__sd_terminals__]
+
+Non-terminals are represented by boxes. Diagrams are modularized using
+named non-terminals. A complex diagram can be broken down into a set of
+non-terminals. Non-terminals also allow recursion (i.e. a non-terminal
+can call itself).
+
+[:__sd_non_terminals__]
+
+[heading Constructs]
+
+The most basic composition is the Sequence. B follows A:
+
+[:__sd_sequence__]
+
+The ordered choice henceforth we will call /alternatives/. In PEG,
+ordered choice and alternatives are not quite the same. PEG allows
+ambiguity of choice where one or more branches can succeed. In PEG, in
+case of ambiguity, the first one always wins.
+
+[:__sd_choice__]
+
+The optional (zero-or-one):
+
+[:__sd_optional__]
+
+Now, the loops. We have the zero-or-more and one-or-more:
+
+[:__sd_kleene__]
+[:__sd_plus__]
+
+Take note that, as in PEG, these loops behave greedily. If there is
+another 'A' just before the end-point, it will always fail because the
+preceding loop has already exhausted all 'A's and there is nothing more
+left. This is a crucial difference between PEG and general Context Free
+Grammars (CFGs). This behavior is quite obvious with syntax diagrams as
+they resemble flow-charts.
+
+[heading Predicates]
+
+Now, the following are Syntax Diagram versions of PEG predicates. These
+are not traditionally found in Syntax Diagrams. These are special
+extensions we invented to closely follow PEGs.
+
+First, we introduce a new element, the Predicate:
+
+[:__sd_predicate__]
+
+This is similar to the conditionals in flow charts where the 'No' branch
+is absent and always signals a failed parse.
+
+We have two versions of the predicate, the /And-Predicate/ and the
+/Not-Predicate/:
+
+[:__sd_and_predicate__]
+[:__sd_not_predicate__]
+
+The /And-Predicate/ tries the predicate, P, and succeeds if P succeeds,
+or otherwise fail. The opposite is true with the /Not-Predicate/. It
+tries the predicate, P, and fails if P succeeds, or otherwise succeeds.
+Both versions do a look-ahead but do not consume any input regardless if
+P succeeds or not.
+
+[endsect]
+
+
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/abstracts.qbk        Mon Feb  8 19:41:53 2010
@@ -0,0 +1,27 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Joel de Guzman
+    Copyright (C) 2001-2010 Hartmut Kaiser
+
+ 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)
+===============================================================================/]
+
+[section Abstracts]
+
+[include        abstracts/syntax_diagram.qbk]
+[include        abstracts/peg.qbk]
+[/include        abstracts/parsing.qbk]
+[/include        abstracts/generating.qbk]
+[/include        abstracts/primitives.qbk]
+[/include        abstracts/operators.qbk]
+[include        abstracts/attributes.qbk]
+[/include        abstracts/semantic_actions.qbk]
+[/include        abstracts/directives.qbk]
+[/include        abstracts/rules.qbk]
+[/include        abstracts/grammars.qbk]
+[/include        abstracts/debugging.qbk]
+[/include        abstracts/error_handling.qbk]
+[/include        abstracts/parse_trees_and_asts.qbk]
+
+[endsect]
+
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/acknowledgments.qbk  Mon Feb  8 19:41:53 2010
@@ -0,0 +1,202 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Joel de Guzman
+    Copyright (C) 2001-2010 Hartmut Kaiser
+
+ 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)
+===============================================================================/]
+
+[section Acknowledgments]
+
+This version of Spirit is a complete rewrite of the /classic/ Spirit many
+people have been contributing to (see below). But there are a couple of people +who already managed to help significantly during this rewrite. We would like to
+express our special acknowledgement to:
+
+[*Eric Niebler] for writing Boost.Proto, without which this rewrite wouldn't
+have been possible, and helping with examples, advices, and suggestions on
+how to use Boost.Proto in the best possible way.
+
+[*Ben Hanson] for providing us with an early version of his __lexertl__ library,
+which is proposed to be included into Boost (as Boost.Lexer). At the time
+of this writing the Boost review for this library is still pending.
+
+[*Francois Barel] for his silent but steady work on making and keeping Spirit
+compatible with all versions of gcc, older and newest ones. He not only
+contributed subrules to Spirit V2.1, but always keeps an eye on the small
+details which are so important to make a difference.
+
+[*Andreas Haberstroh] for proof reading the documentation and fixing those
+non-native-speaker-quirks we managed to introduce into the first versions of
+the documentation.
+
+[*Chris Hoeppler] for taking up the editorial tasks for the initial
+version of this documentation together with Andreas Haberstroh. Chris
+did a lot especially at the last minute when we are about to release.
+
+[*Michael Caisse] also for last minute editing work on the 2.1 release
+documentation.
+
+[*Tobias Schwinger] for proposing expectation points and GCC port of an
+early version.
+
+[*Dave Abrahams] as always, for countless advice and help on C++,
+library development, interfaces, usability and ease of use, for
+reviewing the code and providing valuable feedback and for always
+keeping us on our toes.
+
+[*OvermindDL] for his creative ideas on the mailing list helping to resolve
+even more difficult user problems.
+
+[*Carl Barron] for his early adoption and valuable feedback on the Lexer
+library forcing us to design a proper API covering all of his use cases.
+He also contributed an early version of the variadic attribute API for
+Qi.
+
+[*Daniel James] for improving and maintaining Quickbook, the tool we use
+for this documentation. Also, for bits and pieces here and there such
+documentation suggestions and editorial patches.
+
+[*Stephan Menzel] for his early adoption of Qi and Karma and his willingness +to invest time to spot bugs which were hard to isolate. Also, for his feedback
+on the documentation.
+
+[*Ray Burkholder] and [*Dainis Polis] for last minute feedback on the
+documentation.
+
+Special thanks to spirit-devel and spirit-general mailing lists for
+participating in the discussions, being early adopters of pre-release
+versions of Spirit2 from the very start and helping out in various tasks
+such as helping with support, bug tracking, benchmarking and testing,
+etc. The list include: [*Larry Evans], [*Richard Webb], [*Martin Wille],
+[*Dan Marsden], [*Cedric Venet], [*Allan Odgaard], [*Matthias
+Vallentin], [*Justinas V.D.], [*Darid Tromer].
+
+[*Joao Abecasis] for his early support and involvement in Spirit2
+development and for disturbing my peace every once in a while for a
+couple of jokes.
+
+The list goes on and on... if you've been mentioned thank Joel and
+Hartmut, if not, kick Joao :-)
+
+[heading Acknowledgements from the Spirit V1 /classic/ Documentation]
+
+Special thanks for working on Spirit /classic/ to:
+
+[*Dan Nuffer] for his work on lexers, parse trees, ASTs, XML parsers, the
+multi-pass iterator as well as administering Spirit's site, editing,
+maintaining the CVS and doing the releases plus a zillion of other chores that
+were almost taken for granted.
+
+[*Hartmut Kaiser] for his work on the C parser, the work on the C/C++
+preprocessor, utility parsers, the original port to Intel 5.0, various work on
+Phoenix, porting to v1.5, the meta-parsers, the grouping-parsers, extensive
+testing and painstaking attention to details.
+
+[*Martin Wille] who improved grammar multi thread safety, contributed the eol_p
+parser, the dynamic parsers, documentation and for taking an active role in
+almost every aspect from brainstorming and design to coding. And, as always,
+helps keep the regression tests for g++ on Linux as green as ever :-).
+
+[*Martijn W. Van Der Lee] our Web site administrator and for contributing the
+RFC821 parser.
+
+[*Giovanni Bajo] for last minute tweaks of Spirit 1.8.0 for CodeWarrior 8.3. +Actually, I'm ashamed Giovanni was not in this list already. He's done a lot
+since Spirit 1.5, the first Boost.Spirit release. He's instrumental in the
+porting of the Spirit iterators stuff to the new Boost Iterators Library
+(version 2). He also did various bug fixes and wrote some tests here and there.
+
+[*Juan Carlos Arevalo-Baeza (JCAB)*] for his work on the C++ parser, the position
+iterator, ports to v1.5 and keeping the mailing list discussions alive and
+kicking.
+
+[*Vaclav Vesely], lots of stuff, the no\_actions directive, various patches
+fixes, the distinct parsers, the lazy parser, some phoenix tweaks and add-ons
+(e.g. new\_). Also, *Stefan Slapeta] and wife for editing Vaclav's distinct
+parser doc.
+
+[*Raghavendra Satish] for doing the original v1.3 port to VC++ and his work on
+Phoenix.
+
+[*Noah Stein] for following up and helping Ragav on the VC++ ports.
+
+[*Hakki Dogusan], for his original v1.0 Pascal parser.
+
+[*John (EBo) David] for his work on the VM and watching over my shoulder as I
+code giving the impression of distance eXtreme programming.
+
+[*Chris Uzdavinis] for feeding in comments and valuable suggestions as well as
+editing the documentation.
+
+[*Carsten Stoll], for his work on dynamic parsers.
+
+[*Andy Elvey] and his conifer parser.
+
+[*Bruce Florman], who did the original v1.0 port to VC++.
+
+[*Jeff Westfahl] for porting the loop parsers to v1.5 and contributing the file
+iterator.
+
+[*Peter Simons] for the RFC date parser example and tutorial plus helping out
+with some nitty gritty details.
+
+[*Markus Sch'''&ouml;'''pflin] for suggesting the end_p parser and lots of other
+nifty things and his active presence in the mailing list.
+
+[*Doug Gregor] for mentoring and his ability to see things that others don't.
+
+[*David Abrahams] for giving Joel a job that allows him to still work on Spirit,
+plus countless advice and help on C++ and specifically template
+metaprogramming.
+
+[*Aleksey Gurtovoy] for his MPL library from which we stole many metaprogramming
+tricks especially for less conforming compilers such as Borland and VC6/7.
+
+[*Gustavo Guerra] for his last minute review of Spirit and constant feedback, +plus patches here and there (e.g. proposing the new dot behavior of the real
+numerics parsers).
+
+[*Nicola Musatti], [*Paul Snively], [*Alisdair Meredith] and [*Hugo Duncan] for
+testing and sending in various patches.
+
+[*Steve Rowe] for his splendid work on the TSTs that will soon be taken into
+Spirit.
+
+[*Jonathan de Halleux] for his work on actors.
+
+[*Angus Leeming] for last minute editing work on the 1.8.0 release
+documentation, his work on Phoenix and his active presence in the Spirit
+mailing list.
+
+[*Joao Abecasis] for his active presence in the Spirit mailing list, providing
+user support, participating in the discussions and so on.
+
+[*Guillaume Melquiond] for a last minute patch to multi_pass for 1.8.1.
+
+[*Peder Holt] for his porting work on Phoenix, Fusion and Spirit to VC6.
+
+To Joels wife Mariel who did the graphics in this document.
+
+My, there's a lot in this list! And it's a continuing list. We add people to
+this list everytime. We hope we did not forget anyone. If we missed
+someone you know who has helped in any way, please inform us.
+
+Special thanks also to people who gave feedback and valuable comments,
+particularly members of Boost and Spirit mailing lists. This includes all those
+who participated in the review:
+
+[*John Maddock], our review manager, [*Aleksey Gurtovoy], [*Andre Hentz],
+[*Beman Dawes], [*Carl Daniel], [*Christopher Currie], [*Dan Gohman],
+[*Dan Nuffer], [*Daryle Walker], [*David Abrahams], [*David B. Held],
+[*Dirk Gerrits], [*Douglas Gregor], [*Hartmut Kaiser], [*Iain K.Hanson],
+[*Juan Carlos Arevalo-Baeza], [*Larry Evans], [*Martin Wille],
+[*Mattias Flodin], [*Noah Stein], [*Nuno Lucas], [*Peter Dimov],
+[*Peter Simons], [*Petr Kocmid], [*Ross Smith], [*Scott Kirkwood],
+[*Steve Cleary], [*Thorsten Ottosen], [*Tom Wenisch], [*Vladimir Prus]
+
+Finally thanks to SourceForge for hosting the Spirit project and Boost: a C++ +community comprised of extremely talented library authors who participate in
+the discussion and peer review of well crafted C++ libraries.
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/advanced/customization_points.qbk Mon Feb 8 19:41:53 2010
@@ -0,0 +1,2061 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Hartmut Kaiser
+    Copyright (C) 2001-2010 Joel de Guzman
+
+ 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)
+===============================================================================/]
+
+[import ../example/karma/customize_embedded_container.cpp] [/ this pulls in the embedded_container example] +[import ../example/karma/customize_counter.cpp] [/ this pulls in the counter example] +[import ../example/karma/customize_use_as_container.cpp] [/ this pulls in the use_as_container example]
+
+[def __customize_embedded_container_example__ [link spirit.advanced.customize.iterate.container_iterator.example embedded_container_example]] +[def __customize_counter_example__ [link spirit.advanced.customize.iterate.deref_iterator.example counter_example]] +[def __customize_use_as_container_example__ [link spirit.advanced.customize.iterate.next_iterator.example use_as_container]]
+
+[section:customize Customization of Spirit's Attribute Handling]
+
+[heading Why do we need Attribute Customization Points]
+
+[important Before you read on please be aware that the interfaces described in + this section are not finalized and may change in the future without + attempting to be backwards compatible. We document the customization
+           point interfaces anyways as we think they are important.
+           Understanding customization points helps understanding Spirit.
+           Additionally they prove to be powerful tools enabling full
+ integration of the user's data structures with /Qi's/ parsers and
+           /Karma's/ generators.]
+
+__spirit__ has been written with extensibility in mind. It provides many
+different attribute customization points allowing to integrate custom data
+types with the process of parsing in __qi__ or output generation with
+__karma__. All attribute customization points are exposed using a similar
+technique: full or partial template specialization. __spirit__ generally
+implements the main template, providing a default implementation. You as the +user have to provide a partial or full specialization of this template for the +data types you want to integrate with the library. In fact, the library uses
+these customization points itself for instance to handle the magic of the
+__unused_type__ attribute type.
+
+Here is an example showing the __customize_container_value__ customization point +used by different parsers (such as __qi_kleene__, __qi_plus__, etc.) to find
+the attribute type to be stored in a supplied STL container:
+
+[import ../../../../boost/spirit/home/support/container.hpp]
+
+[customization_container_value_default]
+
+This template is instantiated by the library at the appropriate places while +using the supplied container type as the template argument. The embedded `type` +is used as the attribute type while parsing the elements to be store in that
+container.
+
+The following example shows the predefined specialization for __unused_type__:
+
+[customization_container_value_unused]
+
+which defines its embedded `type` to be __unused_type__ as well, this way
+propagating the 'don't care' attribute status to the embedded parser.
+
+All attribute customization points follow the same scheme. The last template
+parameter is always `typename Enable = void` allowing to apply SFINAE for
+fine grained control over the template specialization process. But most of the
+time you can safely forget about its existence.
+
+The following sections will describe all customization points, together with a
+description which needs to be specialized for what purpose.
+
+[heading The Usage of Customization Points]
+
+The different customizations points are used by different parts of the library.
+Part of the customizations points are used by both, __qi__ and __karma__,
+whereas others are specialized to be applied for one of the sub-libraries only. +We will explain when a specific customization point needs to be implemented and,
+equally important, which customization points need to be implemented at the
+same time. Often it is not sufficient to provide a specialization for one
+single customization point only, in this case you as the user have to provide +all necessary customizations for your data type you want to integrate with the
+library.
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:is_container Determine if a Type Should be Treated as a Container (Qi and Karma)]
+
+[heading is_container]
+
+The template `is_container` is a template meta-function used as an attribute
+customization point. It is invoked by the /Qi/ __qi_sequence__ (`>>`) and
+/Karma/ __karma_sequence__ operators in order to determine whether a supplied
+attribute can potentially be treated as a container.
+
+[heading Header]
+
+    #include <boost/spirit/home/support/container.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::traits`]]
+]
+
+[heading Synopsis]
+
+    template <typename Container, typename Enable>
+    struct is_container
+    {
+        typedef <unspecified> type;
+    };
+
+[heading Template parameters]
+
+[table
+ [[Parameter] [Description] [Default]]
+    [[`Container`]          [The type, `Container` which needs to
+                             be tested whether it has to be treated
+ as a container] [none]] + [[`Enable`] [Helper template parameter usable to selectively
+                             enable or disable certain specializations
+                             of `is_container` utilizing SFINAE (i.e.
+ `boost::enable_if` or `boost::disable_if`).] [`void`]]
+]
+
+[heading Notation]
+
+[variablelist
+    [[`C`]          [A type to be tested whether it needs to be treated
+                     as a container.]]
+    [[`T1`, `T2`, ...]  [Arbitrary types]]
+]
+
+[heading Expression Semantics]
+
+[table
+    [[Expression]                 [Semantics]]
+ [[`is_container<C>::type`] [Result of the metafunction that evaluates to + `mpl::true_` if a given type, `C`, is to be + treated as a container, `mpl::false_` otherwise
+                                   (See __mpl_boolean_constant__).]]
+]
+
+[heading Predefined Specializations]
+
+__spirit__ predefines specializations of this customization point for
+several types. The following table lists those types together with the
+conditions for which the corresponding specializations will evaluate to
+`mpl::true_` (see __mpl_boolean_constant__):
+
+[table
+    [[Template Parameters]     [Value]]
+ [[`T`] [Returns `mpl::true_` if `T` has the following
+                               embedded types defined: `value_type`,
+                               `iterator`, `size_type`, and`reference`.
+                               Otherwise it will return `mpl::false_`.]]
+    [[`boost::optional<T>`]   [Returns `is_container<T>::type`]]
+    [[`boost::variant<T1, T2, ...>`]
+                              [Returns `mpl::true_` if at least one of the
+                              `is_container<TN>::type` returns `mpl::true_`
+                              (where `TN` is `T1`, `T2`, ...).
+                              Otherwise it will return `mpl::false_`.]]
+    [[__unused_type__]        [Returns `mpl::false_`.]]
+]
+
+[heading When to implement]
+
+The customization point `is_container` needs to be implemented for a specific
+type whenever this type is to be used as an attribute in place of a STL
+container. It is applicable for parsers (__qi__) and generators (__karma__).
+As a rule of thumb: it has to be implemented whenever a certain type
+is to be passed as an attribute to a parser or a generator normally exposing a +STL container, `C` and if the type does not expose the interface of a STL container
+(i.e. `is_container<C>::type` would normally return `mpl::false_`). These
+components have an attribute propagation rule in the form:
+
+    a: A --> Op(a): vector<A>
+
+where `Op(a)` stands for any meaningful operation on the component `a`.
+
+[heading Related Attribute Customization Points]
+
+If this customization point is implemented, the following other customization
+points might need to be implemented as well.
+
+[table
+    [[Name]                   [When to implement]]
+ [[__customize_container_value__] [Needs to be implemented whenever `is_container` is implemented.]] + [[__customize_push_back_container__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] + [[__customize_container_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] + [[__customize_begin_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] + [[__customize_end_container__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] + [[__customize_deref_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] + [[__customize_next_iterator__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]] + [[__customize_compare_iterators__] [Karma: __karma_list__, [karma_kleene Kleene (unary `*`)], __karma_plus__, [karma_repeat Repeat].]]
+]
+
+[heading Example]
+
+For examples of how to use the customization point `is_container` please
+see here: __customize_embedded_container_example__,
+__customize_use_as_container_example__, and __customize_counter_example__.
+
+[endsect] [/ is_container]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:transform Transform an Attribute to a Different Type (Qi and Karma)]
+
+[heading transform_attribute]
+
+The template `transform_attribute` is a type used as an attribute customization
+point. It is invoked by /Qi/ `rule` and `attr_cast`, and /Karma/ `rule` and
+[karma_attr_cast `attr_cast`]. It is used to automatically transform the user
+provided attribute to the attribute type expected by the right hand side
+component (for `rule`) or the embedded component (for `attr_cast`).
+
+[heading Module Headers]
+
+    #include <boost/spirit/home/support/attributes.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::traits`]]
+]
+
+[heading Synopsis]
+
+    template <typename Exposed, typename Transformed, typename Enable>
+    struct transform_attribute
+    {
+        typedef <unspecified> type;
+        static type pre(Exposed& val);
+        static void post(Exposed& val, type attr);    // Qi only
+    };
+
+[heading Template parameters]
+
+[table
+    [[Parameter]            [Description]               [Default]]
+    [[`Exposed`]            [The attribute type supplied to the component
+                             which needs to be transformed.]    [none]]
+    [[`Transformed`]        [The attribute type expected by the component
+ to be provided as the result of the transformation.] [none]] + [[`Enable`] [Helper template parameter usable to selectively
+                             enable or disable certain specializations
+ of `transform_attribute` utilizing SFINAE (i.e. + `boost::enable_if` or `boost::disable_if`).] [`void`]]
+]
+
+[heading Notation]
+
+[variablelist Notation
+ [[`Exposed`] [The type, `Exposed` is the type of the attribute as
+                           passed in by the user.]]
+ [[`Transformed`] [The type, `Transformed` is the type of the attribute + as passed along to the right hand side of the `rule`
+                           (embedded component of `attr_cast`).]]
+    [[`exposed`]          [An instance of type `Exposed`.]]
+    [[`transformed`]      [An instance of type `Transformed`.]]
+]
+
+[heading Expression Semantics]
+
+[table
+    [[Expression]       [Semantics]]
+    [[`transform_attribute<Exposed, Transformed>::type`]
+ [Evaluates to the type to be used as the result of the + transformation (to be passed to the right hand side of
+                         the `rule` or to the embedded component of the
+                         `attr_cast`. Most of the time this is equal to
+ `Transformed`, but in other cases this might evaluate to
+                         `Transformed&` instead avoiding superfluous object
+                         creation.]]
+    [[
+``type transform_attribute<Exposed, Transformed>::pre(exposed)``]
+ [Do `pre`-transformation before invoking the right hand + side component for `rule` (or the embedded component + for `attr_cast`). This takes the attribute supplied as by + the user (of type `Exposed`) and returns the attribute + to be passed down the component hierarchy (of the type + as exposed by the metafunction `type`). This function
+                         will be called in /Qi/ and for /Karma/.]]
+    [[
+``void transform_attribute<Exposed, Transformed>::post(exposed, transformed)``] + [Do `post`-transformation after the invocation of the + right hand side component for `rule` (or the embedded + component for `attr_cast`). This takes the original + attribute as supplied by the user and the attribute
+                         as returned from the right hand side (embedded)
+ component and is expected to propagate the result back + into the supplied attribute instance. This function
+                         will be called in /Qi/ only.]]
+]
+
+[heading Predefined Specializations]
+
+[table
+    [[Template parameters]        [Semantics]]
+    [[`Exposed`, `Transformed`]   [`type` evaluates to `Transformed`,
+ `pre()` returns a new instance of `Transformed` + constructed from the argument of type `Exposed`, + `post()` assigns `transformed` to `exposed`.]]
+    [[`Exposed&`, `Transformed`]  [`type` evaluates to `Transformed`,
+ `pre()` returns a new instance of `Transformed` + constructed from the argument of type `Exposed`, + `post()` assigns `transformed` to `exposed`.]]
+    [[`Attrib&`, `Attrib`]        [`type` evaluates to `Attrib&`,
+ `pre()` returns it's argument, `post()` does
+                                   nothing.]]
+ [[`Exposed const`, `Transformed`] [(usind in /Karma/ only) `type` evaluates to + `Transformed`, `pre()` returns it's argument,
+                                   `post()` is not implemented.]]
+ [[`Attrib const&`, `Attrib`] [(usind in /Karma/ only) `type` evaluates to `Attrib const&`, + `pre()` returns it's argument, `post()` is not
+                                   implemented.]]
+ [[`Attrib const`, `Attrib`] [(usind in /Karma/ only) `type` evaluates to `Attrib const&`, + `pre()` returns it's argument, `post()` is not
+                                   implemented.]]
+ [[__unused_type__, `Attrib`] [`type` evaluates to __unused_type__, `pre()`
+                                   and `post()` do nothing.]]
+ [[`Attrib`, __unused_type__] [`type` evaluates to __unused_type__, `pre()`
+                                   and `post()` do nothing.]]
+]
+
+[heading When to implement]
+
+The customization point `transform_attribute` needs to be implemented for a
+specific pair of types whenever the attribute type supplied to a `rule` or
+`attr_cast` cannot automatically transformed to the attribute type expected by
+the right hand side of the `rule` (embedded component of the `attr_cast`)
+because the default implementation as shown above is not applicable. Examples
+for this could be that the type `Transformed` is not constructible from
+the type `Exposed`.
+
+[heading Example]
+
+TBD
+
+[endsect] [/ transform]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[/ section:optional Handling of Optional Attributes (Qi and Karma)]
+
+[/ optional_attribute]
+
+[/ endsect] [/ optional]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:assign_to Store a Parsed Attribute Value (Qi)]
+
+After parsing input and generting an attribute value this value needs to
+assigned to the attribute instance provided by the user. The customization
+points `assign_to_attribute_from_iterators` and `assign_to_attribute_from_value`
+are utilized to adapt this assignment to the concrete type to be assigned.
+This section describes both.
+
+[section:assign_to_attribute_from_iterators Store an Attribute after a Parser Produced a Pair of Iterators (Qi)]
+
+[heading assign_to_attribute_from_iterators]
+
+The template `assign_to_attribute_from_iterators` is a type used as an attribute +customization point. It is invoked by the those /Qi/ parsers not producing any +attribute value but returning a pair of iterators pointing to the matched input
+sequence. It is used to either store the iterator pair into the attribute
+instance provided by the user or to convert the iterator pair into an attribute
+as provided by the user.
+
+[heading Module Headers]
+
+    #include <boost/spirit/home/qi/detail/assign_to.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::traits`]]
+]
+
+[heading Synopsis]
+
+    template <typename Attrib, typename Iterator, typename Enable>
+    struct assign_to_attribute_from_iterators
+    {
+ static void call(Iterator const& first, Iterator const& last, Attrib& attr);
+    };
+
+[heading Template parameters]
+
+[table
+    [[Parameter]            [Description]               [Default]]
+ [[`Attrib`] [The type, `Attrib` is the type of the attribute as + passed in by the user.] [none]] + [[`Iterator`] [The type, `Iterator` is the type of the iterators + as produced by the parser.] [none]] + [[`Enable`] [Helper template parameter usable to selectively
+                             enable or disable certain specializations
+ of `assign_to_attribute_from_value` utilizing SFINAE (i.e. + `boost::enable_if` or `boost::disable_if`).] [`void`]]
+]
+
+[heading Notation]
+
+[variablelist Notation
+ [[`Attrib`] [A type to be used as the target to store the attribute value in.]]
+    [[`attr`]       [A attribute instance of type `Attrib`.]]
+ [[`Iterator`] [The iterator type used by the parser. This type usually + corresponds to the iterators as passed in by the user.]] + [[`begin`, `end`] [Iterator instances of type `Iterator` pointing to the
+                     begin and the end of the matched input sequence.]]
+]
+
+[heading Expression Semantics]
+
+[table
+    [[Expression]       [Semantics]]
+    [[
+``assign_to_attribute_from_iterators<Attrib, Iterator>::call(b, e, attr)``]
+                        [Use the iterators `begin` and `end` to initialize
+                         the attribute `attr`.]]
+]
+
+[heading Predefined Specializations]
+
+[table
+    [[Template Parameters]    [Semantics]]
+ [[`Attrib`, `Iterator`] [Execute an assignment `attr = Attrib(begin, end)`.]]
+    [[__unused_type__, `T`]   [Do nothing.]]
+]
+
+[heading When to implement]
+
+The customization point `assign_to_attribute_from_iterators` needs to be
+implemented for a specific type whenever the default implementation as shown +above is not applicable. Examples for this could be that the type `Attrib` is
+not constructible from the pair of iterators.
+
+[heading Example]
+
+TBD
+
+[endsect] [/ assign_to_attribute_from_iterators]
+
+[section:assign_to_attribute_from_value Store an Attribute Value after a Parser Produced a Value (Qi)]
+
+[heading assign_to_attribute_from_value]
+
+The template `assign_to_attribute_from_value` is a type used as an attribute +customization point. It is invoked by the all primitive /Qi/ parsers in order +to store a parsed attribute value into the attribute instance provided by the
+user.
+
+[heading Module Headers]
+
+    #include <boost/spirit/home/qi/detail/assign_to.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::traits`]]
+]
+
+[heading Synopsis]
+
+    template <typename Attrib, typename T, typename Enable>
+    struct assign_to_attribute_from_value
+    {
+        static void call(T const& val, Attrib& attr);
+    };
+
+[heading Template parameters]
+
+[table
+    [[Parameter]            [Description]               [Default]]
+ [[`Attrib`] [The type, `Attrib` is the type of the attribute as + passed in by the user.] [none]] + [[`T`] [The type, `T` is the type of the attribute instance + as produced by the parser.] [none]] + [[`Enable`] [Helper template parameter usable to selectively
+                             enable or disable certain specializations
+ of `assign_to_attribute_from_value` utilizing SFINAE (i.e. + `boost::enable_if` or `boost::disable_if`).] [`void`]]
+]
+
+[heading Notation]
+
+[variablelist Notation
+ [[`Attrib`] [A type to be used as the target to store the attribute value in.]]
+    [[`attr`]       [A attribute instance of type `Attrib`.]]
+ [[`T`] [A type as produced by the parser. The parser temporarily stores
+                     its parsed values using this type.]]
+    [[`t`]          [A attribute instance of type `T`.]]
+]
+
+[heading Expression Semantics]
+
+[table
+    [[Expression]       [Semantics]]
+    [[
+``assign_to_attribute_from_value<Attrib, T>::call(t, attr)``]
+ [Copy (assign) the value, `t` to the attribute `attr`.]]
+]
+
+[heading Predefined Specializations]
+
+[table
+    [[Template Parameters]    [Semantics]]
+    [[`Attrib`, `T`]          [Assign the argument `t` to `attr`.]]
+    [[__unused_type__, `T`]   [Do nothing.]]
+]
+
+[heading When to implement]
+
+The customization point `assign_to_attribute_from_value` needs to be
+implemented for a specific type whenever the default implementation as shown +above is not applicable. Examples for this could be that the type `Attrib` is
+not copy constructible.
+
+[heading Example]
+
+TBD
+
+[endsect] [/ assign_to_attribute_from_value]
+
+[endsect] [/ assign_to]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:store_value Store Parsed Attribute Values into a Container (Qi)]
+
+In order to customize Spirit to accept a given data type as a container for
+elements parsed by any of the repetitive parsers (__qi_kleene__, __qi_plus__, +__qi_list__, and [qi_repeat Repeat]) two attribute customization points have to be +specialized: __customize_container_value__ and __customize_push_back_container__.
+This section describes both.
+
+[section:container_value Determine the Type to be Stored in a Container (Qi)]
+
+[heading container_value]
+
+The template `container_value` is a template meta function used as an attribute
+customization point. It is invoked by the /Qi/ repetitive parsers
+(__qi_kleene__, __qi_plus__, __qi_list__, and [qi_repeat Repeat]) to determine the
+type to store in a container.
+
+[heading Module Headers]
+
+    #include <boost/spirit/home/support/container.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::traits`]]
+]
+
+[heading Synopsis]
+
+    template <typename Container, typename Enable>
+    struct container_value
+    {
+        typedef <unspecified> type;
+    };
+
+[heading Template parameters]
+
+[table
+    [[Parameter]            [Description]               [Default]]
+    [[`Container`]          [The type `Container` is the type for which the
+ type f the elements has to be deduced.] [none]] + [[`Enable`] [Helper template parameter usable to selectively
+                             enable or disable certain specializations
+                             of `container_value` utilizing SFINAE (i.e.
+ `boost::enable_if` or `boost::disable_if`).] [`void`]]
+]
+
+[heading Notation]
+
+[variablelist
+    [[`C`]          [A type to be tested whether it needs to be treated
+                     as a container.]]
+    [[`T1`, `T2`, ...]  [Arbitrary types]]
+]
+
+[heading Expression Semantics]
+
+[table
+    [[Expression]                 [Semantics]]
+    [[`container_value<C>::type`] [Metafunction that evaluates to the type
+                                   to be stored in a given container type,
+                                   `C`.]]
+]
+
+[heading Predefined Specializations]
+
+__spirit__ predefines specializations of this customization point for
+several types. The following table lists those types together with the types
+exposed and the corresponding semantics:
+
+[table
+    [[Template Parameters]     [Value]]
+ [[`C`] [The non-const `value_type` of the given container
+                               type, `C`. ]]
+    [[`boost::optional<C>`]   [Returns `container_value<C>::type`]]
+    [[`boost::variant<T1, T2, ...>`]
+                              [Returns `container_value<TN>::value` for the
+ first `TN` (out of `T1`, `T2`, ...) for which + `is_container<TN>::type` evaluates to `mpl::true_`.
+                               Otherwise it will return __unused_type__.]]
+    [[__unused_type__]        [Returns __unused_type__.]]
+]
+
+[heading When to implement]
+
+The customization point `is_container` needs to be implemented for a specific
+type whenever this type is to be used as an attribute in place of a STL
+container. It is applicable for parsers (__qi__) only. As a rule of thumb: it +has to be implemented whenever a certain type is to be passed as an attribute +to a parser normally exposing a STL container and if the type does not expose +the interface of a STL container (i.e. no embedded typedef for `value_type`).
+These components have an attribute propagation rule in the form:
+
+    a: A --> Op(a): vector<A>
+
+where `Op(a)` stands for any meaningful operation on the component `a`.
+
+[heading Related Attribute Customization Points]
+
+If this customization point is implemented, the following other customization
+points might need to be implemented as well.
+
+[table
+    [[Name]                   [When to implement]]
+ [[__customize_push_back_container__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] + [[__customize_clear_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]]
+]
+
+[heading Example]
+
+Here is an example showing the default implementation of the
+__customize_container_value__ customization point provided by the library:
+
+[customization_container_value_default]
+
+This template is instantiated by the library at the appropriate places while +using the supplied container type as the template argument. The embedded `type` +is used as the attribute type while parsing the elements to be store in that
+container.
+
+The following example shows the predefined specialization for __unused_type__:
+
+[customization_container_value_unused]
+
+which defines its embedded `type` to be __unused_type__ as well, this way
+propagating the 'don't care' attribute status to the embedded parser.
+
+More examples: TBD.
+
+[endsect] [/ container_value]
+
+[section:push_back Store a Parsed Attribute Value into a Container (Qi)]
+
+[heading push_back_container]
+
+The template `push_back_container` is a type used as an attribute customization +point. It is invoked by the /Qi/ repetitive parsers (__qi_kleene__, __qi_plus__, +__qi_list__, and [qi_repeat Repeat]) to store a parsed attribute value into a
+container.
+
+[heading Module Headers]
+
+    #include <boost/spirit/home/support/container.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::traits`]]
+]
+
+[heading Synopsis]
+
+    template <typename Container, typename Attrib, typename Enable>
+    struct push_back_container
+    {
+        static bool call(Container& c, Attrib const& val);
+    };
+
+[heading Template parameters]
+
+[table
+    [[Parameter]            [Description]               [Default]]
+    [[`Container`]          [The type, `Container` needs to
+                             be tested whether it has to be treated
+ as a container] [none]] + [[`Attrib`] [The type, `Attrib` is the one returned from the + customization point __customize_container_value__ + and represents the attribute value to be stored in + the container of type `Container`.] [none]] + [[`Enable`] [Helper template parameter usable to selectively
+                             enable or disable certain specializations
+ of `push_back_container` utilizing SFINAE (i.e. + `boost::enable_if` or `boost::disable_if`).] [`void`]]
+]
+
+[heading Notation]
+
+[variablelist
+ [[`C`] [A type to be used as a container to store attribute values in.]]
+    [[`c`]          [A container instance of type `C`.]
+ [[`Attrib`] [A type to be used as a container to store attribute values in.]]
+    [[`attr`]       [A attribute instance of type `Attrib`.]]
+    [[`T1`, `T2`, ...]  [Arbitrary types]]
+]
+
+[heading Expression Semantics]
+
+[table
+    [[Expression]                     [Semantics]]
+    [[
+``push_back_container<C, Attrib>::call(c, attr)``]
+ [Static function that is invoked whenever an + attribute value, `attr` needs to be stored + into the container instance `c`. This function + should return `true` on success and `false` + otherwise. Returning `false` causes the
+                                       corresponding parser to fail.]]
+]
+
+[heading Predefined Specializations]
+
+__spirit__ predefines specializations of this customization point for
+several types. The following table lists those types together with the types
+exposed and the corresponding semantics:
+
+[table
+    [[Template Parameters]     [Value]]
+ [[`C`, `Attrib`] [Store the provided attribute instance `attr` into + the given container `c` using the function call
+                                `c.insert(c.end(), attr)`.]]
+    [[`boost::optional<C>`, `Attrib`]
+ [If the provided instance of `boost::optional<>` is not + initialized, invoke the appropriate initialization + and afterwards apply the customization point + `push_back_container<C, Attrib>`, treating the + instance held by the optional (of type `C`) as
+                                the container to store the attribute in.]]
+    [[`boost::variant<T1, T2, ...>`, `Attrib`]
+ [If the instance of the variant currently holds a + value with a type, `TN`, for which `is_container<TN>::type` + evaluates to `mpl::true_`, this customization
+                                point specialization will apply
+ `push_back_container<TN, Attrib>`, treating the + instance held by the variant (of type `TN`) as + the container to store the attribute in. Otherwise
+                                it will raise an assertion.]]
+    [[__unused_type__]         [Do nothing.]]
+]
+
+[heading When to Implement]
+
+The customization point `push_back_container` needs to be implemented for a
+specific type whenever this type is to be used as an attribute in place of a STL +container. It is applicable for parsers (__qi__) only. As a rule of thumb: it +has to be implemented whenever a certain type is to be passed as an attribute +to a parser normally exposing a STL container and if the type does not expose
+the interface of a STL container (i.e. no function being equivalent to
+`c.insert(c.end(), attr)`. These components have an attribute propagation rule
+in the form:
+
+    a: A --> Op(a): vector<A>
+
+where `Op(a)` stands for any meaningful operation on the component `a`.
+
+[heading Related Attribute Customization Points]
+
+If this customization point is implemented, the following other customization
+points might need to be implemented as well.
+
+[table
+    [[Name]                   [When to implement]]
+ [[__customize_container_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]] + [[__customize_clear_value__] [Qi: __qi_list__, __qi_kleene__, __qi_plus__, [qi_repeat Repeat].]]
+]
+
+[heading Example]
+
+Here is an example showing the default implementation of the
+__customize_container_value__ customization point provided by the library:
+
+[customization_push_back_default]
+
+This template is instantiated by the library at the appropriate places while +using the supplied container and element types as the template arguments. The +member function `call()` will be called whenever an element has to be added to
+the supplied container
+
+The following example shows the predefined specialization for __unused_type__:
+
+[customization_push_back_unused]
+
+which defines an empty member function `call()`.
+
+More examples: TBD
+
+[endsect] [/ push_back]
+
+[endsect] [/ store_value]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:clear_value Re-Initialize an Attribute Value before Parsing (Qi)]
+
+[heading clear_value]
+
+The template `clear_value` is a type used as an attribute customization point.
+It is invoked by the /Qi/ repetitive parsers (__qi_kleene__, __qi_plus__,
+__qi_list__, and [qi_repeat Repeat]) in order to re-initialize the attribute +instance passed to the embedded parser after it has been stored in the provided
+container. This re-initialized attribute instance is reused during the next
+iteration of the repetitive parser.
+
+[heading Module Headers]
+
+    #include <boost/spirit/home/support/attributes.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::traits`]]
+]
+
+[heading Synopsis]
+
+    template <typename Attrib, typename Enable>
+    struct clear_value
+    {
+        static void call(Attrib& val);
+    };
+
+[heading Template parameters]
+
+[table
+    [[Parameter]            [Description]               [Default]]
+    [[`Attrib`]             [The type, `Attrib` of the attribute to be
+                             re-initialized.]                 [none]]
+ [[`Enable`] [Helper template parameter usable to selectively
+                             enable or disable certain specializations
+                             of `clear_value` utilizing SFINAE (i.e.
+ `boost::enable_if` or `boost::disable_if`).] [`void`]]
+]
+
+[heading Notation]
+
+[variablelist Notation
+ [[`Attrib`] [A type to be used as a container to store attribute values in.]]
+    [[`attr`]       [A attribute instance of type `Attrib`.]]
+    [[`T1`, `T2`, ...]  [Arbitrary types]]
+]
+
+[heading Expression Semantics]
+
+[table
+    [[Expression]       [Semantics]]
+    [[
+``clear_value<Attrib>::call(Attrib& attr)``] [Re-initialize the instance referred to by
+                              `attr` in the most efficient way.]]
+]
+
+[heading Predefined Specializations]
+
+__spirit__ predefines specializations of this customization point for
+several types. The following table lists those types together with the types
+exposed and the corresponding semantics:
+
+[table
+    [[Template Parameters]     [Value]]
+    [[`Attrib`]               [Re-initialize using assignment of  default
+                               constructed value.]]
+    [[Any type `T` for which `is_container<>::type` is `mpl::true_`]
+ [Call the member function `attr.clear()` for the
+                               passed attribute instance.]]
+ [[`boost::optional<Attrib>`] [Clear the `optional` instance and leave it
+                               uninitialized.]]
+    [[`boost::variant<T1, T2, ...>`][Invoke the `clear_value` customization
+                               point for the currently held value.]]
+    [[`fusion::tuple<T1, T2, ...>`][Invoke the `clear_value` customization
+                               point for all elements of the tuple.]]
+    [[__unused_type__]        [Do nothing.]]
+]
+
+[heading When to Implement]
+
+The customization point `clear_value` needs to be implemented for a
+specific type whenever this type is to be used as an attribute to be stored
+into a STL container and if the type cannot be re-initialized using one of the +specializations listed above. Examples for this might be types not being default
+constructible or container types not exposing a member function `clear()`.
+
+[heading Example]
+
+TBD
+
+[endsect] [/ clear_value]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section:extract_from Extract an Attribute Value to Generate Output (Karma)]
+
+[heading extract_from]
+
+Before generating output for a value this value needs to extracted from the
+attribute instance provided by the user. The customization point
+`extract_from` is utilized to adapt this extraction for any data type possibly
+used to store the values to output.
+
+[heading Module Headers]
+
+    #include <boost/spirit/home/karma/detail/extract_from.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::traits`]]
+]
+
+[heading Synopsis]
+
+    template <typename Attrib, typename Enable>
+    struct extract_from_attribute
+    {
+        typedef <unspecified> type;
+
+        template <typename Context>
+        static type call(Attrib const& attr, Context& context);
+    };
+
+[heading Template parameters]
+
+[table
+    [[Parameter]            [Description]               [Default]]
+ [[`Attrib`] [The type, `Attrib` of the attribute to be used to
+                             generate output from.]                 [none]]
+ [[`Enable`] [Helper template parameter usable to selectively
+                             enable or disable certain specializations
+                             of `clear_value` utilizing SFINAE (i.e.
+ `boost::enable_if` or `boost::disable_if`).] [`void`]] + [[`Context`] [This is the type of the current generator execution
+                             context.]]
+]
+
+[heading Notation]
***The diff for this file has been truncated for email.***
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/advanced/indepth.qbk Mon Feb  8 19:41:53 2010
@@ -0,0 +1,279 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Joel de Guzman
+    Copyright (C) 2001-2010 Hartmut Kaiser
+    Copyright (C) 2009 Andreas Haberstroh?
+
+ 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)
+===============================================================================/]
+
+[section:indepth In Depth]
+
+[section:parsers_indepth Parsers in Depth]
+
+This section is not for the faint of heart. In here, are distilled the inner
+workings of __qi__ parsers, using real code from the __spirit__ library as
+examples. On the other hand, here is no reason to fear reading on, though.
+We tried to explain things step by step while highlighting the important
+insights.
+
+The `__parser_concept__` class is the base class for all parsers.
+
+[import ../../../../boost/spirit/home/qi/parser.hpp]
+[parser_base_parser]
+
+The `__parser_concept__` class does not really know how to parse anything but +instead relies on the template parameter `Derived` to do the actual parsing. +This technique is known as the "Curiously Recurring Template Pattern" in template
+meta-programming circles. This inheritance strategy gives us the power of
+polymorphism without the virtual function overhead. In essence this is a way to
+implement compile time polymorphism.
+
+The Derived parsers, `__primitive_parser_concept__`, `__unary_parser_concept__`, +`__binary_parser_concept__` and `__nary_parser_concept__` provide the necessary +facilities for parser detection, introspection, transformation and visitation.
+
+Derived parsers must support the following:
+
+[variablelist bool parse(f, l, context, skip, attr)
+  [[`f`, `l`] [first/last iterator pair]]
+  [[`context`]    [enclosing rule context (can be unused_type)]]
+  [[`skip`]   [skipper (can be unused_type)]]
+  [[`attr`]   [attribute (can be unused_type)]]
+]
+
+The /parse/ is the main parser entry point. /skipper/ can be an `unused_type`.
+It's a type used every where in __spirit__ to signify "don't-care". There
+is an overload for /skip/ for `unused_type` that is simply a no-op.
+That way, we do not have to write multiple parse functions for
+phrase and character level parsing.
+
+Here are the basic rules for parsing:
+
+* The parser returns `true` if successful, `false` otherwise.
+* If successful, `first` is incremented N number of times, where N
+   is the number of characters parsed. N can be zero --an empty (epsilon)
+   match.
+* If successful, the parsed attribute is assigned to /attr/
+* If unsuccessful, `first` is reset to its position before entering
+   the parser function. /attr/ is untouched.
+
+[variablelist void what(context)
+  [[`context`]    [enclosing rule context (can be `unused_type`)]]
+]
+
+The /what/ function should be obvious. It provides some information
+about ["what] the parser is. It is used as a debugging aid, for
+example.
+
+[variablelist P::template attribute<context>::type
+  [[`P`]       [a parser type]]
+  [[`context`] [A context type (can be unused_type)]]
+]
+
+The /attribute/ metafunction returns the expected attribute type
+of the parser. In some cases, this is context dependent.
+
+In this section, we will dissect two parser types:
+
+[variablelist Parsers
+ [[`__primitive_parser_concept__`] [A parser for primitive data (e.g. integer parsing).]] + [[`__unary_parser_concept__`] [A parser that has single subject (e.g. kleene star).]]
+]
+
+[/------------------------------------------------------------------------------]
+[heading Primitive Parsers]
+
+For our disection study, we will use a __spirit__ primitive, the `int_parser`
+in the boost::spirit::qi namespace.
+
+[import ../../../../boost/spirit/home/qi/numeric/int.hpp]
+[primitive_parsers_int]
+
+The `int_parser` is derived from a `__primitive_parser_concept__<Derived>`, which +in turn derives from `parser<Derived>`. Therefore, it supports the following
+requirements:
+
+* The `parse` member function
+* The `what` member function
+* The nested `attribute` metafunction
+
+/parse/ is the main entry point. For primitive parsers, our first thing to do is
+call:
+
+``
+qi::skip(first, last, skipper);
+``
+
+to do a pre-skip. After pre-skipping, the parser proceeds to do its thing. The
+actual parsing code is placed in `extract_int<T, Radix, MinDigits,
+MaxDigits>::call(first, last, attr);`
+
+This simple no-frills protocol is one of the reasons why __spirit__ is
+fast. If you know the internals of __classic__ and perhaps
+even wrote some parsers with it, this simple __spirit__ mechanism
+is a joy to work with. There are no scanners and all that crap.
+
+The /what/ function just tells us that it is an integer parser. Simple.
+
+The /attribute/ metafunction returns the T template parameter. We associate the +`int_parser` to some placeholders for `short_`, `int_`, `long_` and `long_long`
+types. But, first, we enable these placeholders in namespace boost::spirit:
+
+[primitive_parsers_enable_short_]
+[primitive_parsers_enable_int_]
+[primitive_parsers_enable_long_]
+[primitive_parsers_enable_long_long_]
+
+Notice that `int_parser` is placed in the namespace boost::spirit::qi
+while these /enablers/ are in namespace boost::spirit. The reason is
+that these placeholders are shared by other __spirit__ /domains/. __qi__,
+the parser is one domain. __karma__, the generator is another domain.
+Other parser technologies may be developed and placed in yet
+another domain. Yet, all these can potentially share the same
+placeholders for interoperability. The interpretation of these
+placeholders is domain-specific.
+
+Now that we enabled the placeholders, we have to write generators
+for them. The make_xxx stuff (in boost::spirit::qi namespace):
+
+[primitive_parsers_make_int]
+
+This one above is our main generator. It's a simple function object
+with 2 (unused) arguments. These arguments are
+
+# The actual terminal value obtained by proto. In this case, either
+  a short_, int_, long_ or long_long. We don't care about this.
+
+# Modifiers. We also don't care about this. This allows directives
+  such as `no_case[p]` to pass information to inner parser nodes.
+  We'll see how that works later.
+
+Now:
+
+[primitive_parsers_short_]
+[primitive_parsers_int_]
+[primitive_parsers_long_]
+[primitive_parsers_long_long_]
+
+These, specialize `qi:make_primitive` for specific tags. They all
+inherit from `make_int` which does the actual work.
+
+[heading Composite Parsers]
+
+Let me present the kleene star (also in namespace spirit::qi):
+
+[import ../../../../boost/spirit/home/qi/operator/kleene.hpp]
+[composite_parsers_kleene]
+
+Looks similar in form to its primitive cousin, the `int_parser`. And, again, it
+has the same basic ingredients required by `Derived`.
+
+* The nested attribute metafunction
+* The parse member function
+* The what member function
+
+kleene is a composite parser. It is a parser that composes another
+parser, its ["subject]. It is a `__unary_parser_concept__` and subclasses from it. +Like `__primitive_parser_concept__`, `__unary_parser_concept__<Derived>` derives
+from `parser<Derived>`.
+
+unary_parser<Derived>, has these expression requirements on Derived:
+
+* p.subject -> subject parser ( ['p] is a __unary_parser_concept__ parser.)
+* P::subject_type -> subject parser type ( ['P] is a __unary_parser_concept__ type.)
+
+/parse/ is the main parser entry point. Since this is not a primitive
+parser, we do not need to call `qi::skip(first, last, skipper)`. The
+['subject], if it is a primitive, will do the pre-skip. If if it is
+another composite parser, it will eventually call a primitive parser
+somewhere down the line which will do the pre-skip. This makes it a
+lot more efficient than __classic__. __classic__ puts the skipping business
+into the so-called "scanner" which blindly attempts a pre-skip
+everytime we increment the iterator.
+
+What is the /attribute/ of the kleene? In general, it is a `std::vector<T>`
+where `T` is the attribute of the subject. There is a special case though.
+If `T` is an `unused_type`, then the attribute of kleene is also `unused_type`.
+`traits::build_std_vector` takes care of that minor detail.
+
+So, let's parse. First, we need to provide a local attribute of for
+the subject:
+
+``
+typename traits::attribute_of<Subject, Context>::type val;
+``
+
+`traits::attribute_of<Subject, Context>` simply calls the subject's
+`struct attribute<Context>` nested metafunction.
+
+/val/ starts out default initialized. This val is the one we'll
+pass to the subject's parse function.
+
+The kleene repeats indefinitely while the subject parser is
+successful. On each successful parse, we `push_back` the parsed
+attribute to the kleen's attribute, which is expected to be,
+at the very least, compatible with a `std::vector`. In other words,
+although we say that we want our attribute to be a `std::vector`,
+we try to be more lenient than that. The caller of kleene's
+parse may pass a different attribute type. For as long as it is
+also a conforming STL container with `push_back`, we are ok. Here
+is the kleene loop:
+
+``
+while (subject.parse(first, last, context, skipper, val))
+{
+    // push the parsed value into our attribute
+    traits::push_back(attr, val);
+    traits::clear(val);
+}
+return true;
+``
+Take note that we didn't call attr.push_back(val). Instead, we
+called a Spirit provided function:
+
+``
+traits::push_back(attr, val);
+``
+
+This is a recurring pattern. The reason why we do it this way is
+because attr [*can] be `unused_type`. `traits::push_back` takes care
+of that detail. The overload for unused_type is a no-op. Now, you
+can imagine why __spirit__ is fast! The parsers are so simple and the
+generated code is as efficient as a hand rolled loop. All these
+parser compositions and recursive parse invocations are extensively
+inlined by a modern C++ compiler. In the end, you get a tight loop
+when you use the kleene. No more excess baggage. If the attribute
+is unused, then there is no code generated for that. That's how
+__spirit__ is designed.
+
+The /what/ function simply wraps the output of the subject in a
+"kleene[" ... "]".
+
+Ok, now, like the `int_parser`, we have to hook our parser to the
+_qi_ engine. Here's how we do it:
+
+First, we enable the prefix star operator. In proto, it's called
+the "dereference":
+
+[composite_parsers_kleene_enable_]
+
+This is done in namespace `boost::spirit` like its friend, the `use_terminal`
+specialization for our `int_parser`. Obviously, we use /use_operator/ to
+enable the dereference for the qi::domain.
+
+Then, we need to write our generator (in namespace qi):
+
+[composite_parsers_kleene_generator]
+
+This essentially says; for all expressions of the form: `*p`, to build a kleene
+parser. Elements is a __fusion__ sequence. For the kleene, which is a unary
+operator, expect only one element in the sequence. That element is the subject
+of the kleene.
+
+We still don't care about the Modifiers. We'll see how the modifiers is
+all about when we get to deep directives.
+
+[endsect]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/advanced.qbk Mon Feb  8 19:41:53 2010
@@ -0,0 +1,14 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Joel de Guzman
+    Copyright (C) 2001-2010 Hartmut Kaiser
+
+ 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)
+===============================================================================/]
+
+[section Advanced]
+
+[include        advanced/indepth.qbk]
+[include        advanced/customization_points.qbk]
+
+[endsect]
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/concepts_template.qbk        Mon Feb  8 19:41:53 2010
@@ -0,0 +1,59 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Hartmut Kaiser
+    Copyright (C) 2001-2010 Joel de Guzman
+
+ 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)
+===============================================================================/]
+
+[/------------------------------------------------------------------------------]
+[section XXX]
+
+[heading Description]
+
+Description of XXX concept
+
+[heading Refinement of]
+
+[:Link to base concept]
+
+[variablelist Notation
+    [[`xxx`]     [An XXX]]
+]
+
+[heading Valid Expressions]
+
+(For any XXX the following expressions must be valid:)
+
+In addition to the requirements defined in _XXX-Basic_concept_, for any
+XXX the following must be met:
+
+[table
+    [[Expression]       [Semantics]             [Return type]]
+    [[`xxx`]            [Semantics of `xxx`]    [XXX]]
+]
+
+[heading Type Expressions]
+
+[table
+    [[Expression]       [Description]]
+    [[`XXX`]            [Description of `XXX`]]
+]
+
+[heading Invariants]
+
+For any XXX xxx the following invariants always hold:
+
+[heading Precondition]
+
+Prior to calling FOO the following preconditions should hold:
+
+[heading Precondition]
+
+Upon return from FOO the following postconditions should hold:
+
+[heading Models]
+
+Links to models of XXX concept
+
+[endsect] [/ XXX Concept]
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/customization_point_template.qbk Mon Feb 8 19:41:53 2010
@@ -0,0 +1,87 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Hartmut Kaiser
+    Copyright (C) 2001-2010 Joel de Guzman
+
+ 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)
+===============================================================================/]
+
+[/////////////////////////////////////////////////////////////////////////////]
+[section XXX]
+
+[heading Customization Point]
+
+Short description here...
+
+[heading Module Headers]
+
+    #include <boost/spirit/xxx.hpp>
+
+Also, see __include_structure__.
+
+[note This header file does not need to be included directly by any user
+ program as it is normally included by other Spirit header files relying
+      on its content.]
+
+[heading Namespace]
+
+[table
+    [[Name]]
+    [[`boost::spirit::xxx`]]
+]
+
+[heading Synopsis]
+
+    template <typename T>
+    struct XXX;
+
+[heading Template parameters]
+
+[table
+    [[Parameter]            [Description]               [Default]]
+    [[`T`]                  [What is T]                 []]
+]
+
+[heading Notation]
+
+[variablelist Notation
+    [[`xxx`]     [An XXX]]
+]
+
+[heading Expression Semantics]
+
+Semantics of an expression is defined only where it differs from, or is not
+defined in _concept-of_XXX_.
+
+[table
+    [[Expression]       [Semantics]]
+    [[`xxx`]            [Semantics of `xxx`]]
+]
+
+[heading Predefined Specializations]
+
+[table
+    [[Type]                   [Condition]]
+    [[`xxx`]                  [when does it evaluate to mpl::true_]]
+]
+
+[heading When to implement]
+
+Describe when this customization point needs to be implemented by the user.
+
+[heading Related Attribute Customization Points]
+
+If this customization point is implemented, the following other customization
+points need to be implemented as well.
+
+[table
+    [[Name]                   [When to implement]]
+]
+
+[heading Example]
+
+Real example code. Use Quickbook import mechanism to link to actual
+working code snippets here.
+
+[endsect] [/ XXX]
+
=======================================
--- /dev/null
+++ /trunk/libs/spirit/doc/faq.qbk      Mon Feb  8 19:41:53 2010
@@ -0,0 +1,171 @@
+[/==============================================================================
+    Copyright (C) 2001-2010 Joel de Guzman
+    Copyright (C) 2001-2010 Hartmut Kaiser
+
+ 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)
+===============================================================================/]
+
+[section:faq Spirit FAQ]
+
+[heading I'm getting multiple symbol definition errors while using Visual C++. Anything I could do about that?]
+
+Do you see strange multiple symbol definition linker errors mentioning
+`boost::mpl::failed` and `boost::spirit::qi::rule`? Then this FAQ entry might
+be for you.
+
+__mpl__ implements a macro `BOOST_MPL_ASSERT_MSG()` which essentially is a
+more powerfull version of static_assert. Unfortunately under certain
+circumstances using this macro may lead to the aformentioned linker errors.
+
+__spirit__ allows you to define a preprocessor constant disabling the usage
+of `BOOST_MPL_ASSERT_MSG()`, while switching to `BOOST_STATIC_ASSERT()` instead.
+For that you need define BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG=1. Do this by
+adding
+
+    -DBOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG=1
+
+on the compiler command line or by inserting a
+
+    #define BOOST_SPIRIT_DONT_USE_MPL_ASSERT_MSG 1
+
+into your code before any Spirit headers get included.
+
+Using this trick has no adverse effects on any of the functionality of
+__spirit__. The only change you might see while using this workaround is less
+verbose error messages generated from static_assert.
+
+
+[heading I'm very confused about the header hell in my boost/spirit directory. What's all this about?]
+
+The boost/spirit directory currently holds two versions of the Spirit library:
+__classic__ (former V1.8.x) and SpiritV2. Both are completely independent
+and usually not used at the same time. Do not mix these two in the same grammar.
+
+__classic__ evolved over years in a fairly complex directory structure:
+
+    boost/spirit/actor
+    boost/spirit/attribute
+    boost/spirit/core
+    boost/spirit/debug
+    boost/spirit/dynamic
+    boost/spirit/error_handling
+    boost/spirit/iterator
+    boost/spirit/meta
+    boost/spirit/symbols
+    boost/spirit/tree
+    boost/spirit/utility
+
+While introducing Spirit V2 we restructured the directory structure in order to
+accommodate two versions at the same time. All of __classic__ now lives in
+the directory
+
+    boost/spirit/home/classic
+
+where the directories above contain forwarding headers to the new location
+allowing to maintain application compatibility. The forwarding headers issue a +warning (starting with Boost V1.38) telling the user to change their include +paths. Please expect the above directories/forwarding headers to go away soon.
+
+This explains the need for the directory
+
+    boost/spirit/include
+
+which contains forwarding headers as well. But this time the headers won't go +away. We encourage application writers to use only the includes contained in
+this directory. This allows us to restructure the directories underneath if
+needed without worrying application compatibility. Please use those files in +your application only. If it turns out that some forwarding file is missing,
+please report this as a bug.
+
+Spirit V2 is not about parsing only anymore (as __classic__). It now consists
+out of 3 parts (sub-libraries): __qi__, __karma__, and __lex__. The header
+files for those live in
+
+    boost/spirit/home/qi
+    boost/spirit/home/karma
+    boost/spirit/home/lex
+
+and have forwarding headers in
+
+    boost/spirit/include
+
+__qi__ is the direct successor to __classic__ as it implements a DSEL (domain +specific embedded language) allowing to write parsers using the syntax of C++ +itself (parsers in the sense turning a sequence of bytes into an internal data
+structure). It is not compatible with __classic__, the main concepts are
+similar, though.
+
+__karma__ is the counterpart to __qi__. It implements a similar DSEL but for
+writing generators (i.e. the things turning internal data structures into a
+sequence of bytes, most of the time - strings). __karma__ is the Yang to
+__qi__'s Yin, it's almost like a mirrored picture.
+
+__lex__ is (as the name implies) a library allowing to write lexical analyzers.
+These are either usable standalone or can be used as a frontend for __qi__
+parsers. If you know flex you shouldn't have problems understanding __lex__.
+This library actually doesn't implement the lexer itself. All it does is to
+provide an interface to pre-existing lexical analyzers. Currently it's using +Ben Hansons excellent __lexertl__ library (proposed for a Boost review, BTW) as
+its underlying workhorse.
+
+Again, don't use any of the header files underneath the boost/spirit/home
+directory directly, always include files from the boost/spirit/include
+directory.
+
+The last bit missing is __boost_phoenix__ (which currently still lives under the +Spirit umbrella, but already has been accepted as a Boost library, so it will +move away). __boost_phoenix__ is a library allowing to write functional style C++,
+which is interesting in itself, but as it initially has been developed for
+Spirit, it is nicely integrated and very useful when it comes to writing
+semantic actions. I think using the boost/spirit/include/phoenix_... headers
+will be safe in the future as well, as we will probably redirect to the
+Boost.Phoenix headers as soon as these are available.
+
+
+[heading Why doesn't my symbol table work in a `no_case` directive?]
+
+In order to perform case-insensitive parsing (using __qi_no_case__) with a
+symbol table (i.e. use a __qi_symbols__
+parser in a `no_case` directive), that symbol table needs to be filled with
+all-lowercase contents. Entries containing one or more uppercase characters
+will not match any input.
+
+
+[heading I'm getting a compilation error mentioning `boost::function` and/or
+         `boost::function4`. What does this mean?]
+
+If you are using Visual C++ and have an error like:
+
+[pre
+error C2664: \'bool boost::function4<R,T0,T1,T2,T3>::operator ()(T0,T1,T2,T3) const\' :
+    cannot convert parameter 4 from '...' to '...'
+]
+
+or you are using GCC and have an error like:
+
+[pre
+error: no match for call to '(const boost::function<bool ()(...)>) (...)'
+note: candidates are: ... boost::function4<R,T1,T2,T3,T4>::operator()(T0,T1,T2,T3) const [with ...\]
+]
+
+then this FAQ entry may help you.
+
+The definition of a __rule__ or __grammar__ may contain a skip parser type. If +it does, it means that non-terminal can only be used with a skip parser of a
+compatible type. The error above arises when this is not the case, i.e.:
+
+* a non-terminal defined with a skip parser type is used without a skip parser;
+  for example, a rule with a skip parser type is used inside a `lexeme`
+ directive, or a grammar with a skip parser type is used in `parse` instead of
+  `phrase_parse`,
+* or a non-terminal is used with a skip parser of an incompatible type;
+  for example, a rule defined with one skip parser type calls a second rule
+  defined with another, incompatible skip parser type.
+
+[note The same applies to __karma__, replacing 'skip parser' and `lexeme`
+ by 'delimit generator' and `verbatim`. Similarily, corresponding error
+      messages in __karma__ reference `boost::function3` and the 3rd
+      parameter (instead of the 4th).]
+
+[endsect]
=======================================
***Additional files exist in this changeset.***

Other related posts:

  • » [boost-doc-zh] r380 committed - 升级至1.42.0,第六批,libs/目录下s子目录 - boost-doc-zh