Boost logo

Boost-Commit :

From: eric_at_[hidden]
Date: 2008-05-02 13:44:57


Author: eric_niebler
Date: 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
New Revision: 45029
URL: http://svn.boost.org/trac/boost/changeset/45029

Log:
Merged revisions 44724,44726-44730,44738,44741-44742,44744,44746-44750,44752-44753,44755-44756,44758,44764,44766-44768,44771-44775,44777,44781-44787,44789-44807,44812-44816,44818-44826,44831,44837-44840,44842-44853,44857,44862,44864,44873,44877,44881-44883,44886-44887,44889,44891,44893,44895,44897,44900-44902,44904-44907,44919,44934,44941-44942,44946,44949-44954,44957,44962,44968-44973,44975,44977,44979-44984,44991-44993,44995,44997-45002,45004-45006,45010-45011,45019,45023,45025-45027 via svnmerge from
https://svn.boost.org/svn/boost/trunk

................
  r44724 | daniel_frey | 2008-04-22 12:48:39 -0700 (Tue, 22 Apr 2008) | 1 line
  
  Reduce enable_shared_from_this overhead
................
  r44726 | emildotchevski | 2008-04-22 15:23:27 -0700 (Tue, 22 Apr 2008) | 1 line
  
  seems like <link>static causes errors
................
  r44727 | chris_kohlhoff | 2008-04-22 16:46:15 -0700 (Tue, 22 Apr 2008) | 2 lines
  
  Fix or suppress MSVC level 4 warnings. Fixes #1703.
................
  r44728 | pdimov | 2008-04-22 17:33:58 -0700 (Tue, 22 Apr 2008) | 1 line
  
  Silence an g++ -Wextra warning.
................
  r44729 | noel_belcourt | 2008-04-22 18:35:01 -0700 (Tue, 22 Apr 2008) | 11 lines
  
  Fixed intel-darwin unresolved symbols by changing the
  wide integer type from unsigned int (which managles as
  a 'j') to an int (which mangles as an 'i'). This
  change makes intel-darwin generated code match the
  darwin toolset generated code.
  
  Intel reports this won't be fixed in 10.1 because it's
  an ABI breanking chanage so we won't see this patched
  until the 10.2 compilers.
................
  r44730 | daniel_frey | 2008-04-22 23:12:39 -0700 (Tue, 22 Apr 2008) | 1 line
  
  Reduce enable_shared_from_this overhead (replace _internal_shared_ptr by _internal_shared_count)
................
  r44738 | danieljames | 2008-04-23 00:09:58 -0700 (Wed, 23 Apr 2008) | 85 lines
  
  Merge support for emplace for compilers with rvalue references and variadic templates arguments, and better use of C++0x allocators.
  Merged revisions 44058-44075,44078-44084,44086-44108,44110-44365,44367,44369-44414,44416-44419,44421-44457,44467-44469,44471-44511,44513-44535,44537-44737 via svnmerge from
  https://svn.boost.org/svn/boost/branches/unordered/trunk
  
  ................
    r44467 | danieljames | 2008-04-16 18:35:56 +0100 (Wed, 16 Apr 2008) | 2 lines
    
    Add C++-0x support to the test allocators.
  ................
    r44468 | danieljames | 2008-04-16 18:36:06 +0100 (Wed, 16 Apr 2008) | 2 lines
    
    Add a C++-0x node_constructor.
  ................
    r44469 | danieljames | 2008-04-16 18:36:16 +0100 (Wed, 16 Apr 2008) | 2 lines
    
    C++-0x constructor for node.
  ................
    r44516 | danieljames | 2008-04-17 21:41:48 +0100 (Thu, 17 Apr 2008) | 16 lines
    
    Merge in my work so far on implementing emplace for compilers with variadic
    template & rvalue references.
    
    Merged revisions 44059-44062 via svnmerge from
    https://svn.boost.org/svn/boost/branches/unordered/dev
    
    ........
      r44059 | danieljames | 2008-04-05 17:41:25 +0100 (Sat, 05 Apr 2008) | 1 line
      
      First stab at implementing emplace - only for compilers with variadic template & rvalue references.
    ........
      r44062 | danieljames | 2008-04-05 19:12:09 +0100 (Sat, 05 Apr 2008) | 1 line
      
      Better variable template arguments, need to add proper support to BoostBook.
    ........
  ................
    r44616 | danieljames | 2008-04-20 13:30:19 +0100 (Sun, 20 Apr 2008) | 1 line
    
    Merge with trunk, fixes tabs.
  ................
    r44618 | danieljames | 2008-04-20 13:42:38 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Some extra compile tests.
  ................
    r44619 | danieljames | 2008-04-20 13:42:50 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix an error message.
  ................
    r44703 | danieljames | 2008-04-21 20:19:50 +0100 (Mon, 21 Apr 2008) | 15 lines
    
    Merge latest changes from trunk.
    
    Merged revisions 44616-44702 via svnmerge from
    https://svn.boost.org/svn/boost/trunk
    
    ........
      r44650 | danieljames | 2008-04-20 22:08:57 +0100 (Sun, 20 Apr 2008) | 1 line
      
      Update an include.
    ........
      r44697 | danieljames | 2008-04-21 16:55:40 +0100 (Mon, 21 Apr 2008) | 1 line
      
      Factor out the code for choosing the bucket count, and which bucket that hash values map to make it easier to experiment with alternative policies.
    ........
  ................
    r44733 | danieljames | 2008-04-23 07:55:43 +0100 (Wed, 23 Apr 2008) | 2 lines
    
    Remove 'reserve_extra'.
  ................
    r44734 | danieljames | 2008-04-23 07:55:55 +0100 (Wed, 23 Apr 2008) | 2 lines
    
    More unnecessary copy tests - showing some weakness in the emplace implementation.
  ................
    r44735 | danieljames | 2008-04-23 07:56:06 +0100 (Wed, 23 Apr 2008) | 2 lines
    
    More tests.
  ................
    r44736 | danieljames | 2008-04-23 07:56:19 +0100 (Wed, 23 Apr 2008) | 2 lines
    
    Comment out a test which requires a C++0x std::pair.
  ................
    r44737 | danieljames | 2008-04-23 07:56:35 +0100 (Wed, 23 Apr 2008) | 2 lines
    
    Avoid creating unnecessary copies in unordered_set::emplace and unordered_map::emplace.
  ................
................
  r44741 | noel_belcourt | 2008-04-23 09:16:38 -0700 (Wed, 23 Apr 2008) | 4 lines
  
  Patch PGI to fix config problem (clock_gettime is unresolved
  external) and add required macro define for IOV_MAX support.
................
  r44742 | emildotchevski | 2008-04-23 10:31:56 -0700 (Wed, 23 Apr 2008) | 1 line
  
  Fix for http://tinyurl.com/6owy6b.
................
  r44744 | daniel_frey | 2008-04-23 12:32:44 -0700 (Wed, 23 Apr 2008) | 1 line
  
  Remove dynamic_cast in init_internal_shared_once()
................
  r44746 | noel_belcourt | 2008-04-23 18:40:31 -0700 (Wed, 23 Apr 2008) | 4 lines
  
  Fixup patch to intel-darwin.jam so it looks and
  reads a bit better.
................
  r44747 | noel_belcourt | 2008-04-23 21:58:27 -0700 (Wed, 23 Apr 2008) | 3 lines
  
  Force pgi to always link rt lib, ugh.
................
  r44748 | johnmaddock | 2008-04-24 02:40:31 -0700 (Thu, 24 Apr 2008) | 3 lines
  
  Apply VC-7.1 fixes: sometimes ADL fails, and we need a using declaration in order for the correct overload to be found.
  Add missing #include. to t_distribution_inv.hpp.
  Suppress unnecessary instantiations in instantiate_all.cpp.
................
  r44749 | hkaiser | 2008-04-24 06:52:22 -0700 (Thu, 24 Apr 2008) | 1 line
  
  Phoenix: disambiguated ref() (gcc 4.3 complained...)
................
  r44750 | hkaiser | 2008-04-24 06:54:05 -0700 (Thu, 24 Apr 2008) | 1 line
  
  Spirit.Qi: helping gcc 4.3 to understand what's going on.
................
  r44752 | bemandawes | 2008-04-24 13:29:08 -0700 (Thu, 24 Apr 2008) | 1 line
  
  Fix #1858, typo in non-member operators table
................
  r44753 | grafik | 2008-04-24 13:30:03 -0700 (Thu, 24 Apr 2008) | 1 line
  
  Make it possible to filter which libraries are tested from the CLI with "--filter-tests=" options.
................
  r44755 | djowel | 2008-04-24 15:13:32 -0700 (Thu, 24 Apr 2008) | 1 line
  
  added nullary function support
................
  r44756 | djowel | 2008-04-24 15:13:58 -0700 (Thu, 24 Apr 2008) | 1 line
  
  use plain functions instead of bind
................
  r44758 | noel_belcourt | 2008-04-24 16:05:16 -0700 (Thu, 24 Apr 2008) | 4 lines
  
  Added no two phase name lookup for intel-darwin
  compilers.
................
  r44764 | noel_belcourt | 2008-04-25 08:38:26 -0700 (Fri, 25 Apr 2008) | 4 lines
  
  Enable macros BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE and
  BOOST_HAS_NANOSLEEP.
................
  r44766 | niels_dekker | 2008-04-25 09:50:32 -0700 (Fri, 25 Apr 2008) | 1 line
  
  Improved swap for optional<T>, co-written by Thorsten and Fernando: added support for tweaking whether swap should use T's default constructor. Added swap member function. Discussed at Boost developers' mailing list, "[optional] problems with swap()", http://lists.boost.org/Archives/boost/2008/04/135882.php
................
  r44767 | niels_dekker | 2008-04-25 09:52:34 -0700 (Fri, 25 Apr 2008) | 1 line
  
  Added unit tests, testing optional<T> swap improvements of revision [44766]
................
  r44768 | noel_belcourt | 2008-04-25 10:37:47 -0700 (Fri, 25 Apr 2008) | 3 lines
  
  Get config tests working (missing -lrt).
................
  r44771 | hkaiser | 2008-04-25 19:02:44 -0700 (Fri, 25 Apr 2008) | 1 line
  
  Applied patch provided by Felipe Magno de Almeida [felipe.m.almeida_at_[hidden]].
................
  r44772 | daniel_frey | 2008-04-25 23:36:59 -0700 (Fri, 25 Apr 2008) | 1 line
  
  No need for the new ctors to be templates
................
  r44773 | anthonyw | 2008-04-26 00:34:46 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Fixed g++ compile error
................
  r44774 | speedsnail | 2008-04-26 02:54:07 -0700 (Sat, 26 Apr 2008) | 3 lines
  
  use-project didn't actually do what the comment promised.
  This triggered an error with thread Jamfile that could be seen when bjam was invoked in rootdir with
  bjam --with-wave.
................
  r44775 | pdimov | 2008-04-26 06:39:52 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Added a few more tests.
................
  r44777 | daniel_frey | 2008-04-26 08:42:13 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Added new reset()-counterparts for the new ctors
................
  r44781 | emildotchevski | 2008-04-26 10:43:58 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Added protected destructor to the base type error_info_base
................
  r44782 | daniel_frey | 2008-04-26 12:59:11 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Refactored and optimized enable_shared_from_this
................
  r44783 | hkaiser | 2008-04-26 13:09:56 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Added wrap_action for zero parameter semantic actions
................
  r44784 | hkaiser | 2008-04-26 13:10:36 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Lex: fixed typos in comments
................
  r44785 | hkaiser | 2008-04-26 13:11:25 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Classic: Added some explaining comments to the namespace handling.
................
  r44786 | hkaiser | 2008-04-26 13:12:12 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit: applied patch from #1886, closed now.
................
  r44787 | hkaiser | 2008-04-26 13:24:00 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit: Switched to use unordered from main Boost distribution, removed local copy of unordered.
................
  r44789 | hkaiser | 2008-04-26 14:51:59 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Phoenix: Fixed gcc 4.3.0 compilation issue.
................
  r44790 | grafik | 2008-04-26 15:21:50 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Add the test target name to the bjam XML log output to make it easier to match tests to jam targets.
................
  r44791 | grafik | 2008-04-26 16:15:40 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Re-implement PJL in Python to fix various problems with the C++ version. In brief to remove the need of a good C++ compiler to submit results, remove the post-processing of the raw bjam output, and to fix missing results (for example Spirit classic results).
................
  r44792 | hkaiser | 2008-04-26 17:49:41 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit: disabled some warnings for VC /W4
................
  r44793 | hkaiser | 2008-04-26 18:00:34 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit: suppressed more VC level 4 warnings
................
  r44794 | hkaiser | 2008-04-26 18:04:25 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Fusion: Fixed a VC level 4 warning
................
  r44795 | hkaiser | 2008-04-26 18:08:04 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit: suppressed more VC level 4 warnings.
................
  r44796 | hkaiser | 2008-04-26 18:08:43 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit: suppressed more VC level 4 warnings.
................
  r44797 | hkaiser | 2008-04-26 18:38:42 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Lex: Attempt to fix Intel V9.1 issue.
................
  r44798 | hkaiser | 2008-04-26 18:44:31 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Lex: fixed some gcc 4.3 warnings.
................
  r44799 | hkaiser | 2008-04-26 18:45:05 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Lex: Fixed gcc 4.3 compilation erros.
................
  r44800 | hkaiser | 2008-04-26 18:46:24 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Lex: fixed some gcc 4.3 warnings.
................
  r44801 | hkaiser | 2008-04-26 18:47:35 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Lex: fixed some gcc 4.3 warnings.
................
  r44802 | hkaiser | 2008-04-26 18:50:50 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Karma: Fixed Jamfile
................
  r44803 | hkaiser | 2008-04-26 18:59:44 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Qi: Fixed a ambiguity reported by gcc 4.3
................
  r44804 | hkaiser | 2008-04-26 19:01:22 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit.Karma: Fixed gcc 4.3 compilation issue.
................
  r44805 | hkaiser | 2008-04-26 19:04:07 -0700 (Sat, 26 Apr 2008) | 1 line
  
  Spirit: Fixed a ambiguity reported by VC8 for embedded systems
................
  r44806 | djowel | 2008-04-26 20:21:12 -0700 (Sat, 26 Apr 2008) | 1 line
  
  tweak: const correctness
................
  r44807 | danieljames | 2008-04-27 00:39:49 -0700 (Sun, 27 Apr 2008) | 78 lines
  
  Merge in documentation fixes. Apart from the change to optional's documenation
  Jamfile, which I included by mistake.
  
  Fixes #1659, #1661, #1684, #1685, 1687, #1690, #1801
  
  I wrote about this at:
  
  http://lists.boost.org/Archives/boost/2008/04/136405.php
  
  Merged revisions 44585-44806 via svnmerge from
  https://svn.boost.org/svn/boost/branches/doc
  
  ........
    r44585 | danieljames | 2008-04-19 16:25:27 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix broken link to vacpp in bjam docs. Refs #1512
  ........
    r44586 | danieljames | 2008-04-19 16:27:36 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix broken link to bcpp in bjam docs. Refs #1513
  ........
    r44587 | danieljames | 2008-04-19 16:33:58 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    DateTime documentation - Fix a link to the serialization library. Refs #1659
  ........
    r44588 | danieljames | 2008-04-19 16:35:36 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in interprocess & intrusive. Refs #1661
  ........
    r44589 | danieljames | 2008-04-19 16:37:39 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in the python docs. Refs #1684.
  ........
    r44590 | danieljames | 2008-04-19 16:38:29 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Work around a quickbook bug which is affecting the python docs. Refs #1684.
  ........
    r44591 | danieljames | 2008-04-19 16:39:34 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix a broken link in the numeric conversion docs. Refs #1685
  ........
    r44592 | danieljames | 2008-04-19 16:40:45 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix some links in the optional docs. Refs #1687
  ........
    r44593 | danieljames | 2008-04-19 16:42:09 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix link to the hash documentation from bimap. Refs #1690
  ........
    r44599 | danieljames | 2008-04-19 18:07:33 +0100 (Sat, 19 Apr 2008) | 2 lines
    
    Fix a typo in the format library. Refs #1801
  ........
    r44600 | danieljames | 2008-04-19 19:20:59 +0100 (Sat, 19 Apr 2008) | 1 line
    
    Initialise svnmerge.
  ........
    r44641 | danieljames | 2008-04-20 18:59:47 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix the lincense url in shared container iterator documentation.
  ........
    r44642 | danieljames | 2008-04-20 19:00:00 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix image link in the mpi documentation.
  ........
    r44643 | danieljames | 2008-04-20 19:00:11 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix a typo in the spirit docs.
  ........
    r44644 | danieljames | 2008-04-20 19:00:23 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Escape the slash so that quickbook doesn't think it the start of an italic section, and mess up the link. Refs #1844
  ........
    r44647 | danieljames | 2008-04-20 19:39:47 +0100 (Sun, 20 Apr 2008) | 2 lines
    
    Fix another typo in spirit docs.
  ........
................
  r44812 | djowel | 2008-04-27 01:41:13 -0700 (Sun, 27 Apr 2008) | 1 line
  
  added grammar_class
................
  r44813 | djowel | 2008-04-27 01:41:47 -0700 (Sun, 27 Apr 2008) | 1 line
  
  added grammar_class test
................
  r44814 | djowel | 2008-04-27 01:44:38 -0700 (Sun, 27 Apr 2008) | 1 line
  
  tweak grammar_class test
................
  r44815 | djowel | 2008-04-27 02:11:33 -0700 (Sun, 27 Apr 2008) | 1 line
  
  tweak grammar_class test
................
  r44816 | djowel | 2008-04-27 02:11:49 -0700 (Sun, 27 Apr 2008) | 1 line
  
  tweak grammar_class
................
  r44818 | igaztanaga | 2008-04-27 07:57:11 -0700 (Sun, 27 Apr 2008) | 13 lines
  
  Intrusive:
  
  * Added `linear<>` and `cache_last<>` options to singly linked lists.
  * Added `optimize_multikey<>` option to unordered container hooks.
  * Optimized unordered containers when `store_hash` option is used in the hook.
  * Implementation changed to be exception agnostic so that it can be used
     in environments without exceptions.
  * Added `container_from_iterator` function to tree-based containers.
  
  Interprocess:
  
  * Added anonymous shared memory for UNIX systems.
  * Fixed file lock compilation errors
................
  r44819 | igaztanaga | 2008-04-27 08:03:06 -0700 (Sun, 27 Apr 2008) | 13 lines
  
  Intrusive:
  
  * Added `linear<>` and `cache_last<>` options to singly linked lists.
  * Added `optimize_multikey<>` option to unordered container hooks.
  * Optimized unordered containers when `store_hash` option is used in the hook.
  * Implementation changed to be exception agnostic so that it can be used
     in environments without exceptions.
  * Added `container_from_iterator` function to tree-based containers.
  
  Interprocess:
  
  * Added anonymous shared memory for UNIX systems.
  * Fixed file lock compilation errors
................
  r44820 | hkaiser | 2008-04-27 11:09:29 -0700 (Sun, 27 Apr 2008) | 1 line
  
  Spirit.Lex: introduced workaround for Intel compilers <= V9.1
................
  r44821 | hkaiser | 2008-04-27 11:11:17 -0700 (Sun, 27 Apr 2008) | 1 line
  
  Spirit.Qi: Made it clear for gcc 4.3 which ref() to use.
................
  r44822 | hkaiser | 2008-04-27 11:14:49 -0700 (Sun, 27 Apr 2008) | 1 line
  
  Spirit.Lex: Fixed a gcc 4.3 warning
................
  r44823 | hkaiser | 2008-04-27 11:28:04 -0700 (Sun, 27 Apr 2008) | 1 line
  
  Spirit.Lex: Fixed a gcc 4.3 warning
................
  r44824 | hkaiser | 2008-04-27 11:37:41 -0700 (Sun, 27 Apr 2008) | 1 line
  
  Spirit.Lex: Fixed a gcc 4.3 warning (again, sigh)
................
  r44825 | niels_dekker | 2008-04-27 14:07:10 -0700 (Sun, 27 Apr 2008) | 1 line
  
  Added forward declaration of optional<T>'s boost::swap overload, as mentioned at http://article.gmane.org/gmane.comp.lib.boost.devel/174350 "Re: [optional] problems with swap()"
................
  r44826 | niels_dekker | 2008-04-27 14:09:50 -0700 (Sun, 27 Apr 2008) | 1 line
  
  Replaced "using std::swap" by "using boost::swap" within optional::swap member function, hoping to fix GCC test failures, as mentioned at http://article.gmane.org/gmane.comp.lib.boost.devel/174350 "Re: [optional] problems with swap()"
................
  r44831 | djowel | 2008-04-27 18:07:52 -0700 (Sun, 27 Apr 2008) | 1 line
  
  tweaks
................
  r44837 | daniel_frey | 2008-04-28 00:17:11 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Improved sp_deleter_wrapper implementation
................
  r44838 | anthonyw | 2008-04-28 02:00:58 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Added detail::try_lock_wrapper for use as scoped_try_lock typedefs, to fix issue #1873
................
  r44839 | anthonyw | 2008-04-28 02:04:40 -0700 (Mon, 28 Apr 2008) | 1 line
  
  reverted accidental change
................
  r44840 | anthonyw | 2008-04-28 02:10:38 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Added entry to breaking changes about default-constructed threads and the current thread: issue #1835
................
  r44842 | johnmaddock | 2008-04-28 04:07:14 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Fixes for issue #1871 that prevents duplicate symbol errors with VC++ compilers, when building with /Zc:wchar_t-.
................
  r44843 | djowel | 2008-04-28 04:15:13 -0700 (Mon, 28 Apr 2008) | 1 line
  
  experimental grammar/grammar_def unification
................
  r44844 | djowel | 2008-04-28 04:16:29 -0700 (Mon, 28 Apr 2008) | 1 line
  
  experimental grammar/grammar_def unification
................
  r44845 | djowel | 2008-04-28 04:17:09 -0700 (Mon, 28 Apr 2008) | 1 line
  
  calc2 generating an AST
................
  r44846 | anthonyw | 2008-04-28 05:26:27 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Updated locks.hpp to work with gcc as well as msvc
................
  r44847 | hkaiser | 2008-04-28 06:33:15 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Spirit.Lex: fixed workaround for Intel compilers <= V9.1
................
  r44848 | chris_kohlhoff | 2008-04-28 06:35:27 -0700 (Mon, 28 Apr 2008) | 2 lines
  
  Update asio version number.
................
  r44849 | chris_kohlhoff | 2008-04-28 06:36:18 -0700 (Mon, 28 Apr 2008) | 2 lines
  
  Add raw socket support.
................
  r44850 | hkaiser | 2008-04-28 06:44:40 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Spirit.Qi: Added a missing 'using namespace'.
................
  r44851 | chris_kohlhoff | 2008-04-28 06:56:07 -0700 (Mon, 28 Apr 2008) | 2 lines
  
  Add an experimental two-lock queue implementation for task_io_service.
................
  r44852 | dgregor | 2008-04-28 07:11:46 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Improve documentation on the size/efficiency of boost::function objects
................
  r44853 | hkaiser | 2008-04-28 07:34:02 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Spirit.Qi: calc2_ast: fixed a wrong include statement
................
  r44857 | eric_niebler | 2008-04-28 09:46:33 -0700 (Mon, 28 Apr 2008) | 1 line
  
  add missing #include
................
  r44862 | niels_dekker | 2008-04-28 14:14:15 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Marked MSVC 7.1 optional_test failure as "expected", because of an ADL-related compiler issue.
................
  r44864 | guwi17 | 2008-04-28 14:50:19 -0700 (Mon, 28 Apr 2008) | 4 lines
  
  - fix and close #1829
  - You are right. The scaled norm wrongly assumed that the first element is not zero.
................
  r44873 | daniel_frey | 2008-04-28 22:32:13 -0700 (Mon, 28 Apr 2008) | 1 line
  
  Fixed comment to reflect the intention and the current code
................
  r44877 | johnmaddock | 2008-04-29 03:05:11 -0700 (Tue, 29 Apr 2008) | 2 lines
  
  Changed long long to boost::long_long_type and unsigned long long to boost::ulong_long_type.
  A couple of other typo corrections, to get the code compiling with g++ -pedantic.
................
  r44881 | hkaiser | 2008-04-29 06:53:21 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit.Qi: Fixed grammar_test
................
  r44882 | hkaiser | 2008-04-29 07:09:40 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit.Qi: Fixed grammar_test
................
  r44883 | hkaiser | 2008-04-29 07:47:29 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit.Qi: Minor edits mainly in comments
................
  r44886 | emildotchevski | 2008-04-29 10:17:45 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Added required header #include <new>
................
  r44887 | dgregor | 2008-04-29 10:57:54 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Add support for MPI_SIGNED_CHAR to Boost.MPI
................
  r44889 | dgregor | 2008-04-29 11:18:01 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Remove names of unused variables. Fixes #1832 and fixes #1865
................
  r44891 | dgregor | 2008-04-29 11:34:28 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Correct erroneous call to is_reachable from is_connected. Fixes #870
................
  r44893 | dgregor | 2008-04-29 11:37:26 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Improve logic to guess the toolset name in top-level configure script. Fixes #1087
................
  r44895 | dgregor | 2008-04-29 11:46:17 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Make configure more closely follow autotools conventions. Fixes #1664
................
  r44897 | marshall | 2008-04-29 13:16:19 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Updated bounds on uniform_real and uniform_smallint to allow min == max
................
  r44900 | jurko | 2008-04-29 15:49:36 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Typo corrections & minor stylistic comment changes.
................
  r44901 | hkaiser | 2008-04-29 17:59:08 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit.Karma: Fixed rule, added calc2_ast_dump example
................
  r44902 | hkaiser | 2008-04-29 18:33:53 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit: Fixed main classic header
................
  r44904 | hkaiser | 2008-04-29 18:57:39 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit.Karma: Fixing ref() ambiguity
................
  r44905 | hkaiser | 2008-04-29 18:59:05 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit.Karma: Fixing ref() ambiguity
................
  r44906 | hkaiser | 2008-04-29 19:00:28 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit.Qi: Fixing ref() ambiguity
................
  r44907 | hkaiser | 2008-04-29 19:02:27 -0700 (Tue, 29 Apr 2008) | 1 line
  
  Spirit.Qi: Fixing ref() ambiguity
................
  r44919 | danieljames | 2008-04-30 00:57:04 -0700 (Wed, 30 Apr 2008) | 49 lines
  
  Merge in support for equality operators for the unordered containers and
  hopefully better cross-platform support.
  
  Merged revisions 44778-44835,44837-44918 via svnmerge from
  https://svn.boost.org/svn/boost/branches/unordered/trunk
  
  ........
    r44778 | danieljames | 2008-04-26 17:15:44 +0100 (Sat, 26 Apr 2008) | 2 lines
    
    Remove a trailing comma.
  ........
    r44779 | danieljames | 2008-04-26 17:23:51 +0100 (Sat, 26 Apr 2008) | 1 line
    
    Merge in support for equality operators.
  ........
    r44780 | danieljames | 2008-04-26 17:28:44 +0100 (Sat, 26 Apr 2008) | 1 line
    
    Use my own list container to avoid working around STL container bugs.
  ........
    r44833 | danieljames | 2008-04-28 08:03:43 +0100 (Mon, 28 Apr 2008) | 1 line
    
    Better equality tests.
  ........
    r44834 | danieljames | 2008-04-28 08:04:03 +0100 (Mon, 28 Apr 2008) | 1 line
    
    Remove a superfluous check.
  ........
    r44835 | danieljames | 2008-04-28 08:04:21 +0100 (Mon, 28 Apr 2008) | 1 line
    
    Add equality reference documentation.
  ........
    r44916 | danieljames | 2008-04-30 08:16:52 +0100 (Wed, 30 Apr 2008) | 1 line
    
    New version of list.hpp
  ........
    r44917 | danieljames | 2008-04-30 08:18:31 +0100 (Wed, 30 Apr 2008) | 1 line
    
    Support compilers without ADL in the compile tests.
  ........
    r44918 | danieljames | 2008-04-30 08:25:20 +0100 (Wed, 30 Apr 2008) | 7 lines
    
    Change the typedef of buffered functions as it was confusing MSVC 6.5
    
    get_allocator wasn't compiling when the allocator workaround is used because it
    couldn't cast from the wrapped allocator to an allocator of another type. So
    use value_alloc_ when it's available (it's only unavailable on compilers with
    C++0x support, which don't require the workaround).
  ........
................
  r44934 | hkaiser | 2008-04-30 08:47:07 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Spirit.Karma: Added example calc2_ast_rpn
................
  r44941 | jurko | 2008-04-30 12:24:04 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Comment cleanup - both stylistic & typo corrections.
................
  r44942 | jurko | 2008-04-30 12:26:55 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Comment typo correction.
................
  r44946 | jurko | 2008-04-30 12:45:29 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Added several svn:ignore Subversion properties to make Subversion ignore folders creating during default Boost & Boost Jam builds on Windows.
................
  r44949 | jurko | 2008-04-30 13:00:24 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Removed trailing spaces from tools/build/v2/build/modifiers.jam.
................
  r44950 | hkaiser | 2008-04-30 13:33:23 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Spirit.Karma: Fixed rule tests (pattern.cpp)
................
  r44951 | hkaiser | 2008-04-30 13:41:37 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Spirit.Karma: added #include <boost/config/warning_disable.hpp> to Karma examples
................
  r44952 | hkaiser | 2008-04-30 13:42:11 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Spirit.Lex: added #include <boost/config/warning_disable.hpp> to Lex examples
................
  r44953 | jurko | 2008-04-30 13:58:05 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Corrected a typo in the Boost Build documentation.
................
  r44954 | emildotchevski | 2008-04-30 14:45:00 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Integration of Boost Exception in boost::throw_exception().
................
  r44957 | hkaiser | 2008-04-30 15:54:09 -0700 (Wed, 30 Apr 2008) | 1 line
  
  Spirit.Qi: added #include <boost/config/warning_disable.hpp> to Qi examples
................
  r44962 | djowel | 2008-04-30 19:10:56 -0700 (Wed, 30 Apr 2008) | 1 line
  
  integer overflow fix
................
  r44968 | danieljames | 2008-05-01 02:23:22 -0700 (Thu, 01 May 2008) | 2 lines
  
  Add list.hpp which was missed from the merge.
................
  r44969 | jurko | 2008-05-01 02:39:45 -0700 (Thu, 01 May 2008) | 1 line
  
  Consistently converted tabs to spaces in tools/build/v2/test/BoostBuild.py to avoid confusion reading the Python source.
................
  r44970 | jurko | 2008-05-01 02:55:47 -0700 (Thu, 01 May 2008) | 1 line
  
  Renamed the Tester.wait_for_time_change() function to Tester.wait_for_time_change_since_last_build() to avoid confusion.
................
  r44971 | jurko | 2008-05-01 03:03:15 -0700 (Thu, 01 May 2008) | 1 line
  
  Boost Build documentation typo correction. Removed trailing spaces. Minor stylistic changes.
................
  r44972 | johnmaddock | 2008-05-01 04:51:39 -0700 (Thu, 01 May 2008) | 1 line
  
  Fix broken URL.
................
  r44973 | hkaiser | 2008-05-01 07:17:52 -0700 (Thu, 01 May 2008) | 1 line
  
  Spirit.Karma: Trying to workaround a gcc 4.2.1 bug.
................
  r44975 | jurko | 2008-05-01 08:09:58 -0700 (Thu, 01 May 2008) | 1 line
  
  Boost Build comment typo corrections and minor stylistic changes.
................
  r44977 | hkaiser | 2008-05-01 09:20:38 -0700 (Thu, 01 May 2008) | 1 line
  
  Wave: Changing properties for test.cfg to fix test failures non Windows systems
................
  r44979 | pdimov | 2008-05-01 09:50:39 -0700 (Thu, 01 May 2008) | 1 line
  
  make_shared added; tweaks for old compilers; fixes #1884.
................
  r44980 | jurko | 2008-05-01 10:01:03 -0700 (Thu, 01 May 2008) | 1 line
  
  Minor stylistic comment changes.
................
  r44981 | jurko | 2008-05-01 10:04:22 -0700 (Thu, 01 May 2008) | 1 line
  
  Added explanation comments for match_exact() and match_re() functions in tools/build/v2/test/TestCmd.py. Removed corpse interpreted member from the TescCmd class and the related setter function in tools/build/v2/test/TestCmd.py. Minor stylistic comment changes.
................
  r44982 | jurko | 2008-05-01 10:06:02 -0700 (Thu, 01 May 2008) | 1 line
  
  Updated the main Tester class comment in tools/build/v2/build/v2/test/BoostBuild.py describing all of its available constructor parameters. Minor stylistic changes.
................
  r44983 | jurko | 2008-05-01 10:08:04 -0700 (Thu, 01 May 2008) | 1 line
  
  Updated the Boost Build test system documentation. Now all the command line options are described. Several function descriptions updated.
................
  r44984 | hkaiser | 2008-05-01 10:31:42 -0700 (Thu, 01 May 2008) | 1 line
  
  Spirit.Lex: Removed unused variables
................
  r44991 | jurko | 2008-05-01 12:47:37 -0700 (Thu, 01 May 2008) | 1 line
  
  Fixed a bug with BOOST_BUILD_PATH not getting set correctly in Boost Build unit tests in case it contained spaces.
................
  r44992 | jurko | 2008-05-01 12:55:50 -0700 (Thu, 01 May 2008) | 1 line
  
  Added the default Boost Jam build target folders on cygwin - bin.cygwinx86 & bin.cygwinc86.debug to the svn:ignore list.
................
  r44993 | jurko | 2008-05-01 13:22:12 -0700 (Thu, 01 May 2008) | 1 line
  
  Upgraded the internal Boost Build test system so it can be run from folders whose names contain spaces on Windows. Also added a workaround for a Python bug on Windows where it has some undocumented behavior when starting processes using commands containing quotes.
................
  r44995 | jurko | 2008-05-01 14:19:11 -0700 (Thu, 01 May 2008) | 1 line
  
  Minor stylistic changes.
................
  r44997 | chris_kohlhoff | 2008-05-01 15:00:26 -0700 (Thu, 01 May 2008) | 3 lines
  
  Add a fast path for some speculative read and write operations in the
  epoll_reactor.
................
  r44998 | chris_kohlhoff | 2008-05-01 15:27:21 -0700 (Thu, 01 May 2008) | 3 lines
  
  A memory barrier is needed on some platforms to ensure that all updates
  to the node occur before the tail pointer is updated.
................
  r44999 | jurko | 2008-05-01 17:10:09 -0700 (Thu, 01 May 2008) | 1 line
  
  Minor stylistic changes.
................
  r45000 | jurko | 2008-05-01 17:12:29 -0700 (Thu, 01 May 2008) | 1 line
  
  Added support for tests checking that a build run did not take longer than expected to finish. Minor stylistic changes.
................
  r45001 | jurko | 2008-05-01 17:36:23 -0700 (Thu, 01 May 2008) | 1 line
  
  Added a new regression test making sure that the Boost Jam SORT builtin rule does not start getting quadratic behavior in some special cases as well as testing that the sorting algorithm works correctly. Related to the patch committed in revision 44195. Trimmed trailing spaces in tools/build/v2/test/test_all.py.
................
  r45002 | jurko | 2008-05-01 17:51:05 -0700 (Thu, 01 May 2008) | 1 line
  
  Documentation typo corrected.
................
  r45004 | jurko | 2008-05-01 17:57:29 -0700 (Thu, 01 May 2008) | 1 line
  
  Minor stylistic changes.
................
  r45005 | jurko | 2008-05-01 18:02:01 -0700 (Thu, 01 May 2008) | 1 line
  
  Updated the Boost Build test system's documentation about Tester.run_build_system() parameters. Minor stylistic changes.
................
  r45006 | chris_kohlhoff | 2008-05-02 00:59:01 -0700 (Fri, 02 May 2008) | 3 lines
  
  Fully qualify uses of asio's placeholders to resolve ambiguity with C++0x's
  placeholders namespace.
................
  r45010 | chris_kohlhoff | 2008-05-02 01:38:15 -0700 (Fri, 02 May 2008) | 3 lines
  
  Don't use the names readv and writev for functions defined inside asio as
  these names seem to be macros on Tru64.
................
  r45011 | nesotto | 2008-05-02 01:38:15 -0700 (Fri, 02 May 2008) | 1 line
  
  added missing const in insert()
................
  r45019 | igaztanaga | 2008-05-02 04:07:08 -0700 (Fri, 02 May 2008) | 1 line
  
  Tickets #1883, #1862, #1709
................
  r45023 | jurko | 2008-05-02 08:26:44 -0700 (Fri, 02 May 2008) | 1 line
  
  Minor stylistic Boost Build code changes.
................
  r45025 | grafik | 2008-05-02 08:44:25 -0700 (Fri, 02 May 2008) | 1 line
  
  Use all test sub-projects regardless of filtering so that the tests show up in the bjam XML log.
................
  r45026 | grafik | 2008-05-02 08:52:42 -0700 (Fri, 02 May 2008) | 1 line
  
  Add support for test log processing with process_jam_log.py instead of C++ PJL. (also fixes #1889)
................
  r45027 | pdimov | 2008-05-02 09:49:34 -0700 (Fri, 02 May 2008) | 1 line
  
  Fix throwing enums instead of archive_exceptions.
................

Added:
   branches/proto/v4/boost/asio/basic_raw_socket.hpp
      - copied unchanged from r45027, /trunk/boost/asio/basic_raw_socket.hpp
   branches/proto/v4/boost/asio/detail/indirect_handler_queue.hpp
      - copied unchanged from r45027, /trunk/boost/asio/detail/indirect_handler_queue.hpp
   branches/proto/v4/boost/asio/detail/task_io_service_2lock.hpp
      - copied unchanged from r45027, /trunk/boost/asio/detail/task_io_service_2lock.hpp
   branches/proto/v4/boost/asio/ip/icmp.hpp
      - copied unchanged from r45027, /trunk/boost/asio/ip/icmp.hpp
   branches/proto/v4/boost/asio/raw_socket_service.hpp
      - copied unchanged from r45027, /trunk/boost/asio/raw_socket_service.hpp
   branches/proto/v4/boost/interprocess/anonymous_shared_memory.hpp
      - copied unchanged from r45027, /trunk/boost/interprocess/anonymous_shared_memory.hpp
   branches/proto/v4/boost/intrusive/pointer_plus_bits.hpp
      - copied unchanged from r45027, /trunk/boost/intrusive/pointer_plus_bits.hpp
   branches/proto/v4/boost/make_shared.hpp
      - copied unchanged from r45027, /trunk/boost/make_shared.hpp
   branches/proto/v4/boost/spirit/home/qi/char/detail/get_char.hpp
      - copied unchanged from r45027, /trunk/boost/spirit/home/qi/char/detail/get_char.hpp
   branches/proto/v4/libs/interprocess/example/doc_anonymous_shared_memory.cpp
      - copied unchanged from r45027, /trunk/libs/interprocess/example/doc_anonymous_shared_memory.cpp
   branches/proto/v4/libs/interprocess/example/doc_multi_index.cpp
      - copied unchanged from r45027, /trunk/libs/interprocess/example/doc_multi_index.cpp
   branches/proto/v4/libs/interprocess/example/doc_unordered_map.cpp
      - copied unchanged from r45027, /trunk/libs/interprocess/example/doc_unordered_map.cpp
   branches/proto/v4/libs/interprocess/proj/to-do.txt
      - copied unchanged from r45027, /trunk/libs/interprocess/proj/to-do.txt
   branches/proto/v4/libs/interprocess/proj/vc7ide/anonymous_shared_memory_test.vcproj
      - copied unchanged from r45027, /trunk/libs/interprocess/proj/vc7ide/anonymous_shared_memory_test.vcproj
   branches/proto/v4/libs/interprocess/proj/vc7ide/doc_anonymous_shared_memory.vcproj
      - copied unchanged from r45027, /trunk/libs/interprocess/proj/vc7ide/doc_anonymous_shared_memory.vcproj
   branches/proto/v4/libs/interprocess/proj/vc7ide/doc_multi_index.vcproj
      - copied unchanged from r45027, /trunk/libs/interprocess/proj/vc7ide/doc_multi_index.vcproj
   branches/proto/v4/libs/interprocess/proj/vc7ide/doc_unordered_map.vcproj
      - copied unchanged from r45027, /trunk/libs/interprocess/proj/vc7ide/doc_unordered_map.vcproj
   branches/proto/v4/libs/interprocess/proj/vc7ide/file_lock_test.vcproj
      - copied unchanged from r45027, /trunk/libs/interprocess/proj/vc7ide/file_lock_test.vcproj
   branches/proto/v4/libs/interprocess/proj/vc7ide/multi_index_test.vcproj
      - copied unchanged from r45027, /trunk/libs/interprocess/proj/vc7ide/multi_index_test.vcproj
   branches/proto/v4/libs/interprocess/proj/vc7ide/unordered_test.vcproj
      - copied unchanged from r45027, /trunk/libs/interprocess/proj/vc7ide/unordered_test.vcproj
   branches/proto/v4/libs/interprocess/test/anonymous_shared_memory_test.cpp
      - copied unchanged from r45027, /trunk/libs/interprocess/test/anonymous_shared_memory_test.cpp
   branches/proto/v4/libs/interprocess/test/file_lock_test.cpp
      - copied unchanged from r45027, /trunk/libs/interprocess/test/file_lock_test.cpp
   branches/proto/v4/libs/interprocess/test/multi_index_test.cpp
      - copied unchanged from r45027, /trunk/libs/interprocess/test/multi_index_test.cpp
   branches/proto/v4/libs/interprocess/test/unordered_test.cpp
      - copied unchanged from r45027, /trunk/libs/interprocess/test/unordered_test.cpp
   branches/proto/v4/libs/intrusive/proj/vc7ide/to-do.txt
      - copied unchanged from r45027, /trunk/libs/intrusive/proj/vc7ide/to-do.txt
   branches/proto/v4/libs/smart_ptr/test/make_shared_test.cpp
      - copied unchanged from r45027, /trunk/libs/smart_ptr/test/make_shared_test.cpp
   branches/proto/v4/libs/spirit/example/karma/calc2_ast.hpp
      - copied unchanged from r45027, /trunk/libs/spirit/example/karma/calc2_ast.hpp
   branches/proto/v4/libs/spirit/example/karma/calc2_ast_dump.cpp
      - copied unchanged from r45027, /trunk/libs/spirit/example/karma/calc2_ast_dump.cpp
   branches/proto/v4/libs/spirit/example/karma/calc2_ast_rpn.cpp
      - copied unchanged from r45027, /trunk/libs/spirit/example/karma/calc2_ast_rpn.cpp
   branches/proto/v4/libs/spirit/example/qi/calc2_ast.cpp
      - copied unchanged from r45027, /trunk/libs/spirit/example/qi/calc2_ast.cpp
   branches/proto/v4/libs/unordered/test/helpers/list.hpp
      - copied unchanged from r45027, /trunk/libs/unordered/test/helpers/list.hpp
   branches/proto/v4/libs/unordered/test/unordered/equality_tests.cpp
      - copied unchanged from r45027, /trunk/libs/unordered/test/unordered/equality_tests.cpp
   branches/proto/v4/tools/build/v2/test/sort_rule.py
      - copied unchanged from r45027, /trunk/tools/build/v2/test/sort_rule.py
   branches/proto/v4/tools/regression/src/process_jam_log.py
      - copied unchanged from r45027, /trunk/tools/regression/src/process_jam_log.py
Removed:
   branches/proto/v4/boost/intrusive/detail/no_exceptions_support.hpp
   branches/proto/v4/boost/intrusive/pointer_plus_2_bits.hpp
   branches/proto/v4/boost/intrusive/pointer_plus_bit.hpp
   branches/proto/v4/boost/spirit/home/support/detail/unordered/
   branches/proto/v4/boost/spirit/home/support/detail/unordered_map.hpp
   branches/proto/v4/boost/spirit/home/support/detail/unordered_set.hpp
Properties modified:
   branches/proto/v4/ (props changed)
   branches/proto/v4/libs/wave/test/testwave/testfiles/test.cfg (contents, props changed)
   branches/proto/v4/tools/jam/src/ (props changed)
Text files modified:
   branches/proto/v4/Jamroot | 2
   branches/proto/v4/boost/archive/impl/xml_iarchive_impl.ipp | 2
   branches/proto/v4/boost/archive/impl/xml_wiarchive_impl.ipp | 2
   branches/proto/v4/boost/asio.hpp | 3
   branches/proto/v4/boost/asio/detail/descriptor_ops.hpp | 5
   branches/proto/v4/boost/asio/detail/dev_poll_reactor.hpp | 49
   branches/proto/v4/boost/asio/detail/epoll_reactor.hpp | 96 +
   branches/proto/v4/boost/asio/detail/kqueue_reactor.hpp | 56
   branches/proto/v4/boost/asio/detail/push_options.hpp | 2
   branches/proto/v4/boost/asio/detail/reactive_descriptor_service.hpp | 32
   branches/proto/v4/boost/asio/detail/reactive_socket_service.hpp | 71 -
   branches/proto/v4/boost/asio/detail/select_reactor.hpp | 82 +
   branches/proto/v4/boost/asio/detail/socket_ops.hpp | 4
   branches/proto/v4/boost/asio/detail/task_io_service.hpp | 6
   branches/proto/v4/boost/asio/detail/win_iocp_socket_service.hpp | 52
   branches/proto/v4/boost/asio/version.hpp | 2
   branches/proto/v4/boost/config/compiler/intel.hpp | 6
   branches/proto/v4/boost/config/platform/macos.hpp | 8
   branches/proto/v4/boost/detail/shared_count.hpp | 26
   branches/proto/v4/boost/detail/spinlock_w32.hpp | 2
   branches/proto/v4/boost/detail/yield_k.hpp | 8
   branches/proto/v4/boost/enable_shared_from_this.hpp | 113 +-
   branches/proto/v4/boost/exception/info.hpp | 6
   branches/proto/v4/boost/exception_ptr.hpp | 1
   branches/proto/v4/boost/fusion/container/list/detail/end_impl.hpp | 2
   branches/proto/v4/boost/graph/dijkstra_shortest_paths.hpp | 2
   branches/proto/v4/boost/graph/graph_utility.hpp | 2
   branches/proto/v4/boost/interprocess/allocators/adaptive_pool.hpp | 162 +++
   branches/proto/v4/boost/interprocess/allocators/allocator.hpp | 19
   branches/proto/v4/boost/interprocess/allocators/cached_adaptive_pool.hpp | 8
   branches/proto/v4/boost/interprocess/allocators/cached_node_allocator.hpp | 14
   branches/proto/v4/boost/interprocess/allocators/detail/adaptive_node_pool.hpp | 26
   branches/proto/v4/boost/interprocess/allocators/detail/allocator_common.hpp | 52 +
   branches/proto/v4/boost/interprocess/allocators/detail/node_pool.hpp | 2
   branches/proto/v4/boost/interprocess/allocators/node_allocator.hpp | 75 +
   branches/proto/v4/boost/interprocess/allocators/private_adaptive_pool.hpp | 29
   branches/proto/v4/boost/interprocess/allocators/private_node_allocator.hpp | 233 -----
   branches/proto/v4/boost/interprocess/containers/deque.hpp | 24
   branches/proto/v4/boost/interprocess/containers/detail/node_alloc_holder.hpp | 6
   branches/proto/v4/boost/interprocess/containers/string.hpp | 2
   branches/proto/v4/boost/interprocess/containers/vector.hpp | 79 -
   branches/proto/v4/boost/interprocess/detail/algorithms.hpp | 4
   branches/proto/v4/boost/interprocess/detail/config_begin.hpp | 1
   branches/proto/v4/boost/interprocess/detail/move.hpp | 2
   branches/proto/v4/boost/interprocess/detail/mpl.hpp | 20
   branches/proto/v4/boost/interprocess/detail/named_proxy.hpp | 20
   branches/proto/v4/boost/interprocess/detail/utilities.hpp | 15
   branches/proto/v4/boost/interprocess/ipc/message_queue.hpp | 14
   branches/proto/v4/boost/interprocess/mapped_region.hpp | 7
   branches/proto/v4/boost/interprocess/mem_algo/detail/mem_algo_common.hpp | 97 ++
   branches/proto/v4/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp | 2
   branches/proto/v4/boost/interprocess/mem_algo/rbtree_best_fit.hpp | 34
   branches/proto/v4/boost/interprocess/offset_ptr.hpp | 72 -
   branches/proto/v4/boost/interprocess/sync/emulation/interprocess_condition.hpp | 27
   branches/proto/v4/boost/interprocess/sync/file_lock.hpp | 69 -
   branches/proto/v4/boost/interprocess/sync/named_condition.hpp | 4
   branches/proto/v4/boost/interprocess/windows_shared_memory.hpp | 2
   branches/proto/v4/boost/intrusive/avl_set.hpp | 70 +
   branches/proto/v4/boost/intrusive/avltree.hpp | 31
   branches/proto/v4/boost/intrusive/avltree_algorithms.hpp | 11
   branches/proto/v4/boost/intrusive/circular_list_algorithms.hpp | 4
   branches/proto/v4/boost/intrusive/circular_slist_algorithms.hpp | 12
   branches/proto/v4/boost/intrusive/detail/avltree_node.hpp | 10
   branches/proto/v4/boost/intrusive/detail/common_slist_algorithms.hpp | 2
   branches/proto/v4/boost/intrusive/detail/ebo_functor_holder.hpp | 31
   branches/proto/v4/boost/intrusive/detail/hashtable_node.hpp | 44
   branches/proto/v4/boost/intrusive/detail/list_node.hpp | 5
   branches/proto/v4/boost/intrusive/detail/mpl.hpp | 20
   branches/proto/v4/boost/intrusive/detail/rbtree_node.hpp | 16
   branches/proto/v4/boost/intrusive/detail/slist_node.hpp | 2
   branches/proto/v4/boost/intrusive/detail/tree_algorithms.hpp | 175 ++-
   branches/proto/v4/boost/intrusive/detail/tree_node.hpp | 5
   branches/proto/v4/boost/intrusive/detail/utilities.hpp | 85 +
   branches/proto/v4/boost/intrusive/hashtable.hpp | 1528 ++++++++++++++++++++++++++++-----------
   branches/proto/v4/boost/intrusive/intrusive_fwd.hpp | 6
   branches/proto/v4/boost/intrusive/linear_slist_algorithms.hpp | 14
   branches/proto/v4/boost/intrusive/list.hpp | 18
   branches/proto/v4/boost/intrusive/options.hpp | 35
   branches/proto/v4/boost/intrusive/rbtree.hpp | 62 +
   branches/proto/v4/boost/intrusive/rbtree_algorithms.hpp | 11
   branches/proto/v4/boost/intrusive/set.hpp | 85 ++
   branches/proto/v4/boost/intrusive/sg_set.hpp | 68 +
   branches/proto/v4/boost/intrusive/sgtree.hpp | 25
   branches/proto/v4/boost/intrusive/sgtree_algorithms.hpp | 11
   branches/proto/v4/boost/intrusive/slist.hpp | 58
   branches/proto/v4/boost/intrusive/splay_set.hpp | 68 +
   branches/proto/v4/boost/intrusive/splaytree.hpp | 25
   branches/proto/v4/boost/intrusive/splaytree_algorithms.hpp | 64 +
   branches/proto/v4/boost/intrusive/unordered_set.hpp | 58
   branches/proto/v4/boost/intrusive/unordered_set_hook.hpp | 126 ++
   branches/proto/v4/boost/math/bindings/rr.hpp | 8
   branches/proto/v4/boost/math/common_factor_rt.hpp | 4
   branches/proto/v4/boost/math/concepts/real_concept.hpp | 26
   branches/proto/v4/boost/math/concepts/std_real_concept.hpp | 25
   branches/proto/v4/boost/math/special_functions/detail/round_fwd.hpp | 12
   branches/proto/v4/boost/math/special_functions/detail/t_distribution_inv.hpp | 1
   branches/proto/v4/boost/math/special_functions/math_fwd.hpp | 6
   branches/proto/v4/boost/math/special_functions/modf.hpp | 4
   branches/proto/v4/boost/math/special_functions/round.hpp | 10
   branches/proto/v4/boost/math/special_functions/trunc.hpp | 10
   branches/proto/v4/boost/mpi/datatype.hpp | 5
   branches/proto/v4/boost/numeric/ublas/functional.hpp | 49
   branches/proto/v4/boost/optional/optional.hpp | 104 +
   branches/proto/v4/boost/optional/optional_fwd.hpp | 7
   branches/proto/v4/boost/parameter/aux_/tagged_argument.hpp | 1
   branches/proto/v4/boost/ptr_container/ptr_map_adapter.hpp | 2
   branches/proto/v4/boost/random/uniform_real.hpp | 2
   branches/proto/v4/boost/random/uniform_smallint.hpp | 4
   branches/proto/v4/boost/shared_ptr.hpp | 46
   branches/proto/v4/boost/spirit.hpp | 6
   branches/proto/v4/boost/spirit/home/classic/namespace.hpp | 11
   branches/proto/v4/boost/spirit/home/karma/char/char.hpp | 4
   branches/proto/v4/boost/spirit/home/karma/detail/output_iterator.hpp | 11
   branches/proto/v4/boost/spirit/home/karma/detail/string_generate.hpp | 8
   branches/proto/v4/boost/spirit/home/karma/nonterminal/detail/rule.hpp | 147 ---
   branches/proto/v4/boost/spirit/home/karma/nonterminal/nonterminal.hpp | 36
   branches/proto/v4/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp | 70
   branches/proto/v4/boost/spirit/home/karma/nonterminal/rule.hpp | 24
   branches/proto/v4/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp | 11
   branches/proto/v4/boost/spirit/home/karma/operator/alternative.hpp | 32
   branches/proto/v4/boost/spirit/home/karma/operator/detail/alternative.hpp | 204 +++-
   branches/proto/v4/boost/spirit/home/karma/operator/karma-alt/alternative.hpp | 34
   branches/proto/v4/boost/spirit/home/karma/operator/karma-alt/detail/alternative.hpp | 207 +++-
   branches/proto/v4/boost/spirit/home/lex/lexer/lexer.hpp | 4
   branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp | 26
   branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_functor.hpp | 5
   branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_static_functor.hpp | 2
   branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp | 4
   branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp | 17
   branches/proto/v4/boost/spirit/home/phoenix/operator/io.hpp | 4
   branches/proto/v4/boost/spirit/home/phoenix/statement/detail/switch.hpp | 12
   branches/proto/v4/boost/spirit/home/qi/auxiliary/primitives.hpp | 12
   branches/proto/v4/boost/spirit/home/qi/char/char.hpp | 47 -
   branches/proto/v4/boost/spirit/home/qi/nonterminal/grammar.hpp | 147 +++
   branches/proto/v4/boost/spirit/home/qi/nonterminal/rule.hpp | 20
   branches/proto/v4/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp | 14
   branches/proto/v4/boost/spirit/home/qi/numeric/detail/real_impl.hpp | 11
   branches/proto/v4/boost/spirit/home/qi/operator/list.hpp | 6
   branches/proto/v4/boost/spirit/home/qi/skip.hpp | 2
   branches/proto/v4/boost/spirit/home/qi/string/tst_map.hpp | 2
   branches/proto/v4/boost/spirit/home/support/argument.hpp | 38
   branches/proto/v4/boost/spirit/home/support/as_variant.hpp | 45 +
   branches/proto/v4/boost/spirit/home/support/detail/action_dispatch.hpp | 9
   branches/proto/v4/boost/spirit/home/support/detail/hold_any.hpp | 15
   branches/proto/v4/boost/spirit/home/support/detail/lexer/char_traits.hpp | 46
   branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/parser.hpp | 4
   branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/tokeniser/num_token.hpp | 18
   branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser.hpp | 4
   branches/proto/v4/boost/spirit/home/support/detail/lexer/string_token.hpp | 2
   branches/proto/v4/boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp | 2
   branches/proto/v4/boost/spirit/home/support/iterators/detail/combine_policies.hpp | 2
   branches/proto/v4/boost/spirit/home/support/iterators/detail/first_owner_policy.hpp | 2
   branches/proto/v4/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp | 4
   branches/proto/v4/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp | 8
   branches/proto/v4/boost/spirit/home/support/iterators/detail/multi_pass.hpp | 18
   branches/proto/v4/boost/spirit/home/support/iterators/detail/no_check_policy.hpp | 2
   branches/proto/v4/boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp | 4
   branches/proto/v4/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp | 4
   branches/proto/v4/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp | 2
   branches/proto/v4/boost/thread/detail/move.hpp | 5
   branches/proto/v4/boost/thread/locks.hpp | 62 +
   branches/proto/v4/boost/thread/pthread/mutex.hpp | 4
   branches/proto/v4/boost/thread/pthread/recursive_mutex.hpp | 4
   branches/proto/v4/boost/thread/win32/condition_variable.hpp | 2
   branches/proto/v4/boost/thread/win32/mutex.hpp | 4
   branches/proto/v4/boost/thread/win32/recursive_mutex.hpp | 4
   branches/proto/v4/boost/throw_exception.hpp | 9
   branches/proto/v4/boost/type_traits/type_with_alignment.hpp | 2
   branches/proto/v4/boost/unordered/detail/hash_table.hpp | 7
   branches/proto/v4/boost/unordered/detail/hash_table_impl.hpp | 468 +++++++++++-
   branches/proto/v4/boost/unordered_map.hpp | 61 +
   branches/proto/v4/boost/unordered_set.hpp | 62 +
   branches/proto/v4/configure | 41
   branches/proto/v4/libs/asio/test/basic_datagram_socket.cpp | 2
   branches/proto/v4/libs/asio/test/basic_deadline_timer.cpp | 2
   branches/proto/v4/libs/asio/test/basic_socket_acceptor.cpp | 2
   branches/proto/v4/libs/asio/test/basic_stream_socket.cpp | 2
   branches/proto/v4/libs/asio/test/buffer.cpp | 2
   branches/proto/v4/libs/asio/test/buffered_read_stream.cpp | 2
   branches/proto/v4/libs/asio/test/buffered_stream.cpp | 2
   branches/proto/v4/libs/asio/test/buffered_write_stream.cpp | 2
   branches/proto/v4/libs/asio/test/completion_condition.cpp | 2
   branches/proto/v4/libs/asio/test/datagram_socket_service.cpp | 2
   branches/proto/v4/libs/asio/test/deadline_timer.cpp | 2
   branches/proto/v4/libs/asio/test/deadline_timer_service.cpp | 2
   branches/proto/v4/libs/asio/test/error.cpp | 2
   branches/proto/v4/libs/asio/test/io_service.cpp | 2
   branches/proto/v4/libs/asio/test/ip/address.cpp | 2
   branches/proto/v4/libs/asio/test/ip/address_v4.cpp | 2
   branches/proto/v4/libs/asio/test/ip/address_v6.cpp | 2
   branches/proto/v4/libs/asio/test/ip/basic_endpoint.cpp | 2
   branches/proto/v4/libs/asio/test/ip/basic_resolver.cpp | 2
   branches/proto/v4/libs/asio/test/ip/basic_resolver_entry.cpp | 2
   branches/proto/v4/libs/asio/test/ip/basic_resolver_iterator.cpp | 2
   branches/proto/v4/libs/asio/test/ip/basic_resolver_query.cpp | 2
   branches/proto/v4/libs/asio/test/ip/host_name.cpp | 2
   branches/proto/v4/libs/asio/test/ip/multicast.cpp | 2
   branches/proto/v4/libs/asio/test/ip/resolver_query_base.cpp | 2
   branches/proto/v4/libs/asio/test/ip/resolver_service.cpp | 2
   branches/proto/v4/libs/asio/test/ip/tcp.cpp | 2
   branches/proto/v4/libs/asio/test/ip/udp.cpp | 8
   branches/proto/v4/libs/asio/test/ip/unicast.cpp | 2
   branches/proto/v4/libs/asio/test/ip/v6_only.cpp | 2
   branches/proto/v4/libs/asio/test/is_read_buffered.cpp | 2
   branches/proto/v4/libs/asio/test/is_write_buffered.cpp | 2
   branches/proto/v4/libs/asio/test/local/basic_endpoint.cpp | 2
   branches/proto/v4/libs/asio/test/local/connect_pair.cpp | 2
   branches/proto/v4/libs/asio/test/local/datagram_protocol.cpp | 2
   branches/proto/v4/libs/asio/test/local/stream_protocol.cpp | 2
   branches/proto/v4/libs/asio/test/placeholders.cpp | 2
   branches/proto/v4/libs/asio/test/posix/basic_descriptor.cpp | 2
   branches/proto/v4/libs/asio/test/posix/basic_stream_descriptor.cpp | 2
   branches/proto/v4/libs/asio/test/posix/descriptor_base.cpp | 2
   branches/proto/v4/libs/asio/test/posix/stream_descriptor.cpp | 2
   branches/proto/v4/libs/asio/test/posix/stream_descriptor_service.cpp | 2
   branches/proto/v4/libs/asio/test/read.cpp | 2
   branches/proto/v4/libs/asio/test/read_until.cpp | 2
   branches/proto/v4/libs/asio/test/socket_acceptor_service.cpp | 2
   branches/proto/v4/libs/asio/test/socket_base.cpp | 2
   branches/proto/v4/libs/asio/test/ssl/basic_context.cpp | 2
   branches/proto/v4/libs/asio/test/ssl/context.cpp | 2
   branches/proto/v4/libs/asio/test/ssl/context_base.cpp | 2
   branches/proto/v4/libs/asio/test/ssl/context_service.cpp | 2
   branches/proto/v4/libs/asio/test/ssl/stream.cpp | 2
   branches/proto/v4/libs/asio/test/ssl/stream_base.cpp | 2
   branches/proto/v4/libs/asio/test/ssl/stream_service.cpp | 2
   branches/proto/v4/libs/asio/test/strand.cpp | 2
   branches/proto/v4/libs/asio/test/stream_socket_service.cpp | 2
   branches/proto/v4/libs/asio/test/time_traits.cpp | 2
   branches/proto/v4/libs/asio/test/unit_test.hpp | 1
   branches/proto/v4/libs/asio/test/windows/basic_handle.cpp | 2
   branches/proto/v4/libs/asio/test/windows/basic_stream_handle.cpp | 2
   branches/proto/v4/libs/asio/test/windows/stream_handle.cpp | 2
   branches/proto/v4/libs/asio/test/windows/stream_handle_service.cpp | 2
   branches/proto/v4/libs/asio/test/write.cpp | 2
   branches/proto/v4/libs/bimap/doc/bimap_and_boost.qbk | 4
   branches/proto/v4/libs/date_time/xmldoc/buildinfo.xml | 2
   branches/proto/v4/libs/exception/test/Jamfile.v2 | 7
   branches/proto/v4/libs/filesystem/doc/index.htm | 4
   branches/proto/v4/libs/filesystem/doc/reference.html | 4
   branches/proto/v4/libs/format/doc/format.html | 2
   branches/proto/v4/libs/function/doc/misc.xml | 6
   branches/proto/v4/libs/interprocess/doc/interprocess.qbk | 98 ++
   branches/proto/v4/libs/interprocess/proj/vc7ide/Interprocess.sln | 56 +
   branches/proto/v4/libs/interprocess/proj/vc7ide/interprocesslib.vcproj | 3
   branches/proto/v4/libs/interprocess/test/adaptive_node_pool_test.cpp | 2
   branches/proto/v4/libs/interprocess/test/adaptive_pool_test.cpp | 1
   branches/proto/v4/libs/interprocess/test/allocator_v1.hpp | 8
   branches/proto/v4/libs/interprocess/test/dummy_test_allocator.hpp | 8
   branches/proto/v4/libs/interprocess/test/expand_bwd_test_allocator.hpp | 8
   branches/proto/v4/libs/interprocess/test/expand_bwd_test_template.hpp | 145 ++-
   branches/proto/v4/libs/interprocess/test/list_test.cpp | 6
   branches/proto/v4/libs/interprocess/test/node_pool_test.hpp | 2
   branches/proto/v4/libs/interprocess/test/shared_memory_mapping_test.cpp | 23
   branches/proto/v4/libs/interprocess/test/tree_test.cpp | 2
   branches/proto/v4/libs/interprocess/test/vector_test.cpp | 15
   branches/proto/v4/libs/interprocess/test/windows_shared_memory_mapping_test.cpp | 143 +-
   branches/proto/v4/libs/interprocess/test/windows_shared_memory_test.cpp | 1
   branches/proto/v4/libs/intrusive/doc/intrusive.qbk | 176 +++
   branches/proto/v4/libs/intrusive/index.html | 2
   branches/proto/v4/libs/intrusive/perf/perf_list.cpp | 2
   branches/proto/v4/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj | 8
   branches/proto/v4/libs/intrusive/test/avl_set_test.cpp | 1
   branches/proto/v4/libs/intrusive/test/generic_assoc_test.hpp | 31
   branches/proto/v4/libs/intrusive/test/generic_set_test.hpp | 1
   branches/proto/v4/libs/intrusive/test/itestvalue.hpp | 61 +
   branches/proto/v4/libs/intrusive/test/smart_ptr.hpp | 56 -
   branches/proto/v4/libs/intrusive/test/unordered_multiset_test.cpp | 241 ++++-
   branches/proto/v4/libs/intrusive/test/unordered_set_test.cpp | 48
   branches/proto/v4/libs/math/test/common_factor_test.cpp | 4
   branches/proto/v4/libs/math/test/compile_test/instantiate.hpp | 14
   branches/proto/v4/libs/math/test/compile_test/sf_modf_incl_test.cpp | 2
   branches/proto/v4/libs/math/test/compile_test/sf_round_incl_test.cpp | 6
   branches/proto/v4/libs/math/test/compile_test/sf_trunc_incl_test.cpp | 6
   branches/proto/v4/libs/math/test/compile_test/test_compile_result.hpp | 2
   branches/proto/v4/libs/math/test/pow_test.cpp | 2
   branches/proto/v4/libs/math/test/test_rational_instances/test_rational_double4.cpp | 2
   branches/proto/v4/libs/math/test/test_rational_instances/test_rational_float4.cpp | 2
   branches/proto/v4/libs/math/test/test_rational_instances/test_rational_ldouble4.cpp | 2
   branches/proto/v4/libs/math/test/test_rational_instances/test_rational_real_concept4.cpp | 2
   branches/proto/v4/libs/math/test/test_rationals.cpp | 2
   branches/proto/v4/libs/math/test/test_round.cpp | 4
   branches/proto/v4/libs/math/vc71_fix/instantiate_all.cpp | 4
   branches/proto/v4/libs/mpi/doc/mpi.qbk | 2
   branches/proto/v4/libs/numeric/conversion/doc/conversion.qbk | 2
   branches/proto/v4/libs/optional/doc/optional.qbk | 2
   branches/proto/v4/libs/optional/index.html | 4
   branches/proto/v4/libs/optional/test/optional_test.cpp | 187 ++++
   branches/proto/v4/libs/python/doc/building.rst | 2
   branches/proto/v4/libs/python/doc/tutorial/doc/tutorial.qbk | 4
   branches/proto/v4/libs/python/doc/tutorial/index.html | 4
   branches/proto/v4/libs/regex/src/usinstances.cpp | 3
   branches/proto/v4/libs/regex/src/wc_regex_traits.cpp | 33
   branches/proto/v4/libs/smart_ptr/test/Jamfile.v2 | 1
   branches/proto/v4/libs/smart_ptr/test/esft_regtest.cpp | 37
   branches/proto/v4/libs/spirit/doc/notes/style_guide.qbk | 2
   branches/proto/v4/libs/spirit/doc/what_s_new.qbk | 2
   branches/proto/v4/libs/spirit/example/karma/Jamfile | 7
   branches/proto/v4/libs/spirit/example/karma/actions.cpp | 7
   branches/proto/v4/libs/spirit/example/karma/basic_facilities.cpp | 1
   branches/proto/v4/libs/spirit/example/karma/functor_facilities.cpp | 1
   branches/proto/v4/libs/spirit/example/karma/quick_start1.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/example1.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/example2.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/example3.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/example4.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/example5.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/example6.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/print_numbers.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/static_lexer/word_count_generate.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/static_lexer/word_count_static.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/strip_comments.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/strip_comments_lexer.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/word_count.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/word_count_functor.cpp | 1
   branches/proto/v4/libs/spirit/example/lex/word_count_lexer.cpp | 1
   branches/proto/v4/libs/spirit/example/qi/actions.cpp | 4
   branches/proto/v4/libs/spirit/example/qi/calc1.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/calc2.cpp | 22
   branches/proto/v4/libs/spirit/example/qi/calc3.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/calc3_lexer.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/calc4.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/calc5.cpp | 8
   branches/proto/v4/libs/spirit/example/qi/calc6/calc6.hpp | 3
   branches/proto/v4/libs/spirit/example/qi/calc6/calc6a.cpp | 4
   branches/proto/v4/libs/spirit/example/qi/calc7/calc7.hpp | 3
   branches/proto/v4/libs/spirit/example/qi/calc7/calc7a.cpp | 4
   branches/proto/v4/libs/spirit/example/qi/complex_number.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/employee.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/mini_c/mini_c.hpp | 1
   branches/proto/v4/libs/spirit/example/qi/mini_xml1.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/mini_xml2.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/mini_xml_karma.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/num_list.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/num_list2.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/num_list3.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/roman.cpp | 2
   branches/proto/v4/libs/spirit/example/qi/sum.cpp | 2
   branches/proto/v4/libs/spirit/test/karma/actions.cpp | 7
   branches/proto/v4/libs/spirit/test/karma/lazy.cpp | 10
   branches/proto/v4/libs/spirit/test/karma/list.cpp | 8
   branches/proto/v4/libs/spirit/test/karma/pattern.cpp | 38
   branches/proto/v4/libs/spirit/test/karma/real_numerics.cpp | 6
   branches/proto/v4/libs/spirit/test/karma/test.hpp | 4
   branches/proto/v4/libs/spirit/test/lex/lexertl3.cpp | 1
   branches/proto/v4/libs/spirit/test/lex/lexertl4.cpp | 1
   branches/proto/v4/libs/spirit/test/lex/lexertl5.cpp | 1
   branches/proto/v4/libs/spirit/test/qi/debug.cpp | 3
   branches/proto/v4/libs/spirit/test/qi/difference.cpp | 7
   branches/proto/v4/libs/spirit/test/qi/grammar.cpp | 44 +
   branches/proto/v4/libs/spirit/test/qi/kleene.cpp | 8
   branches/proto/v4/libs/spirit/test/qi/plus.cpp | 8
   branches/proto/v4/libs/spirit/test/qi/range_run.cpp | 4
   branches/proto/v4/libs/spirit/test/qi/real.cpp | 4
   branches/proto/v4/libs/spirit/test/support/hold_any.cpp | 16
   branches/proto/v4/libs/thread/doc/changes.qbk | 5
   branches/proto/v4/libs/thread/test/test_lock_concept.cpp | 61 +
   branches/proto/v4/libs/unordered/doc/ref.xml | 486 ++++++++++++
   branches/proto/v4/libs/unordered/test/exception/insert_exception_tests.cpp | 35
   branches/proto/v4/libs/unordered/test/helpers/equivalent.hpp | 23
   branches/proto/v4/libs/unordered/test/helpers/metafunctions.hpp | 29
   branches/proto/v4/libs/unordered/test/helpers/random_values.hpp | 4
   branches/proto/v4/libs/unordered/test/helpers/strong.hpp | 10
   branches/proto/v4/libs/unordered/test/helpers/test.hpp | 2
   branches/proto/v4/libs/unordered/test/helpers/tracker.hpp | 31
   branches/proto/v4/libs/unordered/test/objects/exception.hpp | 10
   branches/proto/v4/libs/unordered/test/objects/minimal.hpp | 44 +
   branches/proto/v4/libs/unordered/test/objects/test.hpp | 7
   branches/proto/v4/libs/unordered/test/unordered/Jamfile.v2 | 1
   branches/proto/v4/libs/unordered/test/unordered/compile_map.cpp | 37
   branches/proto/v4/libs/unordered/test/unordered/compile_set.cpp | 30
   branches/proto/v4/libs/unordered/test/unordered/compile_tests.hpp | 39
   branches/proto/v4/libs/unordered/test/unordered/constructor_tests.cpp | 6
   branches/proto/v4/libs/unordered/test/unordered/equivalent_keys_tests.cpp | 4
   branches/proto/v4/libs/unordered/test/unordered/erase_equiv_tests.cpp | 16
   branches/proto/v4/libs/unordered/test/unordered/find_tests.cpp | 4
   branches/proto/v4/libs/unordered/test/unordered/insert_tests.cpp | 85 ++
   branches/proto/v4/libs/unordered/test/unordered/unnecessary_copy_tests.cpp | 236 +++++
   branches/proto/v4/libs/utility/shared_container_iterator.html | 2
   branches/proto/v4/libs/wave/test/testwave/testfiles/test.cfg | 456 +++++-----
   branches/proto/v4/status/Jamfile.v2 | 191 ++--
   branches/proto/v4/status/explicit-failures-markup.xml | 9
   branches/proto/v4/tools/build/v2/build/alias.jam | 31
   branches/proto/v4/tools/build/v2/build/generators.jam | 146 +--
   branches/proto/v4/tools/build/v2/build/modifiers.jam | 44
   branches/proto/v4/tools/build/v2/build/property.jam | 2
   branches/proto/v4/tools/build/v2/build/targets.jam | 137 ++-
   branches/proto/v4/tools/build/v2/build/virtual-target.jam | 65 +
   branches/proto/v4/tools/build/v2/doc/src/extending.xml | 16
   branches/proto/v4/tools/build/v2/doc/src/tutorial.xml | 119 +-
   branches/proto/v4/tools/build/v2/kernel/class.jam | 51
   branches/proto/v4/tools/build/v2/test/BoostBuild.py | 158 ++-
   branches/proto/v4/tools/build/v2/test/TestCmd.py | 321 ++++---
   branches/proto/v4/tools/build/v2/test/rebuilds.py | 2
   branches/proto/v4/tools/build/v2/test/test_all.py | 13
   branches/proto/v4/tools/build/v2/test/test_system.html | 388 +++++----
   branches/proto/v4/tools/build/v2/test/unit_test.py | 14
   branches/proto/v4/tools/build/v2/tools/builtin.jam | 23
   branches/proto/v4/tools/build/v2/tools/common.jam | 56
   branches/proto/v4/tools/build/v2/tools/intel-darwin.jam | 7
   branches/proto/v4/tools/build/v2/tools/make.jam | 58
   branches/proto/v4/tools/build/v2/tools/pathscale.jam | 4
   branches/proto/v4/tools/build/v2/tools/pgi.jam | 6
   branches/proto/v4/tools/build/v2/tools/stage.jam | 158 ++--
   branches/proto/v4/tools/build/v2/tools/testing.jam | 4
   branches/proto/v4/tools/build/v2/util/path.jam | 127 +-
   branches/proto/v4/tools/jam/doc/bjam.qbk | 12
   branches/proto/v4/tools/jam/src/compile.c | 11
   branches/proto/v4/tools/regression/src/regression.py | 93 +
   branches/proto/v4/tools/regression/src/run.py | 2
   410 files changed, 8757 insertions(+), 4075 deletions(-)

Modified: branches/proto/v4/Jamroot
==============================================================================
--- branches/proto/v4/Jamroot (original)
+++ branches/proto/v4/Jamroot 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -497,7 +497,7 @@
 }
 
 # Make project ids of all libraries known.
-for local l in $(libraries)
+for local l in $(all-libraries)
 {
     use-project /boost/$(l) : libs/$(l)/build ;
 }

Modified: branches/proto/v4/boost/archive/impl/xml_iarchive_impl.ipp
==============================================================================
--- branches/proto/v4/boost/archive/impl/xml_iarchive_impl.ipp (original)
+++ branches/proto/v4/boost/archive/impl/xml_iarchive_impl.ipp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -143,7 +143,7 @@
 xml_iarchive_impl<Archive>::load_override(class_name_type & t, int){
     const std::string & s = gimpl->rv.class_name;
     if(s.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)
- boost::throw_exception(archive_exception::invalid_class_name);
+ boost::throw_exception( archive_exception( archive_exception::invalid_class_name ) );
     char * tptr = t;
     std::memcpy(tptr, s.data(), s.size());
     tptr[s.size()] = '\0';

Modified: branches/proto/v4/boost/archive/impl/xml_wiarchive_impl.ipp
==============================================================================
--- branches/proto/v4/boost/archive/impl/xml_wiarchive_impl.ipp (original)
+++ branches/proto/v4/boost/archive/impl/xml_wiarchive_impl.ipp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -136,7 +136,7 @@
 xml_wiarchive_impl<Archive>::load_override(class_name_type & t, int){
     const std::wstring & ws = gimpl->rv.class_name;
     if(ws.size() > BOOST_SERIALIZATION_MAX_KEY_SIZE - 1)
- boost::throw_exception(archive_exception::invalid_class_name);
+ boost::throw_exception( archive_exception( archive_exception::invalid_class_name ) );
     copy_to_ptr(t, ws);
 }
 

Modified: branches/proto/v4/boost/asio.hpp
==============================================================================
--- branches/proto/v4/boost/asio.hpp (original)
+++ branches/proto/v4/boost/asio.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -20,6 +20,7 @@
 #include <boost/asio/basic_datagram_socket.hpp>
 #include <boost/asio/basic_deadline_timer.hpp>
 #include <boost/asio/basic_io_object.hpp>
+#include <boost/asio/basic_raw_socket.hpp>
 #include <boost/asio/basic_socket_acceptor.hpp>
 #include <boost/asio/basic_socket_iostream.hpp>
 #include <boost/asio/basic_socket_streambuf.hpp>
@@ -49,6 +50,7 @@
 #include <boost/asio/ip/basic_resolver_iterator.hpp>
 #include <boost/asio/ip/basic_resolver_query.hpp>
 #include <boost/asio/ip/host_name.hpp>
+#include <boost/asio/ip/icmp.hpp>
 #include <boost/asio/ip/multicast.hpp>
 #include <boost/asio/ip/resolver_query_base.hpp>
 #include <boost/asio/ip/resolver_service.hpp>
@@ -68,6 +70,7 @@
 #include <boost/asio/posix/descriptor_base.hpp>
 #include <boost/asio/posix/stream_descriptor.hpp>
 #include <boost/asio/posix/stream_descriptor_service.hpp>
+#include <boost/asio/raw_socket_service.hpp>
 #include <boost/asio/read.hpp>
 #include <boost/asio/read_until.hpp>
 #include <boost/asio/socket_acceptor_service.hpp>

Modified: branches/proto/v4/boost/asio/detail/descriptor_ops.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/descriptor_ops.hpp (original)
+++ branches/proto/v4/boost/asio/detail/descriptor_ops.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -67,13 +67,14 @@
   b.iov_len = size;
 }
 
-inline int readv(int d, buf* bufs, size_t count, boost::system::error_code& ec)
+inline int scatter_read(int d, buf* bufs, size_t count,
+ boost::system::error_code& ec)
 {
   clear_error(ec);
   return error_wrapper(::readv(d, bufs, static_cast<int>(count)), ec);
 }
 
-inline int writev(int d, const buf* bufs, size_t count,
+inline int gather_write(int d, const buf* bufs, size_t count,
     boost::system::error_code& ec)
 {
   clear_error(ec);

Modified: branches/proto/v4/boost/asio/detail/dev_poll_reactor.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/dev_poll_reactor.hpp (original)
+++ branches/proto/v4/boost/asio/detail/dev_poll_reactor.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -54,6 +54,11 @@
   : public boost::asio::detail::service_base<dev_poll_reactor<Own_Thread> >
 {
 public:
+ // Per-descriptor data.
+ struct per_descriptor_data
+ {
+ };
+
   // Constructor.
   dev_poll_reactor(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
@@ -116,11 +121,11 @@
     for (std::size_t i = 0; i < timer_queues_.size(); ++i)
       timer_queues_[i]->destroy_timers();
     timer_queues_.clear();
- }
+ }
 
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
- int register_descriptor(socket_type descriptor)
+ int register_descriptor(socket_type, per_descriptor_data&)
   {
     return 0;
   }
@@ -128,8 +133,8 @@
   // Start a new read operation. The handler object will be invoked when the
   // given descriptor is ready to be read, or an error has occurred.
   template <typename Handler>
- void start_read_op(socket_type descriptor, Handler handler,
- bool allow_speculative_read = true)
+ void start_read_op(socket_type descriptor, per_descriptor_data&,
+ Handler handler, bool allow_speculative_read = true)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
@@ -156,8 +161,8 @@
   // Start a new write operation. The handler object will be invoked when the
   // given descriptor is ready to be written, or an error has occurred.
   template <typename Handler>
- void start_write_op(socket_type descriptor, Handler handler,
- bool allow_speculative_write = true)
+ void start_write_op(socket_type descriptor, per_descriptor_data&,
+ Handler handler, bool allow_speculative_write = true)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
@@ -184,7 +189,8 @@
   // Start a new exception operation. The handler object will be invoked when
   // the given descriptor has exception information, or an error has occurred.
   template <typename Handler>
- void start_except_op(socket_type descriptor, Handler handler)
+ void start_except_op(socket_type descriptor,
+ per_descriptor_data&, Handler handler)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
@@ -203,26 +209,25 @@
     }
   }
 
- // Start new write and exception operations. The handler object will be
- // invoked when the given descriptor is ready for writing or has exception
+ // Start a new write operation. The handler object will be invoked when the
   // information available, or an error has occurred.
   template <typename Handler>
- void start_write_and_except_ops(socket_type descriptor, Handler handler)
+ void start_connect_op(socket_type descriptor,
+ per_descriptor_data&, Handler handler)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
     if (shutdown_)
       return;
 
- bool need_mod = write_op_queue_.enqueue_operation(descriptor, handler);
- need_mod = except_op_queue_.enqueue_operation(descriptor, handler)
- && need_mod;
- if (need_mod)
+ if (write_op_queue_.enqueue_operation(descriptor, handler))
     {
       ::pollfd& ev = add_pending_event_change(descriptor);
- ev.events = POLLOUT | POLLPRI | POLLERR | POLLHUP;
+ ev.events = POLLOUT | POLLERR | POLLHUP;
       if (read_op_queue_.has_operation(descriptor))
         ev.events |= POLLIN;
+ if (except_op_queue_.has_operation(descriptor))
+ ev.events |= POLLPRI;
       interrupter_.interrupt();
     }
   }
@@ -230,25 +235,15 @@
   // Cancel all operations associated with the given descriptor. The
   // handlers associated with the descriptor will be invoked with the
   // operation_aborted error.
- void cancel_ops(socket_type descriptor)
+ void cancel_ops(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     cancel_ops_unlocked(descriptor);
   }
 
- // Enqueue cancellation of all operations associated with the given
- // descriptor. The handlers associated with the descriptor will be invoked
- // with the operation_aborted error. This function does not acquire the
- // dev_poll_reactor's mutex, and so should only be used from within a reactor
- // handler.
- void enqueue_cancel_ops_unlocked(socket_type descriptor)
- {
- pending_cancellations_.push_back(descriptor);
- }
-
   // Cancel any operations that are running against the descriptor and remove
   // its registration from the reactor.
- void close_descriptor(socket_type descriptor)
+ void close_descriptor(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 

Modified: branches/proto/v4/boost/asio/detail/epoll_reactor.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/epoll_reactor.hpp (original)
+++ branches/proto/v4/boost/asio/detail/epoll_reactor.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -54,6 +54,13 @@
   : public boost::asio::detail::service_base<epoll_reactor<Own_Thread> >
 {
 public:
+ // Per-descriptor data.
+ struct per_descriptor_data
+ {
+ bool allow_speculative_read;
+ bool allow_speculative_write;
+ };
+
   // Constructor.
   epoll_reactor(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<epoll_reactor<Own_Thread> >(io_service),
@@ -119,10 +126,14 @@
 
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
- int register_descriptor(socket_type descriptor)
+ int register_descriptor(socket_type descriptor,
+ per_descriptor_data& descriptor_data)
   {
     // No need to lock according to epoll documentation.
 
+ descriptor_data.allow_speculative_read = true;
+ descriptor_data.allow_speculative_write = true;
+
     epoll_event ev = { 0, { 0 } };
     ev.events = 0;
     ev.data.fd = descriptor;
@@ -135,9 +146,19 @@
   // Start a new read operation. The handler object will be invoked when the
   // given descriptor is ready to be read, or an error has occurred.
   template <typename Handler>
- void start_read_op(socket_type descriptor, Handler handler,
- bool allow_speculative_read = true)
+ void start_read_op(socket_type descriptor,
+ per_descriptor_data& descriptor_data,
+ Handler handler, bool allow_speculative_read = true)
   {
+ if (allow_speculative_read && descriptor_data.allow_speculative_read)
+ {
+ if (handler(boost::system::error_code()))
+ return;
+
+ // We only get one shot at a speculative read in this function.
+ allow_speculative_read = false;
+ }
+
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
     if (shutdown_)
@@ -146,8 +167,16 @@
     if (!allow_speculative_read)
       need_epoll_wait_ = true;
     else if (!read_op_queue_.has_operation(descriptor))
+ {
+ // Speculative reads are ok as there are no queued read operations.
+ descriptor_data.allow_speculative_read = true;
+
       if (handler(boost::system::error_code()))
         return;
+ }
+
+ // Speculative reads are not ok as there will be queued read operations.
+ descriptor_data.allow_speculative_read = false;
 
     if (read_op_queue_.enqueue_operation(descriptor, handler))
     {
@@ -174,9 +203,19 @@
   // Start a new write operation. The handler object will be invoked when the
   // given descriptor is ready to be written, or an error has occurred.
   template <typename Handler>
- void start_write_op(socket_type descriptor, Handler handler,
- bool allow_speculative_write = true)
+ void start_write_op(socket_type descriptor,
+ per_descriptor_data& descriptor_data,
+ Handler handler, bool allow_speculative_write = true)
   {
+ if (allow_speculative_write && descriptor_data.allow_speculative_write)
+ {
+ if (handler(boost::system::error_code()))
+ return;
+
+ // We only get one shot at a speculative write in this function.
+ allow_speculative_write = false;
+ }
+
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
     if (shutdown_)
@@ -185,8 +224,16 @@
     if (!allow_speculative_write)
       need_epoll_wait_ = true;
     else if (!write_op_queue_.has_operation(descriptor))
+ {
+ // Speculative writes are ok as there are no queued write operations.
+ descriptor_data.allow_speculative_write = true;
+
       if (handler(boost::system::error_code()))
         return;
+ }
+
+ // Speculative writes are not ok as there will be queued write operations.
+ descriptor_data.allow_speculative_write = false;
 
     if (write_op_queue_.enqueue_operation(descriptor, handler))
     {
@@ -213,7 +260,8 @@
   // Start a new exception operation. The handler object will be invoked when
   // the given descriptor has exception information, or an error has occurred.
   template <typename Handler>
- void start_except_op(socket_type descriptor, Handler handler)
+ void start_except_op(socket_type descriptor,
+ per_descriptor_data&, Handler handler)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
@@ -242,26 +290,29 @@
     }
   }
 
- // Start new write and exception operations. The handler object will be
- // invoked when the given descriptor is ready for writing or has exception
- // information available, or an error has occurred.
+ // Start a new write operation. The handler object will be invoked when the
+ // given descriptor is ready for writing or an error has occurred. Speculative
+ // writes are not allowed.
   template <typename Handler>
- void start_write_and_except_ops(socket_type descriptor, Handler handler)
+ void start_connect_op(socket_type descriptor,
+ per_descriptor_data& descriptor_data, Handler handler)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
     if (shutdown_)
       return;
 
- bool need_mod = write_op_queue_.enqueue_operation(descriptor, handler);
- need_mod = except_op_queue_.enqueue_operation(descriptor, handler)
- && need_mod;
- if (need_mod)
+ // Speculative writes are not ok as there will be queued write operations.
+ descriptor_data.allow_speculative_write = false;
+
+ if (write_op_queue_.enqueue_operation(descriptor, handler))
     {
       epoll_event ev = { 0, { 0 } };
- ev.events = EPOLLOUT | EPOLLPRI | EPOLLERR | EPOLLHUP;
+ ev.events = EPOLLOUT | EPOLLERR | EPOLLHUP;
       if (read_op_queue_.has_operation(descriptor))
         ev.events |= EPOLLIN;
+ if (except_op_queue_.has_operation(descriptor))
+ ev.events |= EPOLLPRI;
       ev.data.fd = descriptor;
 
       int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
@@ -272,7 +323,6 @@
         boost::system::error_code ec(errno,
             boost::asio::error::get_system_category());
         write_op_queue_.dispatch_all_operations(descriptor, ec);
- except_op_queue_.dispatch_all_operations(descriptor, ec);
       }
     }
   }
@@ -280,25 +330,15 @@
   // Cancel all operations associated with the given descriptor. The
   // handlers associated with the descriptor will be invoked with the
   // operation_aborted error.
- void cancel_ops(socket_type descriptor)
+ void cancel_ops(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     cancel_ops_unlocked(descriptor);
   }
 
- // Enqueue cancellation of all operations associated with the given
- // descriptor. The handlers associated with the descriptor will be invoked
- // with the operation_aborted error. This function does not acquire the
- // epoll_reactor's mutex, and so should only be used from within a reactor
- // handler.
- void enqueue_cancel_ops_unlocked(socket_type descriptor)
- {
- pending_cancellations_.push_back(descriptor);
- }
-
   // Cancel any operations that are running against the descriptor and remove
   // its registration from the reactor.
- void close_descriptor(socket_type descriptor)
+ void close_descriptor(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 

Modified: branches/proto/v4/boost/asio/detail/kqueue_reactor.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/kqueue_reactor.hpp (original)
+++ branches/proto/v4/boost/asio/detail/kqueue_reactor.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -61,6 +61,11 @@
   : public boost::asio::detail::service_base<kqueue_reactor<Own_Thread> >
 {
 public:
+ // Per-descriptor data.
+ struct per_descriptor_data
+ {
+ };
+
   // Constructor.
   kqueue_reactor(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
@@ -127,7 +132,7 @@
 
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
- int register_descriptor(socket_type)
+ int register_descriptor(socket_type, per_descriptor_data&)
   {
     return 0;
   }
@@ -135,8 +140,8 @@
   // Start a new read operation. The handler object will be invoked when the
   // given descriptor is ready to be read, or an error has occurred.
   template <typename Handler>
- void start_read_op(socket_type descriptor, Handler handler,
- bool allow_speculative_read = true)
+ void start_read_op(socket_type descriptor, per_descriptor_data&,
+ Handler handler, bool allow_speculative_read = true)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
@@ -165,8 +170,8 @@
   // Start a new write operation. The handler object will be invoked when the
   // given descriptor is ready to be written, or an error has occurred.
   template <typename Handler>
- void start_write_op(socket_type descriptor, Handler handler,
- bool allow_speculative_write = true)
+ void start_write_op(socket_type descriptor, per_descriptor_data&,
+ Handler handler, bool allow_speculative_write = true)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
@@ -195,7 +200,8 @@
   // Start a new exception operation. The handler object will be invoked when
   // the given descriptor has exception information, or an error has occurred.
   template <typename Handler>
- void start_except_op(socket_type descriptor, Handler handler)
+ void start_except_op(socket_type descriptor,
+ per_descriptor_data&, Handler handler)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
@@ -218,11 +224,11 @@
     }
   }
 
- // Start new write and exception operations. The handler object will be
- // invoked when the given descriptor is ready for writing or has exception
- // information available, or an error has occurred.
+ // Start a new write operation. The handler object will be invoked when the
+ // given descriptor is ready to be written, or an error has occurred.
   template <typename Handler>
- void start_write_and_except_ops(socket_type descriptor, Handler handler)
+ void start_connect_op(socket_type descriptor,
+ per_descriptor_data&, Handler handler)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 
@@ -240,46 +246,20 @@
         write_op_queue_.dispatch_all_operations(descriptor, ec);
       }
     }
-
- if (except_op_queue_.enqueue_operation(descriptor, handler))
- {
- struct kevent event;
- if (read_op_queue_.has_operation(descriptor))
- EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
- else
- EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
- if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
- {
- boost::system::error_code ec(errno,
- boost::asio::error::get_system_category());
- except_op_queue_.dispatch_all_operations(descriptor, ec);
- write_op_queue_.dispatch_all_operations(descriptor, ec);
- }
- }
   }
 
   // Cancel all operations associated with the given descriptor. The
   // handlers associated with the descriptor will be invoked with the
   // operation_aborted error.
- void cancel_ops(socket_type descriptor)
+ void cancel_ops(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     cancel_ops_unlocked(descriptor);
   }
 
- // Enqueue cancellation of all operations associated with the given
- // descriptor. The handlers associated with the descriptor will be invoked
- // with the operation_aborted error. This function does not acquire the
- // kqueue_reactor's mutex, and so should only be used from within a reactor
- // handler.
- void enqueue_cancel_ops_unlocked(socket_type descriptor)
- {
- pending_cancellations_.push_back(descriptor);
- }
-
   // Cancel any operations that are running against the descriptor and remove
   // its registration from the reactor.
- void close_descriptor(socket_type descriptor)
+ void close_descriptor(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
 

Modified: branches/proto/v4/boost/asio/detail/push_options.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/push_options.hpp (original)
+++ branches/proto/v4/boost/asio/detail/push_options.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -87,8 +87,10 @@
 
 # pragma warning (disable:4103)
 # pragma warning (push)
+# pragma warning (disable:4127)
 # pragma warning (disable:4244)
 # pragma warning (disable:4355)
+# pragma warning (disable:4512)
 # pragma warning (disable:4675)
 # if defined(_M_IX86) && defined(_Wp64)
 // The /Wp64 option is broken. If you want to check 64 bit portability, use a

Modified: branches/proto/v4/boost/asio/detail/reactive_descriptor_service.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/reactive_descriptor_service.hpp (original)
+++ branches/proto/v4/boost/asio/detail/reactive_descriptor_service.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -67,6 +67,9 @@
 
     // Flags indicating the current state of the descriptor.
     unsigned char flags_;
+
+ // Per-descriptor data used by the reactor.
+ typename Reactor::per_descriptor_data reactor_data_;
   };
 
   // The maximum number of buffers to support in a single operation.
@@ -97,7 +100,7 @@
   {
     if (impl.descriptor_ != -1)
     {
- reactor_.close_descriptor(impl.descriptor_);
+ reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_);
 
       if (impl.flags_ & implementation_type::internal_non_blocking)
       {
@@ -125,7 +128,8 @@
       return ec;
     }
 
- if (int err = reactor_.register_descriptor(native_descriptor))
+ if (int err = reactor_.register_descriptor(
+ native_descriptor, impl.reactor_data_))
     {
       ec = boost::system::error_code(err,
           boost::asio::error::get_system_category());
@@ -150,7 +154,7 @@
   {
     if (is_open(impl))
     {
- reactor_.close_descriptor(impl.descriptor_);
+ reactor_.close_descriptor(impl.descriptor_, impl.reactor_data_);
 
       if (impl.flags_ & implementation_type::internal_non_blocking)
       {
@@ -187,7 +191,7 @@
       return ec;
     }
 
- reactor_.cancel_ops(impl.descriptor_);
+ reactor_.cancel_ops(impl.descriptor_, impl.reactor_data_);
     ec = boost::system::error_code();
     return ec;
   }
@@ -269,7 +273,8 @@
     for (;;)
     {
       // Try to complete the operation without blocking.
- int bytes_sent = descriptor_ops::writev(impl.descriptor_, bufs, i, ec);
+ int bytes_sent = descriptor_ops::gather_write(
+ impl.descriptor_, bufs, i, ec);
 
       // Check if operation succeeded.
       if (bytes_sent >= 0)
@@ -341,7 +346,7 @@
 
       // Write the data.
       boost::system::error_code ec;
- int bytes = descriptor_ops::writev(descriptor_, bufs, i, ec);
+ int bytes = descriptor_ops::gather_write(descriptor_, bufs, i, ec);
 
       // Check if we need to run the operation again.
       if (ec == boost::asio::error::would_block
@@ -405,7 +410,7 @@
         impl.flags_ |= implementation_type::internal_non_blocking;
       }
 
- reactor_.start_write_op(impl.descriptor_,
+ reactor_.start_write_op(impl.descriptor_, impl.reactor_data_,
           write_handler<ConstBufferSequence, Handler>(
             impl.descriptor_, this->get_io_service(), buffers, handler));
     }
@@ -444,7 +449,7 @@
     }
     else
     {
- reactor_.start_write_op(impl.descriptor_,
+ reactor_.start_write_op(impl.descriptor_, impl.reactor_data_,
           null_buffers_handler<Handler>(this->get_io_service(), handler),
           false);
     }
@@ -499,7 +504,8 @@
     for (;;)
     {
       // Try to complete the operation without blocking.
- int bytes_read = descriptor_ops::readv(impl.descriptor_, bufs, i, ec);
+ int bytes_read = descriptor_ops::scatter_read(
+ impl.descriptor_, bufs, i, ec);
 
       // Check if operation succeeded.
       if (bytes_read > 0)
@@ -526,7 +532,7 @@
 
   // Wait until data can be read without blocking.
   size_t read_some(implementation_type& impl,
- const null_buffers& buffers, boost::system::error_code& ec)
+ const null_buffers&, boost::system::error_code& ec)
   {
     if (!is_open(impl))
     {
@@ -578,7 +584,7 @@
 
       // Read some data.
       boost::system::error_code ec;
- int bytes = descriptor_ops::readv(descriptor_, bufs, i, ec);
+ int bytes = descriptor_ops::scatter_read(descriptor_, bufs, i, ec);
       if (bytes == 0)
         ec = boost::asio::error::eof;
 
@@ -644,7 +650,7 @@
         impl.flags_ |= implementation_type::internal_non_blocking;
       }
 
- reactor_.start_read_op(impl.descriptor_,
+ reactor_.start_read_op(impl.descriptor_, impl.reactor_data_,
           read_handler<MutableBufferSequence, Handler>(
             impl.descriptor_, this->get_io_service(), buffers, handler));
     }
@@ -662,7 +668,7 @@
     }
     else
     {
- reactor_.start_read_op(impl.descriptor_,
+ reactor_.start_read_op(impl.descriptor_, impl.reactor_data_,
           null_buffers_handler<Handler>(this->get_io_service(), handler),
           false);
     }

Modified: branches/proto/v4/boost/asio/detail/reactive_socket_service.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/reactive_socket_service.hpp (original)
+++ branches/proto/v4/boost/asio/detail/reactive_socket_service.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -84,6 +84,9 @@
 
     // The protocol associated with the socket.
     protocol_type protocol_;
+
+ // Per-descriptor data used by the reactor.
+ typename Reactor::per_descriptor_data reactor_data_;
   };
 
   // The maximum number of buffers to support in a single operation.
@@ -114,7 +117,7 @@
   {
     if (impl.socket_ != invalid_socket)
     {
- reactor_.close_descriptor(impl.socket_);
+ reactor_.close_descriptor(impl.socket_, impl.reactor_data_);
 
       if (impl.flags_ & implementation_type::internal_non_blocking)
       {
@@ -156,7 +159,7 @@
     if (sock.get() == invalid_socket)
       return ec;
 
- if (int err = reactor_.register_descriptor(sock.get()))
+ if (int err = reactor_.register_descriptor(sock.get(), impl.reactor_data_))
     {
       ec = boost::system::error_code(err,
           boost::asio::error::get_system_category());
@@ -181,7 +184,8 @@
       return ec;
     }
 
- if (int err = reactor_.register_descriptor(native_socket))
+ if (int err = reactor_.register_descriptor(
+ native_socket, impl.reactor_data_))
     {
       ec = boost::system::error_code(err,
           boost::asio::error::get_system_category());
@@ -207,7 +211,7 @@
   {
     if (is_open(impl))
     {
- reactor_.close_descriptor(impl.socket_);
+ reactor_.close_descriptor(impl.socket_, impl.reactor_data_);
 
       if (impl.flags_ & implementation_type::internal_non_blocking)
       {
@@ -243,7 +247,7 @@
       return ec;
     }
 
- reactor_.cancel_ops(impl.socket_);
+ reactor_.cancel_ops(impl.socket_, impl.reactor_data_);
     ec = boost::system::error_code();
     return ec;
   }
@@ -683,7 +687,7 @@
         impl.flags_ |= implementation_type::internal_non_blocking;
       }
 
- reactor_.start_write_op(impl.socket_,
+ reactor_.start_write_op(impl.socket_, impl.reactor_data_,
           send_handler<ConstBufferSequence, Handler>(
             impl.socket_, this->get_io_service(), buffers, flags, handler));
     }
@@ -722,7 +726,7 @@
     }
     else
     {
- reactor_.start_write_op(impl.socket_,
+ reactor_.start_write_op(impl.socket_, impl.reactor_data_,
           null_buffers_handler<Handler>(this->get_io_service(), handler),
           false);
     }
@@ -897,7 +901,7 @@
         impl.flags_ |= implementation_type::internal_non_blocking;
       }
 
- reactor_.start_write_op(impl.socket_,
+ reactor_.start_write_op(impl.socket_, impl.reactor_data_,
           send_to_handler<ConstBufferSequence, Handler>(
             impl.socket_, this->get_io_service(), buffers,
             destination, flags, handler));
@@ -916,7 +920,7 @@
     }
     else
     {
- reactor_.start_write_op(impl.socket_,
+ reactor_.start_write_op(impl.socket_, impl.reactor_data_,
           null_buffers_handler<Handler>(this->get_io_service(), handler),
           false);
     }
@@ -998,8 +1002,7 @@
   }
 
   // Wait until data can be received without blocking.
- size_t receive(implementation_type& impl,
- const null_buffers& buffers,
+ size_t receive(implementation_type& impl, const null_buffers&,
       socket_base::message_flags, boost::system::error_code& ec)
   {
     if (!is_open(impl))
@@ -1127,13 +1130,13 @@
 
       if (flags & socket_base::message_out_of_band)
       {
- reactor_.start_except_op(impl.socket_,
+ reactor_.start_except_op(impl.socket_, impl.reactor_data_,
             receive_handler<MutableBufferSequence, Handler>(
               impl.socket_, this->get_io_service(), buffers, flags, handler));
       }
       else
       {
- reactor_.start_read_op(impl.socket_,
+ reactor_.start_read_op(impl.socket_, impl.reactor_data_,
             receive_handler<MutableBufferSequence, Handler>(
               impl.socket_, this->get_io_service(), buffers, flags, handler));
       }
@@ -1152,12 +1155,12 @@
     }
     else if (flags & socket_base::message_out_of_band)
     {
- reactor_.start_except_op(impl.socket_,
+ reactor_.start_except_op(impl.socket_, impl.reactor_data_,
           null_buffers_handler<Handler>(this->get_io_service(), handler));
     }
     else
     {
- reactor_.start_read_op(impl.socket_,
+ reactor_.start_read_op(impl.socket_, impl.reactor_data_,
           null_buffers_handler<Handler>(this->get_io_service(), handler),
           false);
     }
@@ -1237,9 +1240,9 @@
   }
 
   // Wait until data can be received without blocking.
- size_t receive_from(implementation_type& impl,
- const null_buffers& buffers, endpoint_type& sender_endpoint,
- socket_base::message_flags, boost::system::error_code& ec)
+ size_t receive_from(implementation_type& impl, const null_buffers&,
+ endpoint_type& sender_endpoint, socket_base::message_flags,
+ boost::system::error_code& ec)
   {
     if (!is_open(impl))
     {
@@ -1352,7 +1355,7 @@
         impl.flags_ |= implementation_type::internal_non_blocking;
       }
 
- reactor_.start_read_op(impl.socket_,
+ reactor_.start_read_op(impl.socket_, impl.reactor_data_,
           receive_from_handler<MutableBufferSequence, Handler>(
             impl.socket_, this->get_io_service(), buffers,
             sender_endpoint, flags, handler));
@@ -1377,12 +1380,12 @@
 
       if (flags & socket_base::message_out_of_band)
       {
- reactor_.start_except_op(impl.socket_,
+ reactor_.start_except_op(impl.socket_, impl.reactor_data_,
             null_buffers_handler<Handler>(this->get_io_service(), handler));
       }
       else
       {
- reactor_.start_read_op(impl.socket_,
+ reactor_.start_read_op(impl.socket_, impl.reactor_data_,
             null_buffers_handler<Handler>(this->get_io_service(), handler),
             false);
       }
@@ -1590,7 +1593,7 @@
         impl.flags_ |= implementation_type::internal_non_blocking;
       }
 
- reactor_.start_read_op(impl.socket_,
+ reactor_.start_read_op(impl.socket_, impl.reactor_data_,
           accept_handler<Socket, Handler>(
             impl.socket_, this->get_io_service(),
             peer, impl.protocol_, peer_endpoint,
@@ -1628,28 +1631,17 @@
   class connect_handler
   {
   public:
- connect_handler(socket_type socket, boost::shared_ptr<bool> completed,
- boost::asio::io_service& io_service, Reactor& reactor, Handler handler)
+ connect_handler(socket_type socket,
+ boost::asio::io_service& io_service, Handler handler)
       : socket_(socket),
- completed_(completed),
         io_service_(io_service),
         work_(io_service),
- reactor_(reactor),
         handler_(handler)
     {
     }
 
     bool operator()(const boost::system::error_code& result)
     {
- // Check whether a handler has already been called for the connection.
- // If it has, then we don't want to do anything in this handler.
- if (*completed_)
- return true;
-
- // Cancel the other reactor operation for the connection.
- *completed_ = true;
- reactor_.enqueue_cancel_ops_unlocked(socket_);
-
       // Check whether the operation was successful.
       if (result)
       {
@@ -1684,10 +1676,8 @@
 
   private:
     socket_type socket_;
- boost::shared_ptr<bool> completed_;
     boost::asio::io_service& io_service_;
     boost::asio::io_service::work work_;
- Reactor& reactor_;
     Handler handler_;
   };
 
@@ -1732,10 +1722,9 @@
     {
       // The connection is happening in the background, and we need to wait
       // until the socket becomes writeable.
- boost::shared_ptr<bool> completed(new bool(false));
- reactor_.start_write_and_except_ops(impl.socket_,
- connect_handler<Handler>(impl.socket_, completed,
- this->get_io_service(), reactor_, handler));
+ reactor_.start_connect_op(impl.socket_, impl.reactor_data_,
+ connect_handler<Handler>(impl.socket_,
+ this->get_io_service(), handler));
     }
     else
     {

Modified: branches/proto/v4/boost/asio/detail/select_reactor.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/select_reactor.hpp (original)
+++ branches/proto/v4/boost/asio/detail/select_reactor.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -23,6 +23,7 @@
 #include <cstddef>
 #include <boost/config.hpp>
 #include <boost/date_time/posix_time/posix_time_types.hpp>
+#include <boost/shared_ptr.hpp>
 #include <vector>
 #include <boost/asio/detail/pop_options.hpp>
 
@@ -51,6 +52,11 @@
   : public boost::asio::detail::service_base<select_reactor<Own_Thread> >
 {
 public:
+ // Per-descriptor data.
+ struct per_descriptor_data
+ {
+ };
+
   // Constructor.
   select_reactor(boost::asio::io_service& io_service)
     : boost::asio::detail::service_base<
@@ -107,7 +113,7 @@
 
   // Register a socket with the reactor. Returns 0 on success, system error
   // code on failure.
- int register_descriptor(socket_type descriptor)
+ int register_descriptor(socket_type, per_descriptor_data&)
   {
     return 0;
   }
@@ -115,8 +121,8 @@
   // Start a new read operation. The handler object will be invoked when the
   // given descriptor is ready to be read, or an error has occurred.
   template <typename Handler>
- void start_read_op(socket_type descriptor, Handler handler,
- bool /*allow_speculative_read*/ = true)
+ void start_read_op(socket_type descriptor, per_descriptor_data&,
+ Handler handler, bool /*allow_speculative_read*/ = true)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
@@ -127,8 +133,8 @@
   // Start a new write operation. The handler object will be invoked when the
   // given descriptor is ready to be written, or an error has occurred.
   template <typename Handler>
- void start_write_op(socket_type descriptor, Handler handler,
- bool /*allow_speculative_write*/ = true)
+ void start_write_op(socket_type descriptor, per_descriptor_data&,
+ Handler handler, bool /*allow_speculative_write*/ = true)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
@@ -139,7 +145,8 @@
   // Start a new exception operation. The handler object will be invoked when
   // the given descriptor has exception information, or an error has occurred.
   template <typename Handler>
- void start_except_op(socket_type descriptor, Handler handler)
+ void start_except_op(socket_type descriptor,
+ per_descriptor_data&, Handler handler)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
@@ -147,18 +154,63 @@
         interrupter_.interrupt();
   }
 
+ // Wrapper for connect handlers to enable the handler object to be placed
+ // in both the write and the except operation queues, but ensure that only
+ // one of the handlers is called.
+ template <typename Handler>
+ class connect_handler_wrapper
+ {
+ public:
+ connect_handler_wrapper(socket_type descriptor,
+ boost::shared_ptr<bool> completed,
+ select_reactor<Own_Thread>& reactor, Handler handler)
+ : descriptor_(descriptor),
+ completed_(completed),
+ reactor_(reactor),
+ handler_(handler)
+ {
+ }
+
+ bool operator()(const boost::system::error_code& result)
+ {
+ // Check whether one of the handlers has already been called. If it has,
+ // then we don't want to do anything in this handler.
+ if (*completed_)
+ return true;
+
+ // Cancel the other reactor operation for the connection.
+ *completed_ = true;
+ reactor_.enqueue_cancel_ops_unlocked(descriptor_);
+
+ // Call the contained handler.
+ return handler_(result);
+ }
+
+ private:
+ socket_type descriptor_;
+ boost::shared_ptr<bool> completed_;
+ select_reactor<Own_Thread>& reactor_;
+ Handler handler_;
+ };
+
   // Start new write and exception operations. The handler object will be
   // invoked when the given descriptor is ready for writing or has exception
- // information available, or an error has occurred.
+ // information available, or an error has occurred. The handler will be called
+ // only once.
   template <typename Handler>
- void start_write_and_except_ops(socket_type descriptor, Handler handler)
+ void start_connect_op(socket_type descriptor,
+ per_descriptor_data&, Handler handler)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     if (!shutdown_)
     {
- bool interrupt = write_op_queue_.enqueue_operation(descriptor, handler);
- interrupt = except_op_queue_.enqueue_operation(descriptor, handler)
- || interrupt;
+ boost::shared_ptr<bool> completed(new bool(false));
+ connect_handler_wrapper<Handler> wrapped_handler(
+ descriptor, completed, *this, handler);
+ bool interrupt = write_op_queue_.enqueue_operation(
+ descriptor, wrapped_handler);
+ interrupt = except_op_queue_.enqueue_operation(
+ descriptor, wrapped_handler) || interrupt;
       if (interrupt)
         interrupter_.interrupt();
     }
@@ -167,7 +219,7 @@
   // Cancel all operations associated with the given descriptor. The
   // handlers associated with the descriptor will be invoked with the
   // operation_aborted error.
- void cancel_ops(socket_type descriptor)
+ void cancel_ops(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     cancel_ops_unlocked(descriptor);
@@ -176,8 +228,8 @@
   // Enqueue cancellation of all operations associated with the given
   // descriptor. The handlers associated with the descriptor will be invoked
   // with the operation_aborted error. This function does not acquire the
- // select_reactor's mutex, and so should only be used from within a reactor
- // handler.
+ // select_reactor's mutex, and so should only be used when the reactor lock is
+ // already held.
   void enqueue_cancel_ops_unlocked(socket_type descriptor)
   {
     pending_cancellations_.push_back(descriptor);
@@ -185,7 +237,7 @@
 
   // Cancel any operations that are running against the descriptor and remove
   // its registration from the reactor.
- void close_descriptor(socket_type descriptor)
+ void close_descriptor(socket_type descriptor, per_descriptor_data&)
   {
     boost::asio::detail::mutex::scoped_lock lock(mutex_);
     cancel_ops_unlocked(descriptor);

Modified: branches/proto/v4/boost/asio/detail/socket_ops.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/socket_ops.hpp (original)
+++ branches/proto/v4/boost/asio/detail/socket_ops.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -180,6 +180,10 @@
     socket_type sv[2], boost::system::error_code& ec)
 {
 #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
+ (void)(af);
+ (void)(type);
+ (void)(protocol);
+ (void)(sv);
   ec = boost::asio::error::operation_not_supported;
   return -1;
 #else

Modified: branches/proto/v4/boost/asio/detail/task_io_service.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/task_io_service.hpp (original)
+++ branches/proto/v4/boost/asio/detail/task_io_service.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -15,6 +15,10 @@
 # pragma once
 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
 
+#if defined(BOOST_ASIO_ENABLE_TWO_LOCK_QUEUE)
+#include <boost/asio/detail/task_io_service_2lock.hpp>
+#else // defined(BOOST_ASIO_ENABLE_TWO_LOCK_QUEUE)
+
 #include <boost/asio/detail/push_options.hpp>
 
 #include <boost/asio/io_service.hpp>
@@ -418,4 +422,6 @@
 #include <boost/system/error_code.hpp>
 #include <boost/asio/detail/pop_options.hpp>
 
+#endif // defined(BOOST_ASIO_ENABLE_TWO_LOCK_QUEUE)
+
 #endif // BOOST_ASIO_DETAIL_TASK_IO_SERVICE_HPP

Modified: branches/proto/v4/boost/asio/detail/win_iocp_socket_service.hpp
==============================================================================
--- branches/proto/v4/boost/asio/detail/win_iocp_socket_service.hpp (original)
+++ branches/proto/v4/boost/asio/detail/win_iocp_socket_service.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -114,6 +114,9 @@
     endpoint_type remote_endpoint_;
   };
 
+ // The type of the reactor used for connect operations.
+ typedef detail::select_reactor<true> reactor_type;
+
   // The implementation type of the socket.
   class implementation_type
   {
@@ -157,6 +160,9 @@
     // The protocol associated with the socket.
     protocol_type protocol_;
 
+ // Per-descriptor data used by the reactor.
+ reactor_type::per_descriptor_data reactor_data_;
+
 #if defined(BOOST_ASIO_ENABLE_CANCELIO)
     // The ID of the thread from which it is safe to cancel asynchronous
     // operations. 0 means no asynchronous operations have been started yet.
@@ -305,7 +311,7 @@
             interlocked_compare_exchange_pointer(
               reinterpret_cast<void**>(&reactor_), 0, 0));
       if (reactor)
- reactor->close_descriptor(impl.socket_);
+ reactor->close_descriptor(impl.socket_, impl.reactor_data_);
 
       if (socket_ops::close(impl.socket_, ec) == socket_error_retval)
         return ec;
@@ -335,6 +341,7 @@
     if (!is_open(impl))
     {
       ec = boost::asio::error::bad_descriptor;
+ return ec;
     }
     else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
           ::GetModuleHandleA("KERNEL32"), "CancelIoEx"))
@@ -922,7 +929,7 @@
             reinterpret_cast<void**>(&reactor_), reactor);
       }
 
- reactor->start_write_op(impl.socket_,
+ reactor->start_write_op(impl.socket_, impl.reactor_data_,
           null_buffers_handler<Handler>(this->get_io_service(), handler),
           false);
     }
@@ -1149,7 +1156,7 @@
             reinterpret_cast<void**>(&reactor_), reactor);
       }
 
- reactor->start_write_op(impl.socket_,
+ reactor->start_write_op(impl.socket_, impl.reactor_data_,
           null_buffers_handler<Handler>(this->get_io_service(), handler),
           false);
     }
@@ -1215,8 +1222,7 @@
   }
 
   // Wait until data can be received without blocking.
- size_t receive(implementation_type& impl,
- const null_buffers& buffers,
+ size_t receive(implementation_type& impl, const null_buffers&,
       socket_base::message_flags, boost::system::error_code& ec)
   {
     if (!is_open(impl))
@@ -1463,12 +1469,12 @@
 
       if (flags & socket_base::message_out_of_band)
       {
- reactor->start_except_op(impl.socket_,
+ reactor->start_except_op(impl.socket_, impl.reactor_data_,
             null_buffers_handler<Handler>(this->get_io_service(), handler));
       }
       else
       {
- reactor->start_read_op(impl.socket_,
+ reactor->start_read_op(impl.socket_, impl.reactor_data_,
             null_buffers_handler<Handler>(this->get_io_service(), handler),
             false);
       }
@@ -1530,7 +1536,7 @@
 
   // Wait until data can be received without blocking.
   size_t receive_from(implementation_type& impl,
- const null_buffers& buffers, endpoint_type& sender_endpoint,
+ const null_buffers&, endpoint_type& sender_endpoint,
       socket_base::message_flags, boost::system::error_code& ec)
   {
     if (!is_open(impl))
@@ -1736,12 +1742,12 @@
 
       if (flags & socket_base::message_out_of_band)
       {
- reactor->start_except_op(impl.socket_,
+ reactor->start_except_op(impl.socket_, impl.reactor_data_,
             null_buffers_handler<Handler>(this->get_io_service(), handler));
       }
       else
       {
- reactor->start_read_op(impl.socket_,
+ reactor->start_read_op(impl.socket_, impl.reactor_data_,
             null_buffers_handler<Handler>(this->get_io_service(), handler),
             false);
       }
@@ -1845,8 +1851,7 @@
     }
 
   private:
- static void do_completion_impl(operation* op,
- DWORD last_error, size_t bytes_transferred)
+ static void do_completion_impl(operation* op, DWORD last_error, size_t)
     {
       // Take ownership of the operation object.
       typedef accept_operation<Socket, Handler> op_type;
@@ -2111,14 +2116,10 @@
   {
   public:
     connect_handler(socket_type socket, bool user_set_non_blocking,
- boost::shared_ptr<bool> completed,
- boost::asio::io_service& io_service,
- reactor_type& reactor, Handler handler)
+ boost::asio::io_service& io_service, Handler handler)
       : socket_(socket),
         user_set_non_blocking_(user_set_non_blocking),
- completed_(completed),
         io_service_(io_service),
- reactor_(reactor),
         work_(io_service),
         handler_(handler)
     {
@@ -2126,15 +2127,6 @@
 
     bool operator()(const boost::system::error_code& result)
     {
- // Check whether a handler has already been called for the connection.
- // If it has, then we don't want to do anything in this handler.
- if (*completed_)
- return true;
-
- // Cancel the other reactor operation for the connection.
- *completed_ = true;
- reactor_.enqueue_cancel_ops_unlocked(socket_);
-
       // Check whether the operation was successful.
       if (result)
       {
@@ -2182,9 +2174,7 @@
   private:
     socket_type socket_;
     bool user_set_non_blocking_;
- boost::shared_ptr<bool> completed_;
     boost::asio::io_service& io_service_;
- reactor_type& reactor_;
     boost::asio::io_service::work work_;
     Handler handler_;
   };
@@ -2252,11 +2242,11 @@
       // The connection is happening in the background, and we need to wait
       // until the socket becomes writeable.
       boost::shared_ptr<bool> completed(new bool(false));
- reactor->start_write_and_except_ops(impl.socket_,
+ reactor->start_connect_op(impl.socket_, impl.reactor_data_,
           connect_handler<Handler>(
             impl.socket_,
             (impl.flags_ & implementation_type::user_set_non_blocking) != 0,
- completed, this->get_io_service(), *reactor, handler));
+ this->get_io_service(), handler));
     }
     else
     {
@@ -2287,7 +2277,7 @@
             interlocked_compare_exchange_pointer(
               reinterpret_cast<void**>(&reactor_), 0, 0));
       if (reactor)
- reactor->close_descriptor(impl.socket_);
+ reactor->close_descriptor(impl.socket_, impl.reactor_data_);
 
       // The socket destructor must not block. If the user has changed the
       // linger option to block in the foreground, we will change it back to the

Modified: branches/proto/v4/boost/asio/version.hpp
==============================================================================
--- branches/proto/v4/boost/asio/version.hpp (original)
+++ branches/proto/v4/boost/asio/version.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,6 +18,6 @@
 // BOOST_ASIO_VERSION % 100 is the sub-minor version
 // BOOST_ASIO_VERSION / 100 % 1000 is the minor version
 // BOOST_ASIO_VERSION / 100000 is the major version
-#define BOOST_ASIO_VERSION 100000 // 1.0.0
+#define BOOST_ASIO_VERSION 100100 // 1.1.0
 
 #endif // BOOST_ASIO_VERSION_HPP

Modified: branches/proto/v4/boost/config/compiler/intel.hpp
==============================================================================
--- branches/proto/v4/boost/config/compiler/intel.hpp (original)
+++ branches/proto/v4/boost/config/compiler/intel.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -146,6 +146,12 @@
 #if BOOST_INTEL_CXX_VERSION < 500
 # error "Compiler not supported or configured - please reconfigure"
 #endif
+
+// Intel on MacOS requires
+#if defined(__APPLE__) && defined(__INTEL_COMPILER)
+# define BOOST_NO_TWO_PHASE_NAME_LOOKUP
+#endif
+
 //
 // last known and checked version:
 #if (BOOST_INTEL_CXX_VERSION > 1010)

Modified: branches/proto/v4/boost/config/platform/macos.hpp
==============================================================================
--- branches/proto/v4/boost/config/platform/macos.hpp (original)
+++ branches/proto/v4/boost/config/platform/macos.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -47,6 +47,14 @@
 # define BOOST_NO_STDC_NAMESPACE
 # endif
 
+# if (__GNUC__ == 4)
+
+// Both gcc and intel require these.
+# define BOOST_HAS_PTHREAD_MUTEXATTR_SETTYPE
+# define BOOST_HAS_NANOSLEEP
+
+# endif
+
 #else
 
 // Using the MSL C library.

Modified: branches/proto/v4/boost/detail/shared_count.hpp
==============================================================================
--- branches/proto/v4/boost/detail/shared_count.hpp (original)
+++ branches/proto/v4/boost/detail/shared_count.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -104,11 +104,18 @@
 #endif
     }
 
- template<class P, class D> shared_count(P p, D d): pi_(0)
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
+ template<class Y, class D> shared_count( Y * p, D d ): pi_(0)
+#else
+ template<class P, class D> shared_count( P p, D d ): pi_(0)
+#endif
 #if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
         , id_(shared_count_id)
 #endif
     {
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1200 )
+ typedef Y* P;
+#endif
 #ifndef BOOST_NO_EXCEPTIONS
 
         try
@@ -220,6 +227,18 @@
         if( pi_ != 0 ) pi_->add_ref_copy();
     }
 
+#if defined( BOOST_HAS_RVALUE_REFS )
+
+ shared_count(shared_count && r): pi_(r.pi_) // nothrow
+#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
+ , id_(shared_count_id)
+#endif
+ {
+ r.pi_ = 0;
+ }
+
+#endif
+
     explicit shared_count(weak_count const & r); // throws bad_weak_ptr when r.use_count() == 0
     shared_count( weak_count const & r, sp_nothrow_tag ); // constructs an empty *this when r.use_count() == 0
 
@@ -361,6 +380,11 @@
         return pi_ != 0? pi_->use_count(): 0;
     }
 
+ bool empty() const // nothrow
+ {
+ return pi_ == 0;
+ }
+
     friend inline bool operator==(weak_count const & a, weak_count const & b)
     {
         return a.pi_ == b.pi_;

Modified: branches/proto/v4/boost/detail/spinlock_w32.hpp
==============================================================================
--- branches/proto/v4/boost/detail/spinlock_w32.hpp (original)
+++ branches/proto/v4/boost/detail/spinlock_w32.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -33,7 +33,7 @@
 
 #elif defined(__GNUC__)
 
-#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" ::: "memory" );
+#define BOOST_COMPILER_FENCE __asm__ __volatile__( "" : : : "memory" );
 
 #else
 

Modified: branches/proto/v4/boost/detail/yield_k.hpp
==============================================================================
--- branches/proto/v4/boost/detail/yield_k.hpp (original)
+++ branches/proto/v4/boost/detail/yield_k.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -36,7 +36,7 @@
 
 #elif defined(__GNUC__) && ( defined(__i386__) || defined(__x86_64__) )
 
-#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" ::: "memory" );
+#define BOOST_SMT_PAUSE __asm__ __volatile__( "rep; nop" : : : "memory" );
 
 #endif
 
@@ -111,7 +111,11 @@
     }
     else
     {
- struct timespec rqtp = { 0 };
+ // g++ -Wextra warns on {} or {0}
+ struct timespec rqtp = { 0, 0 };
+
+ // POSIX says that timespec has tv_sec and tv_nsec
+ // But it doesn't guarantee order or placement
 
         rqtp.tv_sec = 0;
         rqtp.tv_nsec = 1000;

Modified: branches/proto/v4/boost/enable_shared_from_this.hpp
==============================================================================
--- branches/proto/v4/boost/enable_shared_from_this.hpp (original)
+++ branches/proto/v4/boost/enable_shared_from_this.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,7 +13,6 @@
 // http://www.boost.org/libs/smart_ptr/enable_shared_from_this.html
 //
 
-#include <boost/weak_ptr.hpp>
 #include <boost/shared_ptr.hpp>
 #include <boost/assert.hpp>
 #include <boost/config.hpp>
@@ -21,40 +20,19 @@
 namespace boost
 {
 
-template<class T> class enable_shared_from_this
-{
-// dynamic cast to template type doesn't work in constructor, so we have
-// to use lazy initialization
- void init_internal_shared_once() const
- {
- if( !owned() && _internal_shared_this.get() == 0 )
- {
- T * p = dynamic_cast<T *>(const_cast<enable_shared_from_this*>(this));
- _internal_shared_this = shared_ptr<T>( p, detail::sp_deleter_wrapper() );
- BOOST_ASSERT(_internal_shared_this.get() == this);
- _internal_weak_this = _internal_shared_this;
- }
- }
-
- bool owned() const
- {
- return _owned;
- }
-
- typedef T _internal_element_type; // for bcc 5.5.1
- mutable shared_ptr<_internal_element_type> _internal_shared_this;
- mutable weak_ptr<_internal_element_type> _internal_weak_this;
- mutable bool _owned;
+template< class T > class enable_shared_from_this;
+template< class T, class Y > void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<T> const * pe );
+template< class T, class Y > void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<T> const * pe, void * /*pd*/ );
 
+template< class T > class enable_shared_from_this
+{
 protected:
 
- enable_shared_from_this():
- _owned(false)
+ enable_shared_from_this()
     {
     }
 
- enable_shared_from_this(enable_shared_from_this const &):
- _owned(false)
+ enable_shared_from_this(enable_shared_from_this const &)
     {
     }
 
@@ -66,74 +44,77 @@
 // virtual destructor because we need a vtable for dynamic_cast from base to derived to work
     virtual ~enable_shared_from_this()
     {
-// make sure no dangling shared_ptr objects were created by the
-// user calling shared_from_this() but never passing ownership of the object
-// to a shared_ptr.
- BOOST_ASSERT(owned() || _internal_shared_this.use_count() <= 1);
+ BOOST_ASSERT( _shared_count.use_count() <= 1 ); // make sure no dangling shared_ptr objects exist
     }
 
 public:
 
     shared_ptr<T> shared_from_this()
     {
- init_internal_shared_once();
- shared_ptr<T> p(_internal_weak_this);
- BOOST_ASSERT(p.get() == this);
- return p;
+ init_weak_once();
+ T * p = dynamic_cast<T *>( this );
+ return shared_ptr<T>( detail::shared_count( _weak_count ), p );
     }
 
     shared_ptr<T const> shared_from_this() const
     {
- init_internal_shared_once();
- shared_ptr<T const> p(_internal_weak_this);
- BOOST_ASSERT(p.get() == this);
- return p;
+ init_weak_once();
+ T const * p = dynamic_cast<T const *>( this );
+ return shared_ptr<T const>( detail::shared_count( _weak_count ), p );
+ }
+
+private:
+
+ mutable detail::weak_count _weak_count;
+ mutable detail::shared_count _shared_count;
+
+ void init_weak_once() const
+ {
+ if( _weak_count.empty() )
+ {
+ detail::shared_count( (void*)0, detail::sp_deleter_wrapper() ).swap( _shared_count );
+ _weak_count = _shared_count;
+ }
     }
 
     template<typename U>
- void _internal_accept_owner(shared_ptr<U> &owner) const
+ void sp_accept_owner( shared_ptr<U> & owner ) const
     {
- if( !_owned )
+ if( _weak_count.use_count() == 0 )
+ {
+ _weak_count = owner.get_shared_count();
+ }else if( !_shared_count.empty() )
         {
- if( !_internal_shared_this )
- {
- T * p = dynamic_cast<T *>(const_cast<enable_shared_from_this*>(this));
- _internal_weak_this = shared_ptr<T>(owner, p);
- }else
- {
- BOOST_ASSERT(owner.unique()); // no weak_ptrs to owner should exist either, but there's no way to check that
- detail::sp_deleter_wrapper * pd = get_deleter<detail::sp_deleter_wrapper>(_internal_shared_this);
- BOOST_ASSERT( pd != 0 );
- pd->set_deleter(owner);
-
- owner.reset( _internal_shared_this, owner.get() );
- _internal_shared_this.reset();
- }
- _owned = true;
+ BOOST_ASSERT( owner.unique() ); // no weak_ptrs to owner should exist either, but there's no way to check that
+ detail::sp_deleter_wrapper * pd = detail::basic_get_deleter<detail::sp_deleter_wrapper>( _shared_count );
+ BOOST_ASSERT( pd != 0 );
+ pd->set_deleter( owner.get_shared_count() );
+
+ owner.reset( _shared_count, owner.get() );
+ detail::shared_count().swap( _shared_count );
         }
     }
+
+ template< class U, class Y > friend void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<U> const * pe );
+ template< class U, class Y > friend void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<U> const * pe, void * /*pd*/ );
 };
 
-template< class T, class Y > inline void sp_accept_owner( boost::shared_ptr<Y> * ptr, boost::enable_shared_from_this<T> const * pe )
+template< class T, class Y > inline void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<T> const * pe )
 {
     if( pe != 0 )
     {
- pe->_internal_accept_owner( *ptr );
+ pe->sp_accept_owner( *ptr );
     }
 }
 
-template< class T, class Y > inline void sp_accept_owner( boost::shared_ptr<Y> * ptr, boost::enable_shared_from_this<T> const * pe, void * /*pd*/ )
+template< class T, class Y > inline void sp_accept_owner( shared_ptr<Y> * ptr, enable_shared_from_this<T> const * pe, void * /*pd*/ )
 {
     if( pe != 0 )
     {
- pe->_internal_accept_owner( *ptr );
+ pe->sp_accept_owner( *ptr );
     }
 }
 
-template< class T, class Y > inline void sp_accept_owner( boost::shared_ptr<Y> * /*ptr*/, boost::enable_shared_from_this<T> const * /*pe*/, boost::detail::sp_deleter_wrapper * /*pd*/ )
-{
-}
-
 } // namespace boost
 
 #endif // #ifndef BOOST_ENABLE_SHARED_FROM_THIS_HPP_INCLUDED

Modified: branches/proto/v4/boost/exception/info.hpp
==============================================================================
--- branches/proto/v4/boost/exception/info.hpp (original)
+++ branches/proto/v4/boost/exception/info.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -36,6 +36,12 @@
 
             virtual std::type_info const & tag_typeid() const = 0;
             virtual std::string value_as_string() const = 0;
+
+ protected:
+
+ ~error_info_base()
+ {
+ }
             };
         }
 

Modified: branches/proto/v4/boost/exception_ptr.hpp
==============================================================================
--- branches/proto/v4/boost/exception_ptr.hpp (original)
+++ branches/proto/v4/boost/exception_ptr.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -10,6 +10,7 @@
 #include <boost/exception/exception.hpp>
 #include <boost/exception/detail/cloning_base.hpp>
 #include <stdexcept>
+#include <new>
 
 namespace
 boost

Modified: branches/proto/v4/boost/fusion/container/list/detail/end_impl.hpp
==============================================================================
--- branches/proto/v4/boost/fusion/container/list/detail/end_impl.hpp (original)
+++ branches/proto/v4/boost/fusion/container/list/detail/end_impl.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -39,7 +39,7 @@
                 type;
     
                 static type
- call(Sequence& t)
+ call(Sequence&)
                 {
                     return type();
                 }

Modified: branches/proto/v4/boost/graph/dijkstra_shortest_paths.hpp
==============================================================================
--- branches/proto/v4/boost/graph/dijkstra_shortest_paths.hpp (original)
+++ branches/proto/v4/boost/graph/dijkstra_shortest_paths.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -109,7 +109,7 @@
       }
 
       template <class Vertex, class Graph>
- void initialize_vertex(Vertex u, Graph& g) { }
+ void initialize_vertex(Vertex /*u*/, Graph& /*g*/) { }
       template <class Edge, class Graph>
       void non_tree_edge(Edge, Graph&) { }
       template <class Vertex, class Graph>

Modified: branches/proto/v4/boost/graph/graph_utility.hpp
==============================================================================
--- branches/proto/v4/boost/graph/graph_utility.hpp (original)
+++ branches/proto/v4/boost/graph/graph_utility.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -385,7 +385,7 @@
         if (*ui != *vi) {
           for (tie(ci, ci_end) = vertices(g); ci != ci_end; ++ci)
             put(color, *ci, Color::white());
- if (! is_reachable(*ui, *vi, color))
+ if (! is_reachable(*ui, *vi, g, color))
             return false;
         }
     return true;

Modified: branches/proto/v4/boost/interprocess/allocators/adaptive_pool.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/adaptive_pool.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/adaptive_pool.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -26,6 +26,7 @@
 #include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
 #include <boost/interprocess/exceptions.hpp>
 #include <boost/interprocess/allocators/detail/allocator_common.hpp>
+#include <boost/interprocess/detail/mpl.hpp>
 #include <memory>
 #include <algorithm>
 #include <cstddef>
@@ -39,7 +40,7 @@
 /// @cond
 
 namespace detail{
-
+/*
 template < unsigned int Version
          , class T
          , class SegmentManager
@@ -61,8 +62,9 @@
    typedef SegmentManager segment_manager;
    typedef adaptive_pool_base
       <Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> self_t;
+ static const std::size_t SizeOfT = sizeof(detail::if_c<detail::is_same<T, void>::value, int, T>::type);
    typedef detail::shared_adaptive_node_pool
- < SegmentManager, sizeof(T), NodesPerChunk, MaxFreeChunks, OverheadPercent> node_pool_t;
+ < SegmentManager, SizeOfT, NodesPerChunk, MaxFreeChunks, OverheadPercent> node_pool_t;
    typedef typename detail::
       pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
 
@@ -157,19 +159,153 @@
    node_pool_ptr mp_node_pool;
    /// @endcond
 };
+*/
+
+template < unsigned int Version
+ , class T
+ , class SegmentManager
+ , std::size_t NodesPerChunk
+ , std::size_t MaxFreeChunks
+ , unsigned char OverheadPercent
+ >
+class adaptive_pool_base
+ : public node_pool_allocation_impl
+ < adaptive_pool_base
+ < Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent>
+ , Version
+ , T
+ , SegmentManager
+ >
+{
+ public:
+ typedef typename SegmentManager::void_pointer void_pointer;
+ typedef SegmentManager segment_manager;
+ typedef adaptive_pool_base
+ <Version, T, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> self_t;
+
+ /// @cond
+
+ template <int dummy>
+ struct node_pool
+ {
+ typedef detail::shared_adaptive_node_pool
+ < SegmentManager, sizeof(T), NodesPerChunk, MaxFreeChunks, OverheadPercent> type;
+
+ static type *get(void *p)
+ { return static_cast<type*>(p); }
+ };
+ /// @endcond
+
+ BOOST_STATIC_ASSERT((Version <=2));
+
+ public:
+ //-------
+ typedef typename detail::
+ pointer_to_other<void_pointer, T>::type pointer;
+ typedef typename detail::
+ pointer_to_other<void_pointer, const T>::type const_pointer;
+ typedef T value_type;
+ typedef typename detail::add_reference
+ <value_type>::type reference;
+ typedef typename detail::add_reference
+ <const value_type>::type const_reference;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ typedef detail::version_type<adaptive_pool_base, Version> version;
+ typedef transform_iterator
+ < typename SegmentManager::
+ multiallocation_iterator
+ , detail::cast_functor <T> > multiallocation_iterator;
+ typedef typename SegmentManager::
+ multiallocation_chain multiallocation_chain;
+
+ //!Obtains adaptive_pool_base from
+ //!adaptive_pool_base
+ template<class T2>
+ struct rebind
+ {
+ typedef adaptive_pool_base<Version, T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> other;
+ };
+
+ /// @cond
+ private:
+ //!Not assignable from related adaptive_pool_base
+ template<unsigned int Version2, class T2, class SegmentManager2, std::size_t N2, std::size_t F2, unsigned char O2>
+ adaptive_pool_base& operator=
+ (const adaptive_pool_base<Version2, T2, SegmentManager2, N2, F2, O2>&);
+
+ /// @endcond
+
+ public:
+ //!Constructor from a segment manager. If not present, constructs a node
+ //!pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ adaptive_pool_base(segment_manager *segment_mngr)
+ : mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
+
+ //!Copy constructor from other adaptive_pool_base. Increments the reference
+ //!count of the associated node pool. Never throws
+ adaptive_pool_base(const adaptive_pool_base &other)
+ : mp_node_pool(other.get_node_pool())
+ {
+ node_pool<0>::get(detail::get_pointer(mp_node_pool))->inc_ref_count();
+ }
+
+ //!Assignment from other adaptive_pool_base
+ adaptive_pool_base& operator=(const adaptive_pool_base &other)
+ {
+ adaptive_pool_base c(other);
+ swap(*this, c);
+ return *this;
+ }
+
+ //!Copy constructor from related adaptive_pool_base. If not present, constructs
+ //!a node pool. Increments the reference count of the associated node pool.
+ //!Can throw boost::interprocess::bad_alloc
+ template<class T2>
+ adaptive_pool_base
+ (const adaptive_pool_base<Version, T2, SegmentManager, NodesPerChunk, MaxFreeChunks, OverheadPercent> &other)
+ : mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
+
+ //!Destructor, removes node_pool_t from memory
+ //!if its reference count reaches to zero. Never throws
+ ~adaptive_pool_base()
+ { detail::destroy_node_pool_if_last_link(node_pool<0>::get(detail::get_pointer(mp_node_pool))); }
+
+ //!Returns a pointer to the node pool.
+ //!Never throws
+ void* get_node_pool() const
+ { return detail::get_pointer(mp_node_pool); }
+
+ //!Returns the segment manager.
+ //!Never throws
+ segment_manager* get_segment_manager()const
+ { return node_pool<0>::get(detail::get_pointer(mp_node_pool))->get_segment_manager(); }
+
+ //!Swaps allocators. Does not throw. If each allocator is placed in a
+ //!different memory segment, the result is undefined.
+ friend void swap(self_t &alloc1, self_t &alloc2)
+ { detail::do_swap(alloc1.mp_node_pool, alloc2.mp_node_pool); }
+
+ /// @cond
+ private:
+ void_pointer mp_node_pool;
+ /// @endcond
+};
 
 //!Equality test for same type
 //!of adaptive_pool_base
-template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
-bool operator==(const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc1,
- const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc2)
+template<unsigned int V, class T, class S, std::size_t NPC, std::size_t F, unsigned char OP> inline
+bool operator==(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
+ const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc2)
    { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
 
 //!Inequality test for same type
 //!of adaptive_pool_base
-template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
-bool operator!=(const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc1,
- const adaptive_pool_base<V, T, S, NodesPerChunk, F, OP> &alloc2)
+template<unsigned int V, class T, class S, std::size_t NPC, std::size_t F, unsigned char OP> inline
+bool operator!=(const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc1,
+ const adaptive_pool_base<V, T, S, NPC, F, OP> &alloc2)
    { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
 
 template < class T
@@ -299,7 +435,7 @@
 
    //!Not assignable from
    //!other adaptive_pool
- adaptive_pool& operator=(const adaptive_pool&);
+ //adaptive_pool& operator=(const adaptive_pool&);
 
    public:
    //!Constructor from a segment manager. If not present, constructs a node
@@ -324,7 +460,7 @@
 
    //!Returns a pointer to the node pool.
    //!Never throws
- node_pool_t* get_node_pool() const;
+ void* get_node_pool() const;
 
    //!Returns the segment manager.
    //!Never throws
@@ -358,9 +494,9 @@
    //!Never throws
    const_pointer address(const_reference value) const;
 
- //!Default construct an object.
- //!Throws if T's default constructor throws
- void construct(const pointer &ptr);
+ //!Copy construct an object.
+ //!Throws if T's copy constructor throws
+ void construct(const pointer &ptr, const_reference v);
 
    //!Destroys object. Throws if object's
    //!destructor throws

Modified: branches/proto/v4/boost/interprocess/allocators/allocator.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/allocator.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/allocator.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -48,15 +48,17 @@
 template<class T, class SegmentManager>
 class allocator
 {
+ public:
+ //Segment manager
+ typedef SegmentManager segment_manager;
+ typedef typename SegmentManager::void_pointer void_pointer;
+
    /// @cond
    private:
 
    //Self type
    typedef allocator<T, SegmentManager> self_t;
 
- //Segment manager
- typedef SegmentManager segment_manager;
-
    //Pointer to void
    typedef typename segment_manager::void_pointer aux_pointer_t;
 
@@ -106,8 +108,6 @@
       <typename SegmentManager::
          multiallocation_chain
       , T> multiallocation_chain;
-// typedef typename SegmentManager::
-// multiallocation_chain multiallocation_chain;
 
    /// @endcond
 
@@ -153,7 +153,7 @@
    //!Deallocates memory previously allocated.
    //!Never throws
    void deallocate(const pointer &ptr, size_type)
- { mp_mngr->deallocate(detail::get_pointer(ptr)); }
+ { mp_mngr->deallocate((void*)detail::get_pointer(ptr)); }
 
    //!Returns the number of elements that could be allocated.
    //!Never throws
@@ -253,10 +253,15 @@
    const_pointer address(const_reference value) const
    { return const_pointer(boost::addressof(value)); }
 
+ //!Copy construct an object
+ //!Throws if T's copy constructor throws
+ void construct(const pointer &ptr, const_reference v)
+ { new((void*)detail::get_pointer(ptr)) value_type(v); }
+
    //!Default construct an object.
    //!Throws if T's default constructor throws
    void construct(const pointer &ptr)
- { new(detail::get_pointer(ptr)) value_type; }
+ { new((void*)detail::get_pointer(ptr)) value_type; }
 
    //!Destroys object. Throws if object's
    //!destructor throws

Modified: branches/proto/v4/boost/interprocess/allocators/cached_adaptive_pool.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/cached_adaptive_pool.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/cached_adaptive_pool.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -119,7 +119,7 @@
          < T
          , detail::shared_adaptive_node_pool
             < SegmentManager
- , sizeof(T)
+ , sizeof(typename detail::if_c<detail::is_same<T, void>::value, int, T>::type)
             , NodesPerChunk
             , MaxFreeChunks
             , OverheadPercent
@@ -252,9 +252,9 @@
    //!Never throws
    const_pointer address(const_reference value) const;
 
- //!Default construct an object.
- //!Throws if T's default constructor throws
- void construct(const pointer &ptr);
+ //!Copy construct an object.
+ //!Throws if T's copy constructor throws
+ void construct(const pointer &ptr, const_reference v);
 
    //!Destroys object. Throws if object's
    //!destructor throws

Modified: branches/proto/v4/boost/interprocess/allocators/cached_node_allocator.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/cached_node_allocator.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/cached_node_allocator.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -225,7 +225,7 @@
 
    //!Default construct an object.
    //!Throws if T's default constructor throws
- void construct(const pointer &ptr);
+ void construct(const pointer &ptr, const_reference v);
 
    //!Destroys object. Throws if object's
    //!destructor throws
@@ -302,15 +302,15 @@
 
 //!Equality test for same type
 //!of cached_node_allocator
-template<class T, class S, std::size_t NodesPerChunk> inline
-bool operator==(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
- const cached_node_allocator<T, S, NodesPerChunk> &alloc2);
+template<class T, class S, std::size_t NPC> inline
+bool operator==(const cached_node_allocator<T, S, NPC> &alloc1,
+ const cached_node_allocator<T, S, NPC> &alloc2);
 
 //!Inequality test for same type
 //!of cached_node_allocator
-template<class T, class S, std::size_t NodesPerChunk> inline
-bool operator!=(const cached_node_allocator<T, S, NodesPerChunk> &alloc1,
- const cached_node_allocator<T, S, NodesPerChunk> &alloc2);
+template<class T, class S, std::size_t NPC> inline
+bool operator!=(const cached_node_allocator<T, S, NPC> &alloc1,
+ const cached_node_allocator<T, S, NPC> &alloc2);
 
 #endif
 

Modified: branches/proto/v4/boost/interprocess/allocators/detail/adaptive_node_pool.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/detail/adaptive_node_pool.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/detail/adaptive_node_pool.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -49,7 +49,7 @@
    private_adaptive_node_pool_impl &operator=(const private_adaptive_node_pool_impl &);
 
    typedef typename SegmentManagerBase::void_pointer void_pointer;
-
+ static const std::size_t PayloadPerAllocation = SegmentManagerBase::PayloadPerAllocation;
    public:
    typedef typename node_slist<void_pointer>::node_t node_t;
    typedef typename node_slist<void_pointer>::node_slist_t free_nodes_t;
@@ -106,9 +106,11 @@
       std::size_t candidate_power_of_2 =
          upper_power_of_2(elements_per_subchunk*real_node_size + HdrOffsetSize);
       bool overhead_satisfied = false;
+ //Now calculate the wors-case overhead for a subchunk
+ const std::size_t max_subchunk_overhead = HdrSize + PayloadPerAllocation;
       while(!overhead_satisfied){
- elements_per_subchunk = (candidate_power_of_2 - HdrOffsetSize)/real_node_size;
- std::size_t overhead_size = candidate_power_of_2 - elements_per_subchunk*real_node_size;
+ elements_per_subchunk = (candidate_power_of_2 - max_subchunk_overhead)/real_node_size;
+ const std::size_t overhead_size = candidate_power_of_2 - elements_per_subchunk*real_node_size;
          if(overhead_size*100/candidate_power_of_2 < overhead_percent){
             overhead_satisfied = true;
          }
@@ -121,14 +123,26 @@
 
    static void calculate_num_subchunks
       (std::size_t alignment, std::size_t real_node_size, std::size_t elements_per_chunk
- ,std::size_t &num_subchunks, std::size_t &real_num_node)
+ ,std::size_t &num_subchunks, std::size_t &real_num_node, std::size_t overhead_percent)
    {
       std::size_t elements_per_subchunk = (alignment - HdrOffsetSize)/real_node_size;
       std::size_t possible_num_subchunk = (elements_per_chunk - 1)/elements_per_subchunk + 1;
- std::size_t hdr_subchunk_elements = (alignment - HdrSize - SegmentManagerBase::PayloadPerAllocation)/real_node_size;
+ std::size_t hdr_subchunk_elements = (alignment - HdrSize - PayloadPerAllocation)/real_node_size;
       while(((possible_num_subchunk-1)*elements_per_subchunk + hdr_subchunk_elements) < elements_per_chunk){
          ++possible_num_subchunk;
       }
+ elements_per_subchunk = (alignment - HdrOffsetSize)/real_node_size;
+ bool overhead_satisfied = false;
+ while(!overhead_satisfied){
+ const std::size_t total_data = (elements_per_subchunk*(possible_num_subchunk-1) + hdr_subchunk_elements)*real_node_size;
+ const std::size_t total_size = alignment*possible_num_subchunk;
+ if((total_size - total_data)*100/total_size < overhead_percent){
+ overhead_satisfied = true;
+ }
+ else{
+ ++possible_num_subchunk;
+ }
+ }
       num_subchunks = possible_num_subchunk;
       real_num_node = (possible_num_subchunk-1)*elements_per_subchunk + hdr_subchunk_elements;
    }
@@ -157,7 +171,7 @@
    , m_chunk_multiset()
    , m_totally_free_chunks(0)
    {
- calculate_num_subchunks(m_real_chunk_alignment, m_real_node_size, nodes_per_chunk, m_num_subchunks, m_real_num_node);
+ calculate_num_subchunks(m_real_chunk_alignment, m_real_node_size, nodes_per_chunk, m_num_subchunks, m_real_num_node, overhead_percent);
    }
 
    //!Destructor. Deallocates all allocated chunks. Never throws

Modified: branches/proto/v4/boost/interprocess/allocators/detail/allocator_common.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/detail/allocator_common.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/detail/allocator_common.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -342,7 +342,12 @@
    //!Default construct an object.
    //!Throws if T's default constructor throws
    void construct(const pointer &ptr)
- { new(detail::get_pointer(ptr)) value_type; }
+ { new((void*)detail::get_pointer(ptr)) value_type; }
+
+ //!Copy construct an object
+ //!Throws if T's copy constructor throws
+ void construct(const pointer &ptr, const_reference v)
+ { new((void*)detail::get_pointer(ptr)) value_type(v); }
 
    //!Destroys object. Throws if object's
    //!destructor throws
@@ -386,36 +391,53 @@
    typedef typename SegmentManager::
       multiallocation_chain multiallocation_chain;
 
+ template <int Dummy>
+ struct node_pool
+ {
+ typedef typename Derived::template node_pool<0>::type type;
+ static type *get(void *p)
+ { return static_cast<type*>(p); }
+ };
+
    public:
    //!Allocate memory for an array of count elements.
    //!Throws boost::interprocess::bad_alloc if there is no enough memory
    pointer allocate(size_type count, cvoid_pointer hint = 0)
    {
       (void)hint;
+ typedef typename node_pool<0>::type node_pool_t;
+ node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
       if(count > this->max_size())
          throw bad_alloc();
       else if(Version == 1 && count == 1)
- return pointer(static_cast<value_type*>(this->derived()->get_node_pool()->allocate_node()));
+ return pointer(static_cast<value_type*>
+ (pool->allocate_node()));
       else
          return pointer(static_cast<value_type*>
- (this->derived()->get_node_pool()->get_segment_manager()->allocate(sizeof(T)*count)));
+ (pool->get_segment_manager()->allocate(sizeof(T)*count)));
    }
 
    //!Deallocate allocated memory. Never throws
    void deallocate(const pointer &ptr, size_type count)
    {
       (void)count;
+ typedef typename node_pool<0>::type node_pool_t;
+ node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
       if(Version == 1 && count == 1)
- this->derived()->get_node_pool()->deallocate_node(detail::get_pointer(ptr));
+ pool->deallocate_node(detail::get_pointer(ptr));
       else
- this->derived()->get_node_pool()->get_segment_manager()->deallocate(detail::get_pointer(ptr));
+ pool->get_segment_manager()->deallocate((void*)detail::get_pointer(ptr));
    }
 
    //!Allocates just one object. Memory allocated with this function
    //!must be deallocated only with deallocate_one().
    //!Throws boost::interprocess::bad_alloc if there is no enough memory
    pointer allocate_one()
- { return pointer(static_cast<value_type*>(this->derived()->get_node_pool()->allocate_node())); }
+ {
+ typedef typename node_pool<0>::type node_pool_t;
+ node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
+ return pointer(static_cast<value_type*>(pool->allocate_node()));
+ }
 
    //!Allocates many elements of size == 1 in a contiguous chunk
    //!of memory. The minimum number to be allocated is min_elements,
@@ -424,13 +446,21 @@
    //!will be assigned to received_size. Memory allocated with this function
    //!must be deallocated only with deallocate_one().
    multiallocation_iterator allocate_individual(std::size_t num_elements)
- { return multiallocation_iterator(this->derived()->get_node_pool()->allocate_nodes(num_elements)); }
+ {
+ typedef typename node_pool<0>::type node_pool_t;
+ node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
+ return multiallocation_iterator(pool->allocate_nodes(num_elements));
+ }
 
    //!Deallocates memory previously allocated with allocate_one().
    //!You should never use deallocate_one to deallocate memory allocated
    //!with other functions different from allocate_one(). Never throws
    void deallocate_one(const pointer &p)
- { this->derived()->get_node_pool()->deallocate_node(detail::get_pointer(p)); }
+ {
+ typedef typename node_pool<0>::type node_pool_t;
+ node_pool_t *pool = node_pool<0>::get(this->derived()->get_node_pool());
+ pool->deallocate_node(detail::get_pointer(p));
+ }
 
    //!Allocates many elements of size == 1 in a contiguous chunk
    //!of memory. The minimum number to be allocated is min_elements,
@@ -439,11 +469,11 @@
    //!will be assigned to received_size. Memory allocated with this function
    //!must be deallocated only with deallocate_one().
    void deallocate_individual(multiallocation_iterator it)
- { this->derived()->get_node_pool()->deallocate_nodes(it.base()); }
+ { node_pool<0>::get(this->derived()->get_node_pool())->deallocate_nodes(it.base()); }
 
    //!Deallocates all free chunks of the pool
    void deallocate_free_chunks()
- { this->derived()->get_node_pool()->deallocate_free_chunks(); }
+ { node_pool<0>::get(this->derived()->get_node_pool())->deallocate_free_chunks(); }
 };
 
 template<class T, class NodePool, unsigned int Version>
@@ -536,7 +566,7 @@
          m_cache.cached_deallocation(detail::get_pointer(ptr));
       }
       else{
- this->get_segment_manager()->deallocate(detail::get_pointer(ptr));
+ this->get_segment_manager()->deallocate((void*)detail::get_pointer(ptr));
       }
    }
 

Modified: branches/proto/v4/boost/interprocess/allocators/detail/node_pool.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/detail/node_pool.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/detail/node_pool.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -253,7 +253,7 @@
       while(!m_chunklist.empty()){
          void *addr = get_chunk_from_hook(&m_chunklist.front(), blocksize);
          m_chunklist.pop_front();
- mp_segment_mngr_base->deallocate(addr);
+ mp_segment_mngr_base->deallocate((void*)addr);
       }
       //Just clear free node list
       m_freelist.clear();

Modified: branches/proto/v4/boost/interprocess/allocators/node_allocator.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/node_allocator.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/node_allocator.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -59,10 +59,19 @@
    typedef SegmentManager segment_manager;
    typedef node_allocator_base
       <Version, T, SegmentManager, NodesPerChunk> self_t;
- typedef detail::shared_node_pool
- < SegmentManager, sizeof(T), NodesPerChunk> node_pool_t;
- typedef typename detail::
- pointer_to_other<void_pointer, node_pool_t>::type node_pool_ptr;
+
+ /// @cond
+
+ template <int dummy>
+ struct node_pool
+ {
+ typedef detail::shared_node_pool
+ < SegmentManager, sizeof(T), NodesPerChunk> type;
+
+ static type *get(void *p)
+ { return static_cast<type*>(p); }
+ };
+ /// @endcond
 
    BOOST_STATIC_ASSERT((Version <=2));
 
@@ -104,7 +113,7 @@
       (const node_allocator_base<Version2, T2, SegmentManager2, N2>&);
 
    //!Not assignable from other node_allocator_base
- node_allocator_base& operator=(const node_allocator_base&);
+ //node_allocator_base& operator=(const node_allocator_base&);
    /// @endcond
 
    public:
@@ -112,14 +121,14 @@
    //!pool. Increments the reference count of the associated node pool.
    //!Can throw boost::interprocess::bad_alloc
    node_allocator_base(segment_manager *segment_mngr)
- : mp_node_pool(detail::get_or_create_node_pool<node_pool_t>(segment_mngr)) { }
+ : mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(segment_mngr)) { }
 
    //!Copy constructor from other node_allocator_base. Increments the reference
    //!count of the associated node pool. Never throws
    node_allocator_base(const node_allocator_base &other)
       : mp_node_pool(other.get_node_pool())
    {
- mp_node_pool->inc_ref_count();
+ node_pool<0>::get(detail::get_pointer(mp_node_pool))->inc_ref_count();
    }
 
    //!Copy constructor from related node_allocator_base. If not present, constructs
@@ -128,22 +137,30 @@
    template<class T2>
    node_allocator_base
       (const node_allocator_base<Version, T2, SegmentManager, NodesPerChunk> &other)
- : mp_node_pool(detail::get_or_create_node_pool<node_pool_t>(other.get_segment_manager())) { }
+ : mp_node_pool(detail::get_or_create_node_pool<typename node_pool<0>::type>(other.get_segment_manager())) { }
+
+ //!Assignment from other node_allocator_base
+ node_allocator_base& operator=(const node_allocator_base &other)
+ {
+ node_allocator_base c(other);
+ swap(*this, c);
+ return *this;
+ }
 
    //!Destructor, removes node_pool_t from memory
    //!if its reference count reaches to zero. Never throws
    ~node_allocator_base()
- { detail::destroy_node_pool_if_last_link(detail::get_pointer(mp_node_pool)); }
+ { detail::destroy_node_pool_if_last_link(node_pool<0>::get(detail::get_pointer(mp_node_pool))); }
 
    //!Returns a pointer to the node pool.
    //!Never throws
- node_pool_t* get_node_pool() const
+ void* get_node_pool() const
    { return detail::get_pointer(mp_node_pool); }
 
    //!Returns the segment manager.
    //!Never throws
    segment_manager* get_segment_manager()const
- { return mp_node_pool->get_segment_manager(); }
+ { return node_pool<0>::get(detail::get_pointer(mp_node_pool))->get_segment_manager(); }
 
    //!Swaps allocators. Does not throw. If each allocator is placed in a
    //!different memory segment, the result is undefined.
@@ -152,22 +169,22 @@
 
    /// @cond
    private:
- node_pool_ptr mp_node_pool;
+ void_pointer mp_node_pool;
    /// @endcond
 };
 
 //!Equality test for same type
 //!of node_allocator_base
-template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
-bool operator==(const node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
- const node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
+template<unsigned int V, class T, class S, std::size_t NPC> inline
+bool operator==(const node_allocator_base<V, T, S, NPC> &alloc1,
+ const node_allocator_base<V, T, S, NPC> &alloc2)
    { return alloc1.get_node_pool() == alloc2.get_node_pool(); }
 
 //!Inequality test for same type
 //!of node_allocator_base
-template<unsigned int V, class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
-bool operator!=(const node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
- const node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
+template<unsigned int V, class T, class S, std::size_t NPC> inline
+bool operator!=(const node_allocator_base<V, T, S, NPC> &alloc1,
+ const node_allocator_base<V, T, S, NPC> &alloc2)
    { return alloc1.get_node_pool() != alloc2.get_node_pool(); }
 
 template < class T
@@ -283,7 +300,7 @@
 
    //!Not assignable from
    //!other node_allocator
- node_allocator& operator=(const node_allocator&);
+ //node_allocator& operator=(const node_allocator&);
 
    public:
    //!Constructor from a segment manager. If not present, constructs a node
@@ -308,7 +325,7 @@
 
    //!Returns a pointer to the node pool.
    //!Never throws
- node_pool_t* get_node_pool() const;
+ void* get_node_pool() const;
 
    //!Returns the segment manager.
    //!Never throws
@@ -342,9 +359,9 @@
    //!Never throws
    const_pointer address(const_reference value) const;
 
- //!Default construct an object.
- //!Throws if T's default constructor throws
- void construct(const pointer &ptr);
+ //!Copy construct an object.
+ //!Throws if T's copy constructor throws
+ void construct(const pointer &ptr, const_reference v);
 
    //!Destroys object. Throws if object's
    //!destructor throws
@@ -414,15 +431,15 @@
 
 //!Equality test for same type
 //!of node_allocator
-template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
-bool operator==(const node_allocator<T, S, NodesPerChunk, F, OP> &alloc1,
- const node_allocator<T, S, NodesPerChunk, F, OP> &alloc2);
+template<class T, class S, std::size_t NPC> inline
+bool operator==(const node_allocator<T, S, NPC> &alloc1,
+ const node_allocator<T, S, NPC> &alloc2);
 
 //!Inequality test for same type
 //!of node_allocator
-template<class T, class S, std::size_t NodesPerChunk, std::size_t F, unsigned char OP> inline
-bool operator!=(const node_allocator<T, S, NodesPerChunk, F, OP> &alloc1,
- const node_allocator<T, S, NodesPerChunk, F, OP> &alloc2);
+template<class T, class S, std::size_t NPC> inline
+bool operator!=(const node_allocator<T, S, NPC> &alloc1,
+ const node_allocator<T, S, NPC> &alloc2);
 
 #endif
 

Modified: branches/proto/v4/boost/interprocess/allocators/private_adaptive_pool.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/private_adaptive_pool.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/private_adaptive_pool.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -55,10 +55,13 @@
    , SegmentManager
>
 {
+ public:
+ //Segment manager
+ typedef SegmentManager segment_manager;
+ typedef typename SegmentManager::void_pointer void_pointer;
+
    /// @cond
    private:
- typedef typename SegmentManager::void_pointer void_pointer;
- typedef SegmentManager segment_manager;
    typedef private_adaptive_pool_base
       < Version, T, SegmentManager, NodesPerChunk
       , MaxFreeChunks, OverheadPercent> self_t;
@@ -104,6 +107,22 @@
    };
 
    /// @cond
+
+ template <int dummy>
+ struct node_pool
+ {
+ typedef detail::private_adaptive_node_pool
+ <SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ , MaxFreeChunks
+ , OverheadPercent
+ > type;
+
+ static type *get(void *p)
+ { return static_cast<type*>(p); }
+ };
+
    private:
    //!Not assignable from related private_adaptive_pool_base
    template<unsigned int Version2, class T2, class MemoryAlgorithm2, std::size_t N2, std::size_t F2, unsigned char OP2>
@@ -355,9 +374,9 @@
    //!Never throws
    const_pointer address(const_reference value) const;
 
- //!Default construct an object.
- //!Throws if T's default constructor throws
- void construct(const pointer &ptr);
+ //!Copy construct an object.
+ //!Throws if T's copy constructor throws
+ void construct(const pointer &ptr, const_reference v);
 
    //!Destroys object. Throws if object's
    //!destructor throws

Modified: branches/proto/v4/boost/interprocess/allocators/private_node_allocator.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/allocators/private_node_allocator.hpp (original)
+++ branches/proto/v4/boost/interprocess/allocators/private_node_allocator.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,201 +7,6 @@
 // See http://www.boost.org/libs/interprocess for documentation.
 //
 //////////////////////////////////////////////////////////////////////////////
-/*
-#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
-#define BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
-
-#if (defined _MSC_VER) && (_MSC_VER >= 1200)
-# pragma once
-#endif
-
-#include <boost/interprocess/detail/config_begin.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-
-#include <boost/interprocess/interprocess_fwd.hpp>
-#include <boost/assert.hpp>
-#include <boost/utility/addressof.hpp>
-#include <boost/interprocess/allocators/detail/node_pool.hpp>
-#include <boost/interprocess/exceptions.hpp>
-#include <boost/interprocess/detail/utilities.hpp>
-#include <boost/interprocess/detail/workaround.hpp>
-#include <memory>
-#include <algorithm>
-#include <cstddef>
-
-//!\file
-//!Describes private_node_allocator pooled shared memory STL compatible allocator
-
-namespace boost {
-namespace interprocess {
-
-//!An STL node allocator that uses a segment manager as memory
-//!source. The internal pointer type will of the same type (raw, smart) as
-//!"typename SegmentManager::void_pointer" type. This allows
-//!placing the allocator in shared memory, memory mapped-files, etc...
-//!This allocator has its own node pool. NodesPerChunk is the number of nodes allocated
-//!at once when the allocator needs runs out of nodes
-template<class T, class SegmentManager, std::size_t NodesPerChunk>
-class private_node_allocator
-{
- /// @cond
- private:
- typedef typename SegmentManager::void_pointer void_pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const void>::type cvoid_pointer;
- typedef SegmentManager segment_manager;
- typedef typename detail::pointer_to_other
- <void_pointer, segment_manager>::type segment_mngr_ptr_t;
- typedef private_node_allocator
- <T, SegmentManager, NodesPerChunk> self_t;
- typedef detail::private_node_pool
- <SegmentManager, sizeof(T), NodesPerChunk> priv_node_pool_t;
- /// @endcond
-
- public:
- //-------
- typedef typename detail::
- pointer_to_other<void_pointer, T>::type pointer;
- typedef typename detail::
- pointer_to_other<void_pointer, const T>::type const_pointer;
- typedef T value_type;
- typedef typename detail::add_reference
- <value_type>::type reference;
- typedef typename detail::add_reference
- <const value_type>::type const_reference;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
-
- //!Obtains node_allocator from other node_allocator
- template<class T2>
- struct rebind
- {
- typedef private_node_allocator<T2, SegmentManager, NodesPerChunk> other;
- };
-
- /// @cond
- private:
- //!Not assignable from related private_node_allocator
- template<class T2, class MemoryAlgorithm2, std::size_t N2>
- private_node_allocator& operator=
- (const private_node_allocator<T2, MemoryAlgorithm2, N2>&);
-
- //!Not assignable from other private_node_allocator
- private_node_allocator& operator=(const private_node_allocator&);
- /// @endcond
-
- public:
-
- //!Constructor from a segment manager
- private_node_allocator(segment_manager *segment_mngr)
- : m_node_pool(segment_mngr){}
-
- //!Copy constructor from other private_node_allocator. Never throws
- private_node_allocator(const private_node_allocator &other)
- : m_node_pool(other.get_segment_manager()){}
-
- //!Copy constructor from related private_node_allocator. Never throws.
- template<class T2>
- private_node_allocator
- (const private_node_allocator<T2, SegmentManager, NodesPerChunk> &other)
- : m_node_pool(other.get_segment_manager())
- {}
-
- //!Destructor, frees all used memory. Never throws
- ~private_node_allocator()
- {}
-
- //!Returns the segment manager. Never throws
- segment_manager* get_segment_manager()const
- { return m_node_pool.get_segment_manager(); }
-
- //!Returns the number of elements that could be allocated. Never throws
- size_type max_size() const
- { return this->get_segment_manager()->get_size()/sizeof(value_type); }
-
- //!Allocate memory for an array of count elements.
- //!Throws boost::interprocess::bad_alloc if there is no enough memory
- pointer allocate(size_type count, cvoid_pointer hint = 0)
- {
- (void)hint;
- if(count > this->max_size())
- throw bad_alloc();
- else if(count == 1)
- return pointer(static_cast<value_type*>(m_node_pool.allocate_node()));
- else
- return pointer(static_cast<value_type*>
- (m_node_pool.get_segment_manager()->allocate(sizeof(T)*count)));
- }
-
- //!Deallocate allocated memory. Never throws
- void deallocate(const pointer &ptr, size_type count)
- {
- if(count == 1)
- m_node_pool.deallocate_node(detail::get_pointer(ptr));
- else
- m_node_pool.get_segment_manager()->deallocate(detail::get_pointer(ptr));
- }
-
- //!Deallocates all free chunks of the pool
- void deallocate_free_chunks()
- { m_node_pool.deallocate_free_chunks(); }
-
- //!Swaps allocators. Does not throw. If each allocator is placed in a
- //!different shared memory segments, the result is undefined.
- friend void swap(self_t &alloc1,self_t &alloc2)
- { alloc1.m_node_pool.swap(alloc2.m_node_pool); }
-
- //These functions are obsolete. These are here to conserve
- //backwards compatibility with containers using them...
-
- //!Returns address of mutable object.
- //!Never throws
- pointer address(reference value) const
- { return pointer(boost::addressof(value)); }
-
- //!Returns address of non mutable object.
- //!Never throws
- const_pointer address(const_reference value) const
- { return const_pointer(boost::addressof(value)); }
-
- //!Default construct an object.
- //!Throws if T's default constructor throws
- void construct(const pointer &ptr)
- { new(detail::get_pointer(ptr)) value_type; }
-
- //!Destroys object. Throws if object's
- //!destructor throws
- void destroy(const pointer &ptr)
- { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
-
- /// @cond
- private:
- priv_node_pool_t m_node_pool;
- /// @endcond
-};
-
-//!Equality test for same type of private_node_allocator
-template<class T, class S, std::size_t NodesPerChunk> inline
-bool operator==(const private_node_allocator<T, S, NodesPerChunk> &alloc1,
- const private_node_allocator<T, S, NodesPerChunk> &alloc2)
-{ return &alloc1 == &alloc2; }
-
-//!Inequality test for same type of private_node_allocator
-template<class T, class S, std::size_t NodesPerChunk> inline
-bool operator!=(const private_node_allocator<T, S, NodesPerChunk> &alloc1,
- const private_node_allocator<T, S, NodesPerChunk> &alloc2)
-{
- return &alloc1 != &alloc2;
-}
-
-} //namespace interprocess {
-} //namespace boost {
-
-#include <boost/interprocess/detail/config_end.hpp>
-
-#endif //#ifndef BOOST_INTERPROCESS_PRIVATE_NODE_ALLOCATOR_HPP
-
-*/
 
 //////////////////////////////////////////////////////////////////////////////
 //
@@ -257,10 +62,13 @@
    , SegmentManager
>
 {
+ public:
+ //Segment manager
+ typedef SegmentManager segment_manager;
+ typedef typename SegmentManager::void_pointer void_pointer;
+
    /// @cond
    private:
- typedef typename SegmentManager::void_pointer void_pointer;
- typedef SegmentManager segment_manager;
    typedef private_node_allocator_base
       < Version, T, SegmentManager, NodesPerChunk> self_t;
    typedef detail::private_node_pool
@@ -303,6 +111,19 @@
    };
 
    /// @cond
+ template <int dummy>
+ struct node_pool
+ {
+ typedef detail::private_node_pool
+ <SegmentManager
+ , sizeof(T)
+ , NodesPerChunk
+ > type;
+
+ static type *get(void *p)
+ { return static_cast<type*>(p); }
+ };
+
    private:
    //!Not assignable from related private_node_allocator_base
    template<unsigned int Version2, class T2, class MemoryAlgorithm2, std::size_t N2>
@@ -356,15 +177,15 @@
 };
 
 //!Equality test for same type of private_node_allocator_base
-template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
-bool operator==(const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
- const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
+template<unsigned int V, class T, class S, std::size_t NPC> inline
+bool operator==(const private_node_allocator_base<V, T, S, NPC> &alloc1,
+ const private_node_allocator_base<V, T, S, NPC> &alloc2)
 { return &alloc1 == &alloc2; }
 
 //!Inequality test for same type of private_node_allocator_base
-template<unsigned int V, class T, class S, std::size_t NodesPerChunk> inline
-bool operator!=(const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc1,
- const private_node_allocator_base<V, T, S, NodesPerChunk> &alloc2)
+template<unsigned int V, class T, class S, std::size_t NPC> inline
+bool operator!=(const private_node_allocator_base<V, T, S, NPC> &alloc1,
+ const private_node_allocator_base<V, T, S, NPC> &alloc2)
 { return &alloc1 != &alloc2; }
 
 template < class T
@@ -539,9 +360,9 @@
    //!Never throws
    const_pointer address(const_reference value) const;
 
- //!Default construct an object.
- //!Throws if T's default constructor throws
- void construct(const pointer &ptr);
+ //!Copy construct an object.
+ //!Throws if T's copy constructor throws
+ void construct(const pointer &ptr, const_reference v);
 
    //!Destroys object. Throws if object's
    //!destructor throws

Modified: branches/proto/v4/boost/interprocess/containers/deque.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/containers/deque.hpp (original)
+++ branches/proto/v4/boost/interprocess/containers/deque.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -658,7 +658,7 @@
    void push_back(const value_type& t)
    {
       if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
- new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
+ new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
          ++this->members_.m_finish.m_cur;
       }
       else
@@ -669,7 +669,7 @@
    void push_back(const detail::moved_object<value_type> &mt)
    {
       if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
- new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
+ new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
          ++this->members_.m_finish.m_cur;
       }
       else
@@ -679,7 +679,7 @@
    void push_back(value_type &&mt)
    {
       if (this->members_.m_finish.m_cur != this->members_.m_finish.m_last - 1) {
- new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
+ new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
          ++this->members_.m_finish.m_cur;
       }
       else
@@ -690,7 +690,7 @@
    void push_front(const value_type& t)
    {
       if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
- new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(t);
+ new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(t);
          --this->members_.m_start.m_cur;
       }
       else
@@ -701,7 +701,7 @@
    void push_front(const detail::moved_object<value_type> &mt)
    {
       if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
- new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(mt);
+ new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(mt);
          --this->members_.m_start.m_cur;
       }
       else
@@ -711,7 +711,7 @@
    void push_front(value_type &&mt)
    {
       if (this->members_.m_start.m_cur != this->members_.m_start.m_first) {
- new(detail::get_pointer(this->members_.m_start.m_cur)- 1)value_type(move(mt));
+ new((void*)(detail::get_pointer(this->members_.m_start.m_cur)- 1))value_type(move(mt));
          --this->members_.m_start.m_cur;
       }
       else
@@ -1217,7 +1217,7 @@
       this->priv_reserve_map_at_back();
       *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
       BOOST_TRY {
- new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
+ new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(t);
          this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
          this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
       }
@@ -1235,7 +1235,7 @@
       this->priv_reserve_map_at_back();
       *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
       BOOST_TRY {
- new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
+ new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(mt);
          this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
          this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
       }
@@ -1251,7 +1251,7 @@
       this->priv_reserve_map_at_back();
       *(this->members_.m_finish.m_node + 1) = this->priv_allocate_node();
       BOOST_TRY {
- new(detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
+ new((void*)detail::get_pointer(this->members_.m_finish.m_cur))value_type(move(mt));
          this->members_.m_finish.priv_set_node(this->members_.m_finish.m_node + 1);
          this->members_.m_finish.m_cur = this->members_.m_finish.m_first;
       }
@@ -1271,7 +1271,7 @@
       BOOST_TRY {
          this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
          this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
- new(detail::get_pointer(this->members_.m_start.m_cur))value_type(t);
+ new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(t);
       }
       BOOST_CATCH(...){
          ++this->members_.m_start;
@@ -1289,7 +1289,7 @@
       BOOST_TRY {
          this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
          this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
- new(detail::get_pointer(this->members_.m_start.m_cur))value_type(mt);
+ new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(mt);
       }
       BOOST_CATCH(...){
          ++this->members_.m_start;
@@ -1306,7 +1306,7 @@
       BOOST_TRY {
          this->members_.m_start.priv_set_node(this->members_.m_start.m_node - 1);
          this->members_.m_start.m_cur = this->members_.m_start.m_last - 1;
- new(detail::get_pointer(this->members_.m_start.m_cur))value_type(move(mt));
+ new((void*)detail::get_pointer(this->members_.m_start.m_cur))value_type(move(mt));
       }
       BOOST_CATCH(...){
          ++this->members_.m_start;

Modified: branches/proto/v4/boost/interprocess/containers/detail/node_alloc_holder.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/containers/detail/node_alloc_holder.hpp (original)
+++ branches/proto/v4/boost/interprocess/containers/detail/node_alloc_holder.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -145,15 +145,15 @@
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class Convertible>
    static void construct(const NodePtr &ptr, const Convertible &value)
- { new(detail::get_pointer(ptr)) Node(value); }
+ { new((void*)detail::get_pointer(ptr)) Node(value); }
    #else
    template<class Convertible>
    static void construct(const NodePtr &ptr, Convertible &&value)
- { new(detail::get_pointer(ptr)) Node(forward<Convertible>(value)); }
+ { new((void*)detail::get_pointer(ptr)) Node(forward<Convertible>(value)); }
    #endif
 
    static void construct(const NodePtr &ptr)
- { new(detail::get_pointer(ptr)) Node(); }
+ { new((void*)detail::get_pointer(ptr)) Node(); }
 
    #ifndef BOOST_INTERPROCESS_RVALUE_REFERENCE
    template<class Convertible1, class Convertible2>

Modified: branches/proto/v4/boost/interprocess/containers/string.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/containers/string.hpp (original)
+++ branches/proto/v4/boost/interprocess/containers/string.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -308,7 +308,7 @@
    }
 
    void construct(pointer p, const value_type &value = value_type())
- { new(detail::get_pointer(p)) value_type(value); }
+ { new((void*)detail::get_pointer(p)) value_type(value); }
 
    void destroy(pointer p, size_type n)
    {

Modified: branches/proto/v4/boost/interprocess/containers/vector.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/containers/vector.hpp (original)
+++ branches/proto/v4/boost/interprocess/containers/vector.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -301,8 +301,8 @@
                          const pointer &reuse,
                          allocator_v2)
    {
- return this->alloc().allocation_command(command, limit_size, preferred_size,
- received_size, reuse);
+ return this->alloc().allocation_command
+ (command, limit_size, preferred_size, received_size, reuse);
    }
 
    size_type next_capacity(size_type additional_objects) const
@@ -434,7 +434,7 @@
    //This is the optimized move iterator for copy constructors
    //so that std::copy and similar can use memcpy
    typedef typename detail::if_c
- <base_t::trivial_copy
+ <base_t::trivial_copy || !is_movable<value_type>::value
       ,T*
       ,detail::move_iterator<T*>
>::type copy_move_it;
@@ -442,7 +442,7 @@
    //This is the optimized move iterator for assignments
    //so that std::uninitialized_copy and similar can use memcpy
    typedef typename detail::if_c
- <base_t::trivial_assign
+ <base_t::trivial_assign || !is_movable<value_type>::value
       ,T*
       ,detail::move_iterator<T*>
>::type assign_move_it;
@@ -859,7 +859,7 @@
    {
       if (this->members_.m_size < this->members_.m_capacity){
          //There is more memory, just construct a new object at the end
- new(detail::get_pointer(this->members_.m_start) + this->members_.m_size)value_type(x);
+ new((void*)(detail::get_pointer(this->members_.m_start) + this->members_.m_size))value_type(x);
          ++this->members_.m_size;
       }
       else{
@@ -878,7 +878,7 @@
    {
       if (this->members_.m_size < this->members_.m_capacity){
          //There is more memory, just construct a new object at the end
- new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(mx);
+ new((void*)detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(mx);
          ++this->members_.m_size;
       }
       else{
@@ -890,7 +890,7 @@
    {
       if (this->members_.m_size < this->members_.m_capacity){
          //There is more memory, just construct a new object at the end
- new(detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(move(mx));
+ new((void*)detail::get_pointer(this->members_.m_start + this->members_.m_size))value_type(move(mx));
          ++this->members_.m_size;
       }
       else{
@@ -1101,7 +1101,7 @@
          T *ptr = detail::get_pointer(this->members_.m_start + this->members_.m_size);
          while(n--){
             //Default construct
- new(ptr++)T();
+ new((void*)ptr++)T();
             ++this->members_.m_size;
          }
       }
@@ -1241,9 +1241,9 @@
          std::uninitialized_copy(copy_move_it(old_finish - n), copy_move_it(old_finish), old_finish);
          this->members_.m_size += n;
          //Copy previous to last objects to the initialized end
- std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish - n), old_finish);
+ std::copy_backward(assign_move_it(pos), assign_move_it(old_finish - n), old_finish);
          //Insert new objects in the pos
- std::copy(first, last, detail::get_pointer(pos));
+ std::copy(first, last, pos);
       }
       else {
          //The new elements don't fit in the [pos, end()) range. Copy
@@ -1254,12 +1254,12 @@
          this->members_.m_size += n - elems_after;
          //Copy old [pos, end()) elements to the uninitialized memory
          std::uninitialized_copy
- ( copy_move_it(detail::get_pointer(pos))
+ ( copy_move_it(pos)
             , copy_move_it(old_finish)
             , detail::get_pointer(this->members_.m_start) + this->members_.m_size);
          this->members_.m_size += elems_after;
          //Copy first new elements in pos
- std::copy(first, mid, detail::get_pointer(pos));
+ std::copy(first, mid, pos);
       }
    }
 
@@ -1277,7 +1277,7 @@
       //the start of the new buffer
       new_finish = std::uninitialized_copy
          ( copy_move_it(detail::get_pointer(this->members_.m_start))
- , copy_move_it(detail::get_pointer(pos))
+ , copy_move_it(pos)
          , old_finish = new_finish);
       construted_values_destroyer.increment_size(new_finish - old_finish);
       //Initialize new objects, starting from previous point
@@ -1287,9 +1287,9 @@
       //Initialize from the rest of the old buffer,
       //starting from previous point
       new_finish = std::uninitialized_copy
- ( copy_move_it(detail::get_pointer(pos))
+ ( copy_move_it(pos)
          , copy_move_it(detail::get_pointer(this->members_.m_start) + this->members_.m_size)
- , detail::get_pointer(new_finish));
+ , new_finish);
 
       //All construction successful, disable rollbacks
       construted_values_destroyer.release();
@@ -1345,13 +1345,11 @@
          //Copy first old values before pos, after that the
          //new objects
          boost::interprocess::uninitialized_copy_copy
- (copy_move_it(old_start), copy_move_it(detail::get_pointer(pos)), first, last, detail::get_pointer(new_start));
+ (copy_move_it(old_start), copy_move_it(pos), first, last, new_start);
          UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore);
          //Now initialize the rest of memory with the last old values
          std::uninitialized_copy
- ( copy_move_it(detail::get_pointer(pos))
- , copy_move_it(old_finish)
- , detail::get_pointer(new_start) + elemsbefore + n);
+ (copy_move_it(pos), copy_move_it(old_finish), new_start + elemsbefore + n);
          //All new elements correctly constructed, avoid new element destruction
          new_values_destroyer.release();
          this->members_.m_size = old_size + n;
@@ -1376,17 +1374,13 @@
          //Copy first old values before pos, after that the
          //new objects
          boost::interprocess::uninitialized_copy_copy
- ( copy_move_it(old_start)
- , copy_move_it(detail::get_pointer(pos))
- , first, last, detail::get_pointer(new_start));
+ (copy_move_it(old_start), copy_move_it(pos), first, last, new_start);
          UCopiedArrayDestructor new_values_destroyer(new_start, elemsbefore);
          size_type raw_gap = s_before - (elemsbefore + n);
          //Now initialize the rest of s_before memory with the
          //first of elements after new values
          std::uninitialized_copy
- ( copy_move_it(detail::get_pointer(pos))
- , copy_move_it(detail::get_pointer(pos) + raw_gap)
- , detail::get_pointer(new_start) + elemsbefore + n);
+ (copy_move_it(pos), copy_move_it(pos + raw_gap), new_start + elemsbefore + n);
          //All new elements correctly constructed, avoid new element destruction
          new_values_destroyer.release();
          //All new elements correctly constructed, avoid old element destruction
@@ -1394,7 +1388,7 @@
          //Update size since we have a contiguous buffer
          this->members_.m_size = old_size + s_before;
          //Now copy remaining last objects in the old buffer begin
- T *to_destroy = std::copy(assign_move_it(detail::get_pointer(pos) + raw_gap), assign_move_it(old_finish), old_start);
+ T *to_destroy = std::copy(assign_move_it(pos + raw_gap), assign_move_it(old_finish), old_start);
          //Now destroy redundant elements except if they were moved and
          //they have trivial destructor after move
          size_type n_destroy = old_finish - to_destroy;
@@ -1460,24 +1454,22 @@
             //Copy the first part of old_begin to raw_mem
             T *start_n = old_start + difference_type(s_before);
             std::uninitialized_copy
- ( copy_move_it(old_start)
- , copy_move_it(start_n)
- , detail::get_pointer(new_start));
+ (copy_move_it(old_start), copy_move_it(start_n), new_start);
             //The buffer is all constructed until old_end,
             //release destroyer and update size
             old_values_destroyer.release();
             this->members_.m_size = old_size + s_before;
             //Now copy the second part of old_begin overwriting himself
- T* next = std::copy(assign_move_it(start_n), assign_move_it(detail::get_pointer(pos)), old_start);
+ T* next = std::copy(assign_move_it(start_n), assign_move_it(pos), old_start);
             if(do_after){
                //Now copy the new_beg elements
- std::copy(first, before_end, detail::get_pointer(next));
+ std::copy(first, before_end, next);
             }
             else{
                //Now copy the all the new elements
- T* move_start = std::copy(first, last, detail::get_pointer(next));
+ T* move_start = std::copy(first, last, next);
                //Now displace old_end elements
- T* move_end = std::copy(assign_move_it(detail::get_pointer(pos)), assign_move_it(old_finish), detail::get_pointer(move_start));
+ T* move_end = std::copy(assign_move_it(pos), assign_move_it(old_finish), move_start);
                //Destroy remaining moved elements from old_end except if
                //they have trivial destructor after being moved
                difference_type n_destroy = s_before - n;
@@ -1513,9 +1505,7 @@
             size_type n_new_init = difference_type(s_before) - elemsbefore;
             std::advance(mid, n_new_init);
             boost::interprocess::uninitialized_copy_copy
- ( copy_move_it(old_start)
- , copy_move_it(detail::get_pointer(pos))
- , first, mid, detail::get_pointer(new_start));
+ (copy_move_it(old_start), copy_move_it(pos), first, mid, new_start);
             //The buffer is all constructed until old_end,
             //release destroyer and update size
             old_values_destroyer.release();
@@ -1529,7 +1519,7 @@
                //Copy all new elements
                T* move_start = std::copy(mid, last, old_start);
                //Displace old_end
- T* move_end = std::copy(copy_move_it(detail::get_pointer(pos)), copy_move_it(old_finish), detail::get_pointer(move_start));
+ T* move_end = std::copy(copy_move_it(pos), copy_move_it(old_finish), move_start);
                //Destroy remaining moved elements from old_end except if they
                //have trivial destructor after being moved
                difference_type n_destroy = s_before - n;
@@ -1584,14 +1574,12 @@
                //First copy the part of old_end raw_mem
                T* finish_n = old_finish - difference_type(n_after);
                std::uninitialized_copy
- ( copy_move_it(detail::get_pointer(finish_n))
- , copy_move_it(old_finish)
- , old_finish);
+ (copy_move_it(finish_n), copy_move_it(old_finish), old_finish);
                this->members_.m_size += n_after;
                //Displace the rest of old_end to the new position
- std::copy_backward(assign_move_it(detail::get_pointer(pos)), assign_move_it(detail::get_pointer(finish_n)), old_finish);
+ std::copy_backward(assign_move_it(pos), assign_move_it(finish_n), old_finish);
                //Now overwrite with new_end
- std::copy(first, last, detail::get_pointer(pos));
+ std::copy(first, last, pos);
             }
             else {
                //The raw_mem from end will divide new_end part
@@ -1610,13 +1598,10 @@
                std::advance(mid, elemsafter);
                //First initialize data in raw memory
                boost::interprocess::uninitialized_copy_copy
- ( mid, last
- , copy_move_it(detail::get_pointer(pos))
- , copy_move_it(old_finish)
- , old_finish);
+ ( mid, last, copy_move_it(pos), copy_move_it(old_finish), old_finish);
                this->members_.m_size += n_after;
                //Now copy the part of new_end over constructed elements
- std::copy(first, mid, detail::get_pointer(pos));
+ std::copy(first, mid, pos);
             }
          }
       }

Modified: branches/proto/v4/boost/interprocess/detail/algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/detail/algorithms.hpp (original)
+++ branches/proto/v4/boost/interprocess/detail/algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -43,7 +43,7 @@
 template<class T, class InpIt>
 inline void construct_in_place_impl(T* dest, const InpIt &source, detail::false_)
 {
- new(dest)T(*source);
+ new((void*)dest)T(*source);
 }
 
 } //namespace detail {
@@ -58,7 +58,7 @@
 template<class T, class U, class D>
 inline void construct_in_place(T *dest, default_construct_iterator<U, D>)
 {
- new(dest)T();
+ new((void*)dest)T();
 }
 
 template<class InIt, class OutIt>

Modified: branches/proto/v4/boost/interprocess/detail/config_begin.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/detail/config_begin.hpp (original)
+++ branches/proto/v4/boost/interprocess/detail/config_begin.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -30,4 +30,5 @@
    #pragma warning (disable : 4711) // function selected for automatic inline expansion
    #pragma warning (disable : 4786) // identifier truncated in debug info
    #pragma warning (disable : 4996) // 'function': was declared deprecated
+ #pragma warning (disable : 4197) // top-level volatile in cast is ignored
 #endif

Modified: branches/proto/v4/boost/interprocess/detail/move.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/detail/move.hpp (original)
+++ branches/proto/v4/boost/interprocess/detail/move.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -79,7 +79,7 @@
    public:
    typedef T type;
 
- move_return(T& returned)
+ move_return(const T& returned)
       : m_moved(moved_object<T>(returned))
    {}
 

Modified: branches/proto/v4/boost/interprocess/detail/mpl.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/detail/mpl.hpp (original)
+++ branches/proto/v4/boost/interprocess/detail/mpl.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -17,7 +17,7 @@
 # pragma once
 #endif
 
-//#include <functional>
+#include <cstddef>
 
 namespace boost {
 namespace interprocess {
@@ -121,6 +121,24 @@
    { return x; }
 };
 
+template<std::size_t S>
+struct ls_zeros
+{
+ static const std::size_t value = (S & std::size_t(1)) ? 0 : (1u + ls_zeros<(S >> 1u)>::value);
+};
+
+template<>
+struct ls_zeros<0>
+{
+ static const std::size_t value = 0;
+};
+
+template<>
+struct ls_zeros<1>
+{
+ static const std::size_t value = 0;
+};
+
 } //namespace detail {
 } //namespace interprocess {
 } //namespace boost {

Modified: branches/proto/v4/boost/interprocess/detail/named_proxy.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/detail/named_proxy.hpp (original)
+++ branches/proto/v4/boost/interprocess/detail/named_proxy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -48,13 +48,13 @@
    self_t operator++(int) { return *this; }
 
    void construct(void *mem)
- { new(mem)T; }
+ { new((void*)mem)T; }
 
    virtual void construct_n(void *mem, std::size_t num, std::size_t &constructed)
    {
- T* memory = static_cast<T*>(mem);
+ T* memory = (T*)(mem);
       for(constructed = 0; constructed < num; ++constructed)
- new(memory++)T;
+ new((void*)memory++)T;
    }
 };
 
@@ -88,13 +88,13 @@
 // : p1((P1 &)p_1), p2((P2 &)p_2) {}
 //
 // void construct(void *mem)
-// { new(object)T(m_p1, m_p2); }
+// { new((void*)object)T(m_p1, m_p2); }
 //
 // virtual void construct_n(void *mem
 // , std::size_t num
 // , std::size_t &constructed)
 // {
-// T* memory = static_cast<T*>(mem);
+// T* memory = (T*)(mem);
 // for(constructed = 0; constructed < num; ++constructed){
 // this->construct(memory++, IsIterator());
 // this->do_increment(IsIterator());
@@ -103,10 +103,10 @@
 //
 // private:
 // void construct(void *mem, detail::true_)
-// { new(mem)T(*m_p1, *m_p2); }
+// { new((void*)mem)T(*m_p1, *m_p2); }
 //
 // void construct(void *mem, detail::false_)
-// { new(mem)T(m_p1, m_p2); }
+// { new((void*)mem)T(m_p1, m_p2); }
 //
 // P1 &m_p1; P2 &m_p2;
 // };
@@ -163,7 +163,7 @@
                         , std::size_t num \
                         , std::size_t &constructed) \
       { \
- T* memory = static_cast<T*>(mem); \
+ T* memory = (T*)(mem); \
          for(constructed = 0; constructed < num; ++constructed){ \
             this->construct(memory++, IsIterator()); \
             this->do_increment(IsIterator()); \
@@ -172,10 +172,10 @@
                                                                            \
       private: \
       void construct(void *mem, detail::true_) \
- { new(mem)T(BOOST_PP_ENUM_PARAMS(n, *m_p)); } \
+ { new((void*)mem)T(BOOST_PP_ENUM_PARAMS(n, *m_p)); } \
                                                                            \
       void construct(void *mem, detail::false_) \
- { new(mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
+ { new((void*)mem)T(BOOST_PP_ENUM_PARAMS(n, m_p)); } \
                                                                            \
       BOOST_PP_REPEAT(n, BOOST_INTERPROCESS_AUX_PARAM_DEFINE, _) \
    }; \

Modified: branches/proto/v4/boost/interprocess/detail/utilities.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/detail/utilities.hpp (original)
+++ branches/proto/v4/boost/interprocess/detail/utilities.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -373,11 +373,24 @@
    return ((orig_size-1)/round_to+1)*round_to;
 }
 
+//Truncates "orig_size" to a multiple of "multiple" bytes.
 inline std::size_t get_truncated_size(std::size_t orig_size, std::size_t multiple)
 {
    return orig_size/multiple*multiple;
 }
-
+
+//Rounds "orig_size" by excess to round_to bytes. round_to must be power of two
+inline std::size_t get_rounded_size_po2(std::size_t orig_size, std::size_t round_to)
+{
+ return ((orig_size-1)&(~(round_to-1))) + round_to;
+}
+
+//Truncates "orig_size" to a multiple of "multiple" bytes. multiple must be power of two
+inline std::size_t get_truncated_size_po2(std::size_t orig_size, std::size_t multiple)
+{
+ return (orig_size & (~(multiple-1)));
+}
+
 template <std::size_t OrigSize, std::size_t RoundTo>
 struct ct_rounded_size
 {

Modified: branches/proto/v4/boost/interprocess/ipc/message_queue.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/ipc/message_queue.hpp (original)
+++ branches/proto/v4/boost/interprocess/ipc/message_queue.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -98,7 +98,7 @@
 
    //!Sends a message stored in buffer "buffer" with size "buffer_size" in the
    //!message queue with priority "priority". If the message queue is full
- //!the sender is retries until time "abs_time" is reached. Returns true if
+ //!the sender retries until time "abs_time" is reached. Returns true if
    //!the message has been successfully sent. Returns false if timeout is reached.
    //!Throws interprocess_error on error.
    bool timed_send (const void *buffer, std::size_t buffer_size,
@@ -106,23 +106,23 @@
 
    //!Receives a message from the message queue. The message is stored in buffer
    //!"buffer", which has size "buffer_size". The received message has size
- //!"recvd_size" and priority "priority". If the message queue is full
- //!the sender is blocked. Throws interprocess_error on error.
+ //!"recvd_size" and priority "priority". If the message queue is empty
+ //!the receiver is blocked. Throws interprocess_error on error.
    void receive (void *buffer, std::size_t buffer_size,
                  std::size_t &recvd_size,unsigned int &priority);
 
    //!Receives a message from the message queue. The message is stored in buffer
    //!"buffer", which has size "buffer_size". The received message has size
- //!"recvd_size" and priority "priority". If the message queue is full
- //!the sender is not blocked and returns false, otherwise returns true.
+ //!"recvd_size" and priority "priority". If the message queue is empty
+ //!the receiver is not blocked and returns false, otherwise returns true.
    //!Throws interprocess_error on error.
    bool try_receive (void *buffer, std::size_t buffer_size,
                      std::size_t &recvd_size,unsigned int &priority);
 
    //!Receives a message from the message queue. The message is stored in buffer
    //!"buffer", which has size "buffer_size". The received message has size
- //!"recvd_size" and priority "priority". If the message queue is full
- //!the sender is retries until time "abs_time" is reached. Returns true if
+ //!"recvd_size" and priority "priority". If the message queue is empty
+ //!the receiver retries until time "abs_time" is reached. Returns true if
    //!the message has been successfully sent. Returns false if timeout is reached.
    //!Throws interprocess_error on error.
    bool timed_receive (void *buffer, std::size_t buffer_size,

Modified: branches/proto/v4/boost/interprocess/mapped_region.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/mapped_region.hpp (original)
+++ branches/proto/v4/boost/interprocess/mapped_region.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -45,6 +45,8 @@
 
 /// @cond
 namespace detail{ class interprocess_tester; }
+namespace detail{ class raw_mapped_region_creator; }
+
 /// @endcond
 
 //!The mapped_region class represents a portion or region created from a
@@ -140,6 +142,7 @@
    #endif
 
    friend class detail::interprocess_tester;
+ friend class detail::raw_mapped_region_creator;
    void dont_close_on_destruction();
    /// @endcond
 };
@@ -362,9 +365,9 @@
       m_base = 0;
    }
    #if (defined BOOST_WINDOWS) && !(defined BOOST_DISABLE_WIN32)
- if(m_file_mapping_hnd){
+ if(m_file_mapping_hnd != detail::invalid_file()){
          winapi::close_handle(m_file_mapping_hnd);
- m_file_mapping_hnd = 0;
+ m_file_mapping_hnd = detail::invalid_file();
       }
    #endif
 }

Modified: branches/proto/v4/boost/interprocess/mem_algo/detail/mem_algo_common.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/mem_algo/detail/mem_algo_common.hpp (original)
+++ branches/proto/v4/boost/interprocess/mem_algo/detail/mem_algo_common.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -23,6 +23,8 @@
 #include <boost/interprocess/detail/utilities.hpp>
 #include <boost/interprocess/detail/type_traits.hpp>
 #include <boost/interprocess/detail/iterators.hpp>
+#include <boost/interprocess/detail/math_functions.hpp>
+#include <boost/interprocess/detail/utilities.hpp>
 #include <boost/assert.hpp>
 #include <boost/static_assert.hpp>
 
@@ -281,6 +283,101 @@
       return this_type::priv_allocate_many(memory_algo, &elem_bytes, n_elements, 0);
    }
 
+ static bool calculate_lcm_and_needs_backwards_lcmed
+ (std::size_t backwards_multiple, std::size_t received_size, std::size_t size_to_achieve,
+ std::size_t &lcm_out, std::size_t &needs_backwards_lcmed_out)
+ {
+ // Now calculate lcm
+ std::size_t max = backwards_multiple;
+ std::size_t min = Alignment;
+ std::size_t needs_backwards;
+ std::size_t needs_backwards_lcmed;
+ std::size_t lcm;
+ std::size_t current_forward;
+ //Swap if necessary
+ if(max < min){
+ std::size_t tmp = min;
+ min = max;
+ max = tmp;
+ }
+ //Check if it's power of two
+ if((backwards_multiple & (backwards_multiple-1)) == 0){
+ if(0 != (size_to_achieve & ((backwards_multiple-1)))){
+ return false;
+ }
+
+ lcm = max;
+ //If we want to use minbytes data to get a buffer between maxbytes
+ //and minbytes if maxbytes can't be achieved, calculate the
+ //biggest of all possibilities
+ current_forward = detail::get_truncated_size_po2(received_size, backwards_multiple);
+ needs_backwards = size_to_achieve - current_forward;
+ assert((needs_backwards % backwards_multiple) == 0);
+ needs_backwards_lcmed = detail::get_rounded_size_po2(needs_backwards, lcm);
+ lcm_out = lcm;
+ needs_backwards_lcmed_out = needs_backwards_lcmed;
+ return true;
+ }
+ //Check if it's multiple of alignment
+ else if((backwards_multiple & (Alignment - 1u)) == 0){
+ lcm = backwards_multiple;
+ current_forward = detail::get_truncated_size(received_size, backwards_multiple);
+ //No need to round needs_backwards because backwards_multiple == lcm
+ needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
+ assert((needs_backwards_lcmed & (Alignment - 1u)) == 0);
+ lcm_out = lcm;
+ needs_backwards_lcmed_out = needs_backwards_lcmed;
+ return true;
+ }
+ //Check if it's multiple of the half of the alignmment
+ else if((backwards_multiple & ((Alignment/2u) - 1u)) == 0){
+ lcm = backwards_multiple*2u;
+ current_forward = detail::get_truncated_size(received_size, backwards_multiple);
+ needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
+ if(0 != (needs_backwards_lcmed & (Alignment-1)))
+ //while(0 != (needs_backwards_lcmed & (Alignment-1)))
+ needs_backwards_lcmed += backwards_multiple;
+ assert((needs_backwards_lcmed % lcm) == 0);
+ lcm_out = lcm;
+ needs_backwards_lcmed_out = needs_backwards_lcmed;
+ return true;
+ }
+ //Check if it's multiple of the half of the alignmment
+ else if((backwards_multiple & ((Alignment/4u) - 1u)) == 0){
+ std::size_t remainder;
+ lcm = backwards_multiple*4u;
+ current_forward = detail::get_truncated_size(received_size, backwards_multiple);
+ needs_backwards_lcmed = needs_backwards = size_to_achieve - current_forward;
+ //while(0 != (needs_backwards_lcmed & (Alignment-1)))
+ //needs_backwards_lcmed += backwards_multiple;
+ if(0 != (remainder = ((needs_backwards_lcmed & (Alignment-1))>>(Alignment/8u)))){
+ if(backwards_multiple & Alignment/2u){
+ needs_backwards_lcmed += (remainder)*backwards_multiple;
+ }
+ else{
+ needs_backwards_lcmed += (4-remainder)*backwards_multiple;
+ }
+ }
+ assert((needs_backwards_lcmed % lcm) == 0);
+ lcm_out = lcm;
+ needs_backwards_lcmed_out = needs_backwards_lcmed;
+ return true;
+ }
+ else{
+ lcm = detail::lcm(max, min);
+ }
+ //If we want to use minbytes data to get a buffer between maxbytes
+ //and minbytes if maxbytes can't be achieved, calculate the
+ //biggest of all possibilities
+ current_forward = detail::get_truncated_size(received_size, backwards_multiple);
+ needs_backwards = size_to_achieve - current_forward;
+ assert((needs_backwards % backwards_multiple) == 0);
+ needs_backwards_lcmed = detail::get_rounded_size(needs_backwards, lcm);
+ lcm_out = lcm;
+ needs_backwards_lcmed_out = needs_backwards_lcmed;
+ return true;
+ }
+
    static multiallocation_iterator allocate_many
       ( MemoryAlgorithm *memory_algo
       , const std::size_t *elem_sizes

Modified: branches/proto/v4/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp (original)
+++ branches/proto/v4/boost/interprocess/mem_algo/detail/simple_seq_fit_impl.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -564,7 +564,7 @@
                         T *reuse_ptr)
 {
    std::pair<void*, bool> ret = priv_allocation_command
- (command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T));
+ (command, limit_size, preferred_size, received_size, (void*)reuse_ptr, sizeof(T));
 
    BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of<T>::value));
    return std::pair<T *, bool>(static_cast<T*>(ret.first), ret.second);

Modified: branches/proto/v4/boost/interprocess/mem_algo/rbtree_best_fit.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/mem_algo/rbtree_best_fit.hpp (original)
+++ branches/proto/v4/boost/interprocess/mem_algo/rbtree_best_fit.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -651,7 +651,7 @@
                         T *reuse_ptr)
 {
    std::pair<void*, bool> ret = priv_allocation_command
- (command, limit_size, preferred_size, received_size, reuse_ptr, sizeof(T));
+ (command, limit_size, preferred_size, received_size, (void*)reuse_ptr, sizeof(T));
 
    BOOST_ASSERT(0 == ((std::size_t)ret.first % detail::alignment_of<T>::value));
    return std::pair<T *, bool>(static_cast<T*>(ret.first), ret.second);
@@ -776,26 +776,16 @@
       assert(prev_block->m_size == reuse->m_prev_size);
       algo_impl_t::assert_alignment(prev_block);
 
- //Let's calculate the number of extra bytes of data before the current
- //block's begin. The value is a multiple of backwards_multiple
- std::size_t needs_backwards = preferred_size -
- detail::get_truncated_size(received_size, backwards_multiple);
-
- const std::size_t lcm = detail::lcm(max_value(backwards_multiple, (std::size_t)Alignment)
- ,min_value(backwards_multiple, (std::size_t)Alignment));
-
- //If we want to use min_size data to get a buffer between preferred_size
- //and min_size if preferred_size can't be achieved, calculate the
- //biggest of all possibilities
- if(!only_preferred_backwards){
- needs_backwards = min_size - detail::get_truncated_size(received_size, backwards_multiple);
+ std::size_t needs_backwards_aligned;
+ std::size_t lcm;
+ if(!algo_impl_t::calculate_lcm_and_needs_backwards_lcmed
+ ( backwards_multiple
+ , received_size
+ , only_preferred_backwards ? preferred_size : min_size
+ , lcm, needs_backwards_aligned)){
+ return 0;
       }
 
- assert((needs_backwards % backwards_multiple) == 0);
-
- const std::size_t needs_backwards_aligned =
- detail::get_rounded_size(needs_backwards, lcm);
-
       //Check if previous block has enough size
       if(std::size_t(prev_block->m_size*Alignment) >= needs_backwards_aligned){
          //Now take all next space. This will succeed
@@ -857,10 +847,8 @@
             m_header.m_imultiset.erase(Imultiset::s_iterator_to(*prev_block));
 
             //Just merge the whole previous block
- needs_backwards = detail::get_truncated_size
- (prev_block->m_size*Alignment, backwards_multiple);
- //received_size = received_size/backwards_multiple*backwards_multiple + needs_backwards;
- received_size = received_size + needs_backwards;
+ //prev_block->m_size*Alignment is multiple of lcm (and backwards_multiple)
+ received_size = received_size + prev_block->m_size*Alignment;
 
             m_header.m_allocated += prev_block->m_size*Alignment;
             //Now update sizes

Modified: branches/proto/v4/boost/interprocess/offset_ptr.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/offset_ptr.hpp (original)
+++ branches/proto/v4/boost/interprocess/offset_ptr.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -53,9 +53,6 @@
 {
    /// @cond
    typedef offset_ptr<PointedType> self_t;
- typedef const PointedType * const_pointer_t;
- typedef typename detail::add_reference
- <const PointedType>::type const_reference_t;
 
    void unspecified_bool_type_func() const {}
    typedef void (self_t::*unspecified_bool_type)() const;
@@ -64,6 +61,9 @@
    __declspec(noinline) //this workaround is needed for msvc-8.0 and msvc-9.0
    #endif
    void set_offset(const volatile void *ptr)
+ { set_offset((const void*)ptr); }
+
+ void set_offset(const void *ptr)
    {
       const char *p = static_cast<const char*>(const_cast<const void*>(ptr));
       //offset == 1 && ptr != 0 is not legal for this pointer
@@ -402,68 +402,44 @@
 
 //Predeclaration to avoid including header
 template<class VoidPointer, std::size_t N>
-struct has_pointer_plus_bit;
+struct max_pointer_plus_bits;
 
-template<std::size_t N>
-struct has_pointer_plus_bit<boost::interprocess::offset_ptr<void>, N>
+template<std::size_t Alignment>
+struct max_pointer_plus_bits<boost::interprocess::offset_ptr<void>, Alignment>
 {
- static const bool value = (N % 4u == 0);
+ //The offset ptr can embed one bit less than the alignment since it
+ //uses offset == 1 to store the null pointer.
+ static const std::size_t value = ::boost::interprocess::detail::ls_zeros<Alignment>::value - 1;
 };
 
 //Predeclaration
-template<class Pointer>
-struct pointer_plus_bit;
+template<class Pointer, std::size_t NumBits>
+struct pointer_plus_bits;
 
-//Specialization
-template<class T>
-struct pointer_plus_bit<boost::interprocess::offset_ptr<T> >
+template<class T, std::size_t NumBits>
+struct pointer_plus_bits<boost::interprocess::offset_ptr<T>, NumBits>
 {
    typedef boost::interprocess::offset_ptr<T> pointer;
+ //Bits are stored in the lower bits of the pointer except the LSB,
+ //because this bit is used to represent the null pointer.
+ static const std::size_t Mask = ((std::size_t(1) << NumBits)-1)<<1u;
 
    static pointer get_pointer(const pointer &n)
- { return (T*)(std::size_t(n.get()) & ~std::size_t(2u)); }
+ { return (T*)(std::size_t(n.get()) & ~std::size_t(Mask)); }
 
    static void set_pointer(pointer &n, pointer p)
- { n = (T*)(std::size_t(p.get()) | (std::size_t(n.get()) & std::size_t(2u))); }
-
- static bool get_bit(const pointer &n)
- { return 0 != (std::size_t(n.get()) & std::size_t(2u)); }
-
- static void set_bit(pointer &n, bool c)
- { n = (T*)(std::size_t(get_pointer(n).get()) | (std::size_t(c) << 1u)); }
-};
-
-//Predeclaration to avoid including header
-template<class VoidPointer, std::size_t N>
-struct has_pointer_plus_2_bits;
-
-template<std::size_t N>
-struct has_pointer_plus_2_bits<boost::interprocess::offset_ptr<void>, N>
-{
- static const bool value = (N % 8u == 0);
-};
-
-//Predeclaration
-template<class Pointer>
-struct pointer_plus_2_bits;
-
-template<class T>
-struct pointer_plus_2_bits<boost::interprocess::offset_ptr<T> >
-{
- typedef boost::interprocess::offset_ptr<T> pointer;
-
- static pointer get_pointer(const pointer &n)
- { return (T*)(std::size_t(n.get()) & ~std::size_t(6u)); }
-
- static void set_pointer(pointer &n, pointer p)
- { n = (T*)(std::size_t(p.get()) | (std::size_t(n.get()) & std::size_t(6u))); }
+ {
+ std::size_t pint = std::size_t(p.get());
+ assert(0 == (std::size_t(pint) & Mask));
+ n = (T*)(pint | (std::size_t(n.get()) & std::size_t(Mask)));
+ }
 
    static std::size_t get_bits(const pointer &n)
- { return(std::size_t(n.get()) & std::size_t(6u)) >> 1u; }
+ { return(std::size_t(n.get()) & std::size_t(Mask)) >> 1u; }
 
    static void set_bits(pointer &n, std::size_t b)
    {
- assert(b < 4);
+ assert(b < (std::size_t(1) << NumBits));
       n = (T*)(std::size_t(get_pointer(n).get()) | (b << 1u));
    }
 };

Modified: branches/proto/v4/boost/interprocess/sync/emulation/interprocess_condition.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/sync/emulation/interprocess_condition.hpp (original)
+++ branches/proto/v4/boost/interprocess/sync/emulation/interprocess_condition.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -86,11 +86,23 @@
       if(now >= abs_time) return false;
    }
 
+ typedef boost::interprocess::scoped_lock<interprocess_mutex> InternalLock;
    //The enter interprocess_mutex guarantees that while executing a notification,
    //no other thread can execute the do_timed_wait method.
    {
       //---------------------------------------------------------------
- boost::interprocess::scoped_lock<interprocess_mutex> lock(m_enter_mut);
+ InternalLock lock;
+ if(tout_enabled){
+ InternalLock dummy(m_enter_mut, abs_time);
+ lock = move(dummy);
+ }
+ else{
+ InternalLock dummy(m_enter_mut);
+ lock = move(dummy);
+ }
+
+ if(!lock)
+ return false;
       //---------------------------------------------------------------
       //We increment the waiting thread count protected so that it will be
       //always constant when another thread enters the notification logic.
@@ -146,7 +158,18 @@
          //Notification occurred, we will lock the checking interprocess_mutex so that
          //if a notify_one notification occurs, only one thread can exit
         //---------------------------------------------------------------
- boost::interprocess::scoped_lock<interprocess_mutex> lock(m_check_mut);
+ InternalLock lock;
+ if(tout_enabled){
+ InternalLock dummy(m_check_mut, abs_time);
+ lock = move(dummy);
+ }
+ else{
+ InternalLock dummy(m_check_mut);
+ lock = move(dummy);
+ }
+
+ if(!lock)
+ return false;
          //---------------------------------------------------------------
          boost::uint32_t result = detail::atomic_cas32
                         ((boost::uint32_t*)&m_command, SLEEP, NOTIFY_ONE);

Modified: branches/proto/v4/boost/interprocess/sync/file_lock.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/sync/file_lock.hpp (original)
+++ branches/proto/v4/boost/interprocess/sync/file_lock.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -20,6 +20,7 @@
 #include <boost/interprocess/exceptions.hpp>
 #include <cassert>
 #include <boost/interprocess/detail/os_file_functions.hpp>
+#include <boost/interprocess/detail/os_thread_functions.hpp>
 #include <boost/interprocess/detail/posix_time_types_wrk.hpp>
 
 //!\file
@@ -108,62 +109,6 @@
 
    bool timed_acquire_file_lock
       (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
- {
- //Obtain current count and target time
- boost::posix_time::ptime now = microsec_clock::universal_time();
- using namespace boost::detail;
-
- if(now >= abs_time) return false;
-
- do{
- if(!try_acquire_file_lock(hnd, acquired))
- return false;
-
- if(acquired)
- return true;
- else{
- now = microsec_clock::universal_time();
-
- if(now >= abs_time){
- acquired = false;
- return true;
- }
- // relinquish current time slice
- winapi::sched_yield();
- }
- }while (true);
- }
-
- bool timed_acquire_file_lock_sharable
- (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
- {
- //Obtain current count and target time
- boost::posix_time::ptime now = microsec_clock::universal_time();
- using namespace boost::detail;
-
- if(now >= abs_time) return false;
-
- do{
- if(!try_acquire_file_lock_sharable(hnd, acquired))
- return false;
-
- if(acquired)
- return true;
- else{
- now = microsec_clock::universal_time();
-
- if(now >= abs_time){
- acquired = false;
- return true;
- }
- // relinquish current time slice
- winapi::sched_yield();
- }
- }while (true);
- }
-
- bool timed_acquire_file_lock
- (file_handle_t hnd, bool &acquired, const boost::posix_time::ptime &abs_time)
    {
       //Obtain current count and target time
       boost::posix_time::ptime now = microsec_clock::universal_time();
@@ -172,7 +117,7 @@
       if(now >= abs_time) return false;
 
       do{
- if(!try_acquire_file_lock(hnd, acquired))
+ if(!detail::try_acquire_file_lock(hnd, acquired))
             return false;
 
          if(acquired)
@@ -185,7 +130,7 @@
                return true;
             }
             // relinquish current time slice
- sleep(0);
+ detail::thread_yield();
          }
       }while (true);
    }
@@ -200,7 +145,7 @@
       if(now >= abs_time) return false;
 
       do{
- if(!try_acquire_file_lock_sharable(hnd, acquired))
+ if(!detail::try_acquire_file_lock_sharable(hnd, acquired))
             return false;
 
          if(acquired)
@@ -213,7 +158,7 @@
                return true;
             }
             // relinquish current time slice
- ::sleep(0);
+ detail::thread_yield();
          }
       }while (true);
    }
@@ -259,7 +204,7 @@
 inline bool file_lock::timed_lock(const boost::posix_time::ptime &abs_time)
 {
    bool result;
- if(!detail::timed_acquire_file_lock(m_file_hnd, result, abs_time)){
+ if(!this->timed_acquire_file_lock(m_file_hnd, result, abs_time)){
       error_info err(system_error_code());
       throw interprocess_exception(err);
    }
@@ -295,7 +240,7 @@
 inline bool file_lock::timed_lock_sharable(const boost::posix_time::ptime &abs_time)
 {
    bool result;
- if(!detail::timed_acquire_file_lock_sharable(m_file_hnd, result, abs_time)){
+ if(!this->timed_acquire_file_lock_sharable(m_file_hnd, result, abs_time)){
       error_info err(system_error_code());
       throw interprocess_exception(err);
    }

Modified: branches/proto/v4/boost/interprocess/sync/named_condition.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/sync/named_condition.hpp (original)
+++ branches/proto/v4/boost/interprocess/sync/named_condition.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -159,7 +159,9 @@
       //unlock internal first to avoid deadlock with near simultaneous waits
       lock_inverter<Lock> inverted_lock(lock);
       scoped_lock<lock_inverter<Lock> > external_unlock(inverted_lock);
- scoped_lock<interprocess_mutex> internal_lock(*this->mutex());
+ if(!external_unlock) return false;
+ scoped_lock<interprocess_mutex> internal_lock(*this->mutex(), abs_time);
+ if(!internal_lock) return false;
       return this->condition()->timed_wait(internal_lock, abs_time);
    }
    #endif

Modified: branches/proto/v4/boost/interprocess/windows_shared_memory.hpp
==============================================================================
--- branches/proto/v4/boost/interprocess/windows_shared_memory.hpp (original)
+++ branches/proto/v4/boost/interprocess/windows_shared_memory.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -169,7 +169,7 @@
 inline bool windows_shared_memory::priv_open_or_create
    (detail::create_enum_t type, const char *filename, mode_t mode, std::size_t size)
 {
- m_name = filename;
+ m_name = filename ? filename : "";
 
    unsigned long file_map_access = 0;
    unsigned long map_access = 0;

Modified: branches/proto/v4/boost/intrusive/avl_set.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/avl_set.hpp (original)
+++ branches/proto/v4/boost/intrusive/avl_set.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -240,7 +240,7 @@
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
    //! of avl_set.
    //!
- //! <b>Effects</b>: Returns a const reference to the avl_set associated to the end iterator
+ //! <b>Effects</b>: Returns a const reference to the set associated to the end iterator
    //!
    //! <b>Throws</b>: Nothing.
    //!
@@ -252,6 +252,34 @@
          , &avl_set_impl::tree_);
    }
 
+ //! <b>Precondition</b>: it must be a valid iterator of set.
+ //!
+ //! <b>Effects</b>: Returns a reference to the set associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static avl_set_impl &container_from_iterator(iterator it)
+ {
+ return *detail::parent_from_member<avl_set_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &avl_set_impl::tree_);
+ }
+
+ //! <b>Precondition</b>: it must be a valid const_iterator of set.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the set associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const avl_set_impl &container_from_iterator(const_iterator it)
+ {
+ return *detail::parent_from_member<avl_set_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &avl_set_impl::tree_);
+ }
+
    //! <b>Effects</b>: Returns the key_compare object used by the avl_set.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1085,6 +1113,12 @@
 
    static const avl_set &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const avl_set &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static avl_set &container_from_iterator(iterator end_iterator)
+ { return static_cast<avl_set &>(Base::container_from_iterator(end_iterator)); }
+
+ static const avl_set &container_from_iterator(const_iterator end_iterator)
+ { return static_cast<const avl_set &>(Base::container_from_iterator(end_iterator)); }
 };
 
 #endif
@@ -1317,6 +1351,34 @@
          , &avl_multiset_impl::tree_);
    }
 
+ //! <b>Precondition</b>: it must be a valid iterator of multiset.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the multiset associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static avl_multiset_impl &container_from_iterator(iterator it)
+ {
+ return *detail::parent_from_member<avl_multiset_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &avl_multiset_impl::tree_);
+ }
+
+ //! <b>Precondition</b>: it must be a valid const_iterator of multiset.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the multiset associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const avl_multiset_impl &container_from_iterator(const_iterator it)
+ {
+ return *detail::parent_from_member<avl_multiset_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &avl_multiset_impl::tree_);
+ }
+
    //! <b>Effects</b>: Returns the key_compare object used by the avl_multiset.
    //!
    //! <b>Complexity</b>: Constant.
@@ -2057,6 +2119,12 @@
 
    static const avl_multiset &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const avl_multiset &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static avl_multiset &container_from_iterator(iterator end_iterator)
+ { return static_cast<avl_multiset &>(Base::container_from_iterator(end_iterator)); }
+
+ static const avl_multiset &container_from_iterator(const_iterator end_iterator)
+ { return static_cast<const avl_multiset &>(Base::container_from_iterator(end_iterator)); }
 };
 
 #endif

Modified: branches/proto/v4/boost/intrusive/avltree.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/avltree.hpp (original)
+++ branches/proto/v4/boost/intrusive/avltree.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -387,6 +387,28 @@
    static const avltree_impl &container_from_end_iterator(const_iterator end_iterator)
    { return priv_container_from_end_iterator(end_iterator); }
 
+ //! <b>Precondition</b>: it must be a valid iterator
+ //! of rbtree.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static avltree_impl &container_from_iterator(iterator it)
+ { return priv_container_from_iterator(it); }
+
+ //! <b>Precondition</b>: it must be a valid end const_iterator
+ //! of rbtree.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const avltree_impl &container_from_iterator(const_iterator it)
+ { return priv_container_from_iterator(it); }
+
    //! <b>Effects</b>: Returns the value_compare object used by the tree.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1233,6 +1255,9 @@
       avltree_impl *avl = detail::parent_from_member<avltree_impl, data_t>(d, &avltree_impl::data_);
       return *avl;
    }
+
+ static avltree_impl &priv_container_from_iterator(const const_iterator &it)
+ { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
 };
 
 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
@@ -1426,6 +1451,12 @@
 
    static const avltree &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const avltree &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static avltree &container_from_iterator(iterator it)
+ { return static_cast<avltree &>(Base::container_from_iterator(it)); }
+
+ static const avltree &container_from_iterator(const_iterator it)
+ { return static_cast<const avltree &>(Base::container_from_iterator(it)); }
 };
 
 #endif

Modified: branches/proto/v4/boost/intrusive/avltree_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/avltree_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/avltree_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -20,7 +20,6 @@
 #include <boost/intrusive/intrusive_fwd.hpp>
 
 #include <boost/intrusive/detail/assert.hpp>
-#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
 #include <boost/intrusive/detail/tree_algorithms.hpp>
 
@@ -641,6 +640,16 @@
       rebalance_after_insertion(header, new_value);
    }
 
+ //! <b>Requires</b>: "n" must be a node inserted in a tree.
+ //!
+ //! <b>Effects</b>: Returns a pointer to the header node of the tree.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ //!
+ //! <b>Throws</b>: Nothing.
+ static node_ptr get_header(node_ptr n)
+ { return tree_algorithms::get_header(n); }
+
    /// @cond
    private:
 

Modified: branches/proto/v4/boost/intrusive/circular_list_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/circular_list_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/circular_list_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -62,8 +62,8 @@
    //! <b>Throws</b>: Nothing.
    static void init(node_ptr this_node)
    {
- NodeTraits::set_next(this_node, 0);
- NodeTraits::set_previous(this_node, 0);
+ NodeTraits::set_next(this_node, node_ptr(0));
+ NodeTraits::set_previous(this_node, node_ptr(0));
    }
 
    //! <b>Effects</b>: Returns true is "this_node" is in a non-used state

Modified: branches/proto/v4/boost/intrusive/circular_slist_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/circular_slist_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/circular_slist_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -305,12 +305,12 @@
    static node_ptr move_backwards(node_ptr p, std::size_t n)
    {
       //Null shift, nothing to do
- if(!n) return 0;
+ if(!n) return node_ptr(0);
       node_ptr first = NodeTraits::get_next(p);
 
       //count() == 1 or 2, nothing to do
       if(NodeTraits::get_next(first) == p)
- return 0;
+ return node_ptr(0);
 
       bool end_found = false;
       node_ptr new_last(0);
@@ -326,7 +326,7 @@
             //Shortcut the shift with the modulo of the size of the list
             n %= i;
             if(!n)
- return 0;
+ return node_ptr(0);
             i = 0;
             //Unlink p and continue the new first node search
             first = NodeTraits::get_next(p);
@@ -357,11 +357,11 @@
    static node_ptr move_forward(node_ptr p, std::size_t n)
    {
       //Null shift, nothing to do
- if(!n) return 0;
+ if(!n) return node_ptr(0);
       node_ptr first = node_traits::get_next(p);
 
       //count() == 1 or 2, nothing to do
- if(node_traits::get_next(first) == p) return 0;
+ if(node_traits::get_next(first) == p) return node_ptr(0);
 
       //Iterate until p is found to know where the current last node is.
       //If the shift count is less than the size of the list, we can also obtain
@@ -380,7 +380,7 @@
          //Shortcut the shift with the modulo of the size of the list
          std::size_t new_before_last_pos = (distance - (n % distance))% distance;
          //If the shift is a multiple of the size there is nothing to do
- if(!new_before_last_pos) return 0;
+ if(!new_before_last_pos) return node_ptr(0);
          
          for( new_last = p
             ; new_before_last_pos--

Modified: branches/proto/v4/boost/intrusive/detail/avltree_node.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/avltree_node.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/avltree_node.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -17,7 +17,7 @@
 #include <iterator>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/avltree_algorithms.hpp>
-#include <boost/intrusive/pointer_plus_2_bits.hpp>
+#include <boost/intrusive/pointer_plus_bits.hpp>
 #include <boost/intrusive/detail/mpl.hpp>
 
 namespace boost {
@@ -111,7 +111,7 @@
       <VoidPointer, const node>::type const_node_ptr;
    typedef typename node::balance balance;
 
- typedef pointer_plus_2_bits<node_ptr> ptr_bit;
+ typedef pointer_plus_bits<node_ptr, 2> ptr_bit;
 
    static node_ptr get_parent(const_node_ptr n)
    { return ptr_bit::get_pointer(n->parent_); }
@@ -148,7 +148,7 @@
 };
 
 //Dispatches the implementation based on the boolean
-template<class VoidPointer, bool compact>
+template<class VoidPointer, bool Compact>
 struct avltree_node_traits_dispatch
    : public default_avltree_node_traits_impl<VoidPointer>
 {};
@@ -164,10 +164,10 @@
    : public avltree_node_traits_dispatch
          < VoidPointer
          , OptimizeSize &&
- has_pointer_plus_2_bits
+ max_pointer_plus_bits
             < VoidPointer
             , detail::alignment_of<compact_avltree_node<VoidPointer> >::value
- >::value
+ >::value >= 2u
>
 {};
 

Modified: branches/proto/v4/boost/intrusive/detail/common_slist_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/common_slist_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/common_slist_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -47,7 +47,7 @@
    { NodeTraits::set_next(this_node, this_node); }
 
    static void init(node_ptr this_node)
- { NodeTraits::set_next(this_node, 0); }
+ { NodeTraits::set_next(this_node, node_ptr(0)); }
 
    static bool unique(const_node_ptr this_node)
    {

Modified: branches/proto/v4/boost/intrusive/detail/ebo_functor_holder.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/ebo_functor_holder.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/ebo_functor_holder.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -23,8 +23,15 @@
 class ebo_functor_holder_impl
 {
    public:
- ebo_functor_holder_impl(){}
- ebo_functor_holder_impl(const T& t):t(t){}
+ ebo_functor_holder_impl()
+ {}
+ ebo_functor_holder_impl(const T& t)
+ : t(t)
+ {}
+ template<class Arg1, class Arg2>
+ ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
+ : t(arg1, arg2)
+ {}
 
    T& get(){return t;}
    const T& get()const{return t;}
@@ -38,8 +45,15 @@
    : public T
 {
    public:
- ebo_functor_holder_impl(){}
- ebo_functor_holder_impl(const T& t):T(t){}
+ ebo_functor_holder_impl()
+ {}
+ ebo_functor_holder_impl(const T& t)
+ : T(t)
+ {}
+ template<class Arg1, class Arg2>
+ ebo_functor_holder_impl(const Arg1& arg1, const Arg2& arg2)
+ : T(arg1, arg2)
+ {}
 
    T& get(){return *this;}
    const T& get()const{return *this;}
@@ -54,7 +68,14 @@
 
    public:
    ebo_functor_holder(){}
- ebo_functor_holder(const T& t):super(t){}
+ ebo_functor_holder(const T& t)
+ : super(t)
+ {}
+
+ template<class Arg1, class Arg2>
+ ebo_functor_holder(const Arg1& arg1, const Arg2& arg2)
+ : super(arg1, arg2)
+ {}
 
    ebo_functor_holder& operator=(const ebo_functor_holder& x)
    {

Modified: branches/proto/v4/boost/intrusive/detail/hashtable_node.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/hashtable_node.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/hashtable_node.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -50,6 +50,7 @@
 template <class Slist>
 struct bucket_impl : public Slist
 {
+ typedef Slist slist_type;
    bucket_impl()
    {}
 
@@ -69,28 +70,6 @@
       //Slist::clear();
       return *this;
    }
-
- static typename Slist::difference_type get_bucket_num
- ( typename Slist::const_iterator it
- , const bucket_impl<Slist> &first_bucket
- , const bucket_impl<Slist> &last_bucket)
- {
- typename Slist::const_iterator
- first(first_bucket.cend()), last(last_bucket.cend());
-
- //The end node is embedded in the singly linked list:
- //iterate until we reach it.
- while(!(first.pointed_node() <= it.pointed_node() &&
- it.pointed_node() <= last.pointed_node())){
- ++it;
- }
- //Now get the bucket_impl from the iterator
- const bucket_impl &b = static_cast<const bucket_impl&>
- (Slist::container_from_end_iterator(it));
-
- //Now just calculate the index b has in the bucket array
- return &b - &first_bucket;
- }
 };
 
 template<class Slist>
@@ -133,6 +112,9 @@
       < typename Container::pointer, const Container>::type const_cont_ptr;
    typedef typename Container::size_type size_type;
 
+ static typename Container::node_ptr downcast_bucket(typename bucket_type::node_ptr p)
+ { return typename Container::node_ptr(&static_cast<typename Container::node&>(*p)); }
+
    public:
    typedef typename detail::add_const_if_c
       <typename Container::value_type, IsConst>::type value_type;
@@ -172,7 +154,7 @@
    { return *this->operator ->(); }
 
    value_type* operator->() const
- { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(slist_it_.pointed_node())); }
+ { return detail::get_pointer(this->get_real_value_traits()->to_value_ptr(downcast_bucket(slist_it_.pointed_node()))); }
 
    const Container *get_container() const
    { return detail::get_pointer(cont_); }
@@ -186,17 +168,19 @@
       const Container *cont = detail::get_pointer(cont_);
       bucket_type* buckets = detail::get_pointer(cont->bucket_pointer());
       size_type buckets_len = cont->bucket_count();
- const_siterator first(buckets[0].cend());
- const_siterator last (buckets[buckets_len].cend());
 
       ++slist_it_;
- if(first.pointed_node() <= slist_it_.pointed_node() &&
- slist_it_.pointed_node()<= last.pointed_node() ){
- size_type n_bucket = (size_type)
- bucket_type::get_bucket_num(slist_it_, buckets[0], buckets[buckets_len]);
+ if(buckets[0].cend().pointed_node() <= slist_it_.pointed_node() &&
+ slist_it_.pointed_node()<= buckets[buckets_len].cend().pointed_node() ){
+ //Now get the bucket_impl from the iterator
+ const bucket_type &b = static_cast<const bucket_type&>
+ (bucket_type::slist_type::container_from_end_iterator(slist_it_));
+
+ //Now just calculate the index b has in the bucket array
+ size_type n_bucket = static_cast<size_type>(&b - &buckets[0]);
          do{
             if (++n_bucket == buckets_len){
- slist_it_ = buckets->end();
+ slist_it_ = (&buckets[0] + buckets_len)->end();
                break;
             }
             slist_it_ = buckets[n_bucket].begin();

Modified: branches/proto/v4/boost/intrusive/detail/list_node.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/list_node.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/list_node.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -32,7 +32,8 @@
 {
    typedef typename boost::pointer_to_other
       <VoidPointer, list_node>::type node_ptr;
- node_ptr prev_, next_;
+ node_ptr next_;
+ node_ptr prev_;
 };
 
 template<class VoidPointer>
@@ -85,7 +86,7 @@
    typedef value_type * pointer;
 
    list_iterator()
- : members_ (0, 0)
+ : members_ (node_ptr(0), 0)
    {}
 
    explicit list_iterator(node_ptr node, const Container *cont_ptr)

Modified: branches/proto/v4/boost/intrusive/detail/mpl.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/mpl.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/mpl.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,8 @@
 #ifndef BOOST_INTRUSIVE_DETAIL_MPL_HPP
 #define BOOST_INTRUSIVE_DETAIL_MPL_HPP
 
+#include <cstddef>
+
 namespace boost {
 namespace intrusive {
 namespace detail {
@@ -290,6 +292,24 @@
    static const bool value = sizeof(empty_helper_t1<Class>) == sizeof(empty_helper_t2);
 };
 
+template<std::size_t S>
+struct ls_zeros
+{
+ static const std::size_t value = (S & std::size_t(1)) ? 0 : (1 + ls_zeros<(S>>1u)>::value);
+};
+
+template<>
+struct ls_zeros<0>
+{
+ static const std::size_t value = 0;
+};
+
+template<>
+struct ls_zeros<1>
+{
+ static const std::size_t value = 0;
+};
+
 } //namespace detail
 } //namespace intrusive
 } //namespace boost

Deleted: branches/proto/v4/boost/intrusive/detail/no_exceptions_support.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/no_exceptions_support.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
+++ (empty file)
@@ -1,28 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2007
-//
-// 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)
-//
-// See http://www.boost.org/libs/intrusive for documentation.
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTRUSIVE_NO_EXCEPTION_SUPPORT_HPP
-
-#if !(defined BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING)
-# include <boost/detail/no_exceptions_support.hpp>
-# define BOOST_INTRUSIVE_TRY BOOST_TRY
-# define BOOST_INTRUSIVE_CATCH(x) BOOST_CATCH(x)
-# define BOOST_INTRUSIVE_RETHROW BOOST_RETHROW
-# define BOOST_INTRUSIVE_CATCH_END BOOST_CATCH_END
-#else
-# define BOOST_INTRUSIVE_TRY { if (true)
-# define BOOST_INTRUSIVE_CATCH(x) else if (false)
-# define BOOST_INTRUSIVE_RETHROW
-# define BOOST_INTRUSIVE_CATCH_END }
-#endif
-
-#endif //#ifndef BOOST_INTRUSIVE_NO_EXCEPTION_SUPPORT_HPP

Modified: branches/proto/v4/boost/intrusive/detail/rbtree_node.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/rbtree_node.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/rbtree_node.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 #include <iterator>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/rbtree_algorithms.hpp>
-#include <boost/intrusive/pointer_plus_bit.hpp>
+#include <boost/intrusive/pointer_plus_bits.hpp>
 #include <boost/intrusive/detail/mpl.hpp>
 
 namespace boost {
@@ -110,7 +110,7 @@
    typedef typename boost::pointer_to_other
       <VoidPointer, const node>::type const_node_ptr;
 
- typedef pointer_plus_bit<node_ptr> ptr_bit;
+ typedef pointer_plus_bits<node_ptr, 1> ptr_bit;
 
    typedef typename node::color color;
 
@@ -133,10 +133,10 @@
    { n->right_ = r; }
 
    static color get_color(const_node_ptr n)
- { return (color)ptr_bit::get_bit(n->parent_); }
+ { return (color)ptr_bit::get_bits(n->parent_); }
 
    static void set_color(node_ptr n, color c)
- { ptr_bit::set_bit(n->parent_, c != 0); }
+ { ptr_bit::set_bits(n->parent_, c != 0); }
 
    static color black()
    { return node::black_t; }
@@ -146,7 +146,7 @@
 };
 
 //Dispatches the implementation based on the boolean
-template<class VoidPointer, bool compact>
+template<class VoidPointer, bool Compact>
 struct rbtree_node_traits_dispatch
    : public default_rbtree_node_traits_impl<VoidPointer>
 {};
@@ -161,11 +161,11 @@
 struct rbtree_node_traits
    : public rbtree_node_traits_dispatch
          < VoidPointer
- , OptimizeSize &&
- has_pointer_plus_bit
+ , OptimizeSize &&
+ (max_pointer_plus_bits
             < VoidPointer
             , detail::alignment_of<compact_rbtree_node<VoidPointer> >::value
- >::value
+ >::value >= 1)
>
 {};
 

Modified: branches/proto/v4/boost/intrusive/detail/slist_node.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/slist_node.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/slist_node.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -78,7 +78,7 @@
    typedef value_type * pointer;
 
    slist_iterator()
- : members_ (0, 0)
+ : members_ (node_ptr(0), 0)
    {}
 
    explicit slist_iterator(node_ptr node, const Container *cont_ptr)

Modified: branches/proto/v4/boost/intrusive/detail/tree_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/tree_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/tree_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -17,7 +17,6 @@
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <cstddef>
-#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
 
 namespace boost {
@@ -97,6 +96,7 @@
 {
    /// @cond
    private:
+
    typedef typename NodeTraits::node node;
    /// @endcond
 
@@ -123,6 +123,26 @@
 
    /// @cond
    private:
+ template<class Disposer>
+ struct dispose_subtree_disposer
+ {
+ dispose_subtree_disposer(Disposer &disp, node_ptr subtree)
+ : disposer_(&disp), subtree_(subtree)
+ {}
+
+ void release()
+ { disposer_ = 0; }
+
+ ~dispose_subtree_disposer()
+ {
+ if(disposer_){
+ dispose_subtree(subtree_, *disposer_);
+ }
+ }
+ Disposer *disposer_;
+ node_ptr subtree_;
+ };
+
    static node_ptr uncast(const_node_ptr ptr)
    {
       return node_ptr(const_cast<node*>(::boost::intrusive::detail::get_pointer(ptr)));
@@ -505,9 +525,21 @@
    //! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
    static void init(node_ptr node)
    {
- NodeTraits::set_parent(node, 0);
- NodeTraits::set_left(node, 0);
- NodeTraits::set_right(node, 0);
+ NodeTraits::set_parent(node, node_ptr(0));
+ NodeTraits::set_left(node, node_ptr(0));
+ NodeTraits::set_right(node, node_ptr(0));
+ };
+
+ //! <b>Effects</b>: Returns true if node is in the same state as if called init(node)
+ //!
+ //! <b>Complexity</b>: Constant.
+ //!
+ //! <b>Throws</b>: Nothing.
+ static bool inited(const_node_ptr node)
+ {
+ return !NodeTraits::get_parent(node) &&
+ !NodeTraits::get_left(node) &&
+ !NodeTraits::get_right(node) ;
    };
 
    //! <b>Requires</b>: node must not be part of any tree.
@@ -522,7 +554,7 @@
    //! <b>Nodes</b>: If node is inserted in a tree, this function corrupts the tree.
    static void init_header(node_ptr header)
    {
- NodeTraits::set_parent(header, 0);
+ NodeTraits::set_parent(header, node_ptr(0));
       NodeTraits::set_left(header, header);
       NodeTraits::set_right(header, header);
    }
@@ -565,7 +597,7 @@
    {
       node_ptr leftmost = NodeTraits::get_left(header);
       if (leftmost == header)
- return 0;
+ return node_ptr(0);
       node_ptr leftmost_parent(NodeTraits::get_parent(leftmost));
       node_ptr leftmost_right (NodeTraits::get_right(leftmost));
       bool is_root = leftmost_parent == header;
@@ -580,12 +612,12 @@
             NodeTraits::set_left(NodeTraits::get_parent(header), leftmost_right);
       }
       else if (is_root){
- NodeTraits::set_parent(header, 0);
+ NodeTraits::set_parent(header, node_ptr(0));
          NodeTraits::set_left(header, header);
          NodeTraits::set_right(header, header);
       }
       else{
- NodeTraits::set_left(leftmost_parent, 0);
+ NodeTraits::set_left(leftmost_parent, node_ptr(0));
          NodeTraits::set_left(header, leftmost_parent);
       }
       return leftmost;
@@ -1143,58 +1175,54 @@
          node_ptr rightmost = target_sub_root;
 
          //First set the subroot
- NodeTraits::set_left(target_sub_root, 0);
- NodeTraits::set_right(target_sub_root, 0);
+ NodeTraits::set_left(target_sub_root, node_ptr(0));
+ NodeTraits::set_right(target_sub_root, node_ptr(0));
          NodeTraits::set_parent(target_sub_root, target_parent);
 
- try {
- while(true) {
- //First clone left nodes
- if( NodeTraits::get_left(current) &&
- !NodeTraits::get_left(insertion_point)) {
- current = NodeTraits::get_left(current);
- node_ptr temp = insertion_point;
- //Clone and mark as leaf
- insertion_point = cloner(current);
- NodeTraits::set_left (insertion_point, 0);
- NodeTraits::set_right (insertion_point, 0);
- //Insert left
- NodeTraits::set_parent(insertion_point, temp);
- NodeTraits::set_left (temp, insertion_point);
- //Update leftmost
- if(rightmost == target_sub_root)
- leftmost = insertion_point;
- }
- //Then clone right nodes
- else if( NodeTraits::get_right(current) &&
- !NodeTraits::get_right(insertion_point)){
- current = NodeTraits::get_right(current);
- node_ptr temp = insertion_point;
- //Clone and mark as leaf
- insertion_point = cloner(current);
- NodeTraits::set_left (insertion_point, 0);
- NodeTraits::set_right (insertion_point, 0);
- //Insert right
- NodeTraits::set_parent(insertion_point, temp);
- NodeTraits::set_right (temp, insertion_point);
- //Update rightmost
- rightmost = insertion_point;
- }
- //If not, go up
- else if(current == source_root){
- break;
- }
- else{
- //Branch completed, go up searching more nodes to clone
- current = NodeTraits::get_parent(current);
- insertion_point = NodeTraits::get_parent(insertion_point);
- }
+ dispose_subtree_disposer<Disposer> rollback(disposer, target_sub_root);
+ while(true) {
+ //First clone left nodes
+ if( NodeTraits::get_left(current) &&
+ !NodeTraits::get_left(insertion_point)) {
+ current = NodeTraits::get_left(current);
+ node_ptr temp = insertion_point;
+ //Clone and mark as leaf
+ insertion_point = cloner(current);
+ NodeTraits::set_left (insertion_point, node_ptr(0));
+ NodeTraits::set_right (insertion_point, node_ptr(0));
+ //Insert left
+ NodeTraits::set_parent(insertion_point, temp);
+ NodeTraits::set_left (temp, insertion_point);
+ //Update leftmost
+ if(rightmost == target_sub_root)
+ leftmost = insertion_point;
+ }
+ //Then clone right nodes
+ else if( NodeTraits::get_right(current) &&
+ !NodeTraits::get_right(insertion_point)){
+ current = NodeTraits::get_right(current);
+ node_ptr temp = insertion_point;
+ //Clone and mark as leaf
+ insertion_point = cloner(current);
+ NodeTraits::set_left (insertion_point, node_ptr(0));
+ NodeTraits::set_right (insertion_point, node_ptr(0));
+ //Insert right
+ NodeTraits::set_parent(insertion_point, temp);
+ NodeTraits::set_right (temp, insertion_point);
+ //Update rightmost
+ rightmost = insertion_point;
+ }
+ //If not, go up
+ else if(current == source_root){
+ break;
+ }
+ else{
+ //Branch completed, go up searching more nodes to clone
+ current = NodeTraits::get_parent(current);
+ insertion_point = NodeTraits::get_parent(insertion_point);
             }
          }
- catch(...) {
- dispose_subtree(target_sub_root, disposer);
- throw;
- }
+ rollback.release();
          leftmost_out = leftmost;
          rightmost_out = rightmost;
       }
@@ -1321,8 +1349,8 @@
              NodeTraits::set_right(header, z);
       }
       NodeTraits::set_parent(z, par);
- NodeTraits::set_right(z, 0);
- NodeTraits::set_left(z, 0);
+ NodeTraits::set_right(z, node_ptr(0));
+ NodeTraits::set_left(z, node_ptr(0));
    }
 
    static void erase(node_ptr header, node_ptr z)
@@ -1384,7 +1412,7 @@
    {
       std::size_t len;
       len = 0;
- if(!old_root) return 0;
+ if(!old_root) return node_ptr(0);
 
       //To avoid irregularities in the algorithm (old_root can be a
       //left or right child or even the root of the tree) just put the
@@ -1392,8 +1420,8 @@
       //information to restore the original relationship after
       //the algorithm is applied.
       node_ptr super_root = NodeTraits::get_parent(old_root);
- assert(super_root);
-
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(super_root);
+
       //Get info
       node_ptr super_root_right_backup = NodeTraits::get_right(super_root);
       bool super_root_is_header = is_header(super_root);
@@ -1464,7 +1492,7 @@
       //information to restore the original relationship after
       //the algorithm is applied.
       node_ptr super_root = NodeTraits::get_parent(old_root);
- assert(super_root);
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(super_root);
 
       //Get info
       node_ptr super_root_right_backup = NodeTraits::get_right(super_root);
@@ -1511,6 +1539,28 @@
       return new_root;
    }
 
+ //! <b>Requires</b>: "n" must be a node inserted in a tree.
+ //!
+ //! <b>Effects</b>: Returns a pointer to the header node of the tree.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ //!
+ //! <b>Throws</b>: Nothing.
+ static node_ptr get_root(node_ptr node)
+ {
+ BOOST_INTRUSIVE_INVARIANT_ASSERT((!inited(node)));
+ node_ptr x = NodeTraits::get_parent(node);
+ if(x){
+ while(!is_header(x)){
+ x = NodeTraits::get_parent(x);
+ }
+ return x;
+ }
+ else{
+ return node;
+ }
+ }
+
    private:
    static void erase_impl(node_ptr header, node_ptr z, data_for_rebalance &info)
    {
@@ -1569,7 +1619,6 @@
       info.x_parent = x_parent;
       info.y = y;
    }
-
 };
 
 } //namespace detail {

Modified: branches/proto/v4/boost/intrusive/detail/tree_node.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/tree_node.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/tree_node.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -168,6 +168,11 @@
          return 0;
    }
 
+ tree_iterator end_iterator_from_it() const
+ {
+ return tree_iterator(node_algorithms::get_header(this->pointed_node()), this->get_container());
+ }
+
    private:
    struct members
       : public detail::select_constptr

Modified: branches/proto/v4/boost/intrusive/detail/utilities.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/detail/utilities.hpp (original)
+++ branches/proto/v4/boost/intrusive/detail/utilities.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -235,16 +235,9 @@
    node_cloner(F f, const Container *cont)
       : base_t(f), cont_(cont)
    {}
-
+
    node_ptr operator()(node_ptr p)
- {
- node_ptr n = cont_->get_real_value_traits().to_node_ptr
- (*base_t::get()(*cont_->get_real_value_traits().to_value_ptr(p)));
- //Cloned node must be in default mode if the linking mode requires it
- if(safemode_or_autounlink)
- BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
- return n;
- }
+ { return this->operator()(*p); }
 
    node_ptr operator()(const node &to_clone)
    {
@@ -396,16 +389,16 @@
 struct link_dispatch
 {};
 
-template<class Container>
-void destructor_impl(Container &cont, detail::link_dispatch<safe_link>)
-{ (void)cont; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!cont.is_linked()); }
-
-template<class Container>
-void destructor_impl(Container &cont, detail::link_dispatch<auto_unlink>)
-{ cont.unlink(); }
+template<class Hook>
+void destructor_impl(Hook &hook, detail::link_dispatch<safe_link>)
+{ (void)hook; BOOST_INTRUSIVE_SAFE_HOOK_DESTRUCTOR_ASSERT(!hook.is_linked()); }
+
+template<class Hook>
+void destructor_impl(Hook &hook, detail::link_dispatch<auto_unlink>)
+{ hook.unlink(); }
 
-template<class Container>
-void destructor_impl(Container &, detail::link_dispatch<normal_link>)
+template<class Hook>
+void destructor_impl(Hook &, detail::link_dispatch<normal_link>)
 {}
 
 template<class T, class NodeTraits, link_mode_type LinkMode, class Tag, int HookType>
@@ -548,6 +541,62 @@
    return (value >> (pow - x)) + 1;
 }
 
+template<class Container, class Disposer>
+class exception_disposer
+{
+ Container *cont_;
+ Disposer &disp_;
+
+ exception_disposer(const exception_disposer&);
+ exception_disposer &operator=(const exception_disposer&);
+
+ public:
+ exception_disposer(Container &cont, Disposer &disp)
+ : cont_(&cont), disp_(disp)
+ {}
+
+ void release()
+ { cont_ = 0; }
+
+ ~exception_disposer()
+ {
+ if(cont_){
+ cont_->clear_and_dispose(disp_);
+ }
+ }
+};
+
+template<class Container, class Disposer>
+class exception_array_disposer
+{
+ Container *cont_;
+ Disposer &disp_;
+ typename Container::size_type &constructed_;
+
+ exception_array_disposer(const exception_array_disposer&);
+ exception_array_disposer &operator=(const exception_array_disposer&);
+
+ public:
+ typedef typename Container::size_type size_type;
+ exception_array_disposer
+ (Container &cont, Disposer &disp, size_type &constructed)
+ : cont_(&cont), disp_(disp), constructed_(constructed)
+ {}
+
+ void release()
+ { cont_ = 0; }
+
+ ~exception_array_disposer()
+ {
+ size_type n = constructed_;
+ if(cont_){
+ while(n--){
+ cont_[n].clear_and_dispose(disp_);
+ }
+ }
+ }
+};
+
 } //namespace detail
 } //namespace intrusive
 } //namespace boost

Modified: branches/proto/v4/boost/intrusive/hashtable.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/hashtable.hpp (original)
+++ branches/proto/v4/boost/intrusive/hashtable.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -14,15 +14,15 @@
 
 #include <boost/intrusive/detail/config_begin.hpp>
 //std C++
-#include <functional>
-#include <utility>
-#include <algorithm>
-#include <cstddef>
+#include <functional> //std::equal_to
+#include <utility> //std::pair
+#include <algorithm> //std::swap, std::lower_bound, std::upper_bound
+#include <cstddef> //std::size_t
+#include <iterator> //std::iterator_traits
 //boost
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/functional/hash.hpp>
-#include <boost/intrusive/detail/no_exceptions_support.hpp>
 //General intrusive utilities
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/pointer_to_other.hpp>
@@ -34,12 +34,128 @@
 #include <boost/intrusive/trivial_value_traits.hpp>
 #include <boost/intrusive/unordered_set_hook.hpp>
 #include <boost/intrusive/slist.hpp>
+#include <boost/intrusive/detail/mpl.hpp>
 
 namespace boost {
 namespace intrusive {
 
 /// @cond
 
+namespace detail {
+
+template <class NodeTraits>
+struct hash_reduced_slist_node_traits
+{
+ template <class U> static detail::one test(...);
+ template <class U> static detail::two test(typename U::reduced_slist_node_traits* = 0);
+ static const bool value = sizeof(test<NodeTraits>(0)) == sizeof(detail::two);
+};
+
+template <class NodeTraits>
+struct apply_reduced_slist_node_traits
+{
+ typedef typename NodeTraits::reduced_slist_node_traits type;
+};
+
+template <class NodeTraits>
+struct reduced_slist_node_traits
+{
+ typedef typename detail::eval_if_c
+ < hash_reduced_slist_node_traits<NodeTraits>::value
+ , apply_reduced_slist_node_traits<NodeTraits>
+ , detail::identity<NodeTraits>
+ >::type type;
+};
+
+template<class NodeTraits>
+struct get_slist_impl
+{
+ typedef trivial_value_traits<NodeTraits, normal_link> trivial_traits;
+
+ //Reducing symbol length
+ struct type : make_slist
+ < typename NodeTraits::node
+ , boost::intrusive::value_traits<trivial_traits>
+ , boost::intrusive::constant_time_size<false>
+ , boost::intrusive::size_type<std::size_t>
+ >::type
+ {};
+};
+
+template<class SupposedValueTraits>
+struct unordered_bucket_impl
+{
+ /// @cond
+ typedef typename detail::eval_if_c
+ < detail::external_value_traits_is_true
+ <SupposedValueTraits>::value
+ , detail::eval_value_traits
+ <SupposedValueTraits>
+ , detail::identity
+ <SupposedValueTraits>
+ >::type real_value_traits;
+
+ typedef typename detail::get_node_traits
+ <real_value_traits>::type node_traits;
+ typedef typename get_slist_impl
+ <typename reduced_slist_node_traits
+ <node_traits>::type
+ >::type slist_impl;
+ typedef detail::bucket_impl<slist_impl> implementation_defined;
+ typedef implementation_defined type;
+};
+
+template<class SupposedValueTraits>
+struct unordered_bucket_ptr_impl
+{
+ /// @cond
+
+ typedef typename detail::eval_if_c
+ < detail::external_value_traits_is_true
+ <SupposedValueTraits>::value
+ , detail::eval_value_traits
+ <SupposedValueTraits>
+ , detail::identity
+ <SupposedValueTraits>
+ >::type real_value_traits;
+ typedef typename detail::get_node_traits
+ <SupposedValueTraits>::type::node_ptr node_ptr;
+ typedef typename unordered_bucket_impl
+ <SupposedValueTraits>::type bucket_type;
+ typedef typename boost::pointer_to_other
+ <node_ptr, bucket_type>::type implementation_defined;
+ /// @endcond
+ typedef implementation_defined type;
+};
+
+} //namespace detail {
+
+/// @endcond
+
+template<class ValueTraitsOrHookOption>
+struct unordered_bucket
+{
+ /// @cond
+ typedef typename ValueTraitsOrHookOption::
+ template pack<none>::value_traits supposed_value_traits;
+ /// @endcond
+ typedef typename detail::unordered_bucket_impl
+ <supposed_value_traits>::type type;
+};
+
+template<class ValueTraitsOrHookOption>
+struct unordered_bucket_ptr
+{
+ /// @cond
+ typedef typename ValueTraitsOrHookOption::
+ template pack<none>::value_traits supposed_value_traits;
+ /// @endcond
+ typedef typename detail::unordered_bucket_ptr_impl
+ <supposed_value_traits>::type type;
+};
+
+/// @cond
+
 namespace detail{
 
 template <class T>
@@ -59,6 +175,23 @@
    static const bool value = store_hash_bool<T>::value > sizeof(one)*2;
 };
 
+template <class T>
+struct optimize_multikey_bool
+{
+ template<bool Add>
+ struct two_or_three {one _[2 + Add];};
+ template <class U> static one test(...);
+ template <class U> static two_or_three<U::optimize_multikey>
+ test (detail::bool_<U::optimize_multikey>* = 0);
+ static const std::size_t value = sizeof(test<T>(0));
+};
+
+template <class T>
+struct optimize_multikey_is_true
+{
+ static const bool value = optimize_multikey_bool<T>::value > sizeof(one)*2;
+};
+
 template<class Config>
 struct bucket_plus_size
    : public detail::size_holder
@@ -92,7 +225,7 @@
    bucket_plus_size<Config> bucket_plus_size_;
 };
 
-template<class Config>
+template<class Config, bool>
 struct bucket_hash_equal_t : public detail::ebo_functor_holder<typename Config::equal>
 {
    typedef typename Config::equal equal;
@@ -105,19 +238,41 @@
    bucket_hash_t<Config> bucket_hash;
 };
 
+template<class Config> //cache_begin == true version
+struct bucket_hash_equal_t<Config, true>
+ : public detail::ebo_functor_holder<typename Config::equal>
+{
+ typedef typename Config::equal equal;
+ typedef typename Config::hash hasher;
+ typedef typename Config::bucket_traits bucket_traits;
+ typedef typename unordered_bucket_ptr_impl
+ <typename Config::value_traits>::type bucket_ptr;
+
+ bucket_hash_equal_t(const bucket_traits &b_traits, const hasher & h, const equal &e)
+ : detail::ebo_functor_holder<typename Config::equal>(e), bucket_hash(b_traits, h)
+ {}
+ bucket_hash_t<Config> bucket_hash;
+ bucket_ptr cached_begin_;
+};
+
 template<class Config>
-struct data_t : public Config::value_traits
+struct hashtable_data_t : public Config::value_traits
 {
    typedef typename Config::value_traits value_traits;
    typedef typename Config::equal equal;
    typedef typename Config::hash hasher;
    typedef typename Config::bucket_traits bucket_traits;
 
- data_t( const bucket_traits &b_traits, const hasher & h
- , const equal &e, const value_traits &val_traits)
+ hashtable_data_t( const bucket_traits &b_traits, const hasher & h
+ , const equal &e, const value_traits &val_traits)
       : Config::value_traits(val_traits), bucket_hash_equal_(b_traits, h, e)
    {}
- bucket_hash_equal_t<Config> bucket_hash_equal_;
+ bucket_hash_equal_t<Config, Config::cache_begin> bucket_hash_equal_;
+};
+
+struct insert_commit_data_impl
+{
+ std::size_t hash;
 };
 
 } //namespace detail {
@@ -137,12 +292,14 @@
 };
 
 template < class ValueTraits
+ , bool UniqueKeys
          , class Hash
          , class Equal
          , class SizeType
          , bool ConstantTimeSize
          , class BucketTraits
          , bool Power2Buckets
+ , bool CacheBegin
>
 struct usetopt
 {
@@ -153,6 +310,8 @@
    typedef BucketTraits bucket_traits;
    static const bool constant_time_size = ConstantTimeSize;
    static const bool power_2_buckets = Power2Buckets;
+ static const bool unique_keys = UniqueKeys;
+ static const bool cache_begin = CacheBegin;
 };
 
 struct default_bucket_traits;
@@ -174,75 +333,12 @@
       , hash<boost::hash<T> >
       , bucket_traits<default_bucket_traits>
       , power_2_buckets<false>
+ , cache_begin<false>
>::type
 {};
 
-template<class NodeTraits>
-struct get_slist_impl
-{
- typedef trivial_value_traits<NodeTraits, normal_link> trivial_traits;
-
- //Reducing symbol length
- struct type : make_slist
- < typename NodeTraits::node
- , boost::intrusive::value_traits<trivial_traits>
- , boost::intrusive::constant_time_size<false>
- , boost::intrusive::size_type<std::size_t>
- >::type
- {};
-};
-
 /// @endcond
 
-template<class ValueTraitsOrHookOption>
-struct unordered_bucket
-{
- /// @cond
- typedef typename ValueTraitsOrHookOption::
- template pack<none>::value_traits supposed_value_traits;
-
- typedef typename detail::eval_if_c
- < detail::external_value_traits_is_true
- <supposed_value_traits>::value
- , detail::eval_value_traits
- <supposed_value_traits>
- , detail::identity
- <supposed_value_traits>
- >::type real_value_traits;
-
- typedef typename detail::get_node_traits
- <real_value_traits>::type node_traits;
- typedef typename get_slist_impl
- <node_traits>::type slist_impl;
- typedef detail::bucket_impl<slist_impl> implementation_defined;
- /// @endcond
- typedef implementation_defined type;
-};
-
-template<class ValueTraitsOrHookOption>
-struct unordered_bucket_ptr
-{
- /// @cond
- typedef typename ValueTraitsOrHookOption::
- template pack<none>::value_traits supposed_value_traits;
- typedef typename detail::eval_if_c
- < detail::external_value_traits_is_true
- <supposed_value_traits>::value
- , detail::eval_value_traits
- <supposed_value_traits>
- , detail::identity
- <supposed_value_traits>
- >::type real_value_traits;
- typedef typename detail::get_node_traits
- <supposed_value_traits>::type::node_ptr node_ptr;
- typedef typename unordered_bucket
- <ValueTraitsOrHookOption>::type bucket_type;
- typedef typename boost::pointer_to_other
- <node_ptr, bucket_type>::type implementation_defined;
- /// @endcond
- typedef implementation_defined type;
-};
-
 //! The class template hashtable is an intrusive hash table container, that
 //! is used to construct intrusive unordered_set and unordered_multiset containers. The
 //! no-throw guarantee holds only, if the Equal object and Hasher don't throw.
@@ -261,7 +357,8 @@
 //!
 //! The container supports the following options:
 //! \c base_hook<>/member_hook<>/value_traits<>,
-//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> .
+//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
+//! \c bucket_traits<>, power_2_buckets<> and cache_begin<>.
 //!
 //! hashtable only provides forward iterators but it provides 4 iterator types:
 //! iterator and const_iterator to navigate through the whole container and
@@ -284,13 +381,12 @@
 template<class Config>
 #endif
 class hashtable_impl
- : private detail::data_t<Config>
+ : private detail::hashtable_data_t<Config>
 {
    public:
    typedef typename Config::value_traits value_traits;
 
    /// @cond
-
    static const bool external_value_traits =
       detail::external_value_traits_is_true<value_traits>::value;
    typedef typename detail::eval_if_c
@@ -306,8 +402,10 @@
       , detail::eval_bucket_traits<bucket_traits>
       , detail::identity<bucket_traits>
>::type real_bucket_traits;
- typedef typename get_slist_impl
- <typename real_value_traits::node_traits>::type slist_impl;
+ typedef typename detail::get_slist_impl
+ <typename detail::reduced_slist_node_traits
+ <typename real_value_traits::node_traits>::type
+ >::type slist_impl;
    /// @endcond
 
    typedef typename real_value_traits::pointer pointer;
@@ -327,7 +425,7 @@
    typedef typename slist_impl::const_iterator const_siterator;
    typedef detail::hashtable_iterator<hashtable_impl, false> iterator;
    typedef detail::hashtable_iterator<hashtable_impl, true> const_iterator;
- typedef typename real_value_traits::node_traits node_traits;
+ typedef typename real_value_traits::node_traits node_traits;
    typedef typename node_traits::node node;
    typedef typename boost::pointer_to_other
       <pointer, node>::type node_ptr;
@@ -338,19 +436,67 @@
    static const bool constant_time_size = Config::constant_time_size;
    static const bool stateful_value_traits = detail::store_cont_ptr_on_it<hashtable_impl>::value;
    static const bool store_hash = detail::store_hash_is_true<node_traits>::value;
+ static const bool unique_keys = Config::unique_keys;
+ static const bool optimize_multikey
+ = detail::optimize_multikey_is_true<node_traits>::value && !unique_keys;
+ static const bool power_2_buckets = Config::power_2_buckets;
+ static const bool cache_begin = Config::cache_begin;
 
    /// @cond
    private:
+ typedef typename slist_impl::node_ptr slist_node_ptr;
+ typedef typename boost::pointer_to_other
+ <slist_node_ptr, void>::type void_pointer;
+ //We'll define group traits, but these won't be instantiated if
+ //optimize_multikey is not true
+ typedef unordered_group_node_traits<void_pointer, node> group_traits;
+ typedef circular_slist_algorithms<group_traits> group_algorithms;
+
    typedef detail::bool_<store_hash> store_hash_t;
+ typedef detail::bool_<optimize_multikey> optimize_multikey_t;
+ typedef detail::bool_<cache_begin> cache_begin_t;
+ typedef detail::bool_<power_2_buckets> power_2_buckets_t;
    typedef detail::size_holder<constant_time_size, size_type> size_traits;
- typedef detail::data_t<Config> base_type;
- typedef detail::transform_iterator
- < typename slist_impl::iterator
- , detail::node_to_value<hashtable_impl, false> > local_iterator_impl;
- typedef detail::transform_iterator
- < typename slist_impl::iterator
- , detail::node_to_value<hashtable_impl, true> > const_local_iterator_impl;
+ typedef detail::hashtable_data_t<Config> base_type;
+
+ template<bool IsConst>
+ struct downcast_node_to_value
+ : public detail::node_to_value<hashtable_impl, IsConst>
+ {
+ typedef detail::node_to_value<hashtable_impl, IsConst> base_t;
+ typedef typename base_t::result_type result_type;
+ typedef typename detail::add_const_if_c
+ <typename slist_impl::node, IsConst>::type &first_argument_type;
+ typedef typename detail::add_const_if_c
+ <node, IsConst>::type &intermediate_argument_type;
+
+ downcast_node_to_value(const hashtable_impl *cont)
+ : base_t(cont)
+ {}
+
+ result_type operator()(first_argument_type arg) const
+ { return this->base_t::operator()(static_cast<intermediate_argument_type>(arg)); }
+ };
+
+ template<class F>
+ struct node_cast_adaptor
+ : private detail::ebo_functor_holder<F>
+ {
+ typedef detail::ebo_functor_holder<F> base_t;
+
+ template<class ConvertibleToF>
+ node_cast_adaptor(const ConvertibleToF &c2f, const hashtable_impl *cont)
+ : base_t(base_t(c2f, cont))
+ {}
+
+ typename base_t::node_ptr operator()(const typename slist_impl::node &to_clone)
+ { return base_t::operator()(static_cast<const node &>(to_clone)); }
+
+ void operator()(typename slist_impl::node_ptr to_clone)
+ { base_t::operator()(node_ptr(&static_cast<node &>(*to_clone))); }
+ };
 
+ private:
    //noncopyable
    hashtable_impl (const hashtable_impl&);
    hashtable_impl operator =(const hashtable_impl&);
@@ -362,103 +508,23 @@
    //Constant-time size is incompatible with auto-unlink hooks!
    BOOST_STATIC_ASSERT(!(constant_time_size && ((int)real_value_traits::link_mode == (int)auto_unlink)));
 
- static const bool power_2_buckets = Config::power_2_buckets;
-
- std::size_t from_hash_to_bucket(std::size_t hash_value) const
- { return from_hash_to_bucket(hash_value, detail::bool_<power_2_buckets>()); }
-
- std::size_t from_hash_to_bucket(std::size_t hash_value, detail::bool_<false>) const
- { return hash_value % this->get_real_bucket_traits().bucket_count(); }
-
- std::size_t from_hash_to_bucket(std::size_t hash_value, detail::bool_<true>) const
- { return hash_value & (this->get_real_bucket_traits().bucket_count() - 1); }
-
- const key_equal &priv_equal() const
- { return static_cast<const key_equal&>(this->bucket_hash_equal_.get()); }
-
- key_equal &priv_equal()
- { return static_cast<key_equal&>(this->bucket_hash_equal_.get()); }
-
- const real_bucket_traits &get_real_bucket_traits(detail::bool_<false>) const
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
-
- const real_bucket_traits &get_real_bucket_traits(detail::bool_<true>) const
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
-
- real_bucket_traits &get_real_bucket_traits(detail::bool_<false>)
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
-
- real_bucket_traits &get_real_bucket_traits(detail::bool_<true>)
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
-
- const real_bucket_traits &get_real_bucket_traits() const
- { return this->get_real_bucket_traits(detail::bool_<external_bucket_traits>()); }
-
- real_bucket_traits &get_real_bucket_traits()
- { return this->get_real_bucket_traits(detail::bool_<external_bucket_traits>()); }
-
- const hasher &priv_hasher() const
- { return static_cast<const hasher&>(this->bucket_hash_equal_.bucket_hash.get()); }
-
- hasher &priv_hasher()
- { return static_cast<hasher&>(this->bucket_hash_equal_.bucket_hash.get()); }
-
- bucket_ptr priv_buckets() const
- { return this->get_real_bucket_traits().bucket_begin(); }
-
- size_type priv_buckets_len() const
- { return this->get_real_bucket_traits().bucket_count(); }
-
- static node_ptr uncast(const_node_ptr ptr)
- {
- return node_ptr(const_cast<node*>(detail::get_pointer(ptr)));
- }
-
- node &from_value_to_node(value_type &v)
- { return *this->get_real_value_traits().to_node_ptr(v); }
-
- const node &from_value_to_node(const value_type &v) const
- { return *this->get_real_value_traits().to_node_ptr(v); }
-
- size_traits &priv_size_traits()
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_; }
-
- const size_traits &priv_size_traits() const
- { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_; }
+ template<class Disposer>
+ node_cast_adaptor<detail::node_disposer<Disposer, hashtable_impl> >
+ make_node_disposer(const Disposer &disposer) const
+ { return node_cast_adaptor<detail::node_disposer<Disposer, hashtable_impl> >(disposer, this); }
 
- struct insert_commit_data_impl
- {
- size_type hash;
- };
    /// @endcond
 
    public:
+ typedef detail::insert_commit_data_impl insert_commit_data;
 
- class local_iterator
- : public local_iterator_impl
- {
- public:
- local_iterator()
- {}
-
- local_iterator(siterator sit, const hashtable_impl *cont)
- : local_iterator_impl(sit, cont)
- {}
- };
-
- class const_local_iterator
- : public const_local_iterator_impl
- {
- public:
- const_local_iterator()
- {}
-
- const_local_iterator(siterator sit, const hashtable_impl *cont)
- : const_local_iterator_impl(sit, cont)
- {}
- };
+ typedef detail::transform_iterator
+ < typename slist_impl::iterator
+ , downcast_node_to_value<false> > local_iterator;
 
- typedef insert_commit_data_impl insert_commit_data;
+ typedef detail::transform_iterator
+ < typename slist_impl::iterator
+ , downcast_node_to_value<true> > const_local_iterator;
 
    /// @cond
 
@@ -503,7 +569,7 @@
                   , const value_traits &v_traits = value_traits())
       : base_type(b_traits, hash_func, equal_func, v_traits)
    {
- priv_clear_buckets();
+ priv_initialize_buckets();
       this->priv_size_traits().set_size(size_type(0));
       BOOST_INTRUSIVE_INVARIANT_ASSERT(this->priv_buckets_len() != 0);
       //Check power of two bucket array if the option is activated
@@ -562,7 +628,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    iterator end()
- { return iterator(invalid_local_it(this->get_real_bucket_traits()), 0); }
+ { return iterator(priv_invalid_local_it(), 0); }
 
    //! <b>Effects</b>: Returns a const_iterator pointing to the end of the unordered_set.
    //!
@@ -578,7 +644,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    const_iterator cend() const
- { return const_iterator(invalid_local_it(this->get_real_bucket_traits()), 0); }
+ { return const_iterator(priv_invalid_local_it(), 0); }
 
    //! <b>Effects</b>: Returns the hasher object used by the unordered_set.
    //!
@@ -598,8 +664,8 @@
 
    //! <b>Effects</b>: Returns true is the container is empty.
    //!
- //! <b>Complexity</b>: if constant_time_size is false, average constant time
- //! (worst case, with empty() == true): O(this->bucket_count()).
+ //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
+ //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
    //! Otherwise constant.
    //!
    //! <b>Throws</b>: Nothing.
@@ -608,6 +674,9 @@
       if(constant_time_size){
          return !this->size();
       }
+ else if(cache_begin){
+ return this->begin() == this->end();
+ }
       else{
          size_type buckets_len = this->priv_buckets_len();
          const bucket_type *b = detail::get_pointer(this->priv_buckets());
@@ -658,7 +727,8 @@
       swap(this->priv_equal(), other.priv_equal());
       swap(this->priv_hasher(), other.priv_hasher());
       //These can't throw
- swap(this->get_real_bucket_traits(), other.get_real_bucket_traits());
+ swap(this->priv_real_bucket_traits(), other.priv_real_bucket_traits());
+ priv_swap_cache(cache_begin_t(), other);
       if(constant_time_size){
          size_type backup = this->priv_size_traits().get_size();
          this->priv_size_traits().set_size(other.priv_size_traits().get_size());
@@ -698,75 +768,71 @@
             const bucket_ptr src_buckets = src.priv_buckets();
             const bucket_ptr dst_buckets = this->priv_buckets();
             size_type constructed;
- BOOST_INTRUSIVE_TRY{
- for( constructed = 0
- ; constructed < dst_bucket_count
+ typedef node_cast_adaptor<detail::node_disposer<Disposer, hashtable_impl> > NodeDisposer;
+ typedef node_cast_adaptor<detail::node_cloner<Cloner, hashtable_impl> > NodeCloner;
+ NodeDisposer node_disp(disposer, this);
+
+ detail::exception_array_disposer<bucket_type, NodeDisposer>
+ rollback(dst_buckets[0], node_disp, constructed);
+ for( constructed = 0
+ ; constructed < dst_bucket_count
+ ; ++constructed){
+ dst_buckets[constructed].clone_from
+ ( src_buckets[constructed]
+ , NodeCloner(cloner, this), node_disp);
+ }
+ if(src_bucket_count != dst_bucket_count){
+ //Now insert the remaining ones using the modulo trick
+ for(//"constructed" comes from the previous loop
+ ; constructed < src_bucket_count
                   ; ++constructed){
- dst_buckets[constructed].clone_from
- ( src_buckets[constructed]
- , detail::node_cloner<Cloner, hashtable_impl>(cloner, this)
- , detail::node_disposer<Disposer, hashtable_impl>(disposer, this)
- );
- }
- if(src_bucket_count != dst_bucket_count){
- //Now insert the remaining ones using the modulo trick
- for(//"constructed" comes from the previous loop
- ; constructed < src_bucket_count
- ; ++constructed){
- bucket_type &dst_b = (power_2_buckets)
- ? dst_buckets[constructed & (dst_bucket_count-1)]
- : dst_buckets[constructed % dst_bucket_count];
- bucket_type &src_b = src_buckets[constructed];
- for( siterator b(src_b.begin()), e(src_b.end())
- ; b != e
- ; ++b){
- dst_b.push_front(*detail::node_cloner<Cloner, hashtable_impl>
- (cloner, this)(b.pointed_node()));
- }
+ bucket_type &dst_b =
+ dst_buckets[priv_hash_to_bucket(constructed, dst_bucket_count)];
+ bucket_type &src_b = src_buckets[constructed];
+ for( siterator b(src_b.begin()), e(src_b.end())
+ ; b != e
+ ; ++b){
+ dst_b.push_front(*(NodeCloner(cloner, this)(*b.pointed_node())));
                   }
                }
             }
- BOOST_INTRUSIVE_CATCH(...){
- while(constructed--){
- dst_buckets[constructed].clear_and_dispose
- (detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
- }
- BOOST_INTRUSIVE_RETHROW;
- }
- BOOST_INTRUSIVE_CATCH_END
+ rollback.release();
             this->priv_size_traits().set_size(src.priv_size_traits().get_size());
+ priv_insertion_update_cache(0u);
+ priv_erasure_update_cache();
          }
          else{
             //Unlike previous cloning algorithm, this can throw
             //if cloner, the hasher or comparison functor throw
             const_iterator b(src.begin()), e(src.end());
- BOOST_INTRUSIVE_TRY{
- for(; b != e; ++b){
- this->insert_equal(*cloner(*b));
- }
+ detail::exception_disposer<hashtable_impl, Disposer>
+ rollback(*this, disposer);
+ for(; b != e; ++b){
+ this->insert_equal(*cloner(*b));
             }
- BOOST_INTRUSIVE_CATCH(...){
- this->clear_and_dispose(disposer);
- BOOST_INTRUSIVE_RETHROW;
- }
- BOOST_INTRUSIVE_CATCH_END
+ rollback.release();
          }
       }
    }
 
    iterator insert_equal(reference value)
    {
- size_type bucket_num, hash_value;
+ size_type bucket_num;
+ std::size_t hash_value;
+ siterator prev;
       siterator it = this->priv_find
- (value, this->priv_hasher(), this->priv_equal(), bucket_num, hash_value);
+ (value, this->priv_hasher(), this->priv_equal(), bucket_num, hash_value, prev);
       bucket_type &b = this->priv_buckets()[bucket_num];
- if(it == invalid_local_it(this->get_real_bucket_traits())){
- it = b.before_begin();
- }
- node_ptr n = node_ptr(&from_value_to_node(value));
+ bool found_equal = it != priv_invalid_local_it();
+ node_ptr n = node_ptr(&priv_value_to_node(value));
       this->priv_store_hash(n, hash_value, store_hash_t());
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
+ if(!found_equal){
+ it = b.before_begin();
+ }
+ this->priv_insert_in_group(found_equal ? dcast_bucket_ptr(it.pointed_node()) : node_ptr(0), n, optimize_multikey_t());
+ priv_insertion_update_cache(bucket_num);
       this->priv_size_traits().increment();
       return iterator(b.insert_after(it, *n), this);
    }
@@ -867,9 +933,10 @@
       , insert_commit_data &commit_data)
    {
       size_type bucket_num;
+ siterator prev;
       siterator prev_pos =
- this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash);
- bool success = prev_pos == invalid_local_it(this->get_real_bucket_traits());
+ this->priv_find(key, hash_func, equal_func, bucket_num, commit_data.hash, prev);
+ bool success = prev_pos == priv_invalid_local_it();
       if(success){
          prev_pos = this->priv_buckets()[bucket_num].before_begin();
       }
@@ -897,14 +964,16 @@
    //! After a successful rehashing insert_commit_data remains valid.
    iterator insert_unique_commit(reference value, const insert_commit_data &commit_data)
    {
- size_type bucket_num = from_hash_to_bucket(commit_data.hash);
+ size_type bucket_num = priv_hash_to_bucket(commit_data.hash);
       bucket_type &b = this->priv_buckets()[bucket_num];
       this->priv_size_traits().increment();
- node_ptr n = node_ptr(&from_value_to_node(value));
+ node_ptr n = node_ptr(&priv_value_to_node(value));
       this->priv_store_hash(n, commit_data.hash, store_hash_t());
       if(safemode_or_autounlink)
          BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT(node_algorithms::unique(n));
- return iterator( b.insert_after(b.before_begin(), *n), this);
+ priv_insertion_update_cache(bucket_num);
+ this->priv_insert_in_group(node_ptr(0), n, optimize_multikey_t());
+ return iterator(b.insert_after(b.before_begin(), *n), this);
    }
 
    //! <b>Effects</b>: Erases the element pointed to by i.
@@ -983,12 +1052,9 @@
    template<class Disposer>
    void erase_and_dispose(const_iterator i, Disposer disposer)
    {
- siterator to_erase(i.slist_it());
- bucket_ptr f(priv_buckets()), l(f + priv_buckets_len());
- bucket_type &b = this->priv_buckets()[bucket_type::get_bucket_num(to_erase, *f, *l)];
- b.erase_after_and_dispose
- (b.previous(to_erase), detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
+ priv_erase(i, disposer, optimize_multikey_t());
       this->priv_size_traits().decrement();
+ priv_erasure_update_cache();
    }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
@@ -1009,67 +1075,27 @@
       if(b == e) return;
 
       //Get the bucket number and local iterator for both iterators
- bucket_ptr f(priv_buckets()), l(f + priv_buckets_len());
- size_type first_bucket_num = bucket_type::get_bucket_num(b.slist_it(), *f, *l);
+ siterator first_local_it(b.slist_it());
+ size_type first_bucket_num = this->priv_get_bucket_num(first_local_it);
 
       siterator before_first_local_it
- = priv_buckets()[first_bucket_num].previous(b.slist_it());
+ = priv_get_previous(priv_buckets()[first_bucket_num], first_local_it);
       size_type last_bucket_num;
       siterator last_local_it;
 
       //For the end iterator, we will assign the end iterator
       //of the last bucket
- if(e == end()){
+ if(e == this->end()){
          last_bucket_num = this->bucket_count() - 1;
          last_local_it = priv_buckets()[last_bucket_num].end();
       }
       else{
          last_local_it = e.slist_it();
- last_bucket_num = bucket_type::get_bucket_num(last_local_it, *f, *l);
+ last_bucket_num = this->priv_get_bucket_num(last_local_it);
       }
-
- const bucket_ptr buckets = priv_buckets();
- //First erase the nodes of the first bucket
- {
- bucket_type &first_b = buckets[first_bucket_num];
- siterator nxt(before_first_local_it); ++nxt;
- siterator end = first_b.end();
- while(nxt != end){
- nxt = first_b.erase_after_and_dispose
- ( before_first_local_it
- , detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
- this->priv_size_traits().decrement();
- }
- }
-
- //Now fully clear the intermediate buckets
- for(size_type i = first_bucket_num+1; i < last_bucket_num; ++i){
- bucket_type &b = buckets[i];
- if(b.empty())
- continue;
- siterator b_begin(b.before_begin());
- siterator nxt(b_begin); ++nxt;
- siterator end = b.end();
- while(nxt != end){
- nxt = b.erase_after_and_dispose
- (b_begin, detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
- this->priv_size_traits().decrement();
- }
- }
-
- //Now erase nodes from the last bucket
- {
- bucket_type &last_b = buckets[last_bucket_num];
- siterator b_begin(last_b.before_begin());
- siterator nxt(b_begin); ++nxt;
- while(nxt != last_local_it){
- nxt = last_b.erase_after_and_dispose
- (b_begin, detail::node_disposer<Disposer, hashtable_impl>
- (disposer, this));
- this->priv_size_traits().decrement();
- }
- }
- }
+ priv_erase_range(before_first_local_it, first_bucket_num, last_local_it, last_bucket_num, disposer);
+ priv_erasure_update_cache(first_bucket_num, last_bucket_num);
+ }
 
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
@@ -1109,40 +1135,35 @@
    size_type erase_and_dispose(const KeyType& key, KeyHasher hash_func
                               ,KeyValueEqual equal_func, Disposer disposer)
    {
+ size_type bucket_num;
+ std::size_t hash;
+ siterator prev;
+ siterator it =
+ this->priv_find(key, hash_func, equal_func, bucket_num, hash, prev);
+ bool success = it != priv_invalid_local_it();
       size_type count(0);
-
- if(constant_time_size && this->empty()){
+ if(!success){
          return 0;
       }
-
- bucket_type &b = this->priv_buckets()[from_hash_to_bucket(hash_func(key))];
- siterator it = b.begin();
- siterator prev = b.before_begin();
-
- bool found = false;
- //Find equal value
- while(it != b.end()){
- const value_type &v =
- *this->get_real_value_traits().to_value_ptr(it.pointed_node());
- if(equal_func(key, v)){
- found = true;
- break;
- }
- ++prev;
- ++it;
+ else if(optimize_multikey){
+ siterator last = bucket_type::s_iterator_to
+ (*node_traits::get_next(priv_get_last_in_group
+ (dcast_bucket_ptr(it.pointed_node()))));
+ this->priv_erase_range_impl(bucket_num, prev, last, disposer, count);
       }
-
- if(!found)
- return 0;
-
- //If found erase all equal values
- for(siterator end = b.end(); it != end &&
- equal_func(key, *this->get_real_value_traits().to_value_ptr(it.pointed_node()))
- ; ++count){
- it = b.erase_after_and_dispose
- (prev, detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
- this->priv_size_traits().decrement();
+ else{
+ //If found erase all equal values
+ bucket_type &b = this->priv_buckets()[bucket_num];
+ for(siterator end = b.end(); it != end; ++count, ++it){
+ slist_node_ptr n(it.pointed_node());
+ if(!equal_func(key, priv_value_from_slist_node(n))){
+ break;
+ }
+ this->priv_size_traits().decrement();
+ }
+ b.erase_after_and_dispose(prev, it, make_node_disposer(disposer));
       }
+ priv_erasure_update_cache();
       return count;
    }
 
@@ -1179,11 +1200,11 @@
          size_type num_buckets = this->bucket_count();
          bucket_ptr b = this->priv_buckets();
          for(; num_buckets--; ++b){
- b->clear_and_dispose
- (detail::node_disposer<Disposer, hashtable_impl>(disposer, this));
+ b->clear_and_dispose(make_node_disposer(disposer));
          }
          this->priv_size_traits().set_size(size_type(0));
       }
+ priv_initialize_cache();
    }
 
    //! <b>Effects</b>: Returns the number of contained elements with the given value
@@ -1246,8 +1267,10 @@
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    iterator find(const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func)
    {
- size_type bucket_n, hash;
- siterator local_it = this->priv_find(key, hash_func, equal_func, bucket_n, hash);
+ size_type bucket_n;
+ std::size_t hash;
+ siterator prev;
+ siterator local_it = this->priv_find(key, hash_func, equal_func, bucket_n, hash, prev);
       return iterator(local_it, this);
    }
 
@@ -1283,8 +1306,10 @@
    const_iterator find
       (const KeyType &key, KeyHasher hash_func, KeyValueEqual equal_func) const
    {
- size_type bucket_n, hash_value;
- siterator sit = this->priv_find(key, hash_func, equal_func, bucket_n, hash_value);
+ size_type bucket_n;
+ std::size_t hash_value;
+ siterator prev;
+ siterator sit = this->priv_find(key, hash_func, equal_func, bucket_n, hash_value, prev);
       return const_iterator(sit, this);
    }
 
@@ -1382,7 +1407,7 @@
    //! <b>Throws</b>: If the internal hash function throws.
    iterator iterator_to(reference value)
    {
- return iterator(bucket_type::s_iterator_to(from_value_to_node(value)), this);
+ return iterator(bucket_type::s_iterator_to(priv_value_to_node(value)), this);
    }
 
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
@@ -1396,12 +1421,9 @@
    //! <b>Throws</b>: If the internal hash function throws.
    const_iterator iterator_to(const_reference value) const
    {
- return const_iterator(bucket_type::s_iterator_to(from_value_to_node(const_cast<reference>(value))), this);
+ return const_iterator(bucket_type::s_iterator_to(priv_value_to_node(const_cast<reference>(value))), this);
    }
 
-
-
-
    //! <b>Requires</b>: value must be an lvalue and shall be in a unordered_set of
    //! appropriate type. Otherwise the behavior is undefined.
    //!
@@ -1417,7 +1439,7 @@
    static local_iterator s_local_iterator_to(reference value)
    {
       BOOST_STATIC_ASSERT((!stateful_value_traits));
- siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->from_value_to_node(value));
+ siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->priv_value_to_node(value));
       return local_iterator(sit, (hashtable_impl*)0);
    }
 
@@ -1436,7 +1458,7 @@
    static const_local_iterator s_local_iterator_to(const_reference value)
    {
       BOOST_STATIC_ASSERT((!stateful_value_traits));
- siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->from_value_to_node(const_cast<value_type&>(value)));
+ siterator sit = bucket_type::s_iterator_to(((hashtable_impl*)0)->priv_value_to_node(const_cast<value_type&>(value)));
       return const_local_iterator(sit, (hashtable_impl*)0);
    }
 
@@ -1451,7 +1473,7 @@
    //! <b>Throws</b>: Nothing.
    local_iterator local_iterator_to(reference value)
    {
- siterator sit = bucket_type::s_iterator_to(this->from_value_to_node(value));
+ siterator sit = bucket_type::s_iterator_to(this->priv_value_to_node(value));
       return local_iterator(sit, this);
    }
 
@@ -1467,7 +1489,7 @@
    const_local_iterator local_iterator_to(const_reference value) const
    {
       siterator sit = bucket_type::s_iterator_to
- (const_cast<node &>(this->from_value_to_node(value)));
+ (const_cast<node &>(this->priv_value_to_node(value)));
       return const_local_iterator(sit, this);
    }
 
@@ -1515,7 +1537,7 @@
    //! <b>Note</b>: the return value is in the range [0, this->bucket_count()).
    template<class KeyType, class KeyHasher>
    size_type bucket(const KeyType& k, const KeyHasher &hash_func) const
- { return from_hash_to_bucket(hash_func(k)); }
+ { return priv_hash_to_bucket(hash_func(k)); }
 
    //! <b>Effects</b>: Returns the bucket array pointer passed in the constructor
    //! or the last rehash function.
@@ -1630,75 +1652,81 @@
       size_type new_buckets_len = new_bucket_traits.bucket_count();
       bucket_ptr old_buckets = this->priv_buckets();
       size_type old_buckets_len = this->priv_buckets_len();
+
       //Check power of two bucket array if the option is activated
       BOOST_INTRUSIVE_INVARIANT_ASSERT
       (!power_2_buckets || (0 == (new_buckets_len & (new_buckets_len-1u))));
 
- BOOST_INTRUSIVE_TRY{
- size_type n = 0;
- const bool same_buffer = old_buckets == new_buckets;
- //If the new bucket length is a common factor
- //of the old one we can avoid hash calculations.
- const bool fast_shrink = (old_buckets_len > new_buckets_len) &&
- (power_2_buckets ||(old_buckets_len % new_buckets_len) == 0);
- //If we are shrinking the same bucket array and it's
- //is a fast shrink, just rehash the last nodes
- if(same_buffer && fast_shrink){
- n = new_buckets_len;
- }
-
- //Iterate through nodes
- for(; n < old_buckets_len; ++n){
- bucket_type &old_bucket = old_buckets[n];
-
- if(!fast_shrink){
- siterator before_i(old_bucket.before_begin());
- siterator end(old_bucket.end());
- siterator i(old_bucket.begin());
- for(;i != end; ++i){
- const value_type &v = *this->get_real_value_traits().to_value_ptr(i.pointed_node());
- const std::size_t hash_value = this->priv_hash_when_rehashing(v, store_hash_t());
- const size_type new_n = (power_2_buckets)
- ? (hash_value & (new_buckets_len-1)) : (hash_value % new_buckets_len);
- //If this is a buffer expansion don't move if it's not necessary
- if(same_buffer && new_n == n){
- ++before_i;
- }
- else{
- bucket_type &new_b = new_buckets[new_n];
- new_b.splice_after(new_b.before_begin(), old_bucket, before_i);
- i = before_i;
- }
+ size_type n = this->priv_get_cache() - this->priv_buckets();
+ const bool same_buffer = old_buckets == new_buckets;
+ //If the new bucket length is a common factor
+ //of the old one we can avoid hash calculations.
+ const bool fast_shrink = (old_buckets_len > new_buckets_len) &&
+ (power_2_buckets ||(old_buckets_len % new_buckets_len) == 0);
+ //If we are shrinking the same bucket array and it's
+ //is a fast shrink, just rehash the last nodes
+ if(same_buffer && fast_shrink){
+ n = new_buckets_len;
+ }
+
+ //Anti-exception stuff: they destroy the elements if something goes wrong
+ typedef detail::init_disposer<node_algorithms> NodeDisposer;
+ NodeDisposer node_disp;
+ detail::exception_array_disposer<bucket_type, NodeDisposer>
+ rollback1(new_buckets[0], node_disp, new_buckets_len);
+ detail::exception_array_disposer<bucket_type, NodeDisposer>
+ rollback2(old_buckets[0], node_disp, old_buckets_len);
+
+ //Put size in a safe value for rollback exception
+ size_type size_backup = this->priv_size_traits().get_size();
+ this->priv_size_traits().set_size(0);
+ //Put cache to safe position
+ priv_initialize_cache();
+ priv_insertion_update_cache(size_type(0u));
+
+ //Iterate through nodes
+ for(; n < old_buckets_len; ++n){
+ bucket_type &old_bucket = old_buckets[n];
+
+ if(!fast_shrink){
+ siterator before_i(old_bucket.before_begin());
+ siterator end(old_bucket.end());
+ siterator i(old_bucket.begin());
+ for(;i != end; ++i){
+ const value_type &v = priv_value_from_slist_node(i.pointed_node());
+ const std::size_t hash_value = this->priv_stored_hash(v, store_hash_t());
+ const size_type new_n = priv_hash_to_bucket(hash_value, new_buckets_len);
+ siterator last = bucket_type::s_iterator_to
+ (*priv_get_last_in_group(dcast_bucket_ptr(i.pointed_node())));
+ if(same_buffer && new_n == n){
+ before_i = last;
                }
- }
- else{
- const size_type new_n = (power_2_buckets)
- ? (n & (new_buckets_len-1))
- : (n % new_buckets_len);
- bucket_type &new_b = new_buckets[new_n];
- new_b.splice_after(new_b.before_begin(), old_bucket);
+ else{
+ bucket_type &new_b = new_buckets[new_n];
+ new_b.splice_after(new_b.before_begin(), old_bucket, before_i, last);
+ }
+ i = before_i;
             }
          }
-
- this->get_real_bucket_traits()= new_bucket_traits;
- }
- BOOST_INTRUSIVE_CATCH(...){
- for(size_type n = 0; n < new_buckets_len; ++n){
- if(safemode_or_autounlink){
- new_buckets[n].clear_and_dispose
- (detail::init_disposer<node_algorithms>());
- old_buckets[n].clear_and_dispose
- (detail::init_disposer<node_algorithms>());
- }
- else{
- new_buckets[n].clear();
- old_buckets[n].clear();
+ else{
+ const size_type new_n = priv_hash_to_bucket(n, new_buckets_len);
+ bucket_type &new_b = new_buckets[new_n];
+ if(!old_bucket.empty()){
+ new_b.splice_after( new_b.before_begin()
+ , old_bucket
+ , old_bucket.before_begin()
+ , priv_get_last(old_bucket));
             }
          }
- this->priv_size_traits().set_size(size_type(0));
- BOOST_INTRUSIVE_RETHROW;
       }
- BOOST_INTRUSIVE_CATCH_END
+
+ this->priv_size_traits().set_size(size_backup);
+ this->priv_real_bucket_traits() = new_bucket_traits;
+ priv_initialize_cache();
+ priv_insertion_update_cache(size_type(0u));
+ priv_erasure_update_cache();
+ rollback1.release();
+ rollback2.release();
    }
 
    //! <b>Effects</b>: Returns the nearest new bucket count optimized for
@@ -1714,8 +1742,7 @@
    {
       const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0];
       const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size;
- size_type const* bound =
- std::lower_bound(primes, primes_end, n);
+ size_type const* bound = std::lower_bound(primes, primes_end, n);
       if(bound == primes_end)
             bound--;
       return size_type(*bound);
@@ -1734,8 +1761,7 @@
    {
       const std::size_t *primes = &detail::prime_list_holder<0>::prime_list[0];
       const std::size_t *primes_end = primes + detail::prime_list_holder<0>::prime_list_size;
- size_type const* bound =
- std::upper_bound(primes, primes_end, n);
+ size_type const* bound = std::upper_bound(primes, primes_end, n);
       if(bound != primes_end)
             bound--;
       return size_type(*bound);
@@ -1743,72 +1769,666 @@
 
    /// @cond
    private:
+ std::size_t priv_hash_to_bucket(std::size_t hash_value) const
+ { return priv_hash_to_bucket(hash_value, power_2_buckets_t()); }
+
+ std::size_t priv_hash_to_bucket(std::size_t hash_value, detail::bool_<false>) const
+ { return hash_value % this->priv_real_bucket_traits().bucket_count(); }
+
+ std::size_t priv_hash_to_bucket(std::size_t hash_value, detail::bool_<true>) const
+ { return hash_value & (this->priv_real_bucket_traits().bucket_count() - 1); }
+
+ std::size_t priv_hash_to_bucket(std::size_t hash_value, std::size_t bucket_len) const
+ { return priv_hash_to_bucket(hash_value, bucket_len, power_2_buckets_t()); }
+
+ std::size_t priv_hash_to_bucket(std::size_t hash_value, std::size_t bucket_len, detail::bool_<false>) const
+ { return hash_value % bucket_len; }
+
+ std::size_t priv_hash_to_bucket(std::size_t hash_value, std::size_t bucket_len, detail::bool_<true>) const
+ { return hash_value & (bucket_len - 1); }
+
+ const key_equal &priv_equal() const
+ { return static_cast<const key_equal&>(this->bucket_hash_equal_.get()); }
+
+ key_equal &priv_equal()
+ { return static_cast<key_equal&>(this->bucket_hash_equal_.get()); }
+
+ value_type &priv_value_from_slist_node(slist_node_ptr n)
+ { return *this->get_real_value_traits().to_value_ptr(dcast_bucket_ptr(n)); }
+
+ const value_type &priv_value_from_slist_node(slist_node_ptr n) const
+ { return *this->get_real_value_traits().to_value_ptr(dcast_bucket_ptr(n)); }
+
+ const real_bucket_traits &priv_real_bucket_traits(detail::bool_<false>) const
+ { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
+
+ const real_bucket_traits &priv_real_bucket_traits(detail::bool_<true>) const
+ { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
+
+ real_bucket_traits &priv_real_bucket_traits(detail::bool_<false>)
+ { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_; }
+
+ real_bucket_traits &priv_real_bucket_traits(detail::bool_<true>)
+ { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_.bucket_traits_.get_bucket_traits(*this); }
+
+ const real_bucket_traits &priv_real_bucket_traits() const
+ { return this->priv_real_bucket_traits(detail::bool_<external_bucket_traits>()); }
+
+ real_bucket_traits &priv_real_bucket_traits()
+ { return this->priv_real_bucket_traits(detail::bool_<external_bucket_traits>()); }
+
+ const hasher &priv_hasher() const
+ { return static_cast<const hasher&>(this->bucket_hash_equal_.bucket_hash.get()); }
+
+ hasher &priv_hasher()
+ { return static_cast<hasher&>(this->bucket_hash_equal_.bucket_hash.get()); }
 
- std::size_t priv_hash_when_rehashing(const value_type &v, detail::true_)
+ bucket_ptr priv_buckets() const
+ { return this->priv_real_bucket_traits().bucket_begin(); }
+
+ size_type priv_buckets_len() const
+ { return this->priv_real_bucket_traits().bucket_count(); }
+
+ static node_ptr uncast(const_node_ptr ptr)
+ { return node_ptr(const_cast<node*>(detail::get_pointer(ptr))); }
+
+ node &priv_value_to_node(value_type &v)
+ { return *this->get_real_value_traits().to_node_ptr(v); }
+
+ const node &priv_value_to_node(const value_type &v) const
+ { return *this->get_real_value_traits().to_node_ptr(v); }
+
+ size_traits &priv_size_traits()
+ { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_; }
+
+ const size_traits &priv_size_traits() const
+ { return this->bucket_hash_equal_.bucket_hash.bucket_plus_size_; }
+
+ template<class Disposer>
+ void priv_erase_range_impl
+ (size_type bucket_num, siterator before_first_it, siterator end, Disposer disposer, size_type &num_erased)
+ {
+ const bucket_ptr buckets = priv_buckets();
+ bucket_type &b = buckets[bucket_num];
+
+ if(before_first_it == b.before_begin() && end == b.end()){
+ priv_erase_range_impl(bucket_num, 1, disposer, num_erased);
+ }
+ else{
+ num_erased = 0;
+ siterator to_erase(before_first_it);
+ ++to_erase;
+ slist_node_ptr end_ptr = end.pointed_node();
+ while(to_erase != end){
+ priv_erase_from_group(end_ptr, dcast_bucket_ptr(to_erase.pointed_node()), optimize_multikey_t());
+ to_erase = b.erase_after_and_dispose(before_first_it, make_node_disposer(disposer));
+ ++num_erased;
+ }
+ this->priv_size_traits().set_size(this->priv_size_traits().get_size()-num_erased);
+ }
+ }
+
+ template<class Disposer>
+ void priv_erase_range_impl
+ (size_type first_bucket_num, size_type num_buckets, Disposer disposer, size_type &num_erased)
+ {
+ //Now fully clear the intermediate buckets
+ const bucket_ptr buckets = priv_buckets();
+ num_erased = 0;
+ for(size_type i = first_bucket_num; i < (num_buckets + first_bucket_num); ++i){
+ bucket_type &b = buckets[i];
+ siterator b_begin(b.before_begin());
+ siterator nxt(b_begin);
+ ++nxt;
+ siterator end(b.end());
+ while(nxt != end){
+ priv_init_group(nxt.pointed_node(), optimize_multikey_t());
+ nxt = b.erase_after_and_dispose
+ (b_begin, make_node_disposer(disposer));
+ this->priv_size_traits().decrement();
+ ++num_erased;
+ }
+ }
+ }
+
+ template<class Disposer>
+ void priv_erase_range( siterator before_first_it, size_type first_bucket
+ , siterator last_it, size_type last_bucket
+ , Disposer disposer)
+ {
+ size_type num_erased;
+ if (first_bucket == last_bucket){
+ priv_erase_range_impl(first_bucket, before_first_it, last_it, disposer, num_erased);
+ }
+ else {
+ bucket_type *b = (&this->priv_buckets()[0]);
+ priv_erase_range_impl(first_bucket, before_first_it, b[first_bucket].end(), disposer, num_erased);
+ if(size_type n = (last_bucket - first_bucket - 1))
+ priv_erase_range_impl(first_bucket + 1, n, disposer, num_erased);
+ priv_erase_range_impl(last_bucket, b[last_bucket].before_begin(), last_it, disposer, num_erased);
+ }
+ }
+
+ static node_ptr dcast_bucket_ptr(typename slist_impl::node_ptr p)
+ { return node_ptr(&static_cast<node&>(*p)); }
+
+ std::size_t priv_stored_hash(const value_type &v, detail::true_)
    { return node_traits::get_hash(this->get_real_value_traits().to_node_ptr(v)); }
 
- std::size_t priv_hash_when_rehashing(const value_type &v, detail::false_)
+ std::size_t priv_stored_hash(const value_type &v, detail::false_)
    { return priv_hasher()(v); }
 
- void priv_store_hash(node_ptr p, std::size_t h, detail::true_)
+ std::size_t priv_stored_hash(slist_node_ptr n, detail::true_)
+ { return node_traits::get_hash(dcast_bucket_ptr(n)); }
+
+ std::size_t priv_stored_hash(slist_node_ptr, detail::false_)
+ {
+ //This code should never be reached!
+ BOOST_INTRUSIVE_INVARIANT_ASSERT(0);
+ return 0;
+ }
+
+ static void priv_store_hash(node_ptr p, std::size_t h, detail::true_)
    { return node_traits::set_hash(p, h); }
 
- void priv_store_hash(node_ptr, std::size_t, detail::false_)
+ static void priv_store_hash(node_ptr, std::size_t, detail::false_)
+ {}
+
+ static void priv_clear_group_nodes(bucket_type &b, detail::true_)
+ {
+ siterator it(b.begin()), itend(b.end());
+ while(it != itend){
+ node_ptr to_erase(dcast_bucket_ptr(it.pointed_node()));
+ ++it;
+ group_algorithms::init(to_erase);
+ }
+ }
+
+ static void priv_clear_group_nodes(bucket_type &, detail::false_)
+ {}
+
+ std::size_t priv_get_bucket_num(siterator it)
+ { return priv_get_bucket_num_hash_dispatch(it, store_hash_t()); }
+
+ std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::true_)
+ {
+ return this->priv_hash_to_bucket
+ (this->priv_stored_hash(it.pointed_node(), store_hash_t()));
+ }
+
+ std::size_t priv_get_bucket_num_hash_dispatch(siterator it, detail::false_)
+ { return priv_get_bucket_num_no_hash_store(it, optimize_multikey_t()); }
+
+ std::size_t priv_get_bucket_num_no_hash_store( siterator it, detail::true_)
+ {
+ bucket_ptr f(priv_buckets()), l(f + priv_buckets_len() - 1);
+ slist_node_ptr bb = priv_get_bucket_before_begin
+ ( f->end().pointed_node()
+ , l->end().pointed_node()
+ , dcast_bucket_ptr(it.pointed_node()));
+ //Now get the bucket_impl from the iterator
+ const bucket_type &b = static_cast<const bucket_type&>
+ (bucket_type::slist_type::container_from_end_iterator(bucket_type::s_iterator_to(*bb)));
+ //Now just calculate the index b has in the bucket array
+ return static_cast<size_type>(&b - &*f);
+ }
+
+ std::size_t priv_get_bucket_num_no_hash_store( siterator it, detail::false_)
+ {
+ bucket_ptr f(priv_buckets()), l(f + priv_buckets_len() - 1);
+ slist_node_ptr first_ptr(f->cend().pointed_node())
+ , last_ptr(l->cend().pointed_node());
+
+ //The end node is embedded in the singly linked list:
+ //iterate until we reach it.
+ while(!(first_ptr <= it.pointed_node() && it.pointed_node() <= last_ptr)){
+ ++it;
+ }
+ //Now get the bucket_impl from the iterator
+ const bucket_type &b = static_cast<const bucket_type&>
+ (bucket_type::container_from_end_iterator(it));
+
+ //Now just calculate the index b has in the bucket array
+ return static_cast<std::size_t>(&b - &*f);
+ }
+
+ void priv_erase_from_group(slist_node_ptr end_ptr, node_ptr to_erase_ptr, detail::true_)
+ {
+ node_ptr nxt_ptr(node_traits::get_next(to_erase_ptr));
+ node_ptr prev_in_group_ptr(group_traits::get_next(to_erase_ptr));
+ bool last_in_group = (end_ptr == nxt_ptr) ||
+ (group_traits::get_next(nxt_ptr) != to_erase_ptr);
+ bool first_in_group = node_traits::get_next(prev_in_group_ptr) != to_erase_ptr;
+
+ if(first_in_group && last_in_group){
+ group_algorithms::init(to_erase_ptr);
+ }
+ else if(first_in_group){
+ group_algorithms::unlink_after(nxt_ptr);
+ }
+ else if(last_in_group){
+ node_ptr first_in_group = //possible_first_in_group ? possible_first_in_group :
+ priv_get_first_in_group_of_last_in_group(to_erase_ptr);
+ group_algorithms::unlink_after(first_in_group);
+ //possible_first_in_group = 0;
+ }
+ else{
+ group_algorithms::unlink_after(nxt_ptr);
+ }
+ }
+
+ void priv_erase_from_group(slist_node_ptr, node_ptr, detail::false_)
+ {}
+
+ void priv_init_group(slist_node_ptr n, detail::true_)
+ { group_algorithms::init(dcast_bucket_ptr(n)); }
+
+ void priv_init_group(slist_node_ptr, detail::false_)
+ {}
+
+ void priv_insert_in_group(node_ptr first_in_group, node_ptr n, detail::true_)
+ {
+ if(first_in_group){
+ if(group_algorithms::unique(first_in_group))
+ group_algorithms::link_after(first_in_group, n);
+ else{
+ group_algorithms::link_after(node_traits::get_next(first_in_group), n);
+ }
+ }
+ else{
+ group_algorithms::init_header(n);
+ }
+ }
+
+ static slist_node_ptr priv_get_bucket_before_begin
+ (slist_node_ptr bucket_beg, slist_node_ptr bucket_end, node_ptr p)
+ {
+ //First find the last node of p's group.
+ //This requires checking the first node of the next group or
+ //the bucket node.
+ node_ptr prev_node = p;
+ node_ptr nxt(node_traits::get_next(p));
+ while(!(bucket_beg <= nxt && nxt <= bucket_end) &&
+ (group_traits::get_next(nxt) == prev_node)){
+ prev_node = nxt;
+ nxt = node_traits::get_next(nxt);
+ }
+
+ //If we've reached the bucket node just return it.
+ if(bucket_beg <= nxt && nxt <= bucket_end){
+ return nxt;
+ }
+
+ //Otherwise, iterate using group links until the bucket node
+ node_ptr first_node_of_group = nxt;
+ node_ptr last_node_group = group_traits::get_next(first_node_of_group);
+ slist_node_ptr possible_end = node_traits::get_next(last_node_group);
+
+ while(!(bucket_beg <= possible_end && possible_end <= bucket_end)){
+ first_node_of_group = dcast_bucket_ptr(possible_end);
+ last_node_group = group_traits::get_next(first_node_of_group);
+ possible_end = node_traits::get_next(last_node_group);
+ }
+ return possible_end;
+ }
+
+ static node_ptr priv_get_prev_to_first_in_group(slist_node_ptr bucket_node, node_ptr first_in_group)
+ {
+ //Just iterate using group links and obtain the node
+ //before "first_in_group)"
+ node_ptr prev_node = dcast_bucket_ptr(bucket_node);
+ node_ptr nxt(node_traits::get_next(prev_node));
+ while(nxt != first_in_group){
+ prev_node = group_traits::get_next(nxt);
+ nxt = node_traits::get_next(prev_node);
+ }
+ return prev_node;
+ }
+
+ static node_ptr priv_get_first_in_group_of_last_in_group(node_ptr last_in_group)
+ {
+ //Just iterate using group links and obtain the node
+ //before "last_in_group"
+ node_ptr possible_first = group_traits::get_next(last_in_group);
+ node_ptr possible_first_prev = group_traits::get_next(possible_first);
+ // The deleted node is at the end of the group, so the
+ // node in the group pointing to it is at the beginning
+ // of the group. Find that to change its pointer.
+ while(possible_first_prev != last_in_group){
+ possible_first = possible_first_prev;
+ possible_first_prev = group_traits::get_next(possible_first);
+ }
+ return possible_first;
+ }
+
+ void priv_insert_in_group(node_ptr, node_ptr, detail::false_)
    {}
+
+ static node_ptr priv_get_last_in_group(node_ptr first_in_group)
+ { return priv_get_last_in_group(first_in_group, optimize_multikey_t()); }
+
+ static node_ptr priv_get_last_in_group(node_ptr first_in_group, detail::true_)
+ { return group_traits::get_next(first_in_group); }
+
+ static node_ptr priv_get_last_in_group(node_ptr n, detail::false_)
+ { return n; }
+
+ siterator priv_get_previous
+ (bucket_type &b, siterator i)
+ { return priv_get_previous(b, i, optimize_multikey_t()); }
+
+ siterator priv_get_previous
+ (bucket_type &b, siterator i, detail::true_)
+ {
+ node_ptr elem(dcast_bucket_ptr(i.pointed_node()));
+ node_ptr prev_in_group(group_traits::get_next(elem));
+ bool first_in_group = node_traits::get_next(prev_in_group) != elem;
+
+ typename bucket_type::node &n = first_in_group
+ ? *priv_get_prev_to_first_in_group(b.end().pointed_node(), elem)
+ : *group_traits::get_next(elem)
+ ;
+ return bucket_type::s_iterator_to(n);
+ }
+
+ siterator priv_get_previous
+ (bucket_type &b, siterator i, detail::false_)
+ { return b.previous(i); }
+
+ static siterator priv_get_last(bucket_type &b)
+ { return priv_get_last(b, optimize_multikey_t()); }
+
+ static siterator priv_get_last(bucket_type &b, detail::true_)
+ {
+ //First find the last node of p's group.
+ //This requires checking the first node of the next group or
+ //the bucket node.
+ slist_node_ptr end_ptr(b.end().pointed_node());
+ node_ptr possible_end(node_traits::get_next( dcast_bucket_ptr(end_ptr)));
+ node_ptr last_node_group(possible_end);
+
+ while(end_ptr != possible_end){
+ last_node_group = group_traits::get_next(dcast_bucket_ptr(possible_end));
+ possible_end = node_traits::get_next(last_node_group);
+ }
+ return bucket_type::s_iterator_to(*last_node_group);
+ }
+
+ static siterator priv_get_last(bucket_type &b, detail::false_)
+ { return b.previous(b.end()); }
+
+ siterator priv_get_previous_and_next_in_group
+ (siterator i, node_ptr &nxt_in_group)
+ {
+ siterator prev;
+ node_ptr elem(dcast_bucket_ptr(i.pointed_node()));
+ bucket_ptr f(priv_buckets()), l(f + priv_buckets_len() - 1);
+
+ slist_node_ptr first_end_ptr(f->cend().pointed_node());
+ slist_node_ptr last_end_ptr (l->cend().pointed_node());
+
+ node_ptr nxt(node_traits::get_next(elem));
+ node_ptr prev_in_group(group_traits::get_next(elem));
+ bool last_in_group = (first_end_ptr <= nxt && nxt <= last_end_ptr) ||
+ (group_traits::get_next(nxt) != elem);
+ bool first_in_group = node_traits::get_next(prev_in_group) != elem;
+
+ if(first_in_group){
+ node_ptr start_pos;
+ if(last_in_group){
+ start_pos = elem;
+ nxt_in_group = 0;
+ }
+ else{
+ start_pos = prev_in_group;
+ nxt_in_group = node_traits::get_next(elem);
+ }
+ slist_node_ptr bucket_node;
+ if(store_hash){
+ bucket_node = this->priv_buckets()
+ [this->priv_hash_to_bucket
+ (this->priv_stored_hash(elem, store_hash_t()))
+ ].before_begin().pointed_node();
+ }
+ else{
+ bucket_node = priv_get_bucket_before_begin
+ (first_end_ptr, last_end_ptr, start_pos);
+ }
+ prev = bucket_type::s_iterator_to
+ (*priv_get_prev_to_first_in_group(bucket_node, elem));
+ }
+ else{
+ if(last_in_group){
+ nxt_in_group = priv_get_first_in_group_of_last_in_group(elem);
+ }
+ else{
+ nxt_in_group = node_traits::get_next(elem);
+ }
+ prev = bucket_type::s_iterator_to(*group_traits::get_next(elem));
+ }
+ return prev;
+ }
+
+ template<class Disposer>
+ void priv_erase(const_iterator i, Disposer disposer, detail::true_)
+ {
+ siterator elem(i.slist_it());
+ node_ptr nxt_in_group;
+ siterator prev = priv_get_previous_and_next_in_group(elem, nxt_in_group);
+ bucket_type::s_erase_after_and_dispose(prev, make_node_disposer(disposer));
+ if(nxt_in_group)
+ group_algorithms::unlink_after(nxt_in_group);
+ if(safemode_or_autounlink)
+ group_algorithms::init(dcast_bucket_ptr(elem.pointed_node()));
+ }
+
+ template <class Disposer>
+ void priv_erase(const_iterator i, Disposer disposer, detail::false_)
+ {
+ siterator to_erase(i.slist_it());
+ bucket_type &b = this->priv_buckets()[this->priv_get_bucket_num(to_erase)];
+ siterator prev(priv_get_previous(b, to_erase));
+ b.erase_after_and_dispose(prev, make_node_disposer(disposer));
+ }
+
+ bucket_ptr priv_invalid_bucket() const
+ {
+ const real_bucket_traits &rbt = this->priv_real_bucket_traits();
+ return rbt.bucket_begin() + rbt.bucket_count();
+ }
    
- static siterator invalid_local_it(const real_bucket_traits &b)
- { return b.bucket_begin()->end(); }
+ siterator priv_invalid_local_it() const
+ { return priv_invalid_bucket()->end(); }
 
    siterator priv_begin(size_type &bucket_num) const
+ { return priv_begin(bucket_num, cache_begin_t()); }
+
+ siterator priv_begin(size_type &bucket_num, detail::bool_<false>) const
    {
+ size_type n = 0;
       size_type buckets_len = this->priv_buckets_len();
- for (bucket_num = 0; bucket_num < buckets_len; ++bucket_num){
- bucket_type &b = this->priv_buckets()[bucket_num];
- if(!b.empty())
+ for (n = 0; n < buckets_len; ++n){
+ bucket_type &b = this->priv_buckets()[n];
+ if(!b.empty()){
+ bucket_num = n;
             return b.begin();
+ }
+ }
+ bucket_num = n;
+ return priv_invalid_local_it();
+ }
+
+ siterator priv_begin(size_type &bucket_num, detail::bool_<true>) const
+ {
+ bucket_num = this->bucket_hash_equal_.cached_begin_ - this->priv_buckets();
+ if(this->bucket_hash_equal_.cached_begin_ == priv_invalid_bucket()){
+ return priv_invalid_local_it();
+ }
+ else{
+ return this->bucket_hash_equal_.cached_begin_->begin();
+ }
+ }
+
+ void priv_initialize_cache()
+ { priv_initialize_cache(cache_begin_t()); }
+
+ void priv_initialize_cache(detail::bool_<true>)
+ { this->bucket_hash_equal_.cached_begin_ = priv_invalid_bucket(); }
+
+ void priv_initialize_cache(detail::bool_<false>)
+ {}
+
+ void priv_insertion_update_cache(size_type insertion_bucket)
+ { priv_insertion_update_cache(insertion_bucket, cache_begin_t()); }
+
+ void priv_insertion_update_cache(size_type insertion_bucket, detail::bool_<true>)
+ {
+ bucket_ptr p = priv_buckets() + insertion_bucket;
+ if(p < this->bucket_hash_equal_.cached_begin_){
+ this->bucket_hash_equal_.cached_begin_ = p;
+ }
+ }
+
+ void priv_insertion_update_cache(size_type, detail::bool_<false>)
+ {}
+
+ void priv_erasure_update_cache(size_type first_bucket, size_type last_bucket)
+ { priv_erasure_update_cache(first_bucket, last_bucket, cache_begin_t()); }
+
+ void priv_erasure_update_cache(size_type first_bucket_num, size_type last_bucket_num, detail::bool_<true>)
+ {
+ //If the last bucket is the end, the cache must be updated
+ //to the last position if all
+ if(priv_get_cache_bucket_num() == first_bucket_num &&
+ priv_buckets()[first_bucket_num].empty() ){
+ priv_set_cache(priv_buckets() + last_bucket_num);
+ priv_erasure_update_cache();
+ }
+ }
+
+ void priv_erasure_update_cache(size_type, size_type, detail::bool_<false>)
+ {}
+
+ void priv_erasure_update_cache()
+ { priv_erasure_update_cache(cache_begin_t()); }
+
+ void priv_erasure_update_cache(detail::bool_<true>)
+ {
+ if(constant_time_size && !size()){
+ priv_initialize_cache();
+ }
+ else{
+ size_type current_n = this->bucket_hash_equal_.cached_begin_ - priv_buckets();
+ for( const size_type num_buckets = this->priv_buckets_len()
+ ; current_n < num_buckets
+ ; ++current_n, ++this->bucket_hash_equal_.cached_begin_){
+ if(!this->bucket_hash_equal_.cached_begin_->empty()){
+ return;
+ }
+ }
+ priv_initialize_cache();
       }
- return invalid_local_it(this->get_real_bucket_traits());
    }
 
+ void priv_erasure_update_cache(detail::bool_<false>)
+ {}
+
+ void priv_swap_cache(detail::bool_<true>, hashtable_impl &other)
+ {
+ std::swap( this->bucket_hash_equal_.cached_begin_
+ , other.bucket_hash_equal_.cached_begin_);
+ }
+
+ void priv_swap_cache(detail::bool_<false>, hashtable_impl &)
+ {}
+
+ bucket_ptr priv_get_cache()
+ { return priv_get_cache(cache_begin_t()); }
+
+ bucket_ptr priv_get_cache(detail::bool_<true>)
+ { return this->bucket_hash_equal_.cached_begin_; }
+
+ bucket_ptr priv_get_cache(detail::bool_<false>)
+ { return this->priv_buckets(); }
+
+ void priv_set_cache(bucket_ptr p)
+ { priv_set_cache(p, cache_begin_t()); }
+
+ void priv_set_cache(bucket_ptr p, detail::bool_<true>)
+ { this->bucket_hash_equal_.cached_begin_ = p; }
+
+ void priv_set_cache(bucket_ptr, detail::bool_<false>)
+ {}
+
+ size_type priv_get_cache_bucket_num()
+ { return priv_get_cache_bucket_num(cache_begin_t()); }
+
+ size_type priv_get_cache_bucket_num(detail::bool_<true>)
+ { return this->bucket_hash_equal_.cached_begin_ - this->priv_buckets(); }
+
+ size_type priv_get_cache_bucket_num(detail::bool_<false>)
+ { return 0u; }
+
    void priv_clear_buckets()
- { priv_clear_buckets(this->priv_buckets(), this->priv_buckets_len()); }
+ {
+ this->priv_clear_buckets
+ ( priv_get_cache()
+ , this->priv_buckets_len() - (priv_get_cache() - priv_buckets()));
+ }
 
- static void priv_clear_buckets(bucket_ptr buckets_ptr, size_type buckets_len)
+ void priv_initialize_buckets()
+ {
+ this->priv_clear_buckets
+ ( priv_buckets(), this->priv_buckets_len());
+ }
+
+ void priv_clear_buckets(bucket_ptr buckets_ptr, size_type buckets_len)
    {
       for(; buckets_len--; ++buckets_ptr){
          if(safemode_or_autounlink){
+ priv_clear_group_nodes(*buckets_ptr, optimize_multikey_t());
             buckets_ptr->clear_and_dispose(detail::init_disposer<node_algorithms>());
          }
          else{
             buckets_ptr->clear();
          }
       }
+ priv_initialize_cache();
    }
 
    template<class KeyType, class KeyHasher, class KeyValueEqual>
    siterator priv_find
       ( const KeyType &key, KeyHasher hash_func
- , KeyValueEqual equal_func, size_type &bucket_number, size_type &h) const
+ , KeyValueEqual equal_func, size_type &bucket_number, std::size_t &h, siterator &previt) const
    {
- bucket_number = from_hash_to_bucket((h = hash_func(key)));
+ bucket_number = priv_hash_to_bucket((h = hash_func(key)));
 
       if(constant_time_size && this->empty()){
- return invalid_local_it(this->get_real_bucket_traits());
+ return priv_invalid_local_it();
       }
       
       bucket_type &b = this->priv_buckets()[bucket_number];
- siterator it = b.begin();
+ previt = b.before_begin();
+ siterator it = previt;
+ ++it;
 
       while(it != b.end()){
- const value_type &v =
- *this->get_real_value_traits().to_value_ptr(it.pointed_node());
+ const value_type &v = priv_value_from_slist_node(it.pointed_node());
          if(equal_func(key, v)){
             return it;
          }
+ if(optimize_multikey){
+ previt = bucket_type::s_iterator_to
+ (*priv_get_last_in_group(dcast_bucket_ptr(it.pointed_node())));
+ it = previt;
+ }
+ else{
+ previt = it;
+ }
          ++it;
       }
 
- return invalid_local_it(this->get_real_bucket_traits());
+ return priv_invalid_local_it();
    }
 
    template<class KeyType, class KeyHasher, class KeyValueEqual>
@@ -1820,33 +2440,44 @@
       , size_type &bucket_number_second
       , size_type &count) const
    {
- size_type h;
+ std::size_t h;
       count = 0;
+ siterator prev;
       //Let's see if the element is present
       std::pair<siterator, siterator> to_return
- ( priv_find(key, hash_func, equal_func, bucket_number_first, h)
- , invalid_local_it(this->get_real_bucket_traits()));
+ ( priv_find(key, hash_func, equal_func, bucket_number_first, h, prev)
+ , priv_invalid_local_it());
       if(to_return.first == to_return.second){
          bucket_number_second = bucket_number_first;
          return to_return;
       }
- ++count;
       //If it's present, find the first that it's not equal in
       //the same bucket
       bucket_type &b = this->priv_buckets()[bucket_number_first];
       siterator it = to_return.first;
- ++it;
-
- while(it != b.end()){
- const value_type &v =
- *this->get_real_value_traits().to_value_ptr(it.pointed_node());
- if(!equal_func(key, v)){
- to_return.second = it;
+ if(optimize_multikey){
+ to_return.second = bucket_type::s_iterator_to
+ (*node_traits::get_next(priv_get_last_in_group
+ (dcast_bucket_ptr(it.pointed_node()))));
+ count = std::distance(it, to_return.second);
+ if(to_return.second != b.end()){
             bucket_number_second = bucket_number_first;
             return to_return;
          }
- ++it;
+ }
+ else{
          ++count;
+ ++it;
+ while(it != b.end()){
+ const value_type &v = priv_value_from_slist_node(it.pointed_node());
+ if(!equal_func(key, v)){
+ to_return.second = it;
+ bucket_number_second = bucket_number_first;
+ return to_return;
+ }
+ ++it;
+ ++count;
+ }
       }
    
       //If we reached the end, find the first, non-empty bucket
@@ -1861,22 +2492,24 @@
       }
 
       //Otherwise, return the end node
- to_return.second = invalid_local_it(this->get_real_bucket_traits());
+ to_return.second = priv_invalid_local_it();
       return to_return;
    }
    /// @endcond
 };
 
 /// @cond
-template<class T, class O1 = none, class O2 = none
- , class O3 = none, class O4 = none
- , class O5 = none, class O6 = none
- , class O7 = none
- >
+template < class T
+ , bool UniqueKeys
+ , class O1 = none, class O2 = none
+ , class O3 = none, class O4 = none
+ , class O5 = none, class O6 = none
+ , class O7 = none, class O8 = none
+ >
 struct make_hashtable_opt
 {
    typedef typename pack_options
- < uset_defaults<T>, O1, O2, O3, O4, O5, O6, O7>::type packed_options;
+ < uset_defaults<T>, O1, O2, O3, O4, O5, O6, O7, O8>::type packed_options;
 
    //Real value traits must be calculated from options
    typedef typename detail::get_value_traits
@@ -1891,9 +2524,16 @@
>::type real_value_traits;
    typedef typename packed_options::bucket_traits specified_bucket_traits;
    /// @endcond
- //Real bucket traits must be calculated from options and calculated valute_traits
- typedef typename get_slist_impl
- <typename real_value_traits::node_traits>::type slist_impl;
+
+ //Real bucket traits must be calculated from options and calculated value_traits
+ typedef typename detail::get_slist_impl
+ <typename detail::reduced_slist_node_traits
+ <typename real_value_traits::node_traits>::type
+ >::type slist_impl;
+
+ typedef typename detail::reduced_slist_node_traits
+ <typename real_value_traits::node_traits>::type node_traits;
+
    typedef typename
       detail::if_c< detail::is_same
                      < specified_bucket_traits
@@ -1905,12 +2545,14 @@
 
    typedef usetopt
       < value_traits
+ , UniqueKeys
       , typename packed_options::hash
       , typename packed_options::equal
       , typename packed_options::size_type
       , packed_options::constant_time_size
       , real_bucket_traits
       , packed_options::power_2_buckets
+ , packed_options::cache_begin
> type;
 };
 /// @endcond
@@ -1923,7 +2565,7 @@
 template<class T, class O1 = none, class O2 = none
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
- , class O7 = none
+ , class O7 = none, class O8 = none
>
 #endif
 struct make_hashtable
@@ -1931,7 +2573,7 @@
    /// @cond
    typedef hashtable_impl
       < typename make_hashtable_opt
- <T, O1, O2, O3, O4, O5, O6, O7>::type
+ <T, false, O1, O2, O3, O4, O5, O6, O7, O8>::type
> implementation_defined;
 
    /// @endcond
@@ -1939,12 +2581,12 @@
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8>
 class hashtable
- : public make_hashtable<T, O1, O2, O3, O4, O5, O6, O7>::type
+ : public make_hashtable<T, O1, O2, O3, O4, O5, O6, O7, O8>::type
 {
    typedef typename make_hashtable
- <T, O1, O2, O3, O4, O5, O6, O7>::type Base;
+ <T, O1, O2, O3, O4, O5, O6, O7, O8>::type Base;
 
    public:
    typedef typename Base::value_traits value_traits;

Modified: branches/proto/v4/boost/intrusive/intrusive_fwd.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/intrusive_fwd.hpp (original)
+++ branches/proto/v4/boost/intrusive/intrusive_fwd.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -283,8 +283,7 @@
>
 class bs_set_member_hook;
 
-//hash/unordered
-//rbtree/set/multiset
+//hashtable/unordered_set/unordered_multiset
 template
    < class T
    , class O1 = none
@@ -294,6 +293,7 @@
    , class O5 = none
    , class O6 = none
    , class O7 = none
+ , class O8 = none
>
 class hashtable;
 
@@ -306,6 +306,7 @@
    , class O5 = none
    , class O6 = none
    , class O7 = none
+ , class O8 = none
>
 class unordered_set;
 
@@ -318,6 +319,7 @@
    , class O5 = none
    , class O6 = none
    , class O7 = none
+ , class O8 = none
>
 class unordered_multiset;
 

Modified: branches/proto/v4/boost/intrusive/linear_slist_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/linear_slist_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/linear_slist_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -136,7 +136,7 @@
    //!
    //! <b>Throws</b>: Nothing.
    static void init_header(node_ptr this_node)
- { NodeTraits::set_next(this_node, 0); }
+ { NodeTraits::set_next(this_node, node_ptr(0)); }
 
    //! <b>Requires</b>: this_node and prev_init_node must be in the same linear list.
    //!
@@ -195,7 +195,7 @@
    //! <b>Complexity</b>: This function is linear to the contained elements.
    static node_ptr reverse(node_ptr p)
    {
- if(!p) return 0;
+ if(!p) return node_ptr(0);
       node_ptr i = NodeTraits::get_next(p);
       node_ptr first(p);
       while(i){
@@ -218,7 +218,7 @@
    //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
    static std::pair<node_ptr, node_ptr> move_first_n_backwards(node_ptr p, std::size_t n)
    {
- std::pair<node_ptr, node_ptr> ret(0, 0);
+ std::pair<node_ptr, node_ptr> ret(node_ptr(0), node_ptr(0));
       //Null shift, or count() == 0 or 1, nothing to do
       if(!n || !p || !NodeTraits::get_next(p)){
          return ret;
@@ -252,12 +252,12 @@
       //If the p has not been found in the previous loop, find it
       //starting in the new first node and unlink it
       if(!end_found){
- old_last = base_t::get_previous_node(first, 0);
+ old_last = base_t::get_previous_node(first, node_ptr(0));
       }
       
       //Now link p after the new last node
       NodeTraits::set_next(old_last, p);
- NodeTraits::set_next(new_last, 0);
+ NodeTraits::set_next(new_last, node_ptr(0));
       ret.first = first;
       ret.second = new_last;
       return ret;
@@ -273,7 +273,7 @@
    //! <b>Complexity</b>: Linear to the number of elements plus the number moved positions.
    static std::pair<node_ptr, node_ptr> move_first_n_forward(node_ptr p, std::size_t n)
    {
- std::pair<node_ptr, node_ptr> ret(0, 0);
+ std::pair<node_ptr, node_ptr> ret(node_ptr(0), node_ptr(0));
       //Null shift, or count() == 0 or 1, nothing to do
       if(!n || !p || !NodeTraits::get_next(p))
          return ret;
@@ -311,7 +311,7 @@
       node_ptr new_first(node_traits::get_next(new_last));
       //Now put the old beginning after the old end
       NodeTraits::set_next(old_last, p);
- NodeTraits::set_next(new_last, 0);
+ NodeTraits::set_next(new_last, node_ptr(0));
       ret.first = new_first;
       ret.second = new_last;
       return ret;

Modified: branches/proto/v4/boost/intrusive/list.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/list.hpp (original)
+++ branches/proto/v4/boost/intrusive/list.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -24,7 +24,7 @@
 #include <boost/intrusive/link_mode.hpp>
 #include <boost/static_assert.hpp>
 #include <boost/intrusive/options.hpp>
-#include <boost/intrusive/detail/no_exceptions_support.hpp>
+#include <boost/intrusive/detail/utilities.hpp>
 #include <iterator>
 #include <algorithm>
 #include <functional>
@@ -732,17 +732,13 @@
    void clone_from(const list_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
- BOOST_INTRUSIVE_TRY{
- const_iterator b(src.begin()), e(src.end());
- for(; b != e; ++b){
- this->push_back(*cloner(*b));
- }
- }
- BOOST_INTRUSIVE_CATCH(...){
- this->clear_and_dispose(disposer);
- BOOST_INTRUSIVE_RETHROW;
+ detail::exception_disposer<list_impl, Disposer>
+ rollback(*this, disposer);
+ const_iterator b(src.begin()), e(src.end());
+ for(; b != e; ++b){
+ this->push_back(*cloner(*b));
       }
- BOOST_INTRUSIVE_CATCH_END
+ rollback.release();
    }
 
    //! <b>Requires</b>: value must be an lvalue and p must be a valid iterator of *this.

Modified: branches/proto/v4/boost/intrusive/options.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/options.hpp (original)
+++ branches/proto/v4/boost/intrusive/options.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -406,6 +406,24 @@
 /// @endcond
 };
 
+//!This option setter specifies if the unordered hook
+//!should offer room to store another link to another node
+//!with the same key.
+//!Storing this link will speed up lookups and insertions on
+//!unordered_multiset containers with a great number of elements
+//!with the same key.
+template<bool Enabled>
+struct optimize_multikey
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool optimize_multikey = Enabled;
+ };
+/// @endcond
+};
+
 //!This option setter specifies if the bucket array will be always power of two.
 //!This allows using masks instead of the default modulo operation to determine
 //!the bucket number from the hash value, leading to better performance.
@@ -423,6 +441,22 @@
 /// @endcond
 };
 
+//!This option setter specifies if the container will cache a pointer to the first
+//!non-empty bucket so that begin() is always constant-time.
+//!This is specially helpful when we can have containers with a few elements
+//!but with big bucket arrays (that is, hashtables with low load factors).
+template<bool Enabled>
+struct cache_begin
+{
+/// @cond
+ template<class Base>
+ struct pack : Base
+ {
+ static const bool cache_begin = Enabled;
+ };
+/// @endcond
+};
+
 /// @cond
 
 template<class Prev, class Next>
@@ -500,6 +534,7 @@
       , optimize_size<false>
       , store_hash<false>
       , linear<false>
+ , optimize_multikey<false>
>::type
 {};
 

Deleted: branches/proto/v4/boost/intrusive/pointer_plus_2_bits.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/pointer_plus_2_bits.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
+++ (empty file)
@@ -1,82 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2007
-//
-// 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)
-//
-// See http://www.boost.org/libs/intrusive for documentation.
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTRUSIVE_POINTER_PLUS_2_BIT_HPP
-#define BOOST_INTRUSIVE_POINTER_PLUS_2_BIT_HPP
-
-namespace boost {
-namespace intrusive {
-
-//!This trait class is used to know if a pointer
-//!can embed 2 extra bits of information if
-//!it's going to be used to point to objects
-//!with an alignment of "Alignment" bytes.
-template<class VoidPointer, std::size_t Alignment>
-struct has_pointer_plus_2_bits
-{
- static const bool value = false;
-};
-
-//!This is an specialization for raw pointers.
-//!Raw pointers can embed two extra bits in the lower bits
-//!if the alignment is multiple of 4.
-template<std::size_t N>
-struct has_pointer_plus_2_bits<void*, N>
-{
- static const bool value = (N % 4u == 0);
-};
-
-//!This is class that is supposed to have static methods
-//!to embed 2 extra bits of information in a pointer.
-//!
-//!This is a declaration and there is no default implementation,
-//!because operations to embed bits change with every pointer type.
-//!
-//!An implementation that detects that a pointer type whose
-//!has_pointer_plus_2_bits<>::value is non-zero can make use of these
-//!operations to embed bits in the pointer.
-template<class Pointer>
-struct pointer_plus_2_bits
-{
- static const bool value = false;
-};
-
-//!This is the specialization to embed 2 extra bits of information
-//!in a raw pointer. Extra bits are stored in the lower bits of the pointer.
-template<class T>
-struct pointer_plus_2_bits<T*>
-{
- typedef T* pointer;
-
- static pointer get_pointer(pointer n)
- { return pointer(std::size_t(n) & ~std::size_t(3u)); }
-
- static void set_pointer(pointer &n, pointer p)
- {
- assert(0 == (std::size_t(p) & std::size_t(3u)));
- n = pointer(std::size_t(p) | (std::size_t(n) & std::size_t(3u)));
- }
-
- static std::size_t get_bits(pointer n)
- { return (std::size_t(n) & std::size_t(3u)); }
-
- static void set_bits(pointer &n, std::size_t c)
- {
- assert(c < 4);
- n = pointer(std::size_t(get_pointer(n)) | c);
- }
-};
-
-} //namespace intrusive
-} //namespace boost
-
-#endif //BOOST_INTRUSIVE_POINTER_PLUS_2_BIT_HPP

Deleted: branches/proto/v4/boost/intrusive/pointer_plus_bit.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/pointer_plus_bit.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
+++ (empty file)
@@ -1,78 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-//
-// (C) Copyright Ion Gaztanaga 2007
-//
-// 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)
-//
-// See http://www.boost.org/libs/intrusive for documentation.
-//
-/////////////////////////////////////////////////////////////////////////////
-
-#ifndef BOOST_INTRUSIVE_POINTER_PLUS_BIT_HPP
-#define BOOST_INTRUSIVE_POINTER_PLUS_BIT_HPP
-
-namespace boost {
-namespace intrusive {
-
-//!This trait class is used to know if a pointer
-//!can embed an extra bit of information if
-//!it's going to be used to point to objects
-//!with an alignment of "Alignment" bytes.
-template<class VoidPointer, std::size_t Alignment>
-struct has_pointer_plus_bit
-{
- static const bool value = false;
-};
-
-//!This is an specialization for raw pointers.
-//!Raw pointers can embed an extra bit in the lower bit
-//!if the alignment is multiple of 2.
-template<std::size_t N>
-struct has_pointer_plus_bit<void*, N>
-{
- static const bool value = (N % 2u == 0);
-};
-
-//!This is class that is supposed to have static methods
-//!to embed an extra bit of information in a pointer.
-//!This is a declaration and there is no default implementation,
-//!because operations to embed the bit change with every pointer type.
-//!
-//!An implementation that detects that a pointer type whose
-//!has_pointer_plus_bit<>::value is non-zero can make use of these
-//!operations to embed the bit in the pointer.
-template<class Pointer>
-struct pointer_plus_bit
-{
- static const bool value = false;
-};
-
-//!This is the specialization to embed an extra bit of information
-//!in a raw pointer. The extra bit is stored in the lower bit of the pointer.
-template<class T>
-struct pointer_plus_bit<T*>
-{
- typedef T* pointer;
-
- static pointer get_pointer(pointer n)
- { return pointer(std::size_t(n) & ~std::size_t(1u)); }
-
- static void set_pointer(pointer &n, pointer p)
- {
- assert(0 == (std::size_t(p) & std::size_t(1u)));
- n = pointer(std::size_t(p) | (std::size_t(n) & std::size_t(1u)));
- }
-
- static bool get_bit(pointer n)
- { return (std::size_t(n) & std::size_t(1u)) != 0; }
-
- static void set_bit(pointer &n, bool c)
- { n = pointer(std::size_t(get_pointer(n)) | std::size_t(c)); }
-};
-
-} //namespace intrusive
-} //namespace boost
-
-#endif //BOOST_INTRUSIVE_POINTER_PLUS_BIT_HPP

Modified: branches/proto/v4/boost/intrusive/rbtree.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/rbtree.hpp (original)
+++ branches/proto/v4/boost/intrusive/rbtree.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -379,7 +379,7 @@
    //! <b>Precondition</b>: end_iterator must be a valid end const_iterator
    //! of rbtree.
    //!
- //! <b>Effects</b>: Returns a const reference to the rbtree associated to the end iterator
+ //! <b>Effects</b>: Returns a const reference to the rbtree associated to the iterator
    //!
    //! <b>Throws</b>: Nothing.
    //!
@@ -387,6 +387,28 @@
    static const rbtree_impl &container_from_end_iterator(const_iterator end_iterator)
    { return priv_container_from_end_iterator(end_iterator); }
 
+ //! <b>Precondition</b>: it must be a valid iterator
+ //! of rbtree.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static rbtree_impl &container_from_iterator(iterator it)
+ { return priv_container_from_iterator(it); }
+
+ //! <b>Precondition</b>: it must be a valid end const_iterator
+ //! of rbtree.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the tree associated to the end iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const rbtree_impl &container_from_iterator(const_iterator it)
+ { return priv_container_from_iterator(it); }
+
    //! <b>Effects</b>: Returns the value_compare object used by the tree.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1176,33 +1198,26 @@
    static void init_node(reference value)
    { node_algorithms::init(value_traits::to_node_ptr(value)); }
 
-/*
- //! <b>Effects</b>: removes x from a tree of the appropriate type. It has no effect,
- //! if x is not in such a tree.
+ //! <b>Effects</b>: removes "value" from the container.
    //!
    //! <b>Throws</b>: Nothing.
    //!
- //! <b>Complexity</b>: Constant time.
+ //! <b>Complexity</b>: Logarithmic time.
    //!
- //! <b>Note</b>: This static function is only usable with the "safe mode"
- //! hook and non-constant time size lists. Otherwise, the user must use
- //! the non-static "erase(reference )" member. If the user calls
- //! this function with a non "safe mode" or constant time size list
- //! a compilation error will be issued.
- template<class T>
- static void remove_node(T& value)
- {
- //This function is only usable for safe mode hooks and non-constant
- //time lists.
- //BOOST_STATIC_ASSERT((!(safemode_or_autounlink && constant_time_size)));
+ //! <b>Note</b>: This static function is only usable with non-constant
+ //! time size containers that have stateless comparison functors.
+ //!
+ //! If the user calls
+ //! this function with a constant time size container or stateful comparison
+ //! functor a compilation error will be issued.
+ static void remove_node(reference value)
+ {
       BOOST_STATIC_ASSERT((!constant_time_size));
- BOOST_STATIC_ASSERT((boost::is_convertible<T, value_type>::value));
       node_ptr to_remove(value_traits::to_node_ptr(value));
- node_algorithms::unlink_and_rebalance(to_remove);
+ node_algorithms::unlink(to_remove);
       if(safemode_or_autounlink)
          node_algorithms::init(to_remove);
    }
-*/
 
    /// @cond
    private:
@@ -1233,6 +1248,9 @@
       rbtree_impl *rb = detail::parent_from_member<rbtree_impl, data_t>(d, &rbtree_impl::data_);
       return *rb;
    }
+
+ static rbtree_impl &priv_container_from_iterator(const const_iterator &it)
+ { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
 };
 
 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
@@ -1426,6 +1444,12 @@
 
    static const rbtree &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const rbtree &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static rbtree &container_from_it(iterator it)
+ { return static_cast<rbtree &>(Base::container_from_iterator(it)); }
+
+ static const rbtree &container_from_it(const_iterator it)
+ { return static_cast<const rbtree &>(Base::container_from_iterator(it)); }
 };
 
 #endif

Modified: branches/proto/v4/boost/intrusive/rbtree_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/rbtree_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/rbtree_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -54,7 +54,6 @@
 #include <boost/intrusive/intrusive_fwd.hpp>
 
 #include <boost/intrusive/detail/assert.hpp>
-#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
 #include <boost/intrusive/detail/tree_algorithms.hpp>
 
@@ -695,6 +694,16 @@
       rebalance_after_insertion(header, new_value);
    }
 
+ //! <b>Requires</b>: "n" must be a node inserted in a tree.
+ //!
+ //! <b>Effects</b>: Returns a pointer to the header node of the tree.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ //!
+ //! <b>Throws</b>: Nothing.
+ static node_ptr get_header(node_ptr n)
+ { return tree_algorithms::get_header(n); }
+
    /// @cond
    private:
 

Modified: branches/proto/v4/boost/intrusive/set.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/set.hpp (original)
+++ branches/proto/v4/boost/intrusive/set.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -226,7 +226,7 @@
    //! <b>Precondition</b>: end_iterator must be a valid end iterator
    //! of set.
    //!
- //! <b>Effects</b>: Returns a const reference to the set associated to the end iterator
+ //! <b>Effects</b>: Returns a reference to the set associated to the end iterator
    //!
    //! <b>Throws</b>: Nothing.
    //!
@@ -253,6 +253,34 @@
          , &set_impl::tree_);
    }
 
+ //! <b>Precondition</b>: it must be a valid iterator of set.
+ //!
+ //! <b>Effects</b>: Returns a reference to the set associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static set_impl &container_from_iterator(iterator it)
+ {
+ return *detail::parent_from_member<set_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &set_impl::tree_);
+ }
+
+ //! <b>Precondition</b>: it must be a valid const_iterator of set.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the set associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const set_impl &container_from_iterator(const_iterator it)
+ {
+ return *detail::parent_from_member<set_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &set_impl::tree_);
+ }
+
    //! <b>Effects</b>: Returns the key_compare object used by the set.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1086,6 +1114,12 @@
 
    static const set &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const set &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static set &container_from_iterator(iterator it)
+ { return static_cast<set &>(Base::container_from_iterator(it)); }
+
+ static const set &container_from_iterator(const_iterator it)
+ { return static_cast<const set &>(Base::container_from_iterator(it)); }
 };
 
 #endif
@@ -1318,6 +1352,34 @@
          , &multiset_impl::tree_);
    }
 
+ //! <b>Precondition</b>: it must be a valid iterator of multiset.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the multiset associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ static multiset_impl &container_from_iterator(iterator it)
+ {
+ return *detail::parent_from_member<multiset_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &multiset_impl::tree_);
+ }
+
+ //! <b>Precondition</b>: it must be a valid const_iterator of multiset.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the multiset associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ static const multiset_impl &container_from_iterator(const_iterator it)
+ {
+ return *detail::parent_from_member<multiset_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &multiset_impl::tree_);
+ }
+
    //! <b>Effects</b>: Returns the key_compare object used by the multiset.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1932,6 +1994,21 @@
    void replace_node(iterator replace_this, reference with_this)
    { tree_.replace_node(replace_this, with_this); }
 
+ //! <b>Effects</b>: removes "value" from the container.
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic time.
+ //!
+ //! <b>Note</b>: This static function is only usable with non-constant
+ //! time size containers that have stateless comparison functors.
+ //!
+ //! If the user calls
+ //! this function with a constant time size container or stateful comparison
+ //! functor a compilation error will be issued.
+ static void remove_node(reference value)
+ { tree_type::remove_node(value); }
+
    /// @cond
    friend bool operator==(const multiset_impl &x, const multiset_impl &y)
    { return x.tree_ == y.tree_; }
@@ -2058,6 +2135,12 @@
 
    static const multiset &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const multiset &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static multiset &container_from_iterator(iterator it)
+ { return static_cast<multiset &>(Base::container_from_iterator(it)); }
+
+ static const multiset &container_from_iterator(const_iterator it)
+ { return static_cast<const multiset &>(Base::container_from_iterator(it)); }
 };
 
 #endif

Modified: branches/proto/v4/boost/intrusive/sg_set.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/sg_set.hpp (original)
+++ branches/proto/v4/boost/intrusive/sg_set.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -252,6 +252,34 @@
          , &sg_set_impl::tree_);
    }
 
+ //! <b>Precondition</b>: it must be a valid iterator of set.
+ //!
+ //! <b>Effects</b>: Returns a reference to the set associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static sg_set_impl &container_from_iterator(iterator it)
+ {
+ return *detail::parent_from_member<sg_set_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &sg_set_impl::tree_);
+ }
+
+ //! <b>Precondition</b>: it must be a valid const_iterator of set.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the set associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const sg_set_impl &container_from_iterator(const_iterator it)
+ {
+ return *detail::parent_from_member<sg_set_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &sg_set_impl::tree_);
+ }
+
    //! <b>Effects</b>: Returns the key_compare object used by the sg_set.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1124,6 +1152,12 @@
 
    static const sg_set &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const sg_set &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static sg_set &container_from_iterator(iterator it)
+ { return static_cast<sg_set &>(Base::container_from_iterator(it)); }
+
+ static const sg_set &container_from_iterator(const_iterator it)
+ { return static_cast<const sg_set &>(Base::container_from_iterator(it)); }
 };
 
 #endif
@@ -1356,6 +1390,34 @@
          , &sg_multiset_impl::tree_);
    }
 
+ //! <b>Precondition</b>: it must be a valid iterator of multiset.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the multiset associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ static sg_multiset_impl &container_from_iterator(iterator it)
+ {
+ return *detail::parent_from_member<sg_multiset_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &sg_multiset_impl::tree_);
+ }
+
+ //! <b>Precondition</b>: it must be a valid const_iterator of multiset.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the multiset associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ static const sg_multiset_impl &container_from_iterator(const_iterator it)
+ {
+ return *detail::parent_from_member<sg_multiset_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &sg_multiset_impl::tree_);
+ }
+
    //! <b>Effects</b>: Returns the key_compare object used by the sg_multiset.
    //!
    //! <b>Complexity</b>: Constant.
@@ -2135,6 +2197,12 @@
 
    static const sg_multiset &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const sg_multiset &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static sg_multiset &container_from_iterator(iterator it)
+ { return static_cast<sg_multiset &>(Base::container_from_iterator(it)); }
+
+ static const sg_multiset &container_from_iterator(const_iterator it)
+ { return static_cast<const sg_multiset &>(Base::container_from_iterator(it)); }
 };
 
 #endif

Modified: branches/proto/v4/boost/intrusive/sgtree.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/sgtree.hpp (original)
+++ branches/proto/v4/boost/intrusive/sgtree.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -527,6 +527,28 @@
    static const sgtree_impl &container_from_end_iterator(const_iterator end_iterator)
    { return priv_container_from_end_iterator(end_iterator); }
 
+ //! <b>Precondition</b>: it must be a valid iterator
+ //! of rbtree.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static sgtree_impl &container_from_iterator(iterator it)
+ { return priv_container_from_iterator(it); }
+
+ //! <b>Precondition</b>: it must be a valid end const_iterator
+ //! of rbtree.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const sgtree_impl &container_from_iterator(const_iterator it)
+ { return priv_container_from_iterator(it); }
+
    //! <b>Effects</b>: Returns the value_compare object used by the tree.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1442,6 +1464,9 @@
       sgtree_impl *scapegoat = detail::parent_from_member<sgtree_impl, data_t>(d, &sgtree_impl::data_);
       return *scapegoat;
    }
+
+ static sgtree_impl &priv_container_from_iterator(const const_iterator &it)
+ { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
 };
 
 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED

Modified: branches/proto/v4/boost/intrusive/sgtree_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/sgtree_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/sgtree_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -22,7 +22,6 @@
 #include <cstddef>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/assert.hpp>
-#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
 #include <boost/intrusive/detail/tree_algorithms.hpp>
 
@@ -640,6 +639,16 @@
    static node_ptr rebalance_subtree(node_ptr old_root)
    { return tree_algorithms::rebalance_subtree(old_root); }
 
+ //! <b>Requires</b>: "n" must be a node inserted in a tree.
+ //!
+ //! <b>Effects</b>: Returns a pointer to the header node of the tree.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ //!
+ //! <b>Throws</b>: Nothing.
+ static node_ptr get_header(node_ptr n)
+ { return tree_algorithms::get_header(n); }
+
    /// @cond
    private:
 

Modified: branches/proto/v4/boost/intrusive/slist.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/slist.hpp (original)
+++ branches/proto/v4/boost/intrusive/slist.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -16,7 +16,6 @@
 
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/static_assert.hpp>
-#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/slist_hook.hpp>
@@ -25,6 +24,7 @@
 #include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/link_mode.hpp>
 #include <boost/intrusive/options.hpp>
+#include <boost/intrusive/detail/utilities.hpp>
 #include <iterator>
 #include <functional>
 #include <algorithm>
@@ -183,10 +183,12 @@
    BOOST_STATIC_ASSERT(!(cache_last && ((int)real_value_traits::link_mode == (int)auto_unlink)));
 
    node_ptr get_end_node()
- { return node_ptr(linear ? 0 : this->get_root_node()); }
+ { return node_ptr(linear ? node_ptr(0) : this->get_root_node()); }
 
    const_node_ptr get_end_node() const
- { return const_node_ptr(linear ? 0 : this->get_root_node()); }
+ {
+ return const_node_ptr
+ (linear ? const_node_ptr(0) : this->get_root_node()); }
 
    node_ptr get_root_node()
    { return node_ptr(&data_.root_plus_size_.root_); }
@@ -203,13 +205,10 @@
    void set_last_node(node_ptr n)
    { return this->set_last_node(n, detail::bool_<cache_last>()); }
 
- node_ptr get_last_node(detail::bool_<false>)
+ static node_ptr get_last_node(detail::bool_<false>)
    { return node_ptr(0); }
 
- const_node_ptr get_last_node(detail::bool_<false>) const
- { return const_node_ptr(0); }
-
- void set_last_node(node_ptr, detail::bool_<false>)
+ static void set_last_node(node_ptr, detail::bool_<false>)
    {}
 
    node_ptr get_last_node(detail::bool_<true>)
@@ -667,18 +666,14 @@
    void clone_from(const slist_impl &src, Cloner cloner, Disposer disposer)
    {
       this->clear_and_dispose(disposer);
- BOOST_INTRUSIVE_TRY{
- iterator prev(this->before_begin());
- const_iterator b(src.begin()), e(src.end());
- for(; b != e; ++b){
- prev = this->insert_after(prev, *cloner(*b));
- }
+ detail::exception_disposer<slist_impl, Disposer>
+ rollback(*this, disposer);
+ iterator prev(this->before_begin());
+ const_iterator b(src.begin()), e(src.end());
+ for(; b != e; ++b){
+ prev = this->insert_after(prev, *cloner(*b));
       }
- BOOST_INTRUSIVE_CATCH(...){
- this->clear_and_dispose(disposer);
- BOOST_INTRUSIVE_RETHROW;
- }
- BOOST_INTRUSIVE_CATCH_END
+ rollback.release();
    }
 
    //! <b>Requires</b>: value must be an lvalue and prev_p must point to an element
@@ -849,13 +844,36 @@
       if(cache_last && (to_erase == this->get_last_node())){
          this->set_last_node(prev_n);
       }
- this->priv_size_traits().decrement();
       if(safemode_or_autounlink)
          node_algorithms::init(to_erase);
       disposer(get_real_value_traits().to_value_ptr(to_erase));
+ this->priv_size_traits().decrement();
+ return it;
+ }
+
+ /// @cond
+
+ template<class Disposer>
+ static iterator s_erase_after_and_dispose(iterator prev, Disposer disposer)
+ {
+ BOOST_STATIC_ASSERT(((!cache_last)&&(!constant_time_size)&&(!stateful_value_traits)));
+ iterator it(prev);
+ ++it;
+ node_ptr to_erase(it.pointed_node());
+ ++it;
+ node_ptr prev_n(prev.pointed_node());
+ node_algorithms::unlink_after(prev_n);
+ if(safemode_or_autounlink)
+ node_algorithms::init(to_erase);
+ disposer(real_value_traits::to_value_ptr(to_erase));
       return it;
    }
 
+ static iterator s_erase_after(iterator prev)
+ { return s_erase_after_and_dispose(prev, detail::null_disposer()); }
+
+ /// @endcond
+
    //! <b>Requires</b>: Disposer::operator()(pointer) shouldn't throw.
    //!
    //! <b>Effects</b>: Erases the range (before_first, last) from

Modified: branches/proto/v4/boost/intrusive/splay_set.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/splay_set.hpp (original)
+++ branches/proto/v4/boost/intrusive/splay_set.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -252,6 +252,34 @@
          , &splay_set_impl::tree_);
    }
 
+ //! <b>Precondition</b>: it must be a valid iterator of set.
+ //!
+ //! <b>Effects</b>: Returns a reference to the set associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ static splay_set_impl &container_from_iterator(iterator it)
+ {
+ return *detail::parent_from_member<splay_set_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &splay_set_impl::tree_);
+ }
+
+ //! <b>Precondition</b>: it must be a valid const_iterator of set.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the set associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const splay_set_impl &container_from_iterator(const_iterator it)
+ {
+ return *detail::parent_from_member<splay_set_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &splay_set_impl::tree_);
+ }
+
    //! <b>Effects</b>: Returns the key_compare object used by the splay_set.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1161,6 +1189,12 @@
 
    static const splay_set &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const splay_set &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static splay_set &container_from_iterator(iterator it)
+ { return static_cast<splay_set &>(Base::container_from_iterator(it)); }
+
+ static const splay_set &container_from_iterator(const_iterator it)
+ { return static_cast<const splay_set &>(Base::container_from_iterator(it)); }
 };
 
 #endif
@@ -1393,6 +1427,34 @@
          , &splay_multiset_impl::tree_);
    }
 
+ //! <b>Precondition</b>: it must be a valid iterator of multiset.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the multiset associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static splay_multiset_impl &container_from_iterator(iterator it)
+ {
+ return *detail::parent_from_member<splay_multiset_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &splay_multiset_impl::tree_);
+ }
+
+ //! <b>Precondition</b>: it must be a valid const_iterator of multiset.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the multiset associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Constant.
+ static const splay_multiset_impl &container_from_iterator(const_iterator it)
+ {
+ return *detail::parent_from_member<splay_multiset_impl, tree_type>
+ ( &tree_type::container_from_iterator(it)
+ , &splay_multiset_impl::tree_);
+ }
+
    //! <b>Effects</b>: Returns the key_compare object used by the splay_multiset.
    //!
    //! <b>Complexity</b>: Constant.
@@ -2209,6 +2271,12 @@
 
    static const splay_multiset &container_from_end_iterator(const_iterator end_iterator)
    { return static_cast<const splay_multiset &>(Base::container_from_end_iterator(end_iterator)); }
+
+ static splay_multiset &container_from_iterator(iterator it)
+ { return static_cast<splay_multiset &>(Base::container_from_iterator(it)); }
+
+ static const splay_multiset &container_from_iterator(const_iterator it)
+ { return static_cast<const splay_multiset &>(Base::container_from_iterator(it)); }
 };
 
 #endif

Modified: branches/proto/v4/boost/intrusive/splaytree.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/splaytree.hpp (original)
+++ branches/proto/v4/boost/intrusive/splaytree.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -387,6 +387,28 @@
    static const splaytree_impl &container_from_end_iterator(const_iterator end_iterator)
    { return priv_container_from_end_iterator(end_iterator); }
 
+ //! <b>Precondition</b>: it must be a valid iterator
+ //! of rbtree.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static splaytree_impl &container_from_iterator(iterator it)
+ { return priv_container_from_iterator(it); }
+
+ //! <b>Precondition</b>: it must be a valid end const_iterator
+ //! of rbtree.
+ //!
+ //! <b>Effects</b>: Returns a const reference to the tree associated to the iterator
+ //!
+ //! <b>Throws</b>: Nothing.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ static const splaytree_impl &container_from_iterator(const_iterator it)
+ { return priv_container_from_iterator(it); }
+
    //! <b>Effects</b>: Returns the value_compare object used by the tree.
    //!
    //! <b>Complexity</b>: Constant.
@@ -1312,6 +1334,9 @@
       splaytree_impl *rb = detail::parent_from_member<splaytree_impl, data_t>(d, &splaytree_impl::data_);
       return *rb;
    }
+
+ static splaytree_impl &priv_container_from_iterator(const const_iterator &it)
+ { return priv_container_from_end_iterator(it.end_iterator_from_it()); }
 };
 
 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED

Modified: branches/proto/v4/boost/intrusive/splaytree_algorithms.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/splaytree_algorithms.hpp (original)
+++ branches/proto/v4/boost/intrusive/splaytree_algorithms.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -50,13 +50,48 @@
 #include <boost/intrusive/detail/assert.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <cstddef>
-#include <boost/intrusive/detail/no_exceptions_support.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
 #include <boost/intrusive/detail/tree_algorithms.hpp>
 
 namespace boost {
 namespace intrusive {
 
+/// @cond
+namespace detail {
+
+template<class NodeTraits>
+struct splaydown_rollback
+{
+ typedef typename NodeTraits::node_ptr node_ptr;
+ splaydown_rollback( const node_ptr *pcur_subtree, node_ptr header
+ , node_ptr leftmost , node_ptr rightmost)
+ : pcur_subtree_(pcur_subtree) , header_(header)
+ , leftmost_(leftmost) , rightmost_(rightmost)
+ {}
+
+ void release()
+ { pcur_subtree_ = 0; }
+
+ ~splaydown_rollback()
+ {
+ if(pcur_subtree_){
+ //Exception can only be thrown by comp, but
+ //tree invariants still hold. *pcur_subtree is the current root
+ //so link it to the header.
+ NodeTraits::set_parent(*pcur_subtree_, header_);
+ NodeTraits::set_parent(header_, *pcur_subtree_);
+ //Recover leftmost/rightmost pointers
+ NodeTraits::set_left (header_, leftmost_);
+ NodeTraits::set_right(header_, rightmost_);
+ }
+ }
+ const node_ptr *pcur_subtree_;
+ node_ptr header_, leftmost_, rightmost_;
+};
+
+} //namespace detail {
+/// @endcond
+
 //! A splay tree is an implementation of a binary search tree. The tree is
 //! self balancing using the splay algorithm as described in
 //!
@@ -656,7 +691,8 @@
       node_ptr leftmost = NodeTraits::get_left(header);
       node_ptr rightmost = NodeTraits::get_right(header);
 
- try{
+ {
+ detail::splaydown_rollback<NodeTraits> rollback(&t, header, leftmost, rightmost);
          node_ptr null = header;
          node_ptr l = null;
          node_ptr r = null;
@@ -712,18 +748,9 @@
          }
 
          assemble(t, l, r, null);
+ rollback.release();
       }
- catch(...){
- //Exception can only be thrown by comp, but
- //tree invariants still hold. t is the current root
- //so link it to the header.
- NodeTraits::set_parent(t, header);
- NodeTraits::set_parent(header, t);
- //Recover leftmost/rightmost pointers
- NodeTraits::set_left (header, leftmost);
- NodeTraits::set_right(header, rightmost);
- throw;
- }
+
       //t is the current root
       NodeTraits::set_parent(header, t);
       NodeTraits::set_parent(t, header);
@@ -755,6 +782,17 @@
    static node_ptr rebalance_subtree(node_ptr old_root)
    { return tree_algorithms::rebalance_subtree(old_root); }
 
+
+ //! <b>Requires</b>: "n" must be a node inserted in a tree.
+ //!
+ //! <b>Effects</b>: Returns a pointer to the header node of the tree.
+ //!
+ //! <b>Complexity</b>: Logarithmic.
+ //!
+ //! <b>Throws</b>: Nothing.
+ static node_ptr get_header(node_ptr n)
+ { return tree_algorithms::get_header(n); }
+
    private:
 
    /// @cond

Modified: branches/proto/v4/boost/intrusive/unordered_set.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/unordered_set.hpp (original)
+++ branches/proto/v4/boost/intrusive/unordered_set.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -38,7 +38,8 @@
 //!
 //! The container supports the following options:
 //! \c base_hook<>/member_hook<>/value_traits<>,
-//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> .
+//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
+//! \c bucket_traits<>, power_2_buckets<> and cache_begin<>.
 //!
 //! unordered_set only provides forward iterators but it provides 4 iterator types:
 //! iterator and const_iterator to navigate through the whole container and
@@ -167,8 +168,8 @@
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_set.
    //!
- //! <b>Complexity</b>: Amortized constant time.
- //! Worst case (empty unordered_set): O(this->bucket_count())
+ //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
+ //! constant time with worst case (empty unordered_set) O(this->bucket_count())
    //!
    //! <b>Throws</b>: Nothing.
    iterator begin()
@@ -177,8 +178,8 @@
    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
    //! of the unordered_set.
    //!
- //! <b>Complexity</b>: Amortized constant time.
- //! Worst case (empty unordered_set): O(this->bucket_count())
+ //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
+ //! constant time with worst case (empty unordered_set) O(this->bucket_count())
    //!
    //! <b>Throws</b>: Nothing.
    const_iterator begin() const
@@ -187,8 +188,8 @@
    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
    //! of the unordered_set.
    //!
- //! <b>Complexity</b>: Amortized constant time.
- //! Worst case (empty unordered_set): O(this->bucket_count())
+ //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
+ //! constant time with worst case (empty unordered_set) O(this->bucket_count())
    //!
    //! <b>Throws</b>: Nothing.
    const_iterator cbegin() const
@@ -236,8 +237,8 @@
 
    //! <b>Effects</b>: Returns true is the container is empty.
    //!
- //! <b>Complexity</b>: if constant-time size option is disabled, average constant time
- //! (worst case, with empty() == true): O(this->bucket_count()).
+ //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
+ //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
    //! Otherwise constant.
    //!
    //! <b>Throws</b>: Nothing.
@@ -959,7 +960,7 @@
 template<class T, class O1 = none, class O2 = none
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
- , class O7 = none
+ , class O7 = none, class O8 = none
>
 #endif
 struct make_unordered_set
@@ -967,19 +968,19 @@
    /// @cond
    typedef unordered_set_impl
       < typename make_hashtable_opt
- <T, O1, O2, O3, O4, O5, O6, O7>::type
+ <T, true, O1, O2, O3, O4, O5, O6, O7, O8>::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8>
 class unordered_set
- : public make_unordered_set<T, O1, O2, O3, O4, O5, O6, O7>::type
+ : public make_unordered_set<T, O1, O2, O3, O4, O5, O6, O7, O8>::type
 {
    typedef typename make_unordered_set
- <T, O1, O2, O3, O4, O5, O6, O7>::type Base;
+ <T, O1, O2, O3, O4, O5, O6, O7, O8>::type Base;
 
    //Assert if passed value traits are compatible with the type
    BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
@@ -1032,7 +1033,8 @@
 //!
 //! The container supports the following options:
 //! \c base_hook<>/member_hook<>/value_traits<>,
-//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<> .
+//! \c constant_time_size<>, \c size_type<>, \c hash<> and \c equal<>
+//! \c bucket_traits<>, power_2_buckets<> and cache_begin<>.
 //!
 //! unordered_multiset only provides forward iterators but it provides 4 iterator types:
 //! iterator and const_iterator to navigate through the whole container and
@@ -1161,8 +1163,8 @@
 
    //! <b>Effects</b>: Returns an iterator pointing to the beginning of the unordered_multiset.
    //!
- //! <b>Complexity</b>: Amortized constant time.
- //! Worst case (empty unordered_multiset): O(this->bucket_count())
+ //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
+ //! constant time with worst case (empty unordered_set) O(this->bucket_count())
    //!
    //! <b>Throws</b>: Nothing.
    iterator begin()
@@ -1171,8 +1173,8 @@
    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
    //! of the unordered_multiset.
    //!
- //! <b>Complexity</b>: Amortized constant time.
- //! Worst case (empty unordered_multiset): O(this->bucket_count())
+ //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
+ //! constant time with worst case (empty unordered_set) O(this->bucket_count())
    //!
    //! <b>Throws</b>: Nothing.
    const_iterator begin() const
@@ -1181,8 +1183,8 @@
    //! <b>Effects</b>: Returns a const_iterator pointing to the beginning
    //! of the unordered_multiset.
    //!
- //! <b>Complexity</b>: Amortized constant time.
- //! Worst case (empty unordered_multiset): O(this->bucket_count())
+ //! <b>Complexity</b>: Constant time if `cache_begin<>` is true. Amortized
+ //! constant time with worst case (empty unordered_set) O(this->bucket_count())
    //!
    //! <b>Throws</b>: Nothing.
    const_iterator cbegin() const
@@ -1230,8 +1232,8 @@
 
    //! <b>Effects</b>: Returns true is the container is empty.
    //!
- //! <b>Complexity</b>: if constant-time size option is disabled, average constant time
- //! (worst case, with empty() == true): O(this->bucket_count()).
+ //! <b>Complexity</b>: if constant-time size and cache_last options are disabled,
+ //! average constant time (worst case, with empty() == true: O(this->bucket_count()).
    //! Otherwise constant.
    //!
    //! <b>Throws</b>: Nothing.
@@ -1891,7 +1893,7 @@
 template<class T, class O1 = none, class O2 = none
                 , class O3 = none, class O4 = none
                 , class O5 = none, class O6 = none
- , class O7 = none
+ , class O7 = none, class O8 = none
>
 #endif
 struct make_unordered_multiset
@@ -1899,19 +1901,19 @@
    /// @cond
    typedef unordered_multiset_impl
       < typename make_hashtable_opt
- <T, O1, O2, O3, O4, O5, O6, O7>::type
+ <T, false, O1, O2, O3, O4, O5, O6, O7, O8>::type
> implementation_defined;
    /// @endcond
    typedef implementation_defined type;
 };
 
 #ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
-template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7>
+template<class T, class O1, class O2, class O3, class O4, class O5, class O6, class O7, class O8>
 class unordered_multiset
- : public make_unordered_multiset<T, O1, O2, O3, O4, O5, O6, O7>::type
+ : public make_unordered_multiset<T, O1, O2, O3, O4, O5, O6, O7, O8>::type
 {
    typedef typename make_unordered_multiset
- <T, O1, O2, O3, O4, O5, O6, O7>::type Base;
+ <T, O1, O2, O3, O4, O5, O6, O7, O8>::type Base;
    //Assert if passed value traits are compatible with the type
    BOOST_STATIC_ASSERT((detail::is_same<typename Base::value_traits::value_type, T>::value));
 

Modified: branches/proto/v4/boost/intrusive/unordered_set_hook.hpp
==============================================================================
--- branches/proto/v4/boost/intrusive/unordered_set_hook.hpp (original)
+++ branches/proto/v4/boost/intrusive/unordered_set_hook.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -17,6 +17,7 @@
 #include <boost/intrusive/detail/config_begin.hpp>
 #include <boost/intrusive/intrusive_fwd.hpp>
 #include <boost/intrusive/detail/utilities.hpp>
+#include <boost/intrusive/detail/pointer_to_other.hpp>
 #include <boost/intrusive/slist_hook.hpp>
 #include <boost/intrusive/options.hpp>
 #include <boost/intrusive/detail/generic_hook.hpp>
@@ -26,35 +27,69 @@
 
 /// @cond
 
-template<class VoidPointer>
-struct slist_node_plus_hash
+template<class VoidPointer, bool StoreHash, bool OptimizeMultiKey>
+struct unordered_node
+ : public slist_node<VoidPointer>
 {
    typedef typename boost::pointer_to_other
- <VoidPointer, slist_node_plus_hash>::type node_ptr;
- node_ptr next_;
+ < VoidPointer
+ , unordered_node<VoidPointer, StoreHash, OptimizeMultiKey>
+ >::type node_ptr;
+// node_ptr next_;
+ node_ptr prev_in_group_;
    std::size_t hash_;
 };
 
-// slist_node_traits can be used with circular_slist_algorithms and supplies
-// a slist_node holding the pointers needed for a singly-linked list
-// it is used by slist_base_hook and slist_member_hook
 template<class VoidPointer>
-struct slist_node_traits_plus_hash
+struct unordered_node<VoidPointer, false, true>
+ : public slist_node<VoidPointer>
+{
+ typedef typename boost::pointer_to_other
+ < VoidPointer
+ , unordered_node<VoidPointer, false, true>
+ >::type node_ptr;
+// node_ptr next_;
+ node_ptr prev_in_group_;
+};
+
+template<class VoidPointer>
+struct unordered_node<VoidPointer, true, false>
+ : public slist_node<VoidPointer>
 {
- typedef slist_node_plus_hash<VoidPointer> node;
+ typedef typename boost::pointer_to_other
+ < VoidPointer
+ , unordered_node<VoidPointer, true, false>
+ >::type node_ptr;
+// node_ptr next_;
+ std::size_t hash_;
+};
+
+template<class VoidPointer, bool StoreHash, bool OptimizeMultiKey>
+struct unordered_node_traits
+ : public slist_node_traits<VoidPointer>
+{
+ typedef slist_node_traits<VoidPointer> reduced_slist_node_traits;
+ typedef unordered_node<VoidPointer, StoreHash, OptimizeMultiKey> node;
    typedef typename boost::pointer_to_other
       <VoidPointer, node>::type node_ptr;
    typedef typename boost::pointer_to_other
       <VoidPointer, const node>::type const_node_ptr;
 
- static const bool store_hash = true;
+ static const bool store_hash = StoreHash;
+ static const bool optimize_multikey = OptimizeMultiKey;
 
    static node_ptr get_next(const_node_ptr n)
- { return n->next_; }
+ { return node_ptr(&static_cast<node &>(*n->next_)); }
 
    static void set_next(node_ptr n, node_ptr next)
    { n->next_ = next; }
 
+ static node_ptr get_prev_in_group(const_node_ptr n)
+ { return n->prev_in_group_; }
+
+ static void set_prev_in_group(node_ptr n, node_ptr prev)
+ { n->prev_in_group_ = prev; }
+
    static std::size_t get_hash(const_node_ptr n)
    { return n->hash_; }
 
@@ -62,15 +97,68 @@
    { n->hash_ = h; }
 };
 
-template<class VoidPointer, bool StoreHash>
+template<class VoidPointer, class Node>
+struct unordered_group_node_traits
+{
+ typedef Node node;
+ typedef typename boost::pointer_to_other
+ <VoidPointer, node>::type node_ptr;
+ typedef typename boost::pointer_to_other
+ <VoidPointer, const node>::type const_node_ptr;
+
+ static node_ptr get_next(const_node_ptr n)
+ { return n->prev_in_group_; }
+
+ static void set_next(node_ptr n, node_ptr next)
+ { n->prev_in_group_ = next; }
+};
+
+template<class NodeTraits>
+struct unordered_algorithms
+ : public circular_slist_algorithms<NodeTraits>
+{
+ typedef circular_slist_algorithms<NodeTraits> base_type;
+ typedef unordered_group_node_traits
+ < typename boost::pointer_to_other
+ < typename NodeTraits::node_ptr
+ , void
+ >::type
+ , typename NodeTraits::node
+ > group_traits;
+ typedef circular_slist_algorithms<group_traits> group_algorithms;
+
+ static void init(typename base_type::node_ptr n)
+ {
+ base_type::init(n);
+ group_algorithms::init(n);
+ }
+
+ static void init_header(typename base_type::node_ptr n)
+ {
+ base_type::init_header(n);
+ group_algorithms::init_header(n);
+ }
+
+ static void unlink(typename base_type::node_ptr n)
+ {
+ base_type::unlink(n);
+ group_algorithms::unlink(n);
+ }
+};
+
+template<class VoidPointer, bool StoreHash, bool OptimizeMultiKey>
 struct get_uset_node_algo
 {
    typedef typename detail::if_c
- < StoreHash
- , slist_node_traits_plus_hash<VoidPointer>
+ < (StoreHash || OptimizeMultiKey)
+ , unordered_node_traits<VoidPointer, StoreHash, OptimizeMultiKey>
       , slist_node_traits<VoidPointer>
>::type node_traits_type;
- typedef circular_slist_algorithms<node_traits_type> type;
+ typedef typename detail::if_c
+ < OptimizeMultiKey
+ , unordered_algorithms<node_traits_type>
+ , circular_slist_algorithms<node_traits_type>
+ >::type type;
 };
 /// @endcond
 
@@ -90,6 +178,7 @@
    typedef detail::generic_hook
    < get_uset_node_algo<typename packed_options::void_pointer
                        , packed_options::store_hash
+ , packed_options::optimize_multikey
>
    , typename packed_options::tag
    , packed_options::link_mode
@@ -104,7 +193,7 @@
 //! the unordered_set/unordered_multi_set and provides an appropriate value_traits class for unordered_set/unordered_multi_set.
 //!
 //! The hook admits the following options: \c tag<>, \c void_pointer<>,
-//! \c link_mode<> and \c store_hash<>.
+//! \c link_mode<>, \c store_hash<> and \c optimize_multikey<>.
 //!
 //! \c tag<> defines a tag to identify the node.
 //! The same tag value can be used in different classes, but if a class is
@@ -119,6 +208,10 @@
 //!
 //! \c store_hash<> will tell the hook to store the hash of the value
 //! to speed up rehashings.
+//!
+//! \c optimize_multikey<> will tell the hook to store a link to form a group
+//! with other value with the same value to speed up searches and insertions
+//! in unordered_multisets with a great number of with equivalent keys.
 #ifdef BOOST_INTRUSIVE_DOXYGEN_INVOKED
 template<class ...Options>
 #else
@@ -211,6 +304,7 @@
    typedef detail::generic_hook
    < get_uset_node_algo< typename packed_options::void_pointer
                        , packed_options::store_hash
+ , packed_options::optimize_multikey
>
    , member_tag
    , packed_options::link_mode

Modified: branches/proto/v4/boost/math/bindings/rr.hpp
==============================================================================
--- branches/proto/v4/boost/math/bindings/rr.hpp (original)
+++ branches/proto/v4/boost/math/bindings/rr.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -79,11 +79,11 @@
       assign_large_int(c);
    }
 #ifdef BOOST_HAS_LONG_LONG
- RR(unsigned long long c)
+ RR(boost::ulong_long_type c)
    {
       assign_large_int(c);
    }
- RR(long long c)
+ RR(boost::long_long_type c)
    {
       assign_large_int(c);
    }
@@ -115,8 +115,8 @@
    RR& operator=(long c) { assign_large_int(c); return *this; }
    RR& operator=(unsigned long c) { assign_large_int(c); return *this; }
 #ifdef BOOST_HAS_LONG_LONG
- RR& operator=(long long c) { assign_large_int(c); return *this; }
- RR& operator=(unsigned long long c) { assign_large_int(c); return *this; }
+ RR& operator=(boost::long_long_type c) { assign_large_int(c); return *this; }
+ RR& operator=(boost::ulong_long_type c) { assign_large_int(c); return *this; }
 #endif
    RR& operator=(float c) { m_value = c; return *this; }
    RR& operator=(double c) { m_value = c; return *this; }

Modified: branches/proto/v4/boost/math/common_factor_rt.hpp
==============================================================================
--- branches/proto/v4/boost/math/common_factor_rt.hpp (original)
+++ branches/proto/v4/boost/math/common_factor_rt.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -303,7 +303,7 @@
     BOOST_PRIVATE_GCD_UF( unsigned long );
 
 #ifdef BOOST_HAS_LONG_LONG
- BOOST_PRIVATE_GCD_UF( unsigned long long );
+ BOOST_PRIVATE_GCD_UF( boost::ulong_long_type );
 #elif defined(BOOST_HAS_MS_INT64)
     BOOST_PRIVATE_GCD_UF( unsigned __int64 );
 #endif
@@ -325,7 +325,7 @@
     BOOST_PRIVATE_GCD_SF( char, unsigned char ); // should work even if unsigned
 
 #ifdef BOOST_HAS_LONG_LONG
- BOOST_PRIVATE_GCD_SF( long long, unsigned long long );
+ BOOST_PRIVATE_GCD_SF( boost::long_long_type, boost::ulong_long_type );
 #elif defined(BOOST_HAS_MS_INT64)
     BOOST_PRIVATE_GCD_SF( __int64, unsigned __int64 );
 #endif

Modified: branches/proto/v4/boost/math/concepts/real_concept.hpp
==============================================================================
--- branches/proto/v4/boost/math/concepts/real_concept.hpp (original)
+++ branches/proto/v4/boost/math/concepts/real_concept.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -67,8 +67,8 @@
    real_concept(unsigned long c) : m_value(c){}
    real_concept(long c) : m_value(c){}
 #if defined(BOOST_HAS_LONG_LONG) || defined(__DECCXX) || defined(__SUNPRO_CC)
- real_concept(unsigned long long c) : m_value(static_cast<real_concept_base_type>(c)){}
- real_concept(long long c) : m_value(static_cast<real_concept_base_type>(c)){}
+ real_concept(boost::ulong_long_type c) : m_value(static_cast<real_concept_base_type>(c)){}
+ real_concept(boost::long_long_type c) : m_value(static_cast<real_concept_base_type>(c)){}
 #elif defined(BOOST_HAS_MS_INT64)
    real_concept(unsigned __int64 c) : m_value(static_cast<real_concept_base_type>(c)){}
    real_concept(__int64 c) : m_value(static_cast<real_concept_base_type>(c)){}
@@ -91,8 +91,8 @@
    real_concept& operator=(long c) { m_value = c; return *this; }
    real_concept& operator=(unsigned long c) { m_value = c; return *this; }
 #ifdef BOOST_HAS_LONG_LONG
- real_concept& operator=(long long c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
- real_concept& operator=(unsigned long long c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
+ real_concept& operator=(boost::long_long_type c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
+ real_concept& operator=(boost::ulong_long_type c) { m_value = static_cast<real_concept_base_type>(c); return *this; }
 #endif
    real_concept& operator=(float c) { m_value = c; return *this; }
    real_concept& operator=(double c) { m_value = c; return *this; }
@@ -253,9 +253,9 @@
 
 #ifdef BOOST_HAS_LONG_LONG
 template <class Policy>
-inline long long llround(const concepts::real_concept& v, const Policy& pol)
+inline boost::long_long_type llround(const concepts::real_concept& v, const Policy& pol)
 { return boost::math::llround(v.value(), pol); }
-inline long long llround(const concepts::real_concept& v)
+inline boost::long_long_type llround(const concepts::real_concept& v)
 { return boost::math::llround(v.value(), policies::policy<>()); }
 #endif
 
@@ -272,9 +272,9 @@
 
 #ifdef BOOST_HAS_LONG_LONG
 template <class Policy>
-inline long long lltrunc(const concepts::real_concept& v, const Policy& pol)
+inline boost::long_long_type lltrunc(const concepts::real_concept& v, const Policy& pol)
 { return boost::math::lltrunc(v.value(), pol); }
-inline long long lltrunc(const concepts::real_concept& v)
+inline boost::long_long_type lltrunc(const concepts::real_concept& v)
 { return boost::math::lltrunc(v.value(), policies::policy<>()); }
 #endif
 
@@ -416,6 +416,16 @@
 
 #endif
 
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+//
+// For some strange reason ADL sometimes fails to find the
+// correct overloads, unless we bring these declarations into scope:
+//
+using concepts::itrunc;
+using concepts::iround;
+
+#endif
+
 } // namespace math
 } // namespace boost
 

Modified: branches/proto/v4/boost/math/concepts/std_real_concept.hpp
==============================================================================
--- branches/proto/v4/boost/math/concepts/std_real_concept.hpp (original)
+++ branches/proto/v4/boost/math/concepts/std_real_concept.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -59,8 +59,8 @@
    std_real_concept(unsigned long c) : m_value(c){}
    std_real_concept(long c) : m_value(c){}
 #if defined(BOOST_HAS_LONG_LONG) || defined(__DECCXX) || defined(__SUNPRO_CC)
- std_real_concept(unsigned long long c) : m_value(static_cast<std_real_concept_base_type>(c)){}
- std_real_concept(long long c) : m_value(static_cast<std_real_concept_base_type>(c)){}
+ std_real_concept(boost::ulong_long_type c) : m_value(static_cast<std_real_concept_base_type>(c)){}
+ std_real_concept(boost::long_long_type c) : m_value(static_cast<std_real_concept_base_type>(c)){}
 #endif
    std_real_concept(float c) : m_value(c){}
    std_real_concept(double c) : m_value(c){}
@@ -80,8 +80,8 @@
    std_real_concept& operator=(long c) { m_value = c; return *this; }
    std_real_concept& operator=(unsigned long c) { m_value = c; return *this; }
 #if defined(BOOST_HAS_LONG_LONG) || defined(__DECCXX) || defined(__SUNPRO_CC)
- std_real_concept& operator=(long long c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }
- std_real_concept& operator=(unsigned long long c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }
+ std_real_concept& operator=(boost::long_long_type c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }
+ std_real_concept& operator=(boost::ulong_long_type c) { m_value = static_cast<std_real_concept_base_type>(c); return *this; }
 #endif
    std_real_concept& operator=(float c) { m_value = c; return *this; }
    std_real_concept& operator=(double c) { m_value = c; return *this; }
@@ -249,11 +249,11 @@
 #ifdef BOOST_HAS_LONG_LONG
 
 template <class Policy>
-inline long long llround(const concepts::std_real_concept& v, const Policy& pol)
+inline boost::long_long_type llround(const concepts::std_real_concept& v, const Policy& pol)
 {
    return boost::math::llround(v.value(), pol);
 }
-inline long long llround(const concepts::std_real_concept& v)
+inline boost::long_long_type llround(const concepts::std_real_concept& v)
 {
    return boost::math::llround(v.value(), policies::policy<>());
 }
@@ -283,11 +283,11 @@
 #ifdef BOOST_HAS_LONG_LONG
 
 template <class Policy>
-inline long long lltrunc(const concepts::std_real_concept& v, const Policy& pol)
+inline boost::long_long_type lltrunc(const concepts::std_real_concept& v, const Policy& pol)
 {
    return boost::math::lltrunc(v.value(), pol);
 }
-inline long long lltrunc(const concepts::std_real_concept& v)
+inline boost::long_long_type lltrunc(const concepts::std_real_concept& v)
 {
    return boost::math::lltrunc(v.value(), policies::policy<>());
 }
@@ -353,6 +353,15 @@
 
 } // namespace tools
 
+#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310)
+using concepts::itrunc;
+using concepts::ltrunc;
+using concepts::lltrunc;
+using concepts::iround;
+using concepts::lround;
+using concepts::llround;
+#endif
+
 } // namespace math
 } // namespace boost
 

Modified: branches/proto/v4/boost/math/special_functions/detail/round_fwd.hpp
==============================================================================
--- branches/proto/v4/boost/math/special_functions/detail/round_fwd.hpp (original)
+++ branches/proto/v4/boost/math/special_functions/detail/round_fwd.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -33,9 +33,9 @@
    long ltrunc(const T& v);
 #ifdef BOOST_HAS_LONG_LONG
    template <class T, class Policy>
- long long lltrunc(const T& v, const Policy& pol);
+ boost::long_long_type lltrunc(const T& v, const Policy& pol);
    template <class T>
- long long lltrunc(const T& v);
+ boost::long_long_type lltrunc(const T& v);
 #endif
    template <class T, class Policy>
    T round(const T& v, const Policy& pol);
@@ -51,9 +51,9 @@
    long lround(const T& v);
 #ifdef BOOST_HAS_LONG_LONG
    template <class T, class Policy>
- long long llround(const T& v, const Policy& pol);
+ boost::long_long_type llround(const T& v, const Policy& pol);
    template <class T>
- long long llround(const T& v);
+ boost::long_long_type llround(const T& v);
 #endif
    template <class T, class Policy>
    T modf(const T& v, T* ipart, const Policy& pol);
@@ -69,9 +69,9 @@
    T modf(const T& v, long* ipart);
 #ifdef BOOST_HAS_LONG_LONG
    template <class T, class Policy>
- T modf(const T& v, long long* ipart, const Policy& pol);
+ T modf(const T& v, boost::long_long_type* ipart, const Policy& pol);
    template <class T>
- T modf(const T& v, long long* ipart);
+ T modf(const T& v, boost::long_long_type* ipart);
 #endif
 
    }

Modified: branches/proto/v4/boost/math/special_functions/detail/t_distribution_inv.hpp
==============================================================================
--- branches/proto/v4/boost/math/special_functions/detail/t_distribution_inv.hpp (original)
+++ branches/proto/v4/boost/math/special_functions/detail/t_distribution_inv.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,7 @@
 
 #include <boost/math/special_functions/cbrt.hpp>
 #include <boost/math/special_functions/round.hpp>
+#include <boost/math/special_functions/trunc.hpp>
 
 namespace boost{ namespace math{ namespace detail{
 

Modified: branches/proto/v4/boost/math/special_functions/math_fwd.hpp
==============================================================================
--- branches/proto/v4/boost/math/special_functions/math_fwd.hpp (original)
+++ branches/proto/v4/boost/math/special_functions/math_fwd.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -664,13 +664,13 @@
 #define BOOST_MATH_DETAIL_LL_FUNC(Policy)\
    \
    template <class T>\
- inline T modf(const T& v, long long* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\
+ inline T modf(const T& v, boost::long_long_type* ipart){ using boost::math::modf; return modf(v, ipart, Policy()); }\
    \
    template <class T>\
- inline long long lltrunc(const T& v){ using boost::math::lltrunc; return lltrunc(v, Policy()); }\
+ inline boost::long_long_type lltrunc(const T& v){ using boost::math::lltrunc; return lltrunc(v, Policy()); }\
    \
    template <class T>\
- inline long long llround(const T& v){ using boost::math::llround; return llround(v, Policy()); }\
+ inline boost::long_long_type llround(const T& v){ using boost::math::llround; return llround(v, Policy()); }\
 
 #else
 #define BOOST_MATH_DETAIL_LL_FUNC(Policy)

Modified: branches/proto/v4/boost/math/special_functions/modf.hpp
==============================================================================
--- branches/proto/v4/boost/math/special_functions/modf.hpp (original)
+++ branches/proto/v4/boost/math/special_functions/modf.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -53,13 +53,13 @@
 
 #ifdef BOOST_HAS_LONG_LONG
 template <class T, class Policy>
-inline T modf(const T& v, long long* ipart, const Policy& pol)
+inline T modf(const T& v, boost::long_long_type* ipart, const Policy& pol)
 {
    *ipart = lltrunc(v, pol);
    return v - *ipart;
 }
 template <class T>
-inline T modf(const T& v, long long* ipart)
+inline T modf(const T& v, boost::long_long_type* ipart)
 {
    return modf(v, ipart, policies::policy<>());
 }

Modified: branches/proto/v4/boost/math/special_functions/round.hpp
==============================================================================
--- branches/proto/v4/boost/math/special_functions/round.hpp (original)
+++ branches/proto/v4/boost/math/special_functions/round.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -71,16 +71,16 @@
 #ifdef BOOST_HAS_LONG_LONG
 
 template <class T, class Policy>
-inline long long llround(const T& v, const Policy& pol)
+inline boost::long_long_type llround(const T& v, const Policy& pol)
 {
    BOOST_MATH_STD_USING
    T r = boost::math::round(v, pol);
- if(fabs(r) > (std::numeric_limits<long long>::max)())
- return static_cast<long long>(policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", 0, v, pol));
- return static_cast<long long>(r);
+ if(fabs(r) > (std::numeric_limits<boost::long_long_type>::max)())
+ return static_cast<boost::long_long_type>(policies::raise_rounding_error("boost::math::llround<%1%>(%1%)", 0, v, pol));
+ return static_cast<boost::long_long_type>(r);
 }
 template <class T>
-inline long long llround(const T& v)
+inline boost::long_long_type llround(const T& v)
 {
    return llround(v, policies::policy<>());
 }

Modified: branches/proto/v4/boost/math/special_functions/trunc.hpp
==============================================================================
--- branches/proto/v4/boost/math/special_functions/trunc.hpp (original)
+++ branches/proto/v4/boost/math/special_functions/trunc.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -71,16 +71,16 @@
 #ifdef BOOST_HAS_LONG_LONG
 
 template <class T, class Policy>
-inline long long lltrunc(const T& v, const Policy& pol)
+inline boost::long_long_type lltrunc(const T& v, const Policy& pol)
 {
    BOOST_MATH_STD_USING
    T r = boost::math::trunc(v, pol);
- if(fabs(r) > (std::numeric_limits<long long>::max)())
- return static_cast<long long>(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, pol));
- return static_cast<long long>(r);
+ if(fabs(r) > (std::numeric_limits<boost::long_long_type>::max)())
+ return static_cast<boost::long_long_type>(policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, pol));
+ return static_cast<boost::long_long_type>(r);
 }
 template <class T>
-inline long long lltrunc(const T& v)
+inline boost::long_long_type lltrunc(const T& v)
 {
    return lltrunc(v, policies::policy<>());
 }

Modified: branches/proto/v4/boost/mpi/datatype.hpp
==============================================================================
--- branches/proto/v4/boost/mpi/datatype.hpp (original)
+++ branches/proto/v4/boost/mpi/datatype.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -293,6 +293,11 @@
 BOOST_MPI_DATATYPE(unsigned __int64, MPI_UNSIGNED_LONG_LONG, builtin);
 #endif
 
+// Define signed char specialization of is_mpi_datatype, if possible.
+#if defined(MPI_SIGNED_CHAR) || (defined(MPI_VERSION) && MPI_VERSION >= 2)
+BOOST_MPI_DATATYPE(signed char, MPI_SIGNED_CHAR, builtin);
+#endif
+
 #endif // Doxygen
 
 namespace detail {

Modified: branches/proto/v4/boost/numeric/ublas/functional.hpp
==============================================================================
--- branches/proto/v4/boost/numeric/ublas/functional.hpp (original)
+++ branches/proto/v4/boost/numeric/ublas/functional.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -446,6 +446,7 @@
             size_type size (e ().size ());
             for (size_type i = 0; i < size; ++ i) {
                 real_type u (type_traits<value_type>::norm_2 (e () (i)));
+ if ( real_type () /* zero */ == u ) continue;
                 if (scale < u) {
                     real_type v (scale / u);
                     sum_squares = sum_squares * v * v + real_type (1);
@@ -1851,6 +1852,8 @@
             return (std::max) (i, j);
         }
     };
+
+ // the first row only contains a single 1. Thus it is not stored.
     template <class Z>
     struct basic_unit_lower : public basic_lower<Z> {
         typedef Z size_type;
@@ -1879,21 +1882,23 @@
         BOOST_UBLAS_INLINE
         size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
             // Zero size strict triangles are bad at this point
- BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ());
- return L::lower_element (i, size_i - 1, j, size_j - 1);
+ BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && i != 0, bad_index ());
+ return L::lower_element (i-1, size_i - 1, j, size_j - 1);
         }
 
         static
         BOOST_UBLAS_INLINE
         size_type mutable_restrict1 (size_type i, size_type j) {
- return (std::max) (i, j);
+ return (std::max) ( (std::max<size_type>)(1, i), j);
         }
         static
         BOOST_UBLAS_INLINE
         size_type mutable_restrict2 (size_type i, size_type j) {
- return (std::min) (i, j);
+ return (std::min) ( (std::max<size_type>)(1, i), j);
         }
     };
+
+ // the last row only contains a single 1. Thus it is not stored.
     template <class Z>
     struct basic_unit_upper : public basic_upper<Z> {
         typedef Z size_type;
@@ -1922,21 +1927,23 @@
         BOOST_UBLAS_INLINE
         size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
             // Zero size strict triangles are bad at this point
- BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ());
- return L::upper_element (i, size_i - 1, j, size_j - 1);
+ BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && j != 0, bad_index ());
+ return L::upper_element (i, size_i - 1, j-1, size_j - 1);
         }
 
         static
         BOOST_UBLAS_INLINE
         size_type mutable_restrict1 (size_type i, size_type j) {
- return (std::min) (i, j);
+ return (std::min) (i, (std::max<size_type>)(1, j));
         }
         static
         BOOST_UBLAS_INLINE
         size_type mutable_restrict2 (size_type i, size_type j) {
- return (std::max) (i, j);
+ return (std::max) (i, (std::max<size_type>)(1, j));
         }
     };
+
+ // the first row only contains a single 1. Thus it is not stored.
     template <class Z>
     struct basic_strict_lower : public basic_lower<Z> {
         typedef Z size_type;
@@ -1970,31 +1977,33 @@
         BOOST_UBLAS_INLINE
         size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
             // Zero size strict triangles are bad at this point
- BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ());
- return L::lower_element (i, size_i - 1, j, size_j - 1);
+ BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && i != 0, bad_index ());
+ return L::lower_element (i-1, size_i - 1, j, size_j - 1);
         }
 
         static
         BOOST_UBLAS_INLINE
         size_type restrict1 (size_type i, size_type j) {
- return (std::max) (i, j);
+ return (std::max) ( (std::max<size_type>)(1, i), j);
         }
         static
         BOOST_UBLAS_INLINE
         size_type restrict2 (size_type i, size_type j) {
- return (std::min) (i, j);
+ return (std::min) ( (std::max<size_type>)(1, i), j);
         }
         static
         BOOST_UBLAS_INLINE
         size_type mutable_restrict1 (size_type i, size_type j) {
- return (std::max) (i, j);
+ return (std::max) ( (std::max<size_type>)(1, i), j);
         }
         static
         BOOST_UBLAS_INLINE
         size_type mutable_restrict2 (size_type i, size_type j) {
- return (std::min) (i, j);
+ return (std::min) ( (std::max<size_type>)(1, i), j);
         }
     };
+
+ // the last row only contains a single 1. Thus it is not stored.
     template <class Z>
     struct basic_strict_upper : public basic_upper<Z> {
         typedef Z size_type;
@@ -2028,29 +2037,29 @@
         BOOST_UBLAS_INLINE
         size_type element (L, size_type i, size_type size_i, size_type j, size_type size_j) {
             // Zero size strict triangles are bad at this point
- BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0, bad_index ());
- return L::upper_element (i, size_i - 1, j, size_j - 1);
+ BOOST_UBLAS_CHECK (size_i != 0 && size_j != 0 && j != 0, bad_index ());
+ return L::upper_element (i, size_i - 1, j-1, size_j - 1);
         }
 
         static
         BOOST_UBLAS_INLINE
         size_type restrict1 (size_type i, size_type j) {
- return (std::min) (i, j);
+ return (std::min) (i, (std::max<size_type>)(1, j));
         }
         static
         BOOST_UBLAS_INLINE
         size_type restrict2 (size_type i, size_type j) {
- return (std::max) (i, j);
+ return (std::max) (i, (std::max<size_type>)(1, j));
         }
         static
         BOOST_UBLAS_INLINE
         size_type mutable_restrict1 (size_type i, size_type j) {
- return (std::min) (i, j);
+ return (std::min) (i, (std::max<size_type>)(1, j));
         }
         static
         BOOST_UBLAS_INLINE
         size_type mutable_restrict2 (size_type i, size_type j) {
- return (std::max) (i, j);
+ return (std::max) (i, (std::max<size_type>)(1, j));
         }
     };
 

Modified: branches/proto/v4/boost/optional/optional.hpp
==============================================================================
--- branches/proto/v4/boost/optional/optional.hpp (original)
+++ branches/proto/v4/boost/optional/optional.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1,4 +1,4 @@
-// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
 //
 // Use, modification, and distribution is subject to the Boost Software
 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,6 +9,9 @@
 // You are welcome to contact the author at:
 // fernando_cacciola_at_[hidden]
 //
+// Revisions:
+// 27 Apr 2008 (improved swap) Fernando Cacciola, Niels Dekker, Thorsten Ottosen
+//
 #ifndef BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
 #define BOOST_OPTIONAL_OPTIONAL_FLC_19NOV2002_HPP
 
@@ -19,6 +22,7 @@
 #include "boost/assert.hpp"
 #include "boost/type.hpp"
 #include "boost/type_traits/alignment_of.hpp"
+#include "boost/type_traits/has_nothrow_constructor.hpp"
 #include "boost/type_traits/type_with_alignment.hpp"
 #include "boost/type_traits/remove_reference.hpp"
 #include "boost/type_traits/is_reference.hpp"
@@ -28,6 +32,7 @@
 #include "boost/detail/reference_content.hpp"
 #include "boost/none.hpp"
 #include "boost/utility/compare_pointees.hpp"
+#include "boost/utility/in_place_factory.hpp"
 
 #include "boost/optional/optional_fwd.hpp"
 
@@ -571,6 +576,14 @@
         return *this ;
       }
 
+ void swap( optional & arg )
+ {
+ // allow for Koenig lookup
+ using boost::swap ;
+ swap(*this, arg);
+ }
+
+
     // Returns a reference to the value if this is initialized, otherwise,
     // the behaviour is UNDEFINED
     // No-throw
@@ -878,44 +891,77 @@
 #define BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
 #endif
 
-// optional's swap:
-// If both are initialized, calls swap(T&, T&). If this swap throws, both will remain initialized but their values are now unspecified.
-// If only one is initialized, calls U.reset(*I), THEN I.reset().
-// If U.reset(*I) throws, both are left UNCHANGED (U is kept uinitialized and I is never reset)
-// If both are uninitialized, do nothing (no-throw)
-template<class T>
-inline
-void optional_swap ( optional<T>& x, optional<T>& y )
-{
- if ( !x && !!y )
- {
- x.reset(*y);
- y.reset();
- }
- else if ( !!x && !y )
- {
- y.reset(*x);
- x.reset();
- }
- else if ( !!x && !!y )
+ template<bool use_default_constructor> struct swap_selector;
+
+ template<>
+ struct swap_selector<true>
   {
-// GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
+ template<class T>
+ static void optional_swap ( optional<T>& x, optional<T>& y )
+ {
+ bool hasX = x;
+ bool hasY = y;
+
+ if ( !hasX && !hasY )
+ return;
+
+ if( !hasX )
+ x = boost::in_place();
+ else if ( !hasY )
+ y = boost::in_place();
+
+ // GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
 #ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
- // allow for Koenig lookup
- using std::swap ;
+ // allow for Koenig lookup
+ using std::swap ;
 #endif
- swap(*x,*y);
- }
-}
+ swap(*x,*y);
+
+ if( !hasX )
+ y = boost::none ;
+ else if( !hasY )
+ x = boost::none ;
+ }
+ };
+
+ template<>
+ struct swap_selector<false>
+ {
+ template<class T>
+ static void optional_swap ( optional<T>& x, optional<T>& y )
+ {
+ if ( !x && !!y )
+ {
+ x = *y;
+ y = boost::none ;
+ }
+ else if ( !!x && !y )
+ {
+ y = *x ;
+ x = boost::none ;
+ }
+ else if ( !!x && !!y )
+ {
+ // GCC > 3.2 and all other compilers have the using declaration at function scope (FLC)
+ #ifndef BOOST_OPTIONAL_STD_SWAP_INTRODUCED_AT_NS_SCOPE
+ // allow for Koenig lookup
+ using std::swap ;
+ #endif
+ swap(*x,*y);
+ }
+ }
+ };
 
 } // namespace optional_detail
 
+template<class T>
+struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor<T> {} ;
+
 template<class T> inline void swap ( optional<T>& x, optional<T>& y )
 {
- optional_detail::optional_swap(x,y);
+ optional_detail::swap_selector<optional_swap_should_use_default_constructor<T>::value>::optional_swap(x, y);
 }
 
-
 } // namespace boost
 
 #endif

Modified: branches/proto/v4/boost/optional/optional_fwd.hpp
==============================================================================
--- branches/proto/v4/boost/optional/optional_fwd.hpp (original)
+++ branches/proto/v4/boost/optional/optional_fwd.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1,4 +1,4 @@
-// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
 //
 // Use, modification, and distribution is subject to the Boost Software
 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,6 +9,9 @@
 // You are welcome to contact the author at:
 // fernando_cacciola_at_[hidden]
 //
+// Revisions:
+// 27 Apr 2008 (added forward declaration of boost::swap overload) Niels Dekker
+//
 #ifndef BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
 #define BOOST_OPTIONAL_OPTIONAL_FWD_FLC_19NOV2002_HPP
 
@@ -16,6 +19,8 @@
 
 template<class T> class optional ;
 
+template<class T> void swap ( optional<T>& , optional<T>& ) ;
+
 } // namespace boost
 
 #endif

Modified: branches/proto/v4/boost/parameter/aux_/tagged_argument.hpp
==============================================================================
--- branches/proto/v4/boost/parameter/aux_/tagged_argument.hpp (original)
+++ branches/proto/v4/boost/parameter/aux_/tagged_argument.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -14,6 +14,7 @@
 # include <boost/mpl/and.hpp>
 # include <boost/mpl/not.hpp>
 # include <boost/type_traits/is_same.hpp>
+# include <boost/type_traits/is_convertible.hpp>
 # include <boost/type_traits/is_reference.hpp>
 
 namespace boost { namespace parameter { namespace aux {

Modified: branches/proto/v4/boost/ptr_container/ptr_map_adapter.hpp
==============================================================================
--- branches/proto/v4/boost/ptr_container/ptr_map_adapter.hpp (original)
+++ branches/proto/v4/boost/ptr_container/ptr_map_adapter.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -626,7 +626,7 @@
         }
 
         template< class U >
- iterator insert( key_type& key, std::auto_ptr<U> x )
+ iterator insert( const key_type& key, std::auto_ptr<U> x )
         {
             return insert( key, x.release() );
         }

Modified: branches/proto/v4/boost/random/uniform_real.hpp
==============================================================================
--- branches/proto/v4/boost/random/uniform_real.hpp (original)
+++ branches/proto/v4/boost/random/uniform_real.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -40,7 +40,7 @@
 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS
     BOOST_STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer);
 #endif
- assert(min_arg < max_arg);
+ assert(min_arg <= max_arg);
   }
 
   // compiler-generated copy ctor and assignment operator are fine

Modified: branches/proto/v4/boost/random/uniform_smallint.hpp
==============================================================================
--- branches/proto/v4/boost/random/uniform_smallint.hpp (original)
+++ branches/proto/v4/boost/random/uniform_smallint.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -81,7 +81,7 @@
 {
   _min = min_arg;
   _max = max_arg;
- assert(min_arg < max_arg);
+ assert(min_arg <= max_arg);
 
   _range = static_cast<base_result>(_max-_min)+1;
   _factor = 1;
@@ -122,7 +122,7 @@
     BOOST_STATIC_ASSERT(!std::numeric_limits<typename base_type::result_type>::is_integer);
 #endif
 
- assert(min_arg < max_arg);
+ assert(min_arg <= max_arg);
     set(min_arg, max_arg);
   }
 

Modified: branches/proto/v4/boost/shared_ptr.hpp
==============================================================================
--- branches/proto/v4/boost/shared_ptr.hpp (original)
+++ branches/proto/v4/boost/shared_ptr.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -228,6 +228,10 @@
     {
     }
 
+ shared_ptr(detail::shared_count const & c, T * p): px(p), pn(c) // never throws
+ {
+ }
+
     // aliasing
     template< class Y >
     shared_ptr( shared_ptr<Y> const & r, T * p ): px( p ), pn( r.pn ) // never throws
@@ -341,6 +345,10 @@
         r.px = 0;
     }
 
+ shared_ptr(detail::shared_count && c, T * p): px(p), pn( static_cast< detail::shared_count && >( c ) ) // never throws
+ {
+ }
+
     shared_ptr & operator=( shared_ptr && r ) // never throws
     {
         this_type( static_cast< shared_ptr && >( r ) ).swap( *this );
@@ -382,6 +390,18 @@
         this_type( r, p ).swap( *this );
     }
 
+ void reset( detail::shared_count const & c, T * p )
+ {
+ this_type( c, p ).swap( *this );
+ }
+
+#if defined( BOOST_HAS_RVALUE_REFS )
+ void reset( detail::shared_count && c, T * p )
+ {
+ this_type( static_cast< detail::shared_count && >( c ), p ).swap( *this );
+ }
+#endif
+
     reference operator* () const // never throws
     {
         BOOST_ASSERT(px != 0);
@@ -467,14 +487,14 @@
         pn.swap(other.pn);
     }
 
- template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
+ detail::shared_count const & get_shared_count() const // never throws
     {
- return pn < rhs.pn;
+ return pn;
     }
 
- void * _internal_get_deleter( detail::sp_typeinfo const & ti ) const
+ template<class Y> bool _internal_less(shared_ptr<Y> const & rhs) const
     {
- return pn.get_deleter( ti );
+ return pn < rhs.pn;
     }
 
     // atomic access
@@ -676,35 +696,35 @@
 // g++ 2.9x doesn't allow static_cast<X const *>(void *)
 // apparently EDG 2.38 and HP aCC A.03.35 also don't accept it
 
-template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
+template<class D> D * basic_get_deleter(shared_count const & c)
 {
- void const * q = p._internal_get_deleter(BOOST_SP_TYPEID(D));
+ void const * q = c.get_deleter(BOOST_SP_TYPEID(D));
     return const_cast<D *>(static_cast<D const *>(q));
 }
 
 #else
 
-template<class D, class T> D * basic_get_deleter(shared_ptr<T> const & p)
+template<class D> D * basic_get_deleter(shared_count const & c)
 {
- return static_cast<D *>(p._internal_get_deleter(BOOST_SP_TYPEID(D)));
+ return static_cast<D *>(c.get_deleter(BOOST_SP_TYPEID(D)));
 }
 
 #endif
 
 class sp_deleter_wrapper
 {
- shared_ptr<const void> _deleter;
+ detail::shared_count _deleter;
 public:
     sp_deleter_wrapper()
     {}
- void set_deleter(const shared_ptr<const void> &deleter)
+ void set_deleter(shared_count const &deleter)
     {
         _deleter = deleter;
     }
     void operator()(const void *)
     {
         BOOST_ASSERT(_deleter.use_count() <= 1);
- _deleter.reset();
+ detail::shared_count().swap( _deleter );
     }
     template<typename D>
     D* get_deleter() const
@@ -717,10 +737,10 @@
 
 template<class D, class T> D * get_deleter(shared_ptr<T> const & p)
 {
- D *del = detail::basic_get_deleter<D>(p);
+ D *del = detail::basic_get_deleter<D>(p.get_shared_count());
     if(del == 0)
     {
- detail::sp_deleter_wrapper *del_wrapper = detail::basic_get_deleter<detail::sp_deleter_wrapper>(p);
+ detail::sp_deleter_wrapper *del_wrapper = detail::basic_get_deleter<detail::sp_deleter_wrapper>(p.get_shared_count());
 // The following get_deleter method call is fully qualified because
 // older versions of gcc (2.95, 3.2.3) fail to compile it when written del_wrapper->get_deleter<D>()
         if(del_wrapper) del = del_wrapper->::boost::detail::sp_deleter_wrapper::get_deleter<D>();

Modified: branches/proto/v4/boost/spirit.hpp
==============================================================================
--- branches/proto/v4/boost/spirit.hpp (original)
+++ branches/proto/v4/boost/spirit.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -10,14 +10,14 @@
 #define BOOST_SPIRIT_DEPRECATED_INCLUDE_SPIRIT
 
 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__DMC__)
-# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic_spirit.hpp")
+# pragma message ("Warning: This header is deprecated. Please use: boost/spirit/include/classic.hpp")
 #elif defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
-# warning "This header is deprecated. Please use: boost/spirit/include/classic_spirit.hpp"
+# warning "This header is deprecated. Please use: boost/spirit/include/classic.hpp"
 #endif
 
 #if !defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
 #define BOOST_SPIRIT_USE_OLD_NAMESPACE
 #endif
-#include <boost/spirit/include/classic_spirit.hpp>
+#include <boost/spirit/include/classic.hpp>
 
 #endif

Modified: branches/proto/v4/boost/spirit/home/classic/namespace.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/classic/namespace.hpp (original)
+++ branches/proto/v4/boost/spirit/home/classic/namespace.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,12 +11,21 @@
 
 #if defined(BOOST_SPIRIT_USE_OLD_NAMESPACE)
 
+// Use the old namespace for Spirit.Classic, everything is located in the
+// namespace boost::spirit.
+// This is in place for backwards compatibility with Spirit V1.8.x. Don't use
+// it when combining Spirit.Classic with other parts of the library
+
 #define BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN /*namespace classic {*/
-#define BOOST_SPIRIT_CLASSIC_NS boost::spirit/*classic*/
+#define BOOST_SPIRIT_CLASSIC_NS boost::spirit/*::classic*/
 #define BOOST_SPIRIT_CLASSIC_NAMESPACE_END /*}*/
         
 #else
 
+// This is the normal (and suggested) mode of operation when using
+// Spirit.Classic. Everything will be located in the namespace
+// boost::spirit::classic, avoiding name clashes with other parts of Spirit.
+
 #define BOOST_SPIRIT_CLASSIC_NAMESPACE_BEGIN namespace classic {
 #define BOOST_SPIRIT_CLASSIC_NS boost::spirit::classic
 #define BOOST_SPIRIT_CLASSIC_NAMESPACE_END }

Modified: branches/proto/v4/boost/spirit/home/karma/char/char.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/char/char.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/char/char.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -111,7 +111,7 @@
                 + '\'';
         }
     };
-
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // lazy_char
@@ -146,7 +146,7 @@
             return "char";
         }
     };
-
+
     ///////////////////////////////////////////////////////////////////////////
     //
     // lower and upper case variants of any_char with an associated parameter

Modified: branches/proto/v4/boost/spirit/home/karma/detail/output_iterator.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/detail/output_iterator.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/detail/output_iterator.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -14,6 +14,7 @@
 #include <vector>
 #include <algorithm>
 
+#include <boost/noncopyable.hpp>
 #include <boost/spirit/home/karma/detail/ostream_iterator.hpp>
 
 namespace boost { namespace spirit { namespace karma { namespace detail
@@ -83,7 +84,7 @@
     
     ///////////////////////////////////////////////////////////////////////////
     template <typename OutputIterator>
- class buffer_sink
+ class buffer_sink : boost::noncopyable
     {
     public:
         buffer_sink()
@@ -144,7 +145,7 @@
     // on demand, such as counting, buffering, and position tracking.
     ///////////////////////////////////////////////////////////////////////////
     template <typename OutputIterator, typename Enable = void>
- class output_iterator
+ class output_iterator : boost::noncopyable
     {
     private:
         enum output_mode
@@ -169,6 +170,9 @@
 
         private:
             output_iterator& parent;
+
+ // suppress warning about assignment operator not being generated
+ output_proxy& operator=(output_proxy const&);
         };
         
 #if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)
@@ -260,6 +264,9 @@
         counting_sink count_data; // for counting
         buffer_sink<OutputIterator> buffer_data; // for buffering
         output_mode mode;
+
+ // suppress warning about assignment operator not being generated
+ output_iterator& operator=(output_iterator const&);
     };
 
     ///////////////////////////////////////////////////////////////////////////

Modified: branches/proto/v4/boost/spirit/home/karma/detail/string_generate.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/detail/string_generate.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/detail/string_generate.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -22,8 +22,7 @@
     inline bool
     string_generate(OutputIterator& sink, Char const* str, unused_type = unused)
     {
- Char ch;
- for (/**/; !!(ch = *str); ++str)
+ for (Char ch = *str; ch != 0; ch = *++str)
             detail::generate_to(sink, ch);
         return true;
     }
@@ -53,11 +52,8 @@
     inline bool
     string_generate(OutputIterator& sink, Char const* str, Tag tag)
     {
- Char ch;
- for (/**/; !!(ch = *str); ++str)
- {
+ for (Char ch = *str; ch != 0; ch = *++str)
             detail::generate_to(sink, ch, tag);
- }
         return true;
     }
 

Modified: branches/proto/v4/boost/spirit/home/karma/nonterminal/detail/rule.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/nonterminal/detail/rule.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/nonterminal/detail/rule.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -33,6 +33,16 @@
 
 namespace boost { namespace spirit { namespace karma { namespace detail
 {
+ struct no_delimiter
+ {
+ // this struct accepts only unused types and
+ // nothing else. This is used by the second
+ // pure virtual parse member function of
+ // virtual_component_base below.
+
+ no_delimiter(unused_type) {}
+ };
+
     template <typename OutputIterator, typename Context, typename Delimiter>
     struct virtual_component_base
     {
@@ -60,7 +70,7 @@
             delimiter_type const& delim) = 0;
 
         virtual bool
- generate(OutputIterator& sink, Context& context, unused_type) = 0;
+ generate(OutputIterator& sink, Context& context, no_delimiter) = 0;
 
         boost::detail::atomic_count use_count;
     };
@@ -83,119 +93,6 @@
     }
 
     ///////////////////////////////////////////////////////////////////////////
- template <typename Component, typename Context>
- struct needs_single_attribute
- : mpl::not_<
- typename fusion::traits::is_sequence<
- typename traits::attribute_of<
- karma::domain, Component, Context>::type
- >::type
- >
- {
- };
-
- ///////////////////////////////////////////////////////////////////////////
- template <typename MustDeref, typename Parameter>
- struct deref_if
- {
- typedef typename
- mpl::eval_if<
- MustDeref,
- fusion::result_of::at_c<Parameter, 1>,
- fusion::result_of::pop_front<Parameter>
- >::type
- type;
-
- template <typename Param>
- static type
- call(Param const& param, mpl::true_)
- {
- return fusion::at_c<1>(param);
- }
-
- template <typename Param>
- static type
- call(Param const& param, mpl::false_)
- {
- return fusion::pop_front(param);
- }
-
- template <typename Param>
- static type
- call(Param const& param)
- {
- return call(param, MustDeref());
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
- template <typename Component, typename Context>
- struct propagate_param
- {
- // If first element of the context (that's the parameter type) contains
- // one element only, then the parameter type to propagate is unused,
- // otherwise we consider to use everything except the first element of
- // this sequence.
- //
- // If the resulting sequence type is a fusion sequence containing
- // exactly one element and the right hand side expects a singular
- // (non-sequence) parameter we pass on the first (and only) element of
- // this sequence, otherwise we pass the parameter sequence itself.
- typedef typename
- boost::add_const<
- typename boost::remove_reference<
- typename fusion::result_of::at_c<Context, 0>::type
- >::type
- >::type
- parameter_type;
-
- // this evaluates to mpl::true_ if the rules parameter type is unused
- typedef typename
- mpl::equal_to<mpl::size<parameter_type>, mpl::long_<1> >::type
- no_parameter;
-
- // this evaluates to mpl::true_ if the rules parameter type contains
- // one element and the right hand side generator expects a single
- // (non-sequence) parameter type
- typedef typename
- mpl::and_<
- mpl::equal_to<mpl::size<parameter_type>, mpl::long_<2> >,
- needs_single_attribute<Component, Context>
- >::type
- must_dereference;
-
- typedef typename
- mpl::eval_if<
- no_parameter,
- mpl::identity<unused_type const>,
- deref_if<must_dereference, parameter_type>
- >::type
- propagated_type;
-
- template <typename Ctx>
- static unused_type const
- call(Ctx& context, mpl::true_)
- {
- return unused;
- }
-
- template <typename Ctx>
- static propagated_type
- call(Ctx& context, mpl::false_)
- {
- return deref_if<must_dereference, parameter_type>::
- call(fusion::at_c<0>(context));
- }
-
- template <typename Ctx>
- static propagated_type
- call(Ctx& context)
- {
- return call(context, no_parameter());
- }
- };
-
- ///////////////////////////////////////////////////////////////////////////
     template <typename OutputIterator, typename Component, typename Context,
         typename Delimiter, typename Auto>
     struct virtual_component
@@ -220,33 +117,37 @@
         bool generate_main(OutputIterator& sink, Context& context,
             Delimiter_ const& delim, mpl::false_)
         {
- // If Auto is false, the component's parameter is unused.
+ // If Auto is false, we synthesize a new (default constructed)
+ // attribute instance based on the attributes of the embedded
+ // generator.
+ typename traits::attribute_of<
+ karma::domain, Component, Context
+ >::type param;
+
             typedef typename Component::director director;
- return director::generate(component, sink, context, delim, unused);
+ return director::generate(component, sink, context, delim, param);
         }
 
         template <typename Delimiter_>
         bool generate_main(OutputIterator& sink, Context& context,
             Delimiter_ const& delim, mpl::true_)
         {
- // If Auto is true, we pass the rule's parameters on to the
+ // If Auto is true, we pass the rule's attribute on to the
             // component.
             typedef typename Component::director director;
             return director::generate(component, sink, context, delim,
- detail::propagate_param<Component, Context>::call(context));
+ fusion::at_c<0>(fusion::at_c<0>(context)));
         }
 
         bool
- generate_main(OutputIterator& /*sink*/, Context& /*context*/, take_no_delimiter,
- mpl::false_)
+ generate_main(OutputIterator&, Context&, take_no_delimiter, mpl::false_)
         {
             BOOST_ASSERT(false); // this should never be called
             return false;
         }
 
         bool
- generate_main(OutputIterator& /*sink*/, Context& /*context*/, take_no_delimiter,
- mpl::true_)
+ generate_main(OutputIterator&, Context&, take_no_delimiter, mpl::true_)
         {
             BOOST_ASSERT(false); // this should never be called
             return false;
@@ -260,7 +161,7 @@
         }
 
         virtual bool
- generate(OutputIterator& sink, Context& context, unused_type)
+ generate(OutputIterator& sink, Context& context, no_delimiter)
         {
             return generate_main(sink, context, unused, Auto());
         }

Modified: branches/proto/v4/boost/spirit/home/karma/nonterminal/nonterminal.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/nonterminal/nonterminal.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/nonterminal/nonterminal.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -59,43 +59,33 @@
             mpl::if_<
                 is_same<result_type_, void>, unused_type, result_type_
>::type
- result_type;
+ attribute_type;
 
         // param_types is a sequence of types passed as parameters to the
         // nonterminal
         typedef typename
             function_types::parameter_types<sig_type>::type
- param_types_;
-
- // if no parameters have been specified, we generate a single
- // unused_type parameter, which is needed to allow grammar parameter
- // propagation to function correctly
- typedef typename
- mpl::if_<
- is_same<typename mpl::size<param_types_>::type, mpl::long_<0> >,
- fusion::single_view<unused_type>,
- param_types_
- >::type
         param_types;
 
+ // the parameter tuple has the attribute value pre-pended
+ typedef typename
+ fusion::result_of::as_vector<
+ fusion::joint_view<
+ fusion::single_view<attribute_type const&>,
+ param_types
+ >
+ >::type
+ retval_param_types;
+
         // locals_type is a sequence of types to be used as local variables
         typedef typename
             fusion::result_of::as_vector<Locals>::type
         locals_type;
 
- // The overall context_type consist of a tuple with:
+ // The overall context_type consists of a tuple with:
         // 1) a tuple of the return value and parameters
         // 2) the locals
- typedef fusion::vector<
- typename fusion::result_of::as_vector<
- fusion::joint_view<
- fusion::single_view<result_type const>,
- param_types
- >
- >::type,
- typename fusion::result_of::as_vector<locals_type>::type
- >
- context_type;
+ typedef fusion::vector<retval_param_types, locals_type> context_type;
 
         typedef nonterminal<Derived, Sig, Locals> self_type;
         typedef nonterminal_holder<Derived const*, Derived> nonterminal_holder_;

Modified: branches/proto/v4/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/nonterminal/nonterminal_director.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -15,6 +15,7 @@
 #include <boost/spirit/home/support/nonterminal/detail/expand_arg.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
 #include <boost/spirit/home/support/component.hpp>
+#include <boost/spirit/home/support/attribute_transform.hpp>
 #include <boost/spirit/home/support/detail/values.hpp>
 #include <boost/fusion/include/transform.hpp>
 #include <boost/fusion/include/join.hpp>
@@ -28,56 +29,63 @@
 {
     struct nonterminal_director
     {
+ // The attribute (parameter) of nonterminals is the type given to them
+ // as the return value of the function signature.
         template <typename Component, typename Context, typename Unused>
         struct attribute
         {
- typedef typename result_of::subject<Component>::type nonterminal_holder;
- typedef typename nonterminal_holder::nonterminal_type::param_types type;
+ typedef typename
+ result_of::subject<Component>::type
+ nonterminal_holder;
+ typedef typename
+ nonterminal_holder::nonterminal_type::attribute_type
+ type;
         };
 
+ // the nonterminal_holder holds an actual nonterminal_object
         template <
             typename NonterminalContext, typename Nonterminal,
- typename OutputIterator, typename Context,
- typename Delimiter, typename Parameter>
+ typename OutputIterator, typename Context, typename Delimiter,
+ typename Parameter>
         static bool generate_nonterminal(
             nonterminal_object<Nonterminal> const& x,
- OutputIterator& sink, Context& context_,
- Delimiter const& delim, Parameter const& param)
+ OutputIterator& sink, Context&, Delimiter const& delim,
+ Parameter const& param)
         {
- // the nonterminal_holder holds an actual nonterminal_object
             typedef typename Nonterminal::locals_type locals_type;
- NonterminalContext context(param, locals_type());
+ fusion::vector<Parameter const&> front(param);
+ NonterminalContext context(front, locals_type());
             return x.obj.generate(sink, context, delim);
         }
 
+ // the nonterminal_holder holds a pointer to a nonterminal
         template <
             typename NonterminalContext, typename Nonterminal,
- typename OutputIterator, typename Context,
- typename Delimiter, typename Parameter>
+ typename OutputIterator, typename Context, typename Delimiter,
+ typename Parameter>
         static bool generate_nonterminal(
             Nonterminal const* ptr,
- OutputIterator& sink, Context& /*context_*/,
- Delimiter const& delim, Parameter const& param)
+ OutputIterator& sink, Context&, Delimiter const& delim,
+ Parameter const& param)
         {
- // the nonterminal_holder holds a pointer to a nonterminal
             typedef typename Nonterminal::locals_type locals_type;
- NonterminalContext context(param, locals_type());
+ fusion::vector<Parameter const&> front(param);
+ NonterminalContext context(front, locals_type());
             return ptr->generate(sink, context, delim);
         }
 
+ // the nonterminal_holder holds a parameterized_nonterminal
         template <
             typename NonterminalContext, typename Nonterminal,
             typename FSequence, typename OutputIterator,
- typename Context, typename Delimiter,
- typename Parameter>
+ typename Context, typename Delimiter, typename Parameter>
         static bool generate_nonterminal(
             parameterized_nonterminal<Nonterminal, FSequence> const& x,
- OutputIterator& sink, Context& context_,
- Delimiter const& delim, Parameter const& /*param*/)
+ OutputIterator& sink, Context& context_, Delimiter const& delim,
+ Parameter const& param)
         {
- // the nonterminal_holder holds a parameterized_nonterminal
             typedef typename Nonterminal::locals_type locals_type;
- fusion::single_view<unused_type const> front(unused);
+ fusion::vector<Parameter const&> front(param);
             NonterminalContext context(
                 fusion::join(
                     front,
@@ -95,8 +103,7 @@
         // main entry point
         ///////////////////////////////////////////////////////////////////////
         template <
- typename Component,
- typename OutputIterator, typename Context,
+ typename Component, typename OutputIterator, typename Context,
             typename Delimiter, typename Parameter>
         static bool generate(
             Component const& component, OutputIterator& sink,
@@ -107,29 +114,16 @@
             nonterminal_holder;
             
             // The overall context_type consists of a tuple with:
- // 1) a tuple of the return value and parameters
+ // 1) a tuple of the attribute and parameters
             // 2) the locals
             // if no signature is specified the first tuple contains
- // an unused_type element at position zero only.
-
+ // the attribute at position zero only.
             typedef typename
                 nonterminal_holder::nonterminal_type::context_type
             context_type;
 
- typedef typename
- mpl::if_<
- is_same<typename remove_const<Parameter>::type, unused_type>,
- context_type,
- Parameter
- >::type
- parameter_type;
-
- // create an parameter if one is not supplied
- parameter_type p (spirit::detail::make_value<parameter_type>::call(param));
-
             return generate_nonterminal<context_type>(
- subject(component).held, sink, context, delim, p
- );
+ subject(component).held, sink, context, delim, param);
         }
 
         template <typename Nonterminal>

Modified: branches/proto/v4/boost/spirit/home/karma/nonterminal/rule.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/nonterminal/rule.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/nonterminal/rule.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -75,9 +75,12 @@
             is_component;
 
             // report invalid expression error as early as possible
- BOOST_MPL_ASSERT_MSG(
- is_component::value,
- xpr_is_not_convertible_to_a_generator, ());
+// BOOST_MPL_ASSERT_MSG(
+// is_component::value,
+// xpr_is_not_convertible_to_a_generator, ());
+
+ // temp workaround for mpl problem
+ BOOST_STATIC_ASSERT(is_component::value);
 
             define(xpr, mpl::false_());
             return *this;
@@ -91,9 +94,12 @@
             is_component;
 
             // report invalid expression error as early as possible
- BOOST_MPL_ASSERT_MSG(
- is_component::value,
- xpr_is_not_convertible_to_a_generator, ());
+// BOOST_MPL_ASSERT_MSG(
+// is_component::value,
+// xpr_is_not_convertible_to_a_generator, ());
+
+ // temp workaround for mpl problem
+ BOOST_STATIC_ASSERT(is_component::value);
 
             r.define(xpr, mpl::true_());
             return r;
@@ -161,9 +167,9 @@
         {
             // If the following line produces a compilation error stating the
             // 3rd parameter is not convertible to the expected type, then you
- // probably trying to use this rule instance with a delimiter which
- // is not compatible with the delimiter type used while defining
- // the type of this rule instance.
+ // are probably trying to use this rule instance with a delimiter
+ // which is not compatible with the delimiter type used while
+ // defining the type of this rule instance.
             return ptr->generate(sink, context, delim);
         }
 

Modified: branches/proto/v4/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/numeric/detail/numeric_utils.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -527,6 +527,12 @@
             return call_n(sink, T(n), p);
         }
         
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
         ///////////////////////////////////////////////////////////////////////
         // This is the workhorse behind the real generator
         ///////////////////////////////////////////////////////////////////////
@@ -617,6 +623,11 @@
             }
             return r;
         }
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
     };
 
 }}}

Modified: branches/proto/v4/boost/spirit/home/karma/operator/alternative.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/operator/alternative.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/operator/alternative.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,13 @@
 #include <boost/spirit/home/support/algorithm/any.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/fusion/include/for_each.hpp>
+#include <boost/fusion/include/mpl.hpp>
+#include <boost/fusion/include/transform.hpp>
 #include <boost/variant.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/insert_range.hpp>
+#include <boost/mpl/transform_view.hpp>
 
 namespace boost { namespace spirit { namespace karma
 {
@@ -51,28 +57,12 @@
             Context& ctx, Delimiter const& d, Parameter const& param)
         {
             typedef detail::alternative_generate_functor<
- Component, OutputIterator, Context, Delimiter, Parameter>
- functor;
+ OutputIterator, Context, Delimiter, Parameter
+ > functor;
 
- functor f(component, sink, ctx, d, param);
- return boost::apply_visitor(f, param);
- }
-
- template <typename Component, typename OutputIterator,
- typename Context, typename Delimiter>
- static bool
- generate(Component const& component, OutputIterator& sink,
- Context& ctx, Delimiter const& d, unused_type)
- {
- typedef typename
- fusion::result_of::value_at_c<
- typename Component::elements_type, 0>::type
- child_component_type;
-
- typedef typename child_component_type::director director;
- return director::generate(
- fusion::at_c<0>(component.elements),
- sink, ctx, d, unused);
+ // f return true if *any* of the parser succeeds
+ functor f (sink, ctx, d, param);
+ return fusion::any(component.elements, f);
         }
 
         template <typename Component>

Modified: branches/proto/v4/boost/spirit/home/karma/operator/detail/alternative.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/operator/detail/alternative.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/operator/detail/alternative.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,102 +11,166 @@
 #pragma once // MS compatible compilers support #pragma once
 #endif
 
+#include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/attribute_of.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
-#include <boost/fusion/include/at.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/type_traits/is_same.hpp>
 #include <boost/utility/enable_if.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/distance.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_convertible.hpp>
 #include <boost/variant.hpp>
 
 namespace boost { namespace spirit { namespace karma { namespace detail
 {
- template <typename Component, typename OutputIterator,
- typename Context, typename Delimiter, typename Parameter>
- struct alternative_generate_functor
+ ///////////////////////////////////////////////////////////////////////////
+ // A component is compatible to a given parameter type if the parameter
+ // is the same as the expected type of the component
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Expected, typename Parameter>
+ struct compute_compatible_component
     {
- typedef bool result_type; // to satisfy boost::variant visition
-
- template <typename Attribute, typename Got>
- struct compute_is_compatible
- {
- typedef typename
- Attribute::types
- types; // mpl sequence of types in the variant
-
- typedef typename
- mpl::begin<types>::type
- begin; // iterator to the first element
+ typedef typename Parameter::types types;
+ typedef typename mpl::end<types>::type end;
+ typedef typename mpl::begin<types>::type begin;
+
+ typedef typename
+ mpl::find_if<
+ types,
+ is_same<mpl::_1, Expected>
+ >::type
+ iter;
 
- typedef typename
- mpl::end<types>::type
- end; // iterator to the last element
-
- typedef typename
- mpl::find_if<
- types,
- is_same<mpl::_1, Got> // $$$ fix this
- >::type
- iter;
+ typedef typename mpl::not_<is_same<iter, end> >::type type;
+ enum { value = type::value };
+ };
 
- typedef typename mpl::distance<begin, iter>::type index;
- typedef typename mpl::not_<is_same<iter, end> >::type type;
- enum { value = type::value };
- };
-
- template <typename Got>
- struct compute_is_compatible<unused_type, Got> : mpl::false_ {};
-
- template <typename Attribute, typename Component_, typename Context_>
- struct is_compatible :
- compute_is_compatible<
- typename traits::attribute_of<
- karma::domain, Component_, Context_>::type,
- Attribute>
+ template <typename Expected>
+ struct compute_compatible_component<Expected, unused_type>
+ : mpl::false_
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // execute a generator if the given parameter type is compatible
+ ///////////////////////////////////////////////////////////////////////////
+
+ // this get's instantiated if the parameter type is _not_ compatible with
+ // the generator
+ template <typename Component, typename Parameter, typename Expected,
+ typename Enable = void>
+ struct alternative_generate
+ {
+ template <typename OutputIterator, typename Context, typename Delimiter>
+ static bool
+ call(Component const&, OutputIterator&, Context&, Delimiter const&,
+ Parameter const&)
         {
- };
+ return false;
+ }
+ };
 
- alternative_generate_functor(Component const& component_,
- OutputIterator& sink_, Context& ctx_,
- Delimiter const& d, Parameter const& p)
- : component(component_), sink(sink_), ctx(ctx_), delim(d), param(p)
- {
+ template <typename Component>
+ struct alternative_generate<Component, unused_type, unused_type>
+ {
+ template <typename OutputIterator, typename Context, typename Delimiter>
+ static bool
+ call(Component const& component, OutputIterator& sink,
+ Context& ctx, Delimiter const& delim, unused_type const&)
+ {
+ // return true if any of the generators succeed
+ typedef typename Component::director director;
+ return director::generate(component, sink, ctx, delim, unused);
         }
+ };
 
- template <typename Attribute>
- bool call(Attribute const& actual_attribute, mpl::true_) const
- {
- typedef is_compatible<Attribute, Component, Context> is_compatible;
- typedef typename is_compatible::index index;
- typedef typename Component::elements_type elements;
+ // this get's instantiated if there is no parameter given for the
+ // alternative generator
+ template <typename Component, typename Expected>
+ struct alternative_generate<Component, unused_type, Expected>
+ : alternative_generate<Component, unused_type, unused_type>
+ {};
+
+ // this get's instantiated if the generator does not expect to receive a
+ // parameter (the generator is self contained).
+ template <typename Component, typename Parameter>
+ struct alternative_generate<Component, Parameter, unused_type>
+ : alternative_generate<Component, unused_type, unused_type>
+ {};
+
+ // this get's instantiated if the parameter type is compatible to the
+ // generator
+ template <typename Component, typename Parameter, typename Expected>
+ struct alternative_generate<
+ Component, Parameter, Expected,
+ typename enable_if<
+ compute_compatible_component<Expected, Parameter>
+ >::type
+ >
+ {
+ template <typename OutputIterator, typename Context, typename Delimiter>
+ static bool
+ call(Component const& component, OutputIterator& sink,
+ Context& ctx, Delimiter const& delim, Parameter const& param)
+ {
+ typedef
+ compute_compatible_component<Expected, Parameter>
+ component_type;
 
             typedef typename
- fusion::result_of::value_at<elements, index>::type
- child_component_type;
+ mpl::distance<
+ typename component_type::begin,
+ typename component_type::iter
+ >::type
+ distance_type;
 
- typedef typename child_component_type::director director;
- return director::generate(
- fusion::at<index>(component.elements),
- sink, ctx, delim, actual_attribute);
+ // make sure, the content of the passed variant matches our
+ // expectations
+ if (param.which() != distance_type::value)
+ return false;
+
+ // returns true if any of the generators succeed
+ typedef
+ typename mpl::deref<
+ typename component_type::iter
+ >::type
+ compatible_type;
+
+ typedef typename Component::director director;
+ return director::generate(component, sink, ctx, delim,
+ get<compatible_type>(param));
         }
+ };
 
- template <typename Attribute>
- bool call(Attribute const&, mpl::false_) const
+ ///////////////////////////////////////////////////////////////////////////
+ // alternative_generate_functor: a functor supplied to spirit::any which
+ // will be executed for every generator in a given alternative generator
+ // expression
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename OutputIterator, typename Context, typename Delimiter,
+ typename Parameter>
+ struct alternative_generate_functor
+ {
+ alternative_generate_functor(OutputIterator& sink_, Context& ctx_,
+ Delimiter const& d, Parameter const& p)
+ : sink(sink_), ctx(ctx_), delim(d), param(p)
         {
- return false;
         }
 
- template <typename Attribute>
- bool operator()(Attribute const& actual_attribute) const
+ template <typename Component>
+ bool operator()(Component const& component)
         {
- typedef mpl::bool_<
- is_compatible<Attribute, Component, Context>::value>
- is_compatible;
+ typedef
+ typename traits::attribute_of<
+ karma::domain, Component, Context>::type
+ expected;
+ typedef
+ alternative_generate<Component, Parameter, expected>
+ generate;
 
- return call(actual_attribute, is_compatible());
+ return generate::call(component, sink, ctx, delim, param);
         }
 
- Component const& component;
         OutputIterator& sink;
         Context& ctx;
         Delimiter const& delim;

Modified: branches/proto/v4/boost/spirit/home/karma/operator/karma-alt/alternative.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/operator/karma-alt/alternative.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/operator/karma-alt/alternative.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1,4 +1,4 @@
-// Copyright (c) 2001-2007 Hartmut Kaiser
+// Copyright (c) 2001-2008 Hartmut Kaiser
 // Copyright (c) 2001-2007 Joel de Guzman
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -18,7 +18,13 @@
 #include <boost/spirit/home/support/algorithm/any.hpp>
 #include <boost/spirit/home/support/unused.hpp>
 #include <boost/fusion/include/for_each.hpp>
+#include <boost/fusion/include/mpl.hpp>
+#include <boost/fusion/include/transform.hpp>
 #include <boost/variant.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/end.hpp>
+#include <boost/mpl/insert_range.hpp>
+#include <boost/mpl/transform_view.hpp>
 
 namespace boost { namespace spirit { namespace karma
 {
@@ -51,28 +57,12 @@
             Context& ctx, Delimiter const& d, Parameter const& param)
         {
             typedef detail::alternative_generate_functor<
- Component, OutputIterator, Context, Delimiter, Parameter>
- functor;
+ OutputIterator, Context, Delimiter, Parameter
+ > functor;
 
- functor f(component, sink, ctx, d, param);
- return boost::apply_visitor(f, param);
- }
-
- template <typename Component, typename OutputIterator,
- typename Context, typename Delimiter>
- static bool
- generate(Component const& component, OutputIterator& sink,
- Context& ctx, Delimiter const& d, unused_type)
- {
- typedef typename
- fusion::result_of::value_at_c<
- typename Component::elements_type, 0>::type
- child_component_type;
-
- typedef typename child_component_type::director director;
- return director::generate(
- fusion::at_c<0>(component.elements),
- sink, ctx, d, unused);
+ // f return true if *any* of the parser succeeds
+ functor f (sink, ctx, d, param);
+ return fusion::any(component.elements, f);
         }
 
         template <typename Component>

Modified: branches/proto/v4/boost/spirit/home/karma/operator/karma-alt/detail/alternative.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/karma/operator/karma-alt/detail/alternative.hpp (original)
+++ branches/proto/v4/boost/spirit/home/karma/operator/karma-alt/detail/alternative.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1,4 +1,4 @@
-// Copyright (c) 2001-2007 Hartmut Kaiser
+// Copyright (c) 2001-2008 Hartmut Kaiser
 // Copyright (c) 2001-2007 Joel de Guzman
 //
 // Distributed under the Boost Software License, Version 1.0. (See accompanying
@@ -11,101 +11,166 @@
 #pragma once // MS compatible compilers support #pragma once
 #endif
 
+#include <boost/spirit/home/support/unused.hpp>
 #include <boost/spirit/home/support/attribute_of.hpp>
 #include <boost/spirit/home/karma/domain.hpp>
-#include <boost/fusion/include/at.hpp>
-#include <boost/fusion/include/value_at.hpp>
-#include <boost/type_traits/is_same.hpp>
 #include <boost/utility/enable_if.hpp>
+#include <boost/mpl/find_if.hpp>
+#include <boost/mpl/deref.hpp>
+#include <boost/mpl/distance.hpp>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/variant.hpp>
 
 namespace boost { namespace spirit { namespace karma { namespace detail
 {
- template <typename Component, typename OutputIterator,
- typename Context, typename Delimiter, typename Parameter>
- struct alternative_generate_functor
+ ///////////////////////////////////////////////////////////////////////////
+ // A component is compatible to a given parameter type if the parameter
+ // is the same as the expected type of the component
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename Expected, typename Parameter>
+ struct is_compatible_component
     {
- typedef bool result_type; // to satisfy boost::variant visition
-
- template <typename Attribute, typename Got>
- struct compute_is_compatible
- {
- typedef typename
- Attribute::types
- types; // mpl sequence of types in the variant
-
- typedef typename
- mpl::begin<types>::type
- begin; // iterator to the first element
+ typedef typename Parameter::types types;
+ typedef typename mpl::end<types>::type end;
+ typedef typename mpl::begin<types>::type begin;
+
+ typedef typename
+ mpl::find_if<
+ types,
+ is_same<mpl::_1, Expected>
+ >::type
+ iter;
 
- typedef typename
- mpl::end<types>::type
- end; // iterator to the last element
-
- typedef typename
- mpl::find_if<
- types,
- is_same<mpl::_1, Got> // $$$ fix this
- >::type
- iter;
+ typedef typename mpl::not_<is_same<iter, end> >::type type;
+ enum { value = type::value };
+ };
 
- typedef typename mpl::distance<begin, iter>::type index;
- typedef typename mpl::not_<is_same<iter, end> >::type type;
- enum { value = type::value };
- };
-
- template <typename Got>
- struct compute_is_compatible<unused_type, Got> : mpl::false_ {};
-
- template <typename Attribute, typename Component_, typename Context_>
- struct is_compatible :
- compute_is_compatible<
- typename traits::attribute_of<
- karma::domain, Component_, Context_>::type,
- Attribute>
+ template <typename Expected>
+ struct is_compatible_component<Expected, unused_type>
+ : mpl::false_
+ {};
+
+ ///////////////////////////////////////////////////////////////////////////
+ // execute a generator if the given parameter type is compatible
+ ///////////////////////////////////////////////////////////////////////////
+
+ // this get's instantiated if the parameter type is _not_ compatible with
+ // the generator
+ template <typename Component, typename Parameter, typename Expected,
+ typename Enable = void>
+ struct alternative_generate
+ {
+ template <typename OutputIterator, typename Context, typename Delimiter>
+ static bool
+ call(Component const&, OutputIterator&, Context&, Delimiter const&,
+ Parameter const&)
         {
- };
+ return false;
+ }
+ };
 
- alternative_generate_functor(Component const& component_,
- OutputIterator& sink_, Context& ctx_,
- Delimiter const& d, Parameter const& p)
- : component(component_), sink(sink_), ctx(ctx_), delim(d), param(p)
- {
+ template <typename Component>
+ struct alternative_generate<Component, unused_type, unused_type>
+ {
+ template <typename OutputIterator, typename Context, typename Delimiter>
+ static bool
+ call(Component const& component, OutputIterator& sink,
+ Context& ctx, Delimiter const& delim, unused_type const&)
+ {
+ // return true if any of the generators succeed
+ typedef typename Component::director director;
+ return director::generate(component, sink, ctx, delim, unused);
         }
+ };
 
- template <typename Attribute>
- bool call(Attribute const& actual_attribute, mpl::true_) const
- {
- typedef is_compatible<Attribute, Component, Context> is_compatible;
- typedef typename is_compatible::index index;
- typedef typename Component::elements_type elements;
+ // this get's instantiated if there is no parameter given for the
+ // alternative generator
+ template <typename Component, typename Expected>
+ struct alternative_generate<Component, unused_type, Expected>
+ : alternative_generate<Component, unused_type, unused_type>
+ {};
+
+ // this get's instantiated if the generator does not expect to receive a
+ // parameter (the generator is self contained).
+ template <typename Component, typename Parameter>
+ struct alternative_generate<Component, Parameter, unused_type>
+ : alternative_generate<Component, unused_type, unused_type>
+ {};
+
+ // this get's instantiated if the parameter type is compatible to the
+ // generator
+ template <typename Component, typename Parameter, typename Expected>
+ struct alternative_generate<
+ Component, Parameter, Expected,
+ typename enable_if<
+ is_compatible_component<Expected, Parameter>
+ >::type
+ >
+ {
+ template <typename OutputIterator, typename Context, typename Delimiter>
+ static bool
+ call(Component const& component, OutputIterator& sink,
+ Context& ctx, Delimiter const& delim, Parameter const& param)
+ {
+ typedef
+ is_compatible_component<Expected, Parameter>
+ component_type;
 
             typedef typename
- fusion::result_of::value_at<elements, index>::type
- child_component_type;
+ mpl::distance<
+ typename component_type::begin,
+ typename component_type::iter
+ >::type
+ distance_type;
 
- typedef typename child_component_type::director director;
- return director::generate(
- fusion::at<index>(component.elements),
- sink, ctx, delim, actual_attribute);
+ // make sure, the content of the passed variant matches our
+ // expectations
+ if (param.which() != distance_type::value)
+ return false;
+
+ // returns true if any of the generators succeed
+ typedef
+ typename mpl::deref<
+ typename component_type::iter
+ >::type
+ compatible_type;
+
+ typedef typename Component::director director;
+ return director::generate(component, sink, ctx, delim,
+ get<compatible_type>(param));
         }
+ };
 
- template <typename Attribute>
- bool call(Attribute const& actual_attribute, mpl::false_) const
+ ///////////////////////////////////////////////////////////////////////////
+ // alternative_generate_functor: a functor supplied to spirit::any which
+ // will be executed for every generator in a given alternative generator
+ // expression
+ ///////////////////////////////////////////////////////////////////////////
+ template <typename OutputIterator, typename Context, typename Delimiter,
+ typename Parameter>
+ struct alternative_generate_functor
+ {
+ alternative_generate_functor(OutputIterator& sink_, Context& ctx_,
+ Delimiter const& d, Parameter const& p)
+ : sink(sink_), ctx(ctx_), delim(d), param(p)
         {
- return false;
         }
 
- template <typename Attribute>
- bool operator()(Attribute const& actual_attribute) const
+ template <typename Component>
+ bool operator()(Component const& component)
         {
- typedef mpl::bool_<
- is_compatible<Attribute, Component, Context>::value>
- is_compatible;
+ typedef
+ typename traits::attribute_of<
+ karma::domain, Component, Context>::type
+ expected;
+ typedef
+ alternative_generate<Component, Parameter, expected>
+ generate;
 
- return call(actual_attribute, is_compatible());
+ return generate::call(component, sink, ctx, delim, param);
         }
 
- Component const& component;
         OutputIterator& sink;
         Context& ctx;
         Delimiter const& delim;

Modified: branches/proto/v4/boost/spirit/home/lex/lexer/lexer.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/lex/lexer/lexer.hpp (original)
+++ branches/proto/v4/boost/spirit/home/lex/lexer/lexer.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -43,8 +43,8 @@
             // initialize proto base class
             typedef
                 terminal_holder<lexer_def_ const*, lexer_def_>
- terminal_holder;
- typedef typename proto::terminal<terminal_holder>::type tag;
+ terminal_holder_;
+ typedef typename proto::terminal<terminal_holder_>::type tag;
             typedef proto::extends<tag, lexer_def_> base_type;
 
             typedef typename LexerDef::id_type id_type;

Modified: branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp (original)
+++ branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/iterator_tokenizer.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,9 +6,11 @@
 #if !defined(BOOST_SPIRIT_LEXERTL_ITERATOR_TOKENISER_MARCH_22_2007_0859AM)
 #define BOOST_SPIRIT_LEXERTL_ITERATOR_TOKENISER_MARCH_22_2007_0859AM
 
+#include <boost/detail/iterator.hpp>
 #include <boost/spirit/home/support/detail/lexer/state_machine.hpp>
 #include <boost/spirit/home/support/detail/lexer/consts.hpp>
 #include <boost/spirit/home/support/detail/lexer/size_t.hpp>
+#include <boost/spirit/home/support/detail/lexer/char_traits.hpp>
 #include <vector>
 
 namespace boost { namespace spirit { namespace lex
@@ -124,7 +126,17 @@
                 }
                 else
                 {
- std::size_t const state_ = ptr_[lookup_[*curr_++]];
+ typedef typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ value_type;
+ typedef typename
+ boost::lexer::char_traits<value_type>::index_type
+ index_type;
+
+ index_type index =
+ boost::lexer::char_traits<value_type>::call(*curr_++);
+ std::size_t const state_ = ptr_[
+ lookup_[static_cast<std::size_t>(index)]];
 
                     if (state_ == 0)
                     {
@@ -204,7 +216,17 @@
                 }
                 else
                 {
- std::size_t const state_ = ptr_[lookup_[*curr_++]];
+ typedef typename
+ boost::detail::iterator_traits<Iterator>::value_type
+ value_type;
+ typedef typename
+ boost::lexer::char_traits<value_type>::index_type
+ index_type;
+
+ index_type index =
+ boost::lexer::char_traits<value_type>::call(*curr_++);
+ std::size_t const state_ = ptr_[
+ lookup_[static_cast<std::size_t>(index)]];
 
                     if (state_ == 0)
                     {

Modified: branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_functor.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_functor.hpp (original)
+++ branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_functor.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -89,7 +89,8 @@
           : Data<Iterator, mpl::false_, mpl::false_>
         {
             typedef Data<Iterator, mpl::false_, mpl::false_> base_type;
-
+ typedef std::size_t state_type;
+
             // initialize the shared data
             template <typename IterData>
             Data (IterData const& data_, Iterator& first_, Iterator const& last_)
@@ -354,7 +355,7 @@
         
         // we don't need this, but it must be there
         template <typename MultiPass>
- static void destroy(MultiPass const& mp)
+ static void destroy(MultiPass const&)
         {}
     };
 

Modified: branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_static_functor.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_static_functor.hpp (original)
+++ branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_static_functor.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -345,7 +345,7 @@
         
         // we don't need this, but it must be there
         template <typename MultiPass>
- static void destroy(MultiPass const& mp)
+ static void destroy(MultiPass const&)
         {}
     };
 

Modified: branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp (original)
+++ branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/lexertl_token.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -101,7 +101,7 @@
     struct lexertl_token;
 
     ///////////////////////////////////////////////////////////////////////////
- // This specialization of the toke type doesn't contain any item data and
+ // This specialization of the token type doesn't contain any item data and
     // doesn't support working with lexer states.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Iterator>
@@ -143,7 +143,7 @@
     };
     
     ///////////////////////////////////////////////////////////////////////////
- // This specialization of the toke type doesn't contain any item data but
+ // This specialization of the token type doesn't contain any item data but
     // supports working with lexer states.
     ///////////////////////////////////////////////////////////////////////////
     template <typename Iterator>

Modified: branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp (original)
+++ branches/proto/v4/boost/spirit/home/lex/lexer/lexertl/wrap_action.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -112,6 +112,23 @@
             using phoenix::arg_names::_1;
             return phoenix::bind(pf, f, _1);
         }
+
+ // semantic actions with 0 argument
+ template <typename F>
+ static void arg0_action(F* f, Attribute const&,
+ std::size_t, bool&, Context&)
+ {
+ f();
+ }
+
+ static FunctionType call(void(*f)())
+ {
+ void (*pf)(void(*)(), Attribute const&, std::size_t,
+ bool&, Context&) = &arg0_action;
+
+ using phoenix::arg_names::_1;
+ return phoenix::bind(pf, f, _1);
+ }
     };
 
     // specialization allowing to skip wrapping for lexer types not supporting

Modified: branches/proto/v4/boost/spirit/home/phoenix/operator/io.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/phoenix/operator/io.hpp (original)
+++ branches/proto/v4/boost/spirit/home/phoenix/operator/io.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -20,14 +20,14 @@
     inline typename detail::enable_if_ostream<T0, T1>::type
     operator<<(T0& a0, actor<T1> const& a1)
     {
- return compose<shift_left_eval>(ref(a0), a1);
+ return compose<shift_left_eval>(phoenix::ref(a0), a1);
     }
 
     template <typename T0, typename T1>
     inline typename detail::enable_if_istream<T0, T1>::type
     operator>>(T0& a0, actor<T1> const& a1)
     {
- return compose<shift_right_eval>(ref(a0), a1);
+ return compose<shift_right_eval>(phoenix::ref(a0), a1);
     }
 
 ///////////////////////////////////////////////////////////////////////////////

Modified: branches/proto/v4/boost/spirit/home/phoenix/statement/detail/switch.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/phoenix/statement/detail/switch.hpp (original)
+++ branches/proto/v4/boost/spirit/home/phoenix/statement/detail/switch.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -107,11 +107,11 @@
                         typename fusion::result_of::begin<Cases>::type
>::type
>
- is_default_case;
+ is_default_case_;
 
             typedef typename
                 mpl::eval_if<
- is_default_case
+ is_default_case_
                   , mpl::identity<Cases>
                   , fusion::result_of::push_front<
                         Cases const, actor<default_case<actor<null_actor> > > >
@@ -135,7 +135,7 @@
             static type
             eval(Cases const& cases)
             {
- return eval(cases, is_default_case());
+ return eval(cases, is_default_case_());
             }
         };
 
@@ -143,12 +143,12 @@
         struct switch_composite
         {
             BOOST_STATIC_ASSERT(fusion::traits::is_sequence<Cases>::value);
- typedef ensure_default<Cases> ensure_default;
+ typedef ensure_default<Cases> ensure_default_;
 
             typedef typename
                 fusion::result_of::as_vector<
                     typename fusion::result_of::push_front<
- typename ensure_default::type, Cond>::type
+ typename ensure_default_::type, Cond>::type
>::type
             tuple_type;
 
@@ -162,7 +162,7 @@
             eval(Cond const& cond, Cases const& cases)
             {
                 return fusion::as_vector(
- fusion::push_front(ensure_default::eval(cases), cond));
+ fusion::push_front(ensure_default_::eval(cases), cond));
             }
         };
 

Modified: branches/proto/v4/boost/spirit/home/qi/auxiliary/primitives.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/auxiliary/primitives.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/auxiliary/primitives.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -32,10 +32,10 @@
           , typename Iterator, typename Context
           , typename Skipper, typename Attribute>
         static bool parse(
- Component const& component
+ Component const& /*component*/
           , Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr)
+ , Context& /*context*/, Skipper const& skipper
+ , Attribute& /*attr*/)
         {
             qi::skip(first, last, skipper);
             return Parser::test(first, last);
@@ -66,10 +66,10 @@
           , typename Iterator, typename Context
           , typename Skipper, typename Attribute>
         static bool parse(
- Component const& component
+ Component const& /*component*/
           , Iterator& first, Iterator const& last
- , Context& context, Skipper const& skipper
- , Attribute& attr)
+ , Context& /*context*/, Skipper const& skipper
+ , Attribute& /*attr*/)
         {
             qi::skip(first, last, skipper);
 

Modified: branches/proto/v4/boost/spirit/home/qi/char/char.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/char/char.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/char/char.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -8,6 +8,7 @@
 #define BOOST_SPIRIT_CHAR_APR_16_2006_1051AM
 
 #include <boost/spirit/home/qi/char/char_parser.hpp>
+#include <boost/spirit/home/qi/char/detail/get_char.hpp>
 #include <boost/spirit/home/qi/domain.hpp>
 #include <boost/fusion/include/at.hpp>
 #include <boost/fusion/include/value_at.hpp>
@@ -53,22 +54,10 @@
             typedef unused_type type; // literal parsers have no attribute
         };
 
- template <typename CharParam>
- static CharParam get_char(CharParam ch)
- {
- return ch;
- }
-
- template <typename CharParam>
- static CharParam get_char(CharParam const* str)
- {
- return *str;
- }
-
         template <typename Component, typename CharParam, typename Context>
         static bool test(Component const& component, CharParam ch, Context&)
         {
- return get_char(fusion::at_c<0>(component.elements)) == ch;
+ return detail::get_char(fusion::at_c<0>(component.elements)) == ch;
         }
 
         template <typename Component>
@@ -76,7 +65,7 @@
         {
             return std::string("'")
                 + spirit::detail::to_narrow_char(
- get_char(fusion::at_c<0>(component.elements)))
+ detail::get_char(fusion::at_c<0>(component.elements)))
                 + '\'';
         }
     };
@@ -203,21 +192,11 @@
             typedef unused_type type; // literal parsers have no attribute
         };
 
- static Char get_char(Char ch)
- {
- return ch;
- }
-
- static Char get_char(Char const* str)
- {
- return *str;
- }
-
         template <typename Component, typename CharParam, typename Context>
         static bool test(Component const& component, CharParam ch, Context&)
         {
- return get_char(fusion::at_c<0>(component.elements)) == ch
- || get_char(fusion::at_c<1>(component.elements)) == ch
+ return detail::get_char(fusion::at_c<0>(component.elements)) == ch
+ || detail::get_char(fusion::at_c<1>(component.elements)) == ch
             ;
         }
 
@@ -227,11 +206,11 @@
             std::string result;
             result += std::string("'")
                 + spirit::detail::to_narrow_char(
- get_char(fusion::at_c<0>(component.elements))) + '\'';
+ detail::get_char(fusion::at_c<0>(component.elements))) + '\'';
             result += " or ";
             result += std::string("'") +
                 spirit::detail::to_narrow_char(
- get_char(fusion::at_c<1>(component.elements))) + '\'';
+ detail::get_char(fusion::at_c<1>(component.elements))) + '\'';
             return result;
         }
     };
@@ -334,22 +313,12 @@
             component<qi::domain, qi::no_case_literal_char<Char>, vector_type>
         type;
 
- static Char get_char(Char ch)
- {
- return ch;
- }
-
- static Char get_char(Char const* str)
- {
- return *str;
- }
-
         static type
         call(Elements const& elements)
         {
             typedef typename Modifier::char_set char_set;
 
- Char ch = get_char(fusion::at_c<0>(elements));
+ Char ch = qi::detail::get_char(fusion::at_c<0>(elements));
             vector_type v(
                 char_set::tolower(ch)
               , char_set::toupper(ch)

Modified: branches/proto/v4/boost/spirit/home/qi/nonterminal/grammar.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/nonterminal/grammar.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/nonterminal/grammar.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -24,7 +24,7 @@
             grammar<Definition>
           , typename Definition::sig_type
           , typename Definition::locals_type
- >
+ >, noncopyable
     {
         typedef typename Definition::sig_type sig_type;
         typedef typename Definition::locals_type locals_type;
@@ -103,24 +103,159 @@
         std::string name_;
     };
 
+ template <
+ typename Iterator
+ , typename T0 = unused_type
+ , typename T1 = unused_type
+ , typename T2 = unused_type
+ >
+ struct grammar_
+ : nonterminal<
+ grammar_<Iterator, T0, T1, T2>
+ , typename qi::rule<Iterator, T0, T1, T2>::sig_type
+ , typename qi::rule<Iterator, T0, T1, T2>::locals_type
+ >, noncopyable
+ {
+ typedef Iterator iterator_type;
+ typedef qi::rule<Iterator, T0, T1, T2> start_type;
+ typedef typename start_type::sig_type sig_type;
+ typedef typename start_type::locals_type locals_type;
+ typedef typename start_type::skipper_type skipper_type;
+ typedef grammar_<Iterator, T0, T1, T2> base_type;
+
+ grammar_(start_type const& start, std::string const& name_ = std::string())
+ : start(start), name_(name_) {}
+
+ std::string name() const
+ {
+ return name_;
+ }
+
+ void name(std::string const& name__)
+ {
+ name_ = name__;
+ }
+
+ std::string name_;
+ start_type const& start;
+
+ private:
+
+ template <typename Iterator_, typename Context, typename Skipper>
+ bool parse(
+ Iterator_& first, Iterator_ const& last
+ , Context& context, Skipper const& skipper) const
+ {
+ return start.parse(first, last, context, skipper);
+ }
+
+ std::string what() const
+ {
+ if (name().empty())
+ {
+ return start.what();
+ }
+ else
+ {
+ return name();
+ }
+ }
+
+ friend struct nonterminal_director;
+ };
+
+
     ///////////////////////////////////////////////////////////////////////////
- // Generator functions helping to construct a proper grammar object
+ // Generator functions helping to construct a proper grammar object
     // instance
     ///////////////////////////////////////////////////////////////////////////
     template <typename Definition>
- inline grammar<Definition>
+ inline grammar<Definition>
     make_parser(Definition const& def)
     {
         return grammar<Definition>(def);
     }
-
+
     template <typename Definition, typename Start>
- inline grammar<Definition>
+ inline grammar<Definition>
     make_parser(Definition const& def, Start const& start)
     {
         return grammar<Definition>(def, start);
     }
-
+
+ ///////////////////////////////////////////////////////////////////////////
+ // The grammar_class template
+ ///////////////////////////////////////////////////////////////////////////
+ template <template <typename, typename> class Def>
+ struct grammar_class {};
+
+ template <typename Iterator, template <typename, typename> class Def>
+ inline bool
+ parse(
+ Iterator& first
+ , Iterator last
+ , grammar_class<Def>& gc)
+ {
+ Def<Iterator, unused_type> def(gc);
+ grammar<Def<Iterator, unused_type> > g(def);
+ return parse(first, last, g);
+ }
+
+ template <typename Iterator
+ , template <typename, typename> class Def, typename Attr>
+ inline bool
+ parse(
+ Iterator& first
+ , Iterator last
+ , grammar_class<Def>& gc
+ , Attr& attr)
+ {
+ Def<Iterator, unused_type> def(gc);
+ grammar<Def<Iterator, unused_type> > g(def);
+ return parse(first, last, g, attr);
+ }
+
+ template <typename Iterator
+ , template <typename, typename> class Def, typename Skipper>
+ inline bool
+ phrase_parse(
+ Iterator& first
+ , Iterator last
+ , grammar_class<Def>& gc
+ , Skipper const& skipper_)
+ {
+ typedef typename
+ result_of::as_component<qi::domain, Skipper>::type
+ skipper_type;
+
+ skipper_type skipper = spirit::as_component(qi::domain(), skipper_);
+
+ Def<Iterator, skipper_type> def(gc);
+ grammar<Def<Iterator, skipper_type> > g(def);
+ return phrase_parse(first, last, g, skipper);
+ }
+
+ template <typename Iterator
+ , template <typename, typename> class Def, typename Attr, typename Skipper>
+ inline bool
+ phrase_parse(
+ Iterator& first
+ , Iterator last
+ , grammar_class<Def>& gc
+ , Attr& attr
+ , Skipper const& skipper_)
+ {
+ typedef typename
+ result_of::as_component<qi::domain, Skipper>::type
+ skipper_type;
+
+ skipper_type skipper = spirit::as_component(qi::domain(), skipper_);
+
+ Def<Iterator, skipper_type> def(gc);
+ grammar<Def<Iterator, skipper_type> > g(def);
+ return phrase_parse(first, last, g, attr, skipper);
+ }
+
 }}}
 
 #endif

Modified: branches/proto/v4/boost/spirit/home/qi/nonterminal/rule.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/nonterminal/rule.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/nonterminal/rule.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -80,10 +80,13 @@
             typedef spirit::traits::is_component<qi::domain, Expr> is_component;
 
             // report invalid expression error as early as possible
- BOOST_MPL_ASSERT_MSG(
- is_component::value,
- xpr_is_not_convertible_to_a_parser, ());
+// BOOST_MPL_ASSERT_MSG(
+// is_component::value,
+// xpr_is_not_convertible_to_a_parser, ());
 
+ // temp workaround for mpl problem
+ BOOST_STATIC_ASSERT(is_component::value);
+
             define(xpr, mpl::false_());
             return *this;
         }
@@ -143,6 +146,9 @@
         template <typename Definition>
         friend struct grammar;
 
+ template <typename Iterator_, typename T0_, typename T1_, typename T2_>
+ friend struct grammar_;
+
         friend struct detail::rule_decorator;
 
         template <typename Expr, typename Auto>
@@ -170,9 +176,9 @@
         {
             // If the following line produces a compilation error stating the
             // 4th parameter is not convertible to the expected type, then you
- // probably trying to use this rule instance with a skipper which
- // is not compatible with the skipper type used while defining the
- // type of this rule instance.
+ // are probably trying to use this rule instance with a skipper
+ // which is not compatible with the skipper type used while
+ // defining the type of this rule instance.
             return ptr->parse(first, last, context, skipper);
         }
 
@@ -214,7 +220,7 @@
             static call(Rule& r, A1 const& a1)
             {
                 typename Rule::pointer_type old (r.ptr);
- r.ptr.reset(new Decorator(r.ptr, a1));
+ r.ptr.reset(new Decorator(r.ptr, a1));
                 return old;
             }
 

Modified: branches/proto/v4/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/numeric/detail/numeric_utils.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -316,6 +316,10 @@
>
     struct extract_int
     {
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
         template <typename Iterator, typename Attribute>
         static bool
         parse_main(
@@ -360,6 +364,9 @@
             }
             return false;
         }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
 
         template <typename Iterator>
         static bool
@@ -401,6 +408,10 @@
     template <typename T, unsigned Radix, typename Accumulator, bool Accumulate>
     struct extract_int<T, Radix, 1, -1, Accumulator, Accumulate>
     {
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
         template <typename Iterator, typename Attribute>
         static bool
         parse_main(
@@ -460,6 +471,9 @@
             first = it;
             return true;
         }
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
 
         template <typename Iterator>
         static bool

Modified: branches/proto/v4/boost/spirit/home/qi/numeric/detail/real_impl.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/numeric/detail/real_impl.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/numeric/detail/real_impl.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -73,6 +73,12 @@
         }
     }
 
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4100) // 'p': unreferenced formal parameter
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
     template <typename T, typename RealPolicies>
     struct real_impl
     {
@@ -209,6 +215,11 @@
             return true;
         }
     };
+
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
+
 }}}}
 
 #endif

Modified: branches/proto/v4/boost/spirit/home/qi/operator/list.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/operator/list.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/operator/list.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -48,7 +48,7 @@
 
             typename container::result_of::value<Attribute>::type val;
             if (ldirector::parse(
- left(component)
+ spirit::left(component)
                   , first, last, context, skipper, val)
                 )
             {
@@ -56,10 +56,10 @@
                 Iterator i = first;
                 while(
                     rdirector::parse(
- right(component)
+ spirit::right(component)
                       , i, last, context, skipper, unused)
                  && ldirector::parse(
- left(component)
+ spirit::left(component)
                       , i, last, context, skipper, val)
                     )
                 {

Modified: branches/proto/v4/boost/spirit/home/qi/skip.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/skip.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/skip.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -26,7 +26,7 @@
     }
 
     template <typename Iterator>
- inline void skip(Iterator& first, Iterator const& last, unused_type)
+ inline void skip(Iterator&, Iterator const&, unused_type)
     {
     }
 }}}

Modified: branches/proto/v4/boost/spirit/home/qi/string/tst_map.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/qi/string/tst_map.hpp (original)
+++ branches/proto/v4/boost/spirit/home/qi/string/tst_map.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -8,7 +8,7 @@
 #define BOOST_SPIRIT_TST_MAP_JUNE_03_2007_1143AM
 
 #include <boost/spirit/home/qi/string/detail/tst.hpp>
-#include <boost/spirit/home/support/detail/unordered_map.hpp>
+#include <boost/unordered_map.hpp>
 #include <boost/pool/object_pool.hpp>
 
 namespace boost { namespace spirit { namespace qi

Modified: branches/proto/v4/boost/spirit/home/support/argument.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/argument.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/argument.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -167,17 +167,50 @@
         }
     };
 
- namespace arg_names
+ struct lexer_state
     {
+ typedef mpl::true_ no_nullary;
 
+ template <typename Env>
+ struct result
+ {
+ typedef typename
+ mpl::at_c<typename Env::args_type, 3>::type::state_type
+ type;
+ };
+
+ template <typename Env>
+ typename result<Env>::type
+ eval(Env const& env) const
+ {
+ return fusion::at_c<3>(env.args()).state;
+ }
+ };
+
+ namespace arg_names
+ {
+ // _0 refers to the whole attribute as generated by the lhs parser
         phoenix::actor<attribute_context> const _0 = attribute_context();
-
+
+ // _1, _2, ... refer to the attributes of the single components the lhs
+ // parser is composed of
         phoenix::actor<argument<0> > const _1 = argument<0>();
         phoenix::actor<argument<1> > const _2 = argument<1>();
         phoenix::actor<argument<2> > const _3 = argument<2>();
 
+ // 'pass' may be used to make a match fail in retrospective
         phoenix::actor<phoenix::argument<2> > const pass = phoenix::argument<2>();
 
+ // 'id' may be used in a lexer semantic action to refer to the token id
+ // of a matched token
+ phoenix::actor<phoenix::argument<1> > const id = phoenix::argument<1>();
+
+ // 'state' may be used in a lexer semantic action to refer to the
+ // current lexer state
+ phoenix::actor<lexer_state> const state = lexer_state();
+
+ // _val refers to the 'return' value of a rule
+ // _r0, _r1, ... refer to the rule arguments
         phoenix::actor<attribute<0> > const _val = attribute<0>();
         phoenix::actor<attribute<0> > const _r0 = attribute<0>();
         phoenix::actor<attribute<1> > const _r1 = attribute<1>();
@@ -187,6 +220,7 @@
         BOOST_PP_REPEAT_FROM_TO(
             3, SPIRIT_ARG_LIMIT, SPIRIT_DECLARE_ARG, _)
 
+ // _a, _b, ... refer to the local variables of a rule
         phoenix::actor<local_var<0> > const _a = local_var<0>();
         phoenix::actor<local_var<1> > const _b = local_var<1>();
         phoenix::actor<local_var<2> > const _c = local_var<2>();

Modified: branches/proto/v4/boost/spirit/home/support/as_variant.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/as_variant.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/as_variant.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -14,6 +14,11 @@
 #include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
 #include <boost/variant/variant_fwd.hpp>
+#include <boost/mpl/fold.hpp>
+#include <boost/mpl/vector.hpp>
+#include <boost/mpl/push_back.hpp>
+#include <boost/mpl/contains.hpp>
+#include <boost/type_traits/is_same.hpp>
 
 namespace boost { namespace spirit { namespace detail
 {
@@ -50,6 +55,22 @@
 #undef BOOST_FUSION_NEXT_CALL_ITERATOR
 #undef BOOST_FUSION_VALUE_OF_ITERATOR
 
+ template <typename Sequence>
+ struct generate_variant
+ {
+ // build a variant generator being able to generate a variant holding
+ // all of the types as given in the typelist
+ typedef typename
+ detail::as_variant<fusion::result_of::size<Sequence>::value>
+ gen;
+
+ // use this generator to create the actual variant
+ typedef typename gen::template apply<
+ typename fusion::result_of::begin<Sequence>::type
+ >::type
+ type;
+ };
+
 }}}
 
 namespace boost { namespace spirit
@@ -57,11 +78,25 @@
     template <typename Sequence>
     struct as_variant
     {
- typedef typename
- detail::as_variant<fusion::result_of::size<Sequence>::value>
- gen;
- typedef typename gen::
- template apply<typename fusion::result_of::begin<Sequence>::type>::type
+ // make sure each of the types occurs only once in the type list
+ typedef typename
+ mpl::fold<
+ Sequence, mpl::vector<>,
+ mpl::if_<
+ mpl::contains<mpl::_1, mpl::_2>,
+ mpl::_1, mpl::push_back<mpl::_1, mpl::_2>
+ >
+ >::type
+ new_sequence;
+
+ // if there is only one type in the list of types we strip off the
+ // variant all together
+ typedef typename
+ mpl::eval_if<
+ mpl::equal_to<mpl::size<new_sequence>, mpl::int_<1> >,
+ mpl::deref<mpl::front<Sequence> >,
+ detail::generate_variant<new_sequence>
+ >::type
         type;
     };
 }}

Modified: branches/proto/v4/boost/spirit/home/support/detail/action_dispatch.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/action_dispatch.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/detail/action_dispatch.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -53,12 +53,19 @@
     template <typename RT, typename A0
       , typename Attribute, typename Context>
     bool action_dispatch(RT(*f)(A0)
- , Attribute& attr, Context& context)
+ , Attribute& attr, Context&)
     {
         f(attr);
         return true;
     }
 
+ template <typename RT, typename Attribute, typename Context>
+ bool action_dispatch(RT(*f)()
+ , Attribute&, Context&)
+ {
+ f();
+ return true;
+ }
 }}}
 
 #endif

Modified: branches/proto/v4/boost/spirit/home/support/detail/hold_any.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/hold_any.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/detail/hold_any.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -27,6 +27,13 @@
 #include <iosfwd>
 
 ///////////////////////////////////////////////////////////////////////////////
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(push)
+# pragma warning(disable: 4100) // 'x': unreferenced formal parameter
+# pragma warning(disable: 4127) // conditional expression is constant
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
 namespace boost { namespace spirit
 {
     struct bad_any_cast
@@ -407,6 +414,12 @@
         return any_cast<nonref const&>(const_cast<hold_any &>(operand));
     }
 
-}}
+///////////////////////////////////////////////////////////////////////////////
+}} // namespace boost::spirit
+
+///////////////////////////////////////////////////////////////////////////////
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+# pragma warning(pop)
+#endif
 
 #endif

Modified: branches/proto/v4/boost/spirit/home/support/detail/lexer/char_traits.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/lexer/char_traits.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/detail/lexer/char_traits.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,23 +13,39 @@
 {
 namespace lexer
 {
-template<typename CharT>
-struct char_traits
-{
- typedef CharT index_type;
-};
+ template<typename CharT>
+ struct char_traits
+ {
+ typedef CharT index_type;
 
-template<>
-struct char_traits<char>
-{
- typedef unsigned char index_type;
-};
+ static index_type call(CharT ch)
+ {
+ return ch;
+ }
+ };
+
+ template<>
+ struct char_traits<char>
+ {
+ typedef unsigned char index_type;
+
+ static index_type call(char ch)
+ {
+ return static_cast<index_type>(ch);
+ }
+ };
+
+ template<>
+ struct char_traits<wchar_t>
+ {
+ typedef wchar_t index_type;
+
+ static index_type call(wchar_t ch)
+ {
+ return ch;
+ }
+ };
 
-template<>
-struct char_traits<wchar_t>
-{
- typedef wchar_t index_type;
-};
 }
 }
 

Modified: branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/parser.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/parser.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/parser.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -243,7 +243,7 @@
         node_ptr_vector &node_ptr_vector_, tree_node_stack &tree_node_stack_)
     {
         assert (handle_.top ()._type == token::SUB &&
- handle_.size () == 1 || handle_.size () == 2);
+ (handle_.size () == 1 || handle_.size () == 2));
 
         if (handle_.size () == 1)
         {
@@ -262,7 +262,7 @@
     static void repeat (token_stack &handle_, token_stack &token_stack_)
     {
         assert (handle_.top ()._type == token::REPEAT &&
- handle_.size () >= 1 && handle_.size () <= 3);
+ (handle_.size () >= 1 && handle_.size () <= 3));
 
         if (handle_.size () == 1)
         {

Modified: branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/tokeniser/num_token.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/tokeniser/num_token.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/tokeniser/num_token.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,6 +6,9 @@
 #ifndef BOOST_LEXER_NUM_TOKEN_HPP
 #define BOOST_LEXER_NUM_TOKEN_HPP
 
+#include <boost/config.hpp>
+#include <boost/detail/workaround.hpp>
+
 #include "../../consts.hpp" // null_token
 #include "../../size_t.hpp"
 
@@ -122,9 +125,18 @@
 
 template<typename CharT>
 const char *basic_num_token<CharT>::_precedence_strings[END + 1] =
-{"BEGIN", "REGEX", "OREXP", "SEQUENCE", "SUB", "EXPRESSION", "REPEAT",
- "DUPLICATE", "|", "CHARSET", "MACRO", "(", ")", "?", "*", "+",
- "{n[,[m]]}", "END"};
+{
+#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(910))
+ {"BEGIN"}, {"REGEX"}, {"OREXP"}, {"SEQUENCE"}, {"SUB"}, {"EXPRESSION"},
+ {"REPEAT"}, {"DUPLICATE"}, {"|"}, {"CHARSET"}, {"MACRO"},
+ {"("}, {")"}, {"?"}, {"*"}, {"+"}, {"{n[,[m]]}"}, {"END"}
+#else
+ "BEGIN", "REGEX", "OREXP", "SEQUENCE", "SUB", "EXPRESSION",
+ "REPEAT", "DUPLICATE", "|", "CHARSET", "MACRO",
+ "(", ")", "?", "*", "+", "{n[,[m]]}", "END"
+#endif
+};
+
 }
 }
 }

Modified: branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/detail/lexer/parser/tokeniser/re_tokeniser.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -391,8 +391,8 @@
                 throw runtime_error ("Unexpected end of regex "
                     "(missing '}').");
             }
- } while (ch_ == '_' || ch_ == '-' || ch_ >= 'A' && ch_ <= 'Z' ||
- ch_ >= 'a' && ch_ <= 'z' || ch_ >= '0' && ch_ <= '9');
+ } while (ch_ == '_' || ch_ == '-' || (ch_ >= 'A' && ch_ <= 'Z') ||
+ (ch_ >= 'a' && ch_ <= 'z') || (ch_ >= '0' && ch_ <= '9'));
 
         if (ch_ != '}')
         {

Modified: branches/proto/v4/boost/spirit/home/support/detail/lexer/string_token.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/lexer/string_token.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/detail/lexer/string_token.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -135,7 +135,7 @@
 
     void intersect (basic_string_token &rhs_, basic_string_token &overlap_)
     {
- if (any () && rhs_.any () || (_negated == rhs_._negated &&
+ if ((any () && rhs_.any ()) || (_negated == rhs_._negated &&
             !any () && !rhs_.any ()))
         {
             intersect_same_types (rhs_, overlap_);

Deleted: branches/proto/v4/boost/spirit/home/support/detail/unordered_map.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/unordered_map.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
+++ (empty file)
@@ -1,660 +0,0 @@
-
-// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
-// Copyright (C) 2005-2006 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_UNORDERED_MAP_HPP_INCLUDED
-#define BOOST_UNORDERED_MAP_HPP_INCLUDED
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <boost/config.hpp>
-
-#include <functional>
-#include <memory>
-
-#include <boost/spirit/home/support/detail/unordered/detail/hash_table.hpp>
-#include <boost/functional/hash.hpp>
-
-namespace boost
-{
- template <class Key,
- class T,
- class Hash = hash<Key>,
- class Pred = std::equal_to<Key>,
- class Alloc = std::allocator<std::pair<const Key, T> > >
- class unordered_map
- {
- typedef boost::unordered_detail::hash_types_unique_keys<
- std::pair<const Key, T>, Key, Hash, Pred, Alloc
- > implementation;
-
- typename implementation::hash_table base;
-
- public:
-
- // types
-
- typedef Key key_type;
- typedef std::pair<const Key, T> value_type;
- typedef T mapped_type;
- typedef Hash hasher;
- typedef Pred key_equal;
-
- typedef Alloc allocator_type;
- typedef typename allocator_type::pointer pointer;
- typedef typename allocator_type::const_pointer const_pointer;
- typedef typename allocator_type::reference reference;
- typedef typename allocator_type::const_reference const_reference;
-
- typedef typename implementation::size_type size_type;
- typedef typename implementation::difference_type difference_type;
-
- typedef typename implementation::iterator iterator;
- typedef typename implementation::const_iterator const_iterator;
- typedef typename implementation::local_iterator local_iterator;
- typedef typename implementation::const_local_iterator const_local_iterator;
-
- // construct/destroy/copy
-
- explicit unordered_map(
- size_type n = boost::unordered_detail::default_initial_bucket_count,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(n, hf, eql, a)
- {
- }
-
- template <class InputIterator>
- unordered_map(InputIterator f, InputIterator l)
- : base(f, l, boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), allocator_type())
- {
- }
-
- template <class InputIterator>
- unordered_map(InputIterator f, InputIterator l,
- size_type n,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(f, l, n, hf, eql, a)
- {
- }
-
- private:
-
- typename implementation::iterator_base const&
- get(const_iterator const& it)
- {
- return boost::unordered_detail::iterator_access::get(it);
- }
-
- public:
-
- allocator_type get_allocator() const
- {
- return base.get_allocator();
- }
-
- // size and capacity
-
- bool empty() const
- {
- return base.empty();
- }
-
- size_type size() const
- {
- return base.size();
- }
-
- size_type max_size() const
- {
- return base.max_size();
- }
-
- // iterators
-
- iterator begin()
- {
- return iterator(base.begin());
- }
-
- const_iterator begin() const
- {
- return const_iterator(base.begin());
- }
-
- iterator end()
- {
- return iterator(base.end());
- }
-
- const_iterator end() const
- {
- return const_iterator(base.end());
- }
-
- const_iterator cbegin() const
- {
- return const_iterator(base.begin());
- }
-
- const_iterator cend() const
- {
- return const_iterator(base.end());
- }
-
- // modifiers
-
- std::pair<iterator, bool> insert(const value_type& obj)
- {
- return boost::unordered_detail::pair_cast<iterator, bool>(
- base.insert(obj));
- }
-
- iterator insert(iterator hint, const value_type& obj)
- {
- return iterator(base.insert(get(hint), obj));
- }
-
- const_iterator insert(const_iterator hint, const value_type& obj)
- {
- return const_iterator(base.insert(get(hint), obj));
- }
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- {
- base.insert(first, last);
- }
-
- iterator erase(iterator position)
- {
- return iterator(base.erase(get(position)));
- }
-
- const_iterator erase(const_iterator position)
- {
- return const_iterator(base.erase(get(position)));
- }
-
- size_type erase(const key_type& k)
- {
- return base.erase(k);
- }
-
- iterator erase(iterator first, iterator last)
- {
- return iterator(base.erase(get(first), get(last)));
- }
-
- const_iterator erase(const_iterator first, const_iterator last)
- {
- return const_iterator(base.erase(get(first), get(last)));
- }
-
- void clear()
- {
- base.clear();
- }
-
- void swap(unordered_map& other)
- {
- base.swap(other.base);
- }
-
- // observers
-
- hasher hash_function() const
- {
- return base.hash_function();
- }
-
- key_equal key_eq() const
- {
- return base.key_eq();
- }
-
- mapped_type& operator[](const key_type &k)
- {
- return base[k].second;
- }
-
- // lookup
-
- iterator find(const key_type& k)
- {
- return iterator(base.find(k));
- }
-
- const_iterator find(const key_type& k) const
- {
- return const_iterator(base.find(k));
- }
-
- size_type count(const key_type& k) const
- {
- return base.count(k);
- }
-
- std::pair<iterator, iterator>
- equal_range(const key_type& k)
- {
- return boost::unordered_detail::pair_cast<iterator, iterator>(
- base.equal_range(k));
- }
-
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& k) const
- {
- return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
- base.equal_range(k));
- }
-
- // bucket interface
-
- size_type bucket_count() const
- {
- return base.bucket_count();
- }
-
- size_type max_bucket_count() const
- {
- return base.max_bucket_count();
- }
-
- size_type bucket_size(size_type n) const
- {
- return base.bucket_size(n);
- }
-
- size_type bucket(const key_type& k) const
- {
- return base.bucket(k);
- }
-
- local_iterator begin(size_type n)
- {
- return local_iterator(base.begin(n));
- }
-
- const_local_iterator begin(size_type n) const
- {
- return const_local_iterator(base.begin(n));
- }
-
- local_iterator end(size_type n)
- {
- return local_iterator(base.end(n));
- }
-
- const_local_iterator end(size_type n) const
- {
- return const_local_iterator(base.end(n));
- }
-
-#if defined(BOOST_UNORDERED_LOCAL_CBEGIN)
- const_local_iterator cbegin(size_type n) const
- {
- return const_local_iterator(base.begin(n));
- }
-
- const_local_iterator cend(size_type n) const
- {
- return const_local_iterator(base.end(n));
- }
-#endif
-
- // hash policy
-
- float load_factor() const
- {
- return base.load_factor();
- }
-
- float max_load_factor() const
- {
- return base.max_load_factor();
- }
-
- void max_load_factor(float m)
- {
- base.max_load_factor(m);
- }
-
- void rehash(size_type n)
- {
- base.rehash(n);
- }
- }; // class template unordered_map
-
- template <class K, class T, class H, class P, class A>
- void swap(unordered_map<K, T, H, P, A> &m1,
- unordered_map<K, T, H, P, A> &m2)
- {
- m1.swap(m2);
- }
-
- template <class Key,
- class T,
- class Hash = hash<Key>,
- class Pred = std::equal_to<Key>,
- class Alloc = std::allocator<std::pair<const Key, T> > >
- class unordered_multimap
- {
- typedef boost::unordered_detail::hash_types_equivalent_keys<
- std::pair<const Key, T>, Key, Hash, Pred, Alloc
- > implementation;
-
- typename implementation::hash_table base;
-
- public:
-
- // types
-
- typedef Key key_type;
- typedef std::pair<const Key, T> value_type;
- typedef T mapped_type;
- typedef Hash hasher;
- typedef Pred key_equal;
-
- typedef Alloc allocator_type;
- typedef typename allocator_type::pointer pointer;
- typedef typename allocator_type::const_pointer const_pointer;
- typedef typename allocator_type::reference reference;
- typedef typename allocator_type::const_reference const_reference;
-
- typedef typename implementation::size_type size_type;
- typedef typename implementation::difference_type difference_type;
-
- typedef typename implementation::iterator iterator;
- typedef typename implementation::const_iterator const_iterator;
- typedef typename implementation::local_iterator local_iterator;
- typedef typename implementation::const_local_iterator const_local_iterator;
-
- // construct/destroy/copy
-
- explicit unordered_multimap(
- size_type n = boost::unordered_detail::default_initial_bucket_count,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(n, hf, eql, a)
- {
- }
-
- template <class InputIterator>
- unordered_multimap(InputIterator f, InputIterator l)
- : base(f, l, boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), allocator_type())
- {
- }
-
- template <class InputIterator>
- unordered_multimap(InputIterator f, InputIterator l,
- size_type n,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(f, l, n, hf, eql, a)
- {
- }
-
- private:
-
- typename implementation::iterator_base const&
- get(const_iterator const& it)
- {
- return boost::unordered_detail::iterator_access::get(it);
- }
-
- public:
-
- allocator_type get_allocator() const
- {
- return base.get_allocator();
- }
-
- // size and capacity
-
- bool empty() const
- {
- return base.empty();
- }
-
- size_type size() const
- {
- return base.size();
- }
-
- size_type max_size() const
- {
- return base.max_size();
- }
-
- // iterators
-
- iterator begin()
- {
- return iterator(base.begin());
- }
-
- const_iterator begin() const
- {
- return const_iterator(base.begin());
- }
-
- iterator end()
- {
- return iterator(base.end());
- }
-
- const_iterator end() const
- {
- return const_iterator(base.end());
- }
-
- const_iterator cbegin() const
- {
- return const_iterator(base.begin());
- }
-
- const_iterator cend() const
- {
- return const_iterator(base.end());
- }
-
- // modifiers
-
- iterator insert(const value_type& obj)
- {
- return iterator(base.insert(obj));
- }
-
- iterator insert(iterator hint, const value_type& obj)
- {
- return iterator(base.insert(get(hint), obj));
- }
-
- const_iterator insert(const_iterator hint, const value_type& obj)
- {
- return const_iterator(base.insert(get(hint), obj));
- }
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- {
- base.insert(first, last);
- }
-
- iterator erase(iterator position)
- {
- return iterator(base.erase(get(position)));
- }
-
- const_iterator erase(const_iterator position)
- {
- return const_iterator(base.erase(get(position)));
- }
-
- size_type erase(const key_type& k)
- {
- return base.erase(k);
- }
-
- iterator erase(iterator first, iterator last)
- {
- return iterator(base.erase(get(first), get(last)));
- }
-
- const_iterator erase(const_iterator first, const_iterator last)
- {
- return const_iterator(base.erase(get(first), get(last)));
- }
-
- void clear()
- {
- base.clear();
- }
-
- void swap(unordered_multimap& other)
- {
- base.swap(other.base);
- }
-
- // observers
-
- hasher hash_function() const
- {
- return base.hash_function();
- }
-
- key_equal key_eq() const
- {
- return base.key_eq();
- }
-
- // lookup
-
- iterator find(const key_type& k)
- {
- return iterator(base.find(k));
- }
-
- const_iterator find(const key_type& k) const
- {
- return const_iterator(base.find(k));
- }
-
- size_type count(const key_type& k) const
- {
- return base.count(k);
- }
-
- std::pair<iterator, iterator>
- equal_range(const key_type& k)
- {
- return boost::unordered_detail::pair_cast<iterator, iterator>(
- base.equal_range(k));
- }
-
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& k) const
- {
- return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
- base.equal_range(k));
- }
-
- // bucket interface
-
- size_type bucket_count() const
- {
- return base.bucket_count();
- }
-
- size_type max_bucket_count() const
- {
- return base.max_bucket_count();
- }
-
- size_type bucket_size(size_type n) const
- {
- return base.bucket_size(n);
- }
-
- size_type bucket(const key_type& k) const
- {
- return base.bucket(k);
- }
-
- local_iterator begin(size_type n)
- {
- return local_iterator(base.begin(n));
- }
-
- const_local_iterator begin(size_type n) const
- {
- return const_local_iterator(base.begin(n));
- }
-
- local_iterator end(size_type n)
- {
- return local_iterator(base.end(n));
- }
-
- const_local_iterator end(size_type n) const
- {
- return const_local_iterator(base.end(n));
- }
-
-#if defined(BOOST_UNORDERED_LOCAL_CBEGIN)
- const_local_iterator cbegin(size_type n) const
- {
- return const_local_iterator(base.begin(n));
- }
-
- const_local_iterator cend(size_type n) const
- {
- return const_local_iterator(base.end(n));
- }
-#endif
-
- // hash policy
-
- float load_factor() const
- {
- return base.load_factor();
- }
-
- float max_load_factor() const
- {
- return base.max_load_factor();
- }
-
- void max_load_factor(float m)
- {
- base.max_load_factor(m);
- }
-
- void rehash(size_type n)
- {
- base.rehash(n);
- }
- }; // class template unordered_multimap
-
- template <class K, class T, class H, class P, class A>
- void swap(unordered_multimap<K, T, H, P, A> &m1,
- unordered_multimap<K, T, H, P, A> &m2)
- {
- m1.swap(m2);
- }
-
-} // namespace boost
-
-#endif // BOOST_UNORDERED_MAP_HPP_INCLUDED

Deleted: branches/proto/v4/boost/spirit/home/support/detail/unordered_set.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/detail/unordered_set.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
+++ (empty file)
@@ -1,595 +0,0 @@
-
-// Copyright (C) 2003-2004 Jeremy B. Maitin-Shepard.
-// Copyright (C) 2005-2006 Daniel James.
-// Distributed under the Boost Software License, Version 1.0. (See accompanying
-// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
-
-#ifndef BOOST_UNORDERED_SET_HPP_INCLUDED
-#define BOOST_UNORDERED_SET_HPP_INCLUDED
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-# pragma once
-#endif
-
-#include <boost/config.hpp>
-
-#include <functional>
-#include <memory>
-
-#include <spirit/support/detail/unordered/detail/hash_table.hpp>
-#include <boost/functional/hash.hpp>
-
-namespace boost
-{
- template <class Value,
- class Hash = hash<Value>,
- class Pred = std::equal_to<Value>,
- class Alloc = std::allocator<Value> >
- class unordered_set
- {
- typedef boost::unordered_detail::hash_types_unique_keys<
- Value, Value, Hash, Pred, Alloc
- > implementation;
-
- typename implementation::hash_table base;
-
- public:
-
- // types
-
- typedef Value key_type;
- typedef Value value_type;
- typedef Hash hasher;
- typedef Pred key_equal;
-
- typedef Alloc allocator_type;
- typedef typename allocator_type::pointer pointer;
- typedef typename allocator_type::const_pointer const_pointer;
- typedef typename allocator_type::reference reference;
- typedef typename allocator_type::const_reference const_reference;
-
- typedef typename implementation::size_type size_type;
- typedef typename implementation::difference_type difference_type;
-
- typedef typename implementation::const_iterator iterator;
- typedef typename implementation::const_iterator const_iterator;
- typedef typename implementation::const_local_iterator local_iterator;
- typedef typename implementation::const_local_iterator const_local_iterator;
-
- // construct/destroy/copy
-
- explicit unordered_set(
- size_type n = boost::unordered_detail::default_initial_bucket_count,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(n, hf, eql, a)
- {
- }
-
- template <class InputIterator>
- unordered_set(InputIterator f, InputIterator l)
- : base(f, l, boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), allocator_type())
- {
- }
-
- template <class InputIterator>
- unordered_set(InputIterator f, InputIterator l, size_type n,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(f, l, n, hf, eql, a)
- {
- }
-
- private:
-
- typename implementation::iterator_base const&
- get(const_iterator const& it)
- {
- return boost::unordered_detail::iterator_access::get(it);
- }
-
- public:
-
- allocator_type get_allocator() const
- {
- return base.get_allocator();
- }
-
- // size and capacity
-
- bool empty() const
- {
- return base.empty();
- }
-
- size_type size() const
- {
- return base.size();
- }
-
- size_type max_size() const
- {
- return base.max_size();
- }
-
- // iterators
-
- iterator begin()
- {
- return iterator(base.begin());
- }
-
- const_iterator begin() const
- {
- return const_iterator(base.begin());
- }
-
- iterator end()
- {
- return iterator(base.end());
- }
-
- const_iterator end() const
- {
- return const_iterator(base.end());
- }
-
- const_iterator cbegin() const
- {
- return const_iterator(base.begin());
- }
-
- const_iterator cend() const
- {
- return const_iterator(base.end());
- }
-
- // modifiers
-
- std::pair<iterator, bool> insert(const value_type& obj)
- {
- return boost::unordered_detail::pair_cast<iterator, bool>(
- base.insert(obj));
- }
-
- const_iterator insert(const_iterator hint, const value_type& obj)
- {
- return const_iterator(base.insert(get(hint), obj));
- }
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- {
- base.insert(first, last);
- }
-
- const_iterator erase(const_iterator position)
- {
- return const_iterator(base.erase(get(position)));
- }
-
- size_type erase(const key_type& k)
- {
- return base.erase(k);
- }
-
- const_iterator erase(const_iterator first, const_iterator last)
- {
- return const_iterator(base.erase(get(first), get(last)));
- }
-
- void clear()
- {
- base.clear();
- }
-
- void swap(unordered_set& other)
- {
- base.swap(other.base);
- }
-
- // observers
-
- hasher hash_function() const
- {
- return base.hash_function();
- }
-
- key_equal key_eq() const
- {
- return base.key_eq();
- }
-
- // lookup
-
- const_iterator find(const key_type& k) const
- {
- return const_iterator(base.find(k));
- }
-
- size_type count(const key_type& k) const
- {
- return base.count(k);
- }
-
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& k) const
- {
- return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
- base.equal_range(k));
- }
-
- // bucket interface
-
- size_type bucket_count() const
- {
- return base.bucket_count();
- }
-
- size_type max_bucket_count() const
- {
- return base.max_bucket_count();
- }
-
- size_type bucket_size(size_type n) const
- {
- return base.bucket_size(n);
- }
-
- size_type bucket(const key_type& k) const
- {
- return base.bucket(k);
- }
-
- local_iterator begin(size_type n)
- {
- return local_iterator(base.begin(n));
- }
-
- const_local_iterator begin(size_type n) const
- {
- return const_local_iterator(base.begin(n));
- }
-
- local_iterator end(size_type n)
- {
- return local_iterator(base.end(n));
- }
-
- const_local_iterator end(size_type n) const
- {
- return const_local_iterator(base.end(n));
- }
-
-#if defined(BOOST_UNORDERED_LOCAL_CBEGIN)
- const_local_iterator cbegin(size_type n) const
- {
- return const_local_iterator(base.begin(n));
- }
-
- const_local_iterator cend(size_type n) const
- {
- return const_local_iterator(base.end(n));
- }
-#endif
-
- // hash policy
-
- float load_factor() const
- {
- return base.load_factor();
- }
-
- float max_load_factor() const
- {
- return base.max_load_factor();
- }
-
- void max_load_factor(float m)
- {
- base.max_load_factor(m);
- }
-
- void rehash(size_type n)
- {
- base.rehash(n);
- }
- }; // class template unordered_set
-
- template <class T, class H, class P, class A>
- void swap(unordered_set<T, H, P, A> &m1,
- unordered_set<T, H, P, A> &m2)
- {
- m1.swap(m2);
- }
-
- template <class Value,
- class Hash = hash<Value>,
- class Pred = std::equal_to<Value>,
- class Alloc = std::allocator<Value> >
- class unordered_multiset
- {
- typedef boost::unordered_detail::hash_types_equivalent_keys<
- Value, Value, Hash, Pred, Alloc
- > implementation;
-
- typename implementation::hash_table base;
-
- public:
-
- //types
-
- typedef Value key_type;
- typedef Value value_type;
- typedef Hash hasher;
- typedef Pred key_equal;
-
- typedef Alloc allocator_type;
- typedef typename allocator_type::pointer pointer;
- typedef typename allocator_type::const_pointer const_pointer;
- typedef typename allocator_type::reference reference;
- typedef typename allocator_type::const_reference const_reference;
-
- typedef typename implementation::size_type size_type;
- typedef typename implementation::difference_type difference_type;
-
- typedef typename implementation::const_iterator iterator;
- typedef typename implementation::const_iterator const_iterator;
- typedef typename implementation::const_local_iterator local_iterator;
- typedef typename implementation::const_local_iterator const_local_iterator;
-
- // construct/destroy/copy
-
- explicit unordered_multiset(
- size_type n = boost::unordered_detail::default_initial_bucket_count,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(n, hf, eql, a)
- {
- }
-
- template <class InputIterator>
- unordered_multiset(InputIterator f, InputIterator l)
- : base(f, l, boost::unordered_detail::default_initial_bucket_count,
- hasher(), key_equal(), allocator_type())
- {
- }
-
- template <class InputIterator>
- unordered_multiset(InputIterator f, InputIterator l, size_type n,
- const hasher &hf = hasher(),
- const key_equal &eql = key_equal(),
- const allocator_type &a = allocator_type())
- : base(f, l, n, hf, eql, a)
- {
- }
-
- private:
-
- typename implementation::iterator_base const&
- get(const_iterator const& it)
- {
- return boost::unordered_detail::iterator_access::get(it);
- }
-
- public:
-
- allocator_type get_allocator() const
- {
- return base.get_allocator();
- }
-
- // size and capacity
-
- bool empty() const
- {
- return base.empty();
- }
-
- size_type size() const
- {
- return base.size();
- }
-
- size_type max_size() const
- {
- return base.max_size();
- }
-
- // iterators
-
- iterator begin()
- {
- return iterator(base.begin());
- }
-
- const_iterator begin() const
- {
- return const_iterator(base.begin());
- }
-
- iterator end()
- {
- return iterator(base.end());
- }
-
- const_iterator end() const
- {
- return const_iterator(base.end());
- }
-
- const_iterator cbegin() const
- {
- return const_iterator(base.begin());
- }
-
- const_iterator cend() const
- {
- return const_iterator(base.end());
- }
-
- // modifiers
-
- iterator insert(const value_type& obj)
- {
- return iterator(base.insert(obj));
- }
-
- const_iterator insert(const_iterator hint, const value_type& obj)
- {
- return const_iterator(base.insert(get(hint), obj));
- }
-
- template <class InputIterator>
- void insert(InputIterator first, InputIterator last)
- {
- base.insert(first, last);
- }
-
- const_iterator erase(const_iterator position)
- {
- return const_iterator(base.erase(get(position)));
- }
-
- size_type erase(const key_type& k)
- {
- return base.erase(k);
- }
-
- const_iterator erase(const_iterator first, const_iterator last)
- {
- return const_iterator(base.erase(get(first), get(last)));
- }
-
- void clear()
- {
- base.clear();
- }
-
- void swap(unordered_multiset& other)
- {
- base.swap(other.base);
- }
-
- // observers
-
- hasher hash_function() const
- {
- return base.hash_function();
- }
-
- key_equal key_eq() const
- {
- return base.key_eq();
- }
-
- // lookup
-
- const_iterator find(const key_type& k) const
- {
- return const_iterator(base.find(k));
- }
-
- size_type count(const key_type& k) const
- {
- return base.count(k);
- }
-
- std::pair<const_iterator, const_iterator>
- equal_range(const key_type& k) const
- {
- return boost::unordered_detail::pair_cast<const_iterator, const_iterator>(
- base.equal_range(k));
- }
-
- // bucket interface
-
- size_type bucket_count() const
- {
- return base.bucket_count();
- }
-
- size_type max_bucket_count() const
- {
- return base.max_bucket_count();
- }
-
- size_type bucket_size(size_type n) const
- {
- return base.bucket_size(n);
- }
-
- size_type bucket(const key_type& k) const
- {
- return base.bucket(k);
- }
-
- local_iterator begin(size_type n)
- {
- return local_iterator(base.begin(n));
- }
-
- const_local_iterator begin(size_type n) const
- {
- return const_local_iterator(base.begin(n));
- }
-
- local_iterator end(size_type n)
- {
- return local_iterator(base.end(n));
- }
-
- const_local_iterator end(size_type n) const
- {
- return const_local_iterator(base.end(n));
- }
-
-#if defined(BOOST_UNORDERED_LOCAL_CBEGIN)
- const_local_iterator cbegin(size_type n) const
- {
- return const_local_iterator(base.begin(n));
- }
-
- const_local_iterator cend(size_type n) const
- {
- return const_local_iterator(base.end(n));
- }
-#endif
-
- // hash policy
-
- float load_factor() const
- {
- return base.load_factor();
- }
-
- float max_load_factor() const
- {
- return base.max_load_factor();
- }
-
- void max_load_factor(float m)
- {
- base.max_load_factor(m);
- }
-
- void rehash(size_type n)
- {
- base.rehash(n);
- }
- }; // class template unordered_multiset
-
- template <class T, class H, class P, class A>
- void swap(unordered_multiset<T, H, P, A> &m1,
- unordered_multiset<T, H, P, A> &m2)
- {
- m1.swap(m2);
- }
-
-} // namespace boost
-
-#endif // BOOST_UNORDERED_SET_HPP_INCLUDED

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/buf_id_check_policy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -76,7 +76,7 @@
             }
 
             template <typename MultiPass>
- static void destroy(MultiPass& mp)
+ static void destroy(MultiPass&)
             {}
 
         protected:

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/combine_policies.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/combine_policies.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/combine_policies.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -344,7 +344,7 @@
       : Storage
     {
         multi_pass_unique() {}
- multi_pass_unique(T const& /*x*/) {}
+ multi_pass_unique(T const&) {}
 
         template <typename MultiPass>
         static void destroy(MultiPass& mp)

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/first_owner_policy.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/first_owner_policy.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/first_owner_policy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -49,7 +49,7 @@
             // to, so don't swap first_. swap is only called from operator=
 
             template <typename MultiPass>
- static bool is_unique(MultiPass const& mp)
+ static bool is_unique(MultiPass const&)
             {
                 return false; // no way to know, so always return false
             }

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/input_iterator_policy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -77,7 +77,7 @@
 
             // test, whether we reached the end of the underlying stream
             template <typename MultiPass>
- static bool input_at_eof(MultiPass const& mp, value_type const& t)
+ static bool input_at_eof(MultiPass const& mp, value_type const&)
             {
                 return mp.input == T();
             }
@@ -97,7 +97,7 @@
         template <typename T>
         struct shared
         {
- explicit shared(T x) {}
+ explicit shared(T) {}
 
             // no shared data elements
         };

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/lex_input_policy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -33,7 +33,7 @@
 
         protected:
             unique() {}
- explicit unique(T x) {}
+ explicit unique(T) {}
 
         public:
             template <typename MultiPass>
@@ -51,13 +51,13 @@
 
             // test, whether we reached the end of the underlying stream
             template <typename MultiPass>
- static bool input_at_eof(MultiPass const& mp, value_type const& t)
+ static bool input_at_eof(MultiPass const&, value_type const& t)
             {
                 return 0 == t;
             }
 
             template <typename MultiPass>
- static bool input_is_valid(MultiPass const& mp, value_type const& t)
+ static bool input_is_valid(MultiPass const&, value_type const& t)
             {
                 return -1 != t;
             }
@@ -67,7 +67,7 @@
         template <typename T>
         struct shared
         {
- explicit shared(T x) {}
+ explicit shared(T) {}
 
             // no shared data elements
         };

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/multi_pass.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/multi_pass.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/multi_pass.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -58,12 +58,12 @@
         default_input_policy() {}
         
         template <typename Functor>
- default_input_policy(Functor const& x) {}
+ default_input_policy(Functor const&) {}
         
         template <typename MultiPass>
- static void destroy(MultiPass& mp) {}
+ static void destroy(MultiPass&) {}
         
- void swap(default_input_policy& /*x*/) {}
+ void swap(default_input_policy&) {}
         
         template <typename MultiPass, typename TokenType>
         static TokenType& advance_input(MultiPass& mp, TokenType& curtok);
@@ -78,12 +78,12 @@
     struct default_ownership_policy
     {
         template <typename MultiPass>
- static void destroy(MultiPass& mp) {}
+ static void destroy(MultiPass&) {}
 
         void swap(default_ownership_policy&) {}
 
         template <typename MultiPass>
- static void clone(MultiPass& mp) {}
+ static void clone(MultiPass&) {}
 
         template <typename MultiPass>
         static bool release(MultiPass& mp);
@@ -95,7 +95,7 @@
     struct default_storage_policy
     {
         template <typename MultiPass>
- static void destroy(MultiPass& mp) {}
+ static void destroy(MultiPass&) {}
 
         void swap(default_storage_policy&) {}
 
@@ -103,10 +103,10 @@
         static typename MultiPass::reference dereference(MultiPass const& mp);
         
         template <typename MultiPass>
- static void increment(MultiPass& mp) {}
+ static void increment(MultiPass&) {}
         
         template <typename MultiPass>
- static void clear_queue(MultiPass& mp) {}
+ static void clear_queue(MultiPass&) {}
 
         template <typename MultiPass>
         static bool is_eof(MultiPass const& mp);
@@ -121,7 +121,7 @@
     struct default_checking_policy
     {
         template <typename MultiPass>
- static void destroy(MultiPass& mp) {}
+ static void destroy(MultiPass&) {}
 
         void swap(default_checking_policy&) {}
 

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/no_check_policy.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/no_check_policy.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/no_check_policy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -31,7 +31,7 @@
             static void clear_queue(MultiPass&) {}
 
             template <typename MultiPass>
- static void destroy(MultiPass& mp) {}
+ static void destroy(MultiPass&) {}
         };
 
         ///////////////////////////////////////////////////////////////////////

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/ref_counted_policy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -25,7 +25,7 @@
         ///////////////////////////////////////////////////////////////////////
         struct unique // : detail::default_ownership_policy
         {
- void swap(unique& x) {}
+ void swap(unique&) {}
 
             // clone is called when a copy of the iterator is made, so
             // increment the ref-count.
@@ -54,7 +54,7 @@
             }
 
             template <typename MultiPass>
- static void destroy(MultiPass& mp)
+ static void destroy(MultiPass&)
             {}
         };
 

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/split_functor_input_policy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -71,10 +71,10 @@
 
         protected:
             unique() {}
- explicit unique(Functor const& x) {}
+ explicit unique(Functor const&) {}
 
         public:
- void swap(unique& x) {}
+ void swap(unique&) {}
 
             // get the next token
             template <typename MultiPass>

Modified: branches/proto/v4/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp
==============================================================================
--- branches/proto/v4/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp (original)
+++ branches/proto/v4/boost/spirit/home/support/iterators/detail/split_std_deque_policy.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -145,7 +145,7 @@
             }
             
             template <typename MultiPass>
- static void destroy(MultiPass& mp)
+ static void destroy(MultiPass&)
             {}
 
         protected:

Modified: branches/proto/v4/boost/thread/detail/move.hpp
==============================================================================
--- branches/proto/v4/boost/thread/detail/move.hpp (original)
+++ branches/proto/v4/boost/thread/detail/move.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,6 +18,11 @@
                 t(t_)
             {}
 
+ T& operator*() const
+ {
+ return t;
+ }
+
             T* operator->() const
             {
                 return &t;

Modified: branches/proto/v4/boost/thread/locks.hpp
==============================================================================
--- branches/proto/v4/boost/thread/locks.hpp (original)
+++ branches/proto/v4/boost/thread/locks.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -587,6 +587,68 @@
         }
     };
 
+ namespace detail
+ {
+ template<typename Mutex>
+ class try_lock_wrapper:
+ private unique_lock<Mutex>
+ {
+ typedef unique_lock<Mutex> base;
+ public:
+ explicit try_lock_wrapper(Mutex& m):
+ base(m,try_to_lock)
+ {}
+
+ try_lock_wrapper(Mutex& m_,adopt_lock_t):
+ base(m_,adopt_lock)
+ {}
+ try_lock_wrapper(Mutex& m_,defer_lock_t):
+ base(m_,defer_lock)
+ {}
+ try_lock_wrapper(Mutex& m_,try_to_lock_t):
+ base(m_,try_to_lock)
+ {}
+ try_lock_wrapper(detail::thread_move_t<try_lock_wrapper<Mutex> > other):
+ base(detail::thread_move_t<base>(*other))
+ {}
+
+ operator detail::thread_move_t<try_lock_wrapper<Mutex> >()
+ {
+ return move();
+ }
+
+ detail::thread_move_t<try_lock_wrapper<Mutex> > move()
+ {
+ return detail::thread_move_t<try_lock_wrapper<Mutex> >(*this);
+ }
+
+ try_lock_wrapper& operator=(detail::thread_move_t<try_lock_wrapper<Mutex> > other)
+ {
+ try_lock_wrapper temp(other);
+ swap(temp);
+ return *this;
+ }
+
+ void swap(try_lock_wrapper& other)
+ {
+ base::swap(other);
+ }
+ void swap(detail::thread_move_t<try_lock_wrapper<Mutex> > other)
+ {
+ base::swap(*other);
+ }
+
+ using base::lock;
+ using base::try_lock;
+ using base::unlock;
+ using base::owns_lock;
+ using base::operator!;
+ using base::mutex;
+ using base::release;
+ typedef typename base::bool_type bool_type;
+ using base::operator bool_type;
+ };
+ }
 }
 
 #endif

Modified: branches/proto/v4/boost/thread/pthread/mutex.hpp
==============================================================================
--- branches/proto/v4/boost/thread/pthread/mutex.hpp (original)
+++ branches/proto/v4/boost/thread/pthread/mutex.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -69,7 +69,7 @@
         }
 
         typedef unique_lock<mutex> scoped_lock;
- typedef scoped_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
     };
 
     typedef mutex try_mutex;
@@ -187,7 +187,7 @@
 #endif
 
         typedef unique_lock<timed_mutex> scoped_timed_lock;
- typedef scoped_timed_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
     };
 

Modified: branches/proto/v4/boost/thread/pthread/recursive_mutex.hpp
==============================================================================
--- branches/proto/v4/boost/thread/pthread/recursive_mutex.hpp (original)
+++ branches/proto/v4/boost/thread/pthread/recursive_mutex.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -77,7 +77,7 @@
             return !res;
         }
         typedef unique_lock<recursive_mutex> scoped_lock;
- typedef scoped_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
     };
 
     typedef recursive_mutex recursive_try_mutex;
@@ -239,7 +239,7 @@
 #endif
 
         typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
- typedef scoped_timed_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
     };
 

Modified: branches/proto/v4/boost/thread/win32/condition_variable.hpp
==============================================================================
--- branches/proto/v4/boost/thread/win32/condition_variable.hpp (original)
+++ branches/proto/v4/boost/thread/win32/condition_variable.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -156,7 +156,7 @@
             {
                 relocker<lock_type> locker(lock);
                 
- entry_manager entry=get_wait_entry();
+ entry_manager entry(get_wait_entry());
 
                 locker.unlock();
 

Modified: branches/proto/v4/boost/thread/win32/mutex.hpp
==============================================================================
--- branches/proto/v4/boost/thread/win32/mutex.hpp (original)
+++ branches/proto/v4/boost/thread/win32/mutex.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -32,7 +32,7 @@
         }
 
         typedef unique_lock<mutex> scoped_lock;
- typedef scoped_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<mutex> scoped_try_lock;
     };
 
     typedef mutex try_mutex;
@@ -53,7 +53,7 @@
         }
 
         typedef unique_lock<timed_mutex> scoped_timed_lock;
- typedef scoped_timed_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
     };
 }

Modified: branches/proto/v4/boost/thread/win32/recursive_mutex.hpp
==============================================================================
--- branches/proto/v4/boost/thread/win32/recursive_mutex.hpp (original)
+++ branches/proto/v4/boost/thread/win32/recursive_mutex.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -32,7 +32,7 @@
         }
 
         typedef unique_lock<recursive_mutex> scoped_lock;
- typedef scoped_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock;
     };
 
     typedef recursive_mutex recursive_try_mutex;
@@ -52,7 +52,7 @@
         }
 
         typedef unique_lock<recursive_timed_mutex> scoped_timed_lock;
- typedef scoped_timed_lock scoped_try_lock;
+ typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock;
         typedef scoped_timed_lock scoped_lock;
     };
 }

Modified: branches/proto/v4/boost/throw_exception.hpp
==============================================================================
--- branches/proto/v4/boost/throw_exception.hpp (original)
+++ branches/proto/v4/boost/throw_exception.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -23,6 +23,11 @@
 
 #ifdef BOOST_NO_EXCEPTIONS
 # include <exception>
+#else
+# ifndef BOOST_EXCEPTION_DISABLE
+# include <boost/exception/enable_current_exception.hpp>
+# include <boost/exception/enable_error_info.hpp>
+# endif
 #endif
 
 namespace boost
@@ -36,7 +41,11 @@
 
 template<class E> inline void throw_exception(E const & e)
 {
+#ifndef BOOST_EXCEPTION_DISABLE
+ throw enable_current_exception(enable_error_info(e));
+#else
     throw e;
+#endif
 }
 
 #endif

Modified: branches/proto/v4/boost/type_traits/type_with_alignment.hpp
==============================================================================
--- branches/proto/v4/boost/type_traits/type_with_alignment.hpp (original)
+++ branches/proto/v4/boost/type_traits/type_with_alignment.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -242,7 +242,7 @@
 BOOST_TT_AUX_BOOL_TRAIT_IMPL_SPEC1(is_pod,::boost::align::a32,true)
 }
 #endif
-#if defined(BOOST_MSVC) || (defined(BOOST_INTEL) && defined(_MSC_VER))
+#if (defined(BOOST_MSVC) || (defined(BOOST_INTEL) && defined(_MSC_VER))) && _MSC_VER >= 1300
 //
 // MSVC supports types which have alignments greater than the normal
 // maximum: these are used for example in the types __m64 and __m128

Modified: branches/proto/v4/boost/unordered/detail/hash_table.hpp
==============================================================================
--- branches/proto/v4/boost/unordered/detail/hash_table.hpp (original)
+++ branches/proto/v4/boost/unordered/detail/hash_table.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -32,6 +32,13 @@
 
 #include <boost/mpl/aux_/config/eti.hpp>
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+#include <boost/type_traits/remove_reference.hpp>
+#include <boost/type_traits/remove_const.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <boost/mpl/not.hpp>
+#endif
+
 #if BOOST_WORKAROUND(__BORLANDC__, <= 0x0582)
 #define BOOST_UNORDERED_BORLAND_BOOL(x) (bool)(x)
 #else

Modified: branches/proto/v4/boost/unordered/detail/hash_table_impl.hpp
==============================================================================
--- branches/proto/v4/boost/unordered/detail/hash_table_impl.hpp (original)
+++ branches/proto/v4/boost/unordered/detail/hash_table_impl.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -108,15 +108,114 @@
             struct node : node_base
             {
             public:
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template <typename... Args>
+ node(Args&&... args)
+ : node_base(), value_(std::forward<Args>(args)...) {}
+#else
                 node(value_type const& v) : node_base(), value_(v) {}
+#endif
 
                 value_type value_;
             };
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+
+ // allocators
+ //
+ // Stores all the allocators that we're going to need.
+
+ struct allocators
+ {
+ node_allocator node_alloc_;
+ bucket_allocator bucket_alloc_;
+
+ allocators(value_allocator const& a)
+ : node_alloc_(a), bucket_alloc_(a)
+ {}
+
+ void destroy(link_ptr ptr)
+ {
+ node_ptr n(node_alloc_.address(*static_cast<node*>(&*ptr)));
+ node_alloc_.destroy(n);
+ node_alloc_.deallocate(n, 1);
+ }
+
+ void swap(allocators& x)
+ {
+ unordered_detail::hash_swap(node_alloc_, x.node_alloc_);
+ unordered_detail::hash_swap(bucket_alloc_, x.bucket_alloc_);
+ }
+
+ bool operator==(allocators const& x)
+ {
+ return node_alloc_ == x.node_alloc_;
+ }
+ };
+
             // node_constructor
             //
             // Used to construct nodes in an exception safe manner.
 
+ class node_constructor
+ {
+ allocators& allocators_;
+
+ node_ptr node_;
+ bool node_constructed_;
+
+ public:
+
+ node_constructor(allocators& a)
+ : allocators_(a),
+ node_(), node_constructed_(false)
+ {
+ }
+
+ ~node_constructor()
+ {
+ if (node_) {
+ if (node_constructed_)
+ allocators_.node_alloc_.destroy(node_);
+ allocators_.node_alloc_.deallocate(node_, 1);
+ }
+ }
+
+ template <typename... Args>
+ void construct(Args&&... args)
+ {
+ BOOST_ASSERT(!node_);
+ node_constructed_ = false;
+
+ node_ = allocators_.node_alloc_.allocate(1);
+ allocators_.node_alloc_.construct(node_, std::forward<Args>(args)...);
+ node_constructed_ = true;
+ }
+
+ node_ptr get() const
+ {
+ BOOST_ASSERT(node_);
+ return node_;
+ }
+
+ // no throw
+ link_ptr release()
+ {
+ node_ptr p = node_;
+ unordered_detail::reset(node_);
+ return link_ptr(allocators_.bucket_alloc_.address(*p));
+ }
+
+ private:
+ node_constructor(node_constructor const&);
+ node_constructor& operator=(node_constructor const&);
+ };
+#else
+
+ // allocators
+ //
+ // Stores all the allocators that we're going to need.
+
             struct allocators
             {
                 node_allocator node_alloc_;
@@ -151,6 +250,10 @@
                 }
             };
 
+ // node_constructor
+ //
+ // Used to construct nodes in an exception safe manner.
+
             class node_constructor
             {
                 allocators& allocators_;
@@ -201,6 +304,27 @@
                     value_constructed_ = true;
                 }
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template <typename... Args>
+ void construct(Args&&... args)
+ {
+ BOOST_ASSERT(!node_);
+ value_constructed_ = false;
+ node_base_constructed_ = false;
+
+ node_ = allocators_.node_alloc_.allocate(1);
+
+ allocators_.node_base_alloc_.construct(
+ allocators_.node_base_alloc_.address(*node_),
+ node_base());
+ node_base_constructed_ = true;
+
+ allocators_.value_alloc_.construct(
+ allocators_.value_alloc_.address(node_->value_), std::forward<Args>(args)...);
+ value_constructed_ = true;
+ }
+#endif
+
                 node_ptr get() const
                 {
                     BOOST_ASSERT(node_);
@@ -219,6 +343,7 @@
                 node_constructor(node_constructor const&);
                 node_constructor& operator=(node_constructor const&);
             };
+#endif
 
             // Methods for navigating groups of elements with equal keys.
 
@@ -1003,11 +1128,13 @@
         private:
 
 
- typedef boost::unordered_detail::buffered_functions<Hash, Pred> buffered_functions;
- typedef BOOST_DEDUCED_TYPENAME buffered_functions::functions functions;
- typedef BOOST_DEDUCED_TYPENAME buffered_functions::functions_ptr functions_ptr;
+ typedef boost::unordered_detail::buffered_functions<Hash, Pred>
+ function_store;
+ typedef BOOST_DEDUCED_TYPENAME function_store::functions functions;
+ typedef BOOST_DEDUCED_TYPENAME function_store::functions_ptr
+ functions_ptr;
 
- buffered_functions functions_;
+ function_store functions_;
             float mlf_;
             size_type max_load_;
 
@@ -1251,10 +1378,17 @@
             // accessors
 
             // no throw
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ node_allocator get_allocator() const
+ {
+ return data_.allocators_.node_alloc_;
+ }
+#else
             value_allocator get_allocator() const
             {
                 return data_.allocators_.value_alloc_;
             }
+#endif
 
             // no throw
             hasher const& hash_function() const
@@ -1356,26 +1490,6 @@
                 return need_to_reserve;
             }
 
- // basic exception safety
- //
- // This version of reserve is called when inserting a range
- // into a container with equivalent keys, it creates more buckets
- // if the resulting load factor would be over 80% of the load
- // factor. This is to try to avoid excessive rehashes.
- bool reserve_extra(size_type n)
- {
- using namespace std;
-
- bool need_to_reserve = n >= max_load_;
- // throws - basic:
- if (need_to_reserve) {
- rehash_impl(double_to_size_t(floor(
- n / (double) mlf_ * 1.25)) + 1);
- }
- BOOST_ASSERT(n < max_load_ || n > max_size());
- return need_to_reserve;
- }
-
         public:
 
             // no throw
@@ -1422,6 +1536,41 @@
                 return v.first;
             }
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ struct no_key {};
+
+ template <typename Arg1, typename... Args>
+ static typename boost::enable_if<
+ boost::mpl::and_<
+ boost::mpl::not_<boost::is_same<key_type, value_type> >,
+ boost::is_same<Arg1, key_type>
+ >,
+ key_type>::type const& extract_key(Arg1 const& k, Args const&...)
+ {
+ return k;
+ }
+
+ template <typename First, typename Second>
+ static typename boost::enable_if<
+ boost::mpl::and_<
+ boost::mpl::not_<boost::is_same<key_type, value_type> >,
+ boost::is_same<key_type,
+ typename boost::remove_const<
+ typename boost::remove_reference<First>::type
+ >::type>
+ >,
+ key_type>::type const& extract_key(std::pair<First, Second> const& v)
+ {
+ return v.first;
+ }
+
+ template <typename... Args>
+ static no_key extract_key(Args const&...)
+ {
+ return no_key();
+ }
+#endif
+
         public:
 
             // if hash function throws, basic exception safety
@@ -1526,16 +1675,70 @@
             // strong otherwise
             iterator_base insert(value_type const& v)
             {
- key_type const& k = extract_key(v);
- size_type hash_value = hash_function()(k);
- bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);
- link_ptr position = find_iterator(bucket, k);
+ // Create the node before rehashing in case it throws an
+ // exception (need strong safety in such a case).
+ node_constructor a(data_.allocators_);
+ a.construct(v);
+
+ return insert_impl(a);
+ }
+
+ // Insert (equivalent key containers)
 
+ // if hash function throws, basic exception safety
+ // strong otherwise
+ iterator_base insert_hint(iterator_base const& it, value_type const& v)
+ {
                 // Create the node before rehashing in case it throws an
                 // exception (need strong safety in such a case).
                 node_constructor a(data_.allocators_);
                 a.construct(v);
 
+ return insert_hint_impl(it, a);
+ }
+
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ // Insert (equivalent key containers)
+ // (I'm using an overloaded insert for both 'insert' and 'emplace')
+
+ // if hash function throws, basic exception safety
+ // strong otherwise
+ template <class... Args>
+ iterator_base insert(Args&&... args)
+ {
+ // Create the node before rehashing in case it throws an
+ // exception (need strong safety in such a case).
+ node_constructor a(data_.allocators_);
+ a.construct(std::forward<Args>(args)...);
+
+ return insert_impl(a);
+ }
+
+ // Insert (equivalent key containers)
+ // (I'm using an overloaded insert for both 'insert' and 'emplace')
+
+ // if hash function throws, basic exception safety
+ // strong otherwise
+ template <class... Args>
+ iterator_base insert_hint(iterator_base const& it, Args&&... args)
+ {
+ // Create the node before rehashing in case it throws an
+ // exception (need strong safety in such a case).
+ node_constructor a(data_.allocators_);
+ a.construct(std::forward<Args>(args)...);
+
+ return insert_hint_impl(it, a);
+ }
+
+#endif
+
+ iterator_base insert_impl(node_constructor& a)
+ {
+ key_type const& k = extract_key(a.get()->value_);
+ size_type hash_value = hash_function()(k);
+ bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);
+ link_ptr position = find_iterator(bucket, k);
+
                 // reserve has basic exception safety if the hash function
                 // throws, strong otherwise.
                 if(reserve(size() + 1))
@@ -1550,17 +1753,13 @@
                 );
             }
 
- // Insert (equivalent key containers)
-
- // if hash function throws, basic exception safety
- // strong otherwise
- iterator_base insert_hint(iterator_base const& it, value_type const& v)
+ iterator_base insert_hint_impl(iterator_base const& it, node_constructor& a)
             {
                 // equal can throw, but with no effects
- if (it == data_.end() || !equal(extract_key(v), *it)) {
+ if (it == data_.end() || !equal(extract_key(a.get()->value_), *it)) {
                     // Use the standard insert if the iterator doesn't point
                     // to a matching key.
- return insert(v);
+ return insert_impl(a);
                 }
                 else {
                     // Find the first node in the group - so that the node
@@ -1570,15 +1769,10 @@
                     while(data_.prev_in_group(start)->next_ == start)
                         start = data_.prev_in_group(start);
 
- // Create the node before rehashing in case it throws an
- // exception (need strong safety in such a case).
- node_constructor a(data_.allocators_);
- a.construct(v);
-
                     // reserve has basic exception safety if the hash function
                     // throws, strong otherwise.
                     bucket_ptr base = reserve(size() + 1) ?
- get_bucket(extract_key(v)) : it.bucket_;
+ get_bucket(extract_key(a.get()->value_)) : it.bucket_;
 
                     // Nothing after this point can throw
 
@@ -1602,7 +1796,7 @@
                 }
                 else {
                     // Only require basic exception safety here
- reserve_extra(size() + distance);
+ reserve(size() + distance);
                     node_constructor a(data_.allocators_);
 
                     for (; i != j; ++i) {
@@ -1729,6 +1923,104 @@
                     return insert(v).first;
             }
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ // Insert (unique keys)
+ // (I'm using an overloaded insert for both 'insert' and 'emplace')
+ //
+ // TODO:
+ // For sets: create a local key without creating the node?
+ // For maps: use the first argument as the key.
+
+ // if hash function throws, basic exception safety
+ // strong otherwise
+ template<typename... Args>
+ std::pair<iterator_base, bool> insert(Args&&... args)
+ {
+ return insert_impl(
+ extract_key(std::forward<Args>(args)...),
+ std::forward<Args>(args)...);
+ }
+
+ template<typename... Args>
+ std::pair<iterator_base, bool> insert_impl(key_type const& k, Args&&... args)
+ {
+ // No side effects in this initial code
+ size_type hash_value = hash_function()(k);
+ bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);
+ link_ptr pos = find_iterator(bucket, k);
+
+ if (BOOST_UNORDERED_BORLAND_BOOL(pos)) {
+ // Found an existing key, return it (no throw).
+ return std::pair<iterator_base, bool>(
+ iterator_base(bucket, pos), false);
+
+ } else {
+ // Doesn't already exist, add to bucket.
+ // Side effects only in this block.
+
+ // Create the node before rehashing in case it throws an
+ // exception (need strong safety in such a case).
+ node_constructor a(data_.allocators_);
+ a.construct(std::forward<Args>(args)...);
+
+ // reserve has basic exception safety if the hash function
+ // throws, strong otherwise.
+ if(reserve(size() + 1))
+ bucket = data_.bucket_ptr_from_hash(hash_value);
+
+ // Nothing after this point can throw.
+
+ link_ptr n = data_.link_node_in_bucket(a, bucket);
+
+ return std::pair<iterator_base, bool>(
+ iterator_base(bucket, n), true);
+ }
+ }
+
+ template<typename... Args>
+ std::pair<iterator_base, bool> insert_impl(no_key, Args&&... args)
+ {
+ // Construct the node regardless - in order to get the key.
+ // It will be discarded if it isn't used
+ node_constructor a(data_.allocators_);
+ a.construct(std::forward<Args>(args)...);
+
+ // No side effects in this initial code
+ key_type const& k = extract_key(a.get()->value_);
+ size_type hash_value = hash_function()(k);
+ bucket_ptr bucket = data_.bucket_ptr_from_hash(hash_value);
+ link_ptr pos = find_iterator(bucket, k);
+
+ if (BOOST_UNORDERED_BORLAND_BOOL(pos)) {
+ // Found an existing key, return it (no throw).
+ return std::pair<iterator_base, bool>(
+ iterator_base(bucket, pos), false);
+ } else {
+ // reserve has basic exception safety if the hash function
+ // throws, strong otherwise.
+ if(reserve(size() + 1))
+ bucket = data_.bucket_ptr_from_hash(hash_value);
+
+ // Nothing after this point can throw.
+
+ return std::pair<iterator_base, bool>(iterator_base(bucket,
+ data_.link_node_in_bucket(a, bucket)), true);
+ }
+ }
+
+ // Insert (unique keys)
+ // (I'm using an overloaded insert for both 'insert' and 'emplace')
+
+ // if hash function throws, basic exception safety
+ // strong otherwise
+ template<typename... Args>
+ iterator_base insert_hint(iterator_base const& it, Args&&... args)
+ {
+ // Life is complicated - just call the normal implementation.
+ return insert(std::forward<Args>(args)...).first;
+ }
+#endif
+
             // Insert from iterators (unique keys)
 
             template <typename I>
@@ -1853,6 +2145,98 @@
                 }
             }
 
+ //
+ // equals
+ //
+
+private:
+#if BOOST_UNORDERED_EQUIVALENT_KEYS
+ static inline bool group_equals(link_ptr it1, link_ptr it2,
+ type_wrapper<key_type>*)
+ {
+ return data::group_count(it1) == data::group_count(it2);
+ }
+
+ static inline bool group_equals(link_ptr it1, link_ptr it2, void*)
+ {
+ link_ptr end1 = data::next_group(it1);
+ link_ptr end2 = data::next_group(it2);
+ do {
+ if(data::get_value(it1).second != data::get_value(it2).second) return false;
+ it1 = it1->next_;
+ it2 = it2->next_;
+ } while(it1 != end1 && it2 != end2);
+ return it1 == end1 && it2 == end2;
+ }
+#else
+ static inline bool group_equals(link_ptr it1, link_ptr it2,
+ type_wrapper<key_type>*)
+ {
+ return true;
+ }
+
+ static inline bool group_equals(link_ptr it1, link_ptr it2, void*)
+ {
+ return data::get_value(it1).second == data::get_value(it2).second;
+ }
+#endif
+
+public:
+ bool equals(BOOST_UNORDERED_TABLE const& other) const
+ {
+ if(size() != other.size()) return false;
+
+ for(bucket_ptr i = data_.cached_begin_bucket_,
+ j = data_.buckets_end(); i != j; ++i)
+ {
+ for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
+ {
+ link_ptr other_pos = other.find_iterator(other.extract_key(data::get_value(it)));
+ if(!BOOST_UNORDERED_BORLAND_BOOL(other_pos) ||
+ !group_equals(it, other_pos, (type_wrapper<value_type>*)0))
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ inline std::size_t group_hash(link_ptr it, type_wrapper<key_type>*) const
+ {
+ std::size_t seed = data::group_count(it);
+ std::size_t hashed_key = hash_function()(data::get_value(it));
+ boost::hash_combine(seed, hashed_key);
+ return seed;
+ }
+
+ inline std::size_t group_hash(link_ptr it, void*) const
+ {
+ std::size_t seed = hash_function()(data::get_value(it).first);
+
+ link_ptr end = data::next_group(it);
+
+ do {
+ boost::hash_combine(seed, data::get_value(it).second);
+ it = it->next_;
+ } while(it != end);
+
+ return seed;
+ }
+
+ std::size_t hash_value() const
+ {
+ std::size_t seed = 0;
+
+ for(bucket_ptr i = data_.cached_begin_bucket_,
+ j = data_.buckets_end(); i != j; ++i)
+ {
+ for(link_ptr it(i->next_); BOOST_UNORDERED_BORLAND_BOOL(it); it = data::next_group(it))
+ seed ^= group_hash(it, (type_wrapper<value_type>*)0);
+ }
+
+ return seed;
+ }
+
         private:
 
             // strong exception safety, no side effects

Modified: branches/proto/v4/boost/unordered_map.hpp
==============================================================================
--- branches/proto/v4/boost/unordered_map.hpp (original)
+++ branches/proto/v4/boost/unordered_map.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,8 +18,8 @@
 #include <functional>
 #include <memory>
 
-#include <boost/unordered/detail/hash_table.hpp>
 #include <boost/functional/hash.hpp>
+#include <boost/unordered/detail/hash_table.hpp>
 
 #if !defined(BOOST_HAS_RVALUE_REFS)
 #include <boost/unordered/detail/move.hpp>
@@ -199,6 +199,21 @@
 
         // modifiers
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template <class... Args>
+ std::pair<iterator, bool> emplace(Args&&... args)
+ {
+ return boost::unordered_detail::pair_cast<iterator, bool>(
+ base.insert(std::forward<Args>(args)...));
+ }
+
+ template <class... Args>
+ iterator emplace(const_iterator hint, Args&&... args)
+ {
+ return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
+ }
+#endif
+
         std::pair<iterator, bool> insert(const value_type& obj)
         {
             return boost::unordered_detail::pair_cast<iterator, bool>(
@@ -372,6 +387,21 @@
         {
             base.rehash(n);
         }
+
+ friend bool operator==(unordered_map const& m1, unordered_map const& m2)
+ {
+ return m1.base.equals(m2.base);
+ }
+
+ friend bool operator!=(unordered_map const& m1, unordered_map const& m2)
+ {
+ return !m1.base.equals(m2.base);
+ }
+
+ friend std::size_t hash_value(unordered_map const& m)
+ {
+ return m.base.hash_value();
+ }
     }; // class template unordered_map
 
     template <class K, class T, class H, class P, class A>
@@ -553,6 +583,20 @@
 
         // modifiers
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ {
+ return iterator(base.insert(std::forward<Args>(args)...));
+ }
+
+ template <class... Args>
+ iterator emplace(const_iterator hint, Args&&... args)
+ {
+ return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
+ }
+#endif
+
         iterator insert(const value_type& obj)
         {
             return iterator(base.insert(obj));
@@ -710,6 +754,21 @@
         {
             base.rehash(n);
         }
+
+ friend bool operator==(unordered_multimap const& m1, unordered_multimap const& m2)
+ {
+ return m1.base.equals(m2.base);
+ }
+
+ friend bool operator!=(unordered_multimap const& m1, unordered_multimap const& m2)
+ {
+ return !m1.base.equals(m2.base);
+ }
+
+ friend std::size_t hash_value(unordered_multimap const& m)
+ {
+ return m.base.hash_value();
+ }
     }; // class template unordered_multimap
 
     template <class K, class T, class H, class P, class A>

Modified: branches/proto/v4/boost/unordered_set.hpp
==============================================================================
--- branches/proto/v4/boost/unordered_set.hpp (original)
+++ branches/proto/v4/boost/unordered_set.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,8 +18,8 @@
 #include <functional>
 #include <memory>
 
-#include <boost/unordered/detail/hash_table.hpp>
 #include <boost/functional/hash.hpp>
+#include <boost/unordered/detail/hash_table.hpp>
 
 #if !defined(BOOST_HAS_RVALUE_REFS)
 #include <boost/unordered/detail/move.hpp>
@@ -196,6 +196,22 @@
 
         // modifiers
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template <class... Args>
+ std::pair<iterator, bool> emplace(Args&&... args)
+ {
+ return boost::unordered_detail::pair_cast<iterator, bool>(
+ base.insert(std::forward<Args>(args)...));
+ }
+
+ template <class... Args>
+ iterator emplace(const_iterator hint, Args&&... args)
+ {
+ return iterator(
+ base.insert_hint(get(hint), std::forward<Args>(args)...));
+ }
+#endif
+
         std::pair<iterator, bool> insert(const value_type& obj)
         {
             return boost::unordered_detail::pair_cast<iterator, bool>(
@@ -342,6 +358,21 @@
         {
             base.rehash(n);
         }
+
+ friend bool operator==(unordered_set const& m1, unordered_set const& m2)
+ {
+ return m1.base.equals(m2.base);
+ }
+
+ friend bool operator!=(unordered_set const& m1, unordered_set const& m2)
+ {
+ return !m1.base.equals(m2.base);
+ }
+
+ friend std::size_t hash_value(unordered_set const& m)
+ {
+ return m.base.hash_value();
+ }
     }; // class template unordered_set
 
     template <class T, class H, class P, class A>
@@ -520,6 +551,20 @@
 
         // modifiers
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template <class... Args>
+ iterator emplace(Args&&... args)
+ {
+ return iterator(base.insert(std::forward<Args>(args)...));
+ }
+
+ template <class... Args>
+ iterator emplace(const_iterator hint, Args&&... args)
+ {
+ return iterator(base.insert_hint(get(hint), std::forward<Args>(args)...));
+ }
+#endif
+
         iterator insert(const value_type& obj)
         {
             return iterator(base.insert(obj));
@@ -665,6 +710,21 @@
         {
             base.rehash(n);
         }
+
+ friend bool operator==(unordered_multiset const& m1, unordered_multiset const& m2)
+ {
+ return m1.base.equals(m2.base);
+ }
+
+ friend bool operator!=(unordered_multiset const& m1, unordered_multiset const& m2)
+ {
+ return !m1.base.equals(m2.base);
+ }
+
+ friend std::size_t hash_value(unordered_multiset const& m)
+ {
+ return m.base.hash_value();
+ }
     }; // class template unordered_multiset
 
     template <class T, class H, class P, class A>

Modified: branches/proto/v4/configure
==============================================================================
--- branches/proto/v4/configure (original)
+++ branches/proto/v4/configure 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -185,7 +185,28 @@
 
 # Determine the toolset, if not already decided
 if test "x$TOOLSET" = x; then
- TOOLSET=`$my_dir/tools/jam/src/build.sh --guess-toolset`
+ guessed_toolset=`$my_dir/tools/jam/src/build.sh --guess-toolset`
+ case $guessed_toolset in
+ acc | darwin | gcc | como | mipspro | pathscale | pgi | qcc | vacpp )
+ TOOLSET=$guessed_toolset
+ ;;
+
+ intel-* )
+ TOOLSET=intel
+ ;;
+
+ mingw )
+ TOOLSET=gcc
+ ;;
+
+ sun* )
+ TOOLSET=sun
+ ;;
+
+ * )
+ # Not supported by Boost.Build
+ ;;
+ esac
 fi
 
 rm -f config.log
@@ -223,15 +244,15 @@
 
 # Setup paths
 if test "x$EPREFIX" = x; then
- EPREFIX=$PREFIX
+ EPREFIX="\$(prefix)"
 fi
 
 if test "x$LIBDIR" = x; then
- LIBDIR="$EPREFIX/lib"
+ LIBDIR="\$(exec_prefix)/lib"
 fi
 
 if test "x$INCLUDEDIR" = x; then
- INCLUDEDIR="$PREFIX/include"
+ INCLUDEDIR="\$(prefix)/include"
 fi
 
 # Find Python
@@ -318,10 +339,10 @@
 cat > Makefile <<EOF
 BJAM=$BJAM
 BJAM_CONFIG=$BJAM_CONFIG
-PREFIX=$PREFIX
-EPREFIX=$EPREFIX
-LIBDIR=$LIBDIR
-INCLUDEDIR=$INCLUDEDIR
+prefix=$PREFIX
+exec_prefix=$EPREFIX
+libdir=$LIBDIR
+includedir=$INCLUDEDIR
 LIBS=$LIBS
 
 all: .dummy
@@ -339,8 +360,8 @@
         @cd status && ../\$(BJAM) \$(BJAM_CONFIG) --user-config=../user-config.jam || echo "Some Boost regression tests failed. This is normal for many compilers."
 
 install: .dummy
- @echo "\$(BJAM) \$(BJAM_CONFIG) --user-config=user-config.jam --prefix=\$(PREFIX) --exec-prefix=\$(EPREFIX) --libdir=\$(LIBDIR) --includedir=\$(INCLUDEDIR) \$(LIBS) install"
- @\$(BJAM) \$(BJAM_CONFIG) --user-config=user-config.jam --prefix=\$(PREFIX) --exec-prefix=\$(EPREFIX) --libdir=\$(LIBDIR) --includedir=\$(INCLUDEDIR) \$(LIBS) install || echo "Not all Boost libraries built properly."
+ @echo "\$(BJAM) \$(BJAM_CONFIG) --user-config=user-config.jam --prefix=\$(prefix) --exec-prefix=\$(exec_prefix) --libdir=\$(libdir) --includedir=\$(includedir) \$(LIBS) install"
+ @\$(BJAM) \$(BJAM_CONFIG) --user-config=user-config.jam --prefix=\$(prefix) --exec-prefix=\$(exec_prefix) --libdir=\$(libdir) --includedir=\$(includedir) \$(LIBS) install || echo "Not all Boost libraries built properly."
 
 .dummy:
 

Modified: branches/proto/v4/libs/asio/test/basic_datagram_socket.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/basic_datagram_socket.cpp (original)
+++ branches/proto/v4/libs/asio/test/basic_datagram_socket.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("basic_datagram_socket");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/basic_deadline_timer.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/basic_deadline_timer.cpp (original)
+++ branches/proto/v4/libs/asio/test/basic_deadline_timer.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("basic_deadline_timer");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/basic_socket_acceptor.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/basic_socket_acceptor.cpp (original)
+++ branches/proto/v4/libs/asio/test/basic_socket_acceptor.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("basic_socket_acceptor");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/basic_stream_socket.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/basic_stream_socket.cpp (original)
+++ branches/proto/v4/libs/asio/test/basic_stream_socket.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("basic_stream_socket");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/buffer.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/buffer.cpp (original)
+++ branches/proto/v4/libs/asio/test/buffer.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -139,7 +139,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("buffer");
   test->add(BOOST_TEST_CASE(&buffer_compile::test));

Modified: branches/proto/v4/libs/asio/test/buffered_read_stream.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/buffered_read_stream.cpp (original)
+++ branches/proto/v4/libs/asio/test/buffered_read_stream.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -209,7 +209,7 @@
   client_socket.async_read_some(boost::asio::buffer(read_buf), handle_read_eof);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("buffered_read_stream");
   test->add(BOOST_TEST_CASE(&test_sync_operations));

Modified: branches/proto/v4/libs/asio/test/buffered_stream.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/buffered_stream.cpp (original)
+++ branches/proto/v4/libs/asio/test/buffered_stream.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -224,7 +224,7 @@
   client_socket.async_read_some(boost::asio::buffer(read_buf), handle_read_eof);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("buffered_stream");
   test->add(BOOST_TEST_CASE(&test_sync_operations));

Modified: branches/proto/v4/libs/asio/test/buffered_write_stream.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/buffered_write_stream.cpp (original)
+++ branches/proto/v4/libs/asio/test/buffered_write_stream.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -224,7 +224,7 @@
   client_socket.async_read_some(boost::asio::buffer(read_buf), handle_read_eof);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("buffered_write_stream");
   test->add(BOOST_TEST_CASE(&test_sync_operations));

Modified: branches/proto/v4/libs/asio/test/completion_condition.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/completion_condition.cpp (original)
+++ branches/proto/v4/libs/asio/test/completion_condition.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("completion_condition");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/datagram_socket_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/datagram_socket_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/datagram_socket_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("datagram_socket_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/deadline_timer.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/deadline_timer.cpp (original)
+++ branches/proto/v4/libs/asio/test/deadline_timer.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -179,7 +179,7 @@
   BOOST_CHECK(expected_end < end || expected_end == end);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("deadline_timer");
   test->add(BOOST_TEST_CASE(&deadline_timer_test));

Modified: branches/proto/v4/libs/asio/test/deadline_timer_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/deadline_timer_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/deadline_timer_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("deadline_timer_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/error.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/error.cpp (original)
+++ branches/proto/v4/libs/asio/test/error.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -82,7 +82,7 @@
   test_error_code(boost::asio::error::would_block);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("error");
   test->add(BOOST_TEST_CASE(&error_test));

Modified: branches/proto/v4/libs/asio/test/io_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/io_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/io_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -234,7 +234,7 @@
   BOOST_CHECK(exception_count == 2);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("io_service");
   test->add(BOOST_TEST_CASE(&io_service_test));

Modified: branches/proto/v4/libs/asio/test/ip/address.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/address.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/address.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/address");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ip/address_v4.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/address_v4.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/address_v4.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -124,7 +124,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/address_v4");
   test->add(BOOST_TEST_CASE(&ip_address_v4_compile::test));

Modified: branches/proto/v4/libs/asio/test/ip/address_v6.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/address_v6.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/address_v6.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -145,7 +145,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/address_v6");
   test->add(BOOST_TEST_CASE(&ip_address_v6_compile::test));

Modified: branches/proto/v4/libs/asio/test/ip/basic_endpoint.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/basic_endpoint.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/basic_endpoint.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/basic_endpoint");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ip/basic_resolver.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/basic_resolver.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/basic_resolver.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/basic_resolver");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ip/basic_resolver_entry.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/basic_resolver_entry.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/basic_resolver_entry.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/basic_resolver_entry");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ip/basic_resolver_iterator.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/basic_resolver_iterator.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/basic_resolver_iterator.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/basic_resolver_iterator");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ip/basic_resolver_query.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/basic_resolver_query.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/basic_resolver_query.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/basic_resolver_query");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ip/host_name.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/host_name.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/host_name.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -49,7 +49,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/host_name");
   test->add(BOOST_TEST_CASE(&ip_host_name_compile::test));

Modified: branches/proto/v4/libs/asio/test/ip/multicast.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/multicast.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/multicast.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -340,7 +340,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/multicast");
   test->add(BOOST_TEST_CASE(&ip_multicast_compile::test));

Modified: branches/proto/v4/libs/asio/test/ip/resolver_query_base.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/resolver_query_base.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/resolver_query_base.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/resolver_query_base");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ip/resolver_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/resolver_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/resolver_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/resolver_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ip/tcp.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/tcp.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/tcp.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -371,7 +371,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/tcp");
   test->add(BOOST_TEST_CASE(&ip_tcp_compile::test));

Modified: branches/proto/v4/libs/asio/test/ip/udp.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/udp.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/udp.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -311,10 +311,12 @@
   target_endpoint = sender_endpoint;
   s1.async_send_to(buffer(send_msg, sizeof(send_msg)), target_endpoint,
       boost::bind(handle_send, sizeof(send_msg),
- placeholders::error, placeholders::bytes_transferred));
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
   s2.async_receive_from(buffer(recv_msg, sizeof(recv_msg)), sender_endpoint,
       boost::bind(handle_recv, sizeof(recv_msg),
- placeholders::error, placeholders::bytes_transferred));
+ boost::asio::placeholders::error,
+ boost::asio::placeholders::bytes_transferred));
 
   ios.run();
 
@@ -325,7 +327,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/udp");
   test->add(BOOST_TEST_CASE(&ip_udp_socket_compile::test));

Modified: branches/proto/v4/libs/asio/test/ip/unicast.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/unicast.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/unicast.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -162,7 +162,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/unicast");
   test->add(BOOST_TEST_CASE(&ip_unicast_compile::test));

Modified: branches/proto/v4/libs/asio/test/ip/v6_only.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ip/v6_only.cpp (original)
+++ branches/proto/v4/libs/asio/test/ip/v6_only.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -125,7 +125,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ip/v6_only");
   test->add(BOOST_TEST_CASE(&ip_v6_only_compile::test));

Modified: branches/proto/v4/libs/asio/test/is_read_buffered.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/is_read_buffered.cpp (original)
+++ branches/proto/v4/libs/asio/test/is_read_buffered.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -118,7 +118,7 @@
       boost::asio::buffered_stream<test_stream> >::value);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("is_read_buffered");
   test->add(BOOST_TEST_CASE(&is_read_buffered_test));

Modified: branches/proto/v4/libs/asio/test/is_write_buffered.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/is_write_buffered.cpp (original)
+++ branches/proto/v4/libs/asio/test/is_write_buffered.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -118,7 +118,7 @@
       boost::asio::buffered_stream<test_stream> >::value);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("is_write_buffered");
   test->add(BOOST_TEST_CASE(&is_write_buffered_test));

Modified: branches/proto/v4/libs/asio/test/local/basic_endpoint.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/local/basic_endpoint.cpp (original)
+++ branches/proto/v4/libs/asio/test/local/basic_endpoint.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("local/basic_endpoint");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/local/connect_pair.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/local/connect_pair.cpp (original)
+++ branches/proto/v4/libs/asio/test/local/connect_pair.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -68,7 +68,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("local/connect_pair");
   test->add(BOOST_TEST_CASE(&local_connect_pair_compile::test));

Modified: branches/proto/v4/libs/asio/test/local/datagram_protocol.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/local/datagram_protocol.cpp (original)
+++ branches/proto/v4/libs/asio/test/local/datagram_protocol.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -225,7 +225,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("local/datagram_protocol");
   test->add(BOOST_TEST_CASE(&local_datagram_protocol_socket_compile::test));

Modified: branches/proto/v4/libs/asio/test/local/stream_protocol.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/local/stream_protocol.cpp (original)
+++ branches/proto/v4/libs/asio/test/local/stream_protocol.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -202,7 +202,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("local/stream_protocol");
   test->add(BOOST_TEST_CASE(&local_stream_protocol_socket_compile::test));

Modified: branches/proto/v4/libs/asio/test/placeholders.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/placeholders.cpp (original)
+++ branches/proto/v4/libs/asio/test/placeholders.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("placeholders");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/posix/basic_descriptor.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/posix/basic_descriptor.cpp (original)
+++ branches/proto/v4/libs/asio/test/posix/basic_descriptor.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,7 +19,7 @@
 #include <boost/asio.hpp>
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("posix/basic_descriptor");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/posix/basic_stream_descriptor.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/posix/basic_stream_descriptor.cpp (original)
+++ branches/proto/v4/libs/asio/test/posix/basic_stream_descriptor.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,7 +19,7 @@
 #include <boost/asio.hpp>
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("posix/basic_stream_descriptor");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/posix/descriptor_base.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/posix/descriptor_base.cpp (original)
+++ branches/proto/v4/libs/asio/test/posix/descriptor_base.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,7 +19,7 @@
 #include <boost/asio.hpp>
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("posix/descriptor_base");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/posix/stream_descriptor.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/posix/stream_descriptor.cpp (original)
+++ branches/proto/v4/libs/asio/test/posix/stream_descriptor.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -119,7 +119,7 @@
 } // namespace posix_stream_descriptor_compile
 
 //------------------------------------------------------------------------------
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("posix/stream_descriptor");
   test->add(BOOST_TEST_CASE(&posix_stream_descriptor_compile::test));

Modified: branches/proto/v4/libs/asio/test/posix/stream_descriptor_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/posix/stream_descriptor_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/posix/stream_descriptor_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,7 +19,7 @@
 #include <boost/asio.hpp>
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("posix/stream_descriptor_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/read.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/read.cpp (original)
+++ branches/proto/v4/libs/asio/test/read.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -619,7 +619,7 @@
   BOOST_CHECK(s.check(buffers, 50));
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("read");
   test->add(BOOST_TEST_CASE(&test_2_arg_read));

Modified: branches/proto/v4/libs/asio/test/read_until.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/read_until.cpp (original)
+++ branches/proto/v4/libs/asio/test/read_until.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -421,7 +421,7 @@
   BOOST_CHECK(length == 0);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("read_until");
   test->add(BOOST_TEST_CASE(&test_char_read_until));

Modified: branches/proto/v4/libs/asio/test/socket_acceptor_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/socket_acceptor_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/socket_acceptor_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("socket_acceptor_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/socket_base.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/socket_base.cpp (original)
+++ branches/proto/v4/libs/asio/test/socket_base.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -644,7 +644,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("socket_base");
   test->add(BOOST_TEST_CASE(&socket_base_compile::test));

Modified: branches/proto/v4/libs/asio/test/ssl/basic_context.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ssl/basic_context.cpp (original)
+++ branches/proto/v4/libs/asio/test/ssl/basic_context.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ssl/basic_context");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ssl/context.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ssl/context.cpp (original)
+++ branches/proto/v4/libs/asio/test/ssl/context.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ssl/context");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ssl/context_base.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ssl/context_base.cpp (original)
+++ branches/proto/v4/libs/asio/test/ssl/context_base.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ssl/context_base");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ssl/context_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ssl/context_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/ssl/context_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ssl/context_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ssl/stream.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ssl/stream.cpp (original)
+++ branches/proto/v4/libs/asio/test/ssl/stream.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -118,7 +118,7 @@
 
 //------------------------------------------------------------------------------
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ssl/stream");
   test->add(BOOST_TEST_CASE(&ssl_stream_compile::test));

Modified: branches/proto/v4/libs/asio/test/ssl/stream_base.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ssl/stream_base.cpp (original)
+++ branches/proto/v4/libs/asio/test/ssl/stream_base.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ssl/stream_base");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/ssl/stream_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/ssl/stream_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/ssl/stream_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("ssl/stream_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/strand.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/strand.cpp (original)
+++ branches/proto/v4/libs/asio/test/strand.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -163,7 +163,7 @@
   BOOST_CHECK(exception_count == 2);
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("strand");
   test->add(BOOST_TEST_CASE(&strand_test));

Modified: branches/proto/v4/libs/asio/test/stream_socket_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/stream_socket_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/stream_socket_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("stream_socket_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/time_traits.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/time_traits.cpp (original)
+++ branches/proto/v4/libs/asio/test/time_traits.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
 #include "unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("time_traits");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/unit_test.hpp
==============================================================================
--- branches/proto/v4/libs/asio/test/unit_test.hpp (original)
+++ branches/proto/v4/libs/asio/test/unit_test.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -31,6 +31,7 @@
 #if defined(BOOST_MSVC)
 # pragma warning (push)
 # pragma warning (disable:4244)
+# pragma warning (disable:4702)
 #endif // defined(BOOST_MSVC)
 
 #include <boost/test/unit_test.hpp>

Modified: branches/proto/v4/libs/asio/test/windows/basic_handle.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/windows/basic_handle.cpp (original)
+++ branches/proto/v4/libs/asio/test/windows/basic_handle.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,7 +19,7 @@
 #include <boost/asio.hpp>
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("windows/basic_handle");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/windows/basic_stream_handle.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/windows/basic_stream_handle.cpp (original)
+++ branches/proto/v4/libs/asio/test/windows/basic_stream_handle.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,7 +19,7 @@
 #include <boost/asio.hpp>
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("windows/basic_stream_handle");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/windows/stream_handle.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/windows/stream_handle.cpp (original)
+++ branches/proto/v4/libs/asio/test/windows/stream_handle.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -106,7 +106,7 @@
 } // namespace windows_stream_handle_compile
 
 //------------------------------------------------------------------------------
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("windows/stream_handle");
   test->add(BOOST_TEST_CASE(&windows_stream_handle_compile::test));

Modified: branches/proto/v4/libs/asio/test/windows/stream_handle_service.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/windows/stream_handle_service.cpp (original)
+++ branches/proto/v4/libs/asio/test/windows/stream_handle_service.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,7 +19,7 @@
 #include <boost/asio.hpp>
 #include "../unit_test.hpp"
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("windows/stream_handle_service");
   test->add(BOOST_TEST_CASE(&null_test));

Modified: branches/proto/v4/libs/asio/test/write.cpp
==============================================================================
--- branches/proto/v4/libs/asio/test/write.cpp (original)
+++ branches/proto/v4/libs/asio/test/write.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -573,7 +573,7 @@
   BOOST_CHECK(s.check(buffers, 50));
 }
 
-test_suite* init_unit_test_suite(int argc, char* argv[])
+test_suite* init_unit_test_suite(int, char*[])
 {
   test_suite* test = BOOST_TEST_SUITE("write");
   test->add(BOOST_TEST_CASE(&test_2_arg_write));

Modified: branches/proto/v4/libs/bimap/doc/bimap_and_boost.qbk
==============================================================================
--- branches/proto/v4/libs/bimap/doc/bimap_and_boost.qbk (original)
+++ branches/proto/v4/libs/bimap/doc/bimap_and_boost.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -219,7 +219,7 @@
 This is a statistical property depending on the typical distribution of keys in a given application, so it is not feasible to have a general-purpose hash function with excellent results in every possible scenario; the default value for this parameter uses Boost.Hash, which often provides good enough results.
 
 Boost.Hash can be
-[@http://www.boost.org/regression-logs/cs-win32_metacomm/doc/html/hash/custom.html
+[@http://www.boost.org/doc/html/hash/custom.html
 extended for custom data types],
 enabling to use the default parameter of the unordered set types with any user types.
 
@@ -474,4 +474,4 @@
 
 [endsect]
 
-[endsect]
\ No newline at end of file
+[endsect]

Modified: branches/proto/v4/libs/date_time/xmldoc/buildinfo.xml
==============================================================================
--- branches/proto/v4/libs/date_time/xmldoc/buildinfo.xml (original)
+++ branches/proto/v4/libs/date_time/xmldoc/buildinfo.xml 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -146,7 +146,7 @@
       <listitem><ulink url="../../libs/conversion/lexical_cast.htm">boost.lexical_cast </ulink> </listitem>
       <listitem><ulink url="../../libs/smart_ptr/smart_ptr.htm">boost.smart_ptr (local time only)</ulink> </listitem>
       <listitem><ulink url="../../libs/algorithm/string/">boost::string_algorithms </ulink> </listitem>
- <listitem><ulink url="../../libs/algorithm/serialize/">boost::serialize (serialization code only) </ulink> </listitem>
+ <listitem><ulink url="../../libs/serialization/index.html">boost::serialize (serialization code only) </ulink> </listitem>
     </itemizedlist>
     so these libraries need to be installed.
   </para>

Modified: branches/proto/v4/libs/exception/test/Jamfile.v2
==============================================================================
--- branches/proto/v4/libs/exception/test/Jamfile.v2 (original)
+++ branches/proto/v4/libs/exception/test/Jamfile.v2 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,13 +7,6 @@
 
 import testing ;
 
-project :
- requirements
- <link>static
- <runtime-link>static
- <toolset>msvc:<cxxflags>/Za
- ;
-
 #to_string
 run is_output_streamable_test.cpp ;
 run has_to_string_test.cpp ;

Modified: branches/proto/v4/libs/filesystem/doc/index.htm
==============================================================================
--- branches/proto/v4/libs/filesystem/doc/index.htm (original)
+++ branches/proto/v4/libs/filesystem/doc/index.htm 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -332,7 +332,7 @@
 systems which will work with the Filesystem Library.</p>
 <p>The object-library can be built for static or dynamic (shared/dll) linking.
 This is controlled by the BOOST_ALL_DYN_LINK or BOOST_FILESYSTEM_DYN_LINK
-macros. See the <a href="http://www.boost.org/more/separate_compilation.html">Separate
+macros. See the <a href="http://www.boost.org/development/separate_compilation.html">Separate
 Compilation</a> page for a description of the techniques used.</p>
 <h3>Note for <a name="Cgywin">Cygwin</a> users</h3>
 <p>The library's implementation code automatically detects the current platform,
@@ -562,4 +562,4 @@
 
 </body>
 
-</html>
\ No newline at end of file
+</html>

Modified: branches/proto/v4/libs/filesystem/doc/reference.html
==============================================================================
--- branches/proto/v4/libs/filesystem/doc/reference.html (original)
+++ branches/proto/v4/libs/filesystem/doc/reference.html 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1099,7 +1099,7 @@
     <span style="background-color: #FFFFFF">basic_path&lt;String, Traits&gt;</span></code></td>
     <td width="55%" height="30"><code><span style="background-color: #FFFFFF">
     basic_path&lt;String, Traits&gt; tmp(a);<br>
- return a /= </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">;</span></code></td>
+ return tmp /= </span></code><i><b><span style="background-color: #FFFFFF">b'</span></b></i><code><span style="background-color: #FFFFFF">;</span></code></td>
   </tr>
   <tr>
     <td width="20%" align="center" height="19" valign="top"><code>
@@ -3057,7 +3057,7 @@
 <p>Distributed under the Boost Software License, Version 1.0. See
 <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a></p>
 <p>Revised
-<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->19 April 2008<!--webbot bot="Timestamp" endspan i-checksum="28399" --></p>
+<!--webbot bot="Timestamp" S-Type="EDITED" S-Format="%d %B %Y" startspan -->24 April 2008<!--webbot bot="Timestamp" endspan i-checksum="28390" --></p>
 
 </body>
 

Modified: branches/proto/v4/libs/format/doc/format.html
==============================================================================
--- branches/proto/v4/libs/format/doc/format.html (original)
+++ branches/proto/v4/libs/format/doc/format.html 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -79,7 +79,7 @@
 
       <blockquote>
         <pre>
-cout &lt;&lt; format("%2% %1%") % 36 % 77 )
+cout &lt;&lt; format("%2% %1%") % 36 % 77;
 </pre>
       </blockquote>or later on, as in
 

Modified: branches/proto/v4/libs/function/doc/misc.xml
==============================================================================
--- branches/proto/v4/libs/function/doc/misc.xml (original)
+++ branches/proto/v4/libs/function/doc/misc.xml 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -24,7 +24,7 @@
 <para> And, of course, function pointers have several advantages over Boost.Function:
 
 <itemizedlist spacing="compact">
- <listitem><para> Function pointers are smaller (the size of one pointer instead of three) </para></listitem>
+ <listitem><para> Function pointers are smaller (the size of one pointer instead of four or more) </para></listitem>
     <listitem><para> Function pointers are faster (Boost.Function may require two calls through function pointers) </para></listitem>
     <listitem><para> Function pointers are backward-compatible with C libraries.</para></listitem>
     <listitem><para> More readable error messages. </para></listitem>
@@ -37,12 +37,12 @@
 
 <section>
   <title>Function object wrapper size</title>
-<para> Function object wrappers will be the size of two function pointers plus one function pointer or data pointer (whichever is larger). On common 32-bit platforms, this amounts to 12 bytes per wrapper. Additionally, the function object target will be allocated on the heap.</para>
+ <para> Function object wrappers will be the size of a struct containing a member function pointer and two data pointers. The actual size can vary significantly depending on the underlying platform; on 32-bit Mac OS X with GCC, this amounts to 16 bytes, while it is 32 bytes Windows with Visual C++. Additionally, the function object target may be allocated on the heap, if it cannot be placed into the small-object buffer in the <code>boost::function</code> object.</para>
 </section>
 
 <section>
   <title>Copying efficiency</title>
-<para> Copying function object wrappers may require allocating memory for a copy of the function object target. The default allocator may be replaced with a faster custom allocator or one may choose to allow the function object wrappers to only store function object targets by reference (using <computeroutput>ref</computeroutput>) if the cost of this cloning becomes prohibitive.</para>
+ <para> Copying function object wrappers may require allocating memory for a copy of the function object target. The default allocator may be replaced with a faster custom allocator or one may choose to allow the function object wrappers to only store function object targets by reference (using <computeroutput>ref</computeroutput>) if the cost of this cloning becomes prohibitive. Small function objects can be stored within the <code>boost::function</code> object itself, improving copying efficiency.</para>
  </section>
 
 <section>

Modified: branches/proto/v4/libs/interprocess/doc/interprocess.qbk
==============================================================================
--- branches/proto/v4/libs/interprocess/doc/interprocess.qbk (original)
+++ branches/proto/v4/libs/interprocess/doc/interprocess.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -58,6 +58,15 @@
 not need any separate compilation so the user can define `BOOST_DATE_TIME_NO_LIB`
 to avoid Boost from trying to automatically link the [*Boost.DateTime].
 
+In POSIX systems, [*Boost.Interprocess] uses pthread system calls to implement
+classes like mutexes, condition variables, etc... In some operating systems,
+these POSIX calls are implemented in separate libraries that are not automatically
+linked by the compiler. For example, in some Linux systems POSIX pthread functions
+are implemented in `librt.a` library, so you might need to add that library
+when linking an executable or shared library that uses [*Boost.Interprocess].
+If you obtain linking errors related to those pthread functions, please revise
+your system's documentation to know which library implements them.
+
 [endsect]
 
 [section:tested_compilers Tested compilers]
@@ -551,6 +560,30 @@
 
 [endsect]
 
+[section:anonymous_shared_memory Anonymous shared memory for UNIX systems]
+
+Creating a shared memory segment and mapping it can be a bit tedious when several
+processes are involved. When processes are related via `fork()` operating system
+call in UNIX sytems a simpler method is available using anonymous shared memory.
+
+This feature has been implemented in UNIX systems mapping the device `\dev\zero` or
+just using the `MAP_ANONYMOUS` in a POSIX conformant `mmap` system call.
+
+This feature is wrapped in [*Boost.Interprocess] using the `anonymous_shared_memory()`
+function, which returns a `mapped_region` object holding an anonymous shared memory
+segment that can be shared by related processes.
+
+Here's is an example:
+
+[import ../example/doc_anonymous_shared_memory.cpp]
+[doc_anonymous_shared_memory]
+
+Once the segment is created, a `fork()` call can
+be used so that `region` is used to communicate two related processes.
+
+[endsect]
+
+
 [section:windows_shared_memory Native windows shared memory]
 
 Windows operating system also offers shared memory, but the lifetime of this
@@ -1298,7 +1331,7 @@
 [blurb ['[*void lock()]]]
 
 [*Effects:]
- The calling thread tries to obtain ownership of the mutex, and if another thread has ownership of the mutex, it waits until it can obtain the ownership. If a thread takes ownership of the mutex the mutex must be unlocked by the same mutex. If the mutex supports recursive locking, the mutex must be unlocked the same number of times it is locked.
+ The calling thread tries to obtain ownership of the mutex, and if another thread has ownership of the mutex, it waits until it can obtain the ownership. If a thread takes ownership of the mutex the mutex must be unlocked by the same thread. If the mutex supports recursive locking, the mutex must be unlocked the same number of times it is locked.
 
 [*Throws:] *interprocess_exception* on error.
 
@@ -4935,6 +4968,41 @@
 
 [endsect]
 
+[section:additional_containers Boost containers compatible with Boost.Interprocess]
+
+As mentioned, container developers might need to change their implementation to make them
+compatible with Boost.Interprocess, because implementation usually ignore allocators with
+smart pointers. Hopefully several Boost containers are compatible with [*Interprocess].
+
+[section:unordered Boost unordered containers]
+
+[*Boost.Unordered] containers are compatible with Interprocess, so programmers can store
+hash containers in shared memory and memory mapped files. Here's an small example storing
+`unordered_map` in shared memory:
+
+[import ../example/doc_unordered_map.cpp]
+[doc_unordered_map]
+
+[endsect]
+
+[section:multi_index Boost.MultiIndex containers]
+
+The widely used [*Boost.MultiIndex] library is compatible with [*Boost.Interprocess] so
+we can construct pretty good databases in shared memory. Constructing databases in shared
+memory is a bit tougher than in normal memory, usually because those databases contain strings
+and those strings need to be placed in shared memory. Shared memory strings require
+an allocator in their constructors so this usually makes object insertion a bit more
+complicated.
+
+Here's is an example that shows how to put a multi index container in shared memory:
+
+[import ../example/doc_multi_index.cpp]
+[doc_multi_index]
+
+[endsect]
+
+[endsect]
+
 [section:memory_algorithms Memory allocation algorithms]
 
 [section:simple_seq_fit simple_seq_fit: A simple shared memory management algorithm]
@@ -5704,7 +5772,7 @@
 to the segment manager. Because of this,
 in [*Boost.Interprocess] all managed memory segments derive from a common class that
 implements memory-independent (shared memory, memory mapped files) functions:
-[@../../../../boost/interprocess/detail/managed_memory_impl.hpp
+[@../../boost/interprocess/detail/managed_memory_impl.hpp
 boost::interprocess::detail::basic_managed_memory_impl]
 
 Deriving from this class, [*Boost.Interprocess] implements several managed memory
@@ -5766,7 +5834,7 @@
    to the segment manager.
 
 The pool is implemented by the
-[@../../../../boost/interprocess/allocators/detail/node_pool.hpp
+[@../../boost/interprocess/allocators/detail/node_pool.hpp
 private_node_pool and shared_node_pool] classes.
 
 [endsect]
@@ -5809,7 +5877,7 @@
    to the segment manager.
 
 The adaptive pool is implemented by the
-[@../../../../boost/interprocess/allocators/detail/adaptive_node_pool.hpp
+[@../../boost/interprocess/allocators/detail/adaptive_node_pool.hpp
 private_adaptive_node_pool and adaptive_node_pool] classes.
 
 [endsect]
@@ -6262,7 +6330,7 @@
 For example, the index type `flat_map_index` based in `boost::interprocess::flat_map`
 is just defined as:
 
-[import ../../../boost/interprocess/indexes/flat_map_index.hpp]
+[import ../../boost/interprocess/indexes/flat_map_index.hpp]
 [flat_map_index]
 
 
@@ -6385,6 +6453,12 @@
 
 [section:release_notes Release Notes]
 
+[section:release_notes_boost_1_36_00 Boost 1.36 Release]
+
+* Added anonymous shared memory for UNIX systems.
+
+[endsect]
+
 [section:release_notes_boost_1_35_00 Boost 1.35 Release]
 
 * Added auxiliary utilities to ease the definition and construction of
@@ -6654,20 +6728,6 @@
 
 [endsect]
 
-[section:future_containers Unordered associative containers and other containers]
-
-We should be able to construct boost::unordered_xxx family in managed memory segments,
-so that there is no code duplication in boost. So [*Boost.Interprocess] should cooperate
-with boost container developers instead of duplicating effort writing it's own containers.
-
-A very interesting project is making [*boost::multi_index] compatible with
-[*Boost.Interprocess] ready for shared memory. This could be a good basis for memory
-mapped data-bases. The work to achieve this, however, can be huge. It would be
-interesting a collaboration with [*Intrusive] library to achieve shared memory
-intrusive containers.
-
-[endsect]
-
 [endsect]
 
 [endsect]

Modified: branches/proto/v4/libs/interprocess/proj/vc7ide/Interprocess.sln
==============================================================================
--- branches/proto/v4/libs/interprocess/proj/vc7ide/Interprocess.sln (original)
+++ branches/proto/v4/libs/interprocess/proj/vc7ide/Interprocess.sln 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -415,6 +415,34 @@
         ProjectSection(ProjectDependencies) = postProject
         EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_anonymous_shared_memory", "doc_anonymous_shared_memory.vcproj", "{6DE178C3-12FE-6032-4FC7-879B63B9F651}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "anonymous_shared_memory_test", "anonymous_shared_memory_test.vcproj", "{58DE8A13-4FA7-6252-36FE-B3A0A6D92812}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_unordered_map", "doc_unordered_map.vcproj", "{9C185DF3-B75F-1928-8F6D-735108AABE62}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_multi_index", "doc_multi_index.vcproj", "{918C5DF3-1928-B73F-F626-7358518CBE62}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unordered_test", "unordered_test.vcproj", "{C3CE1183-09F2-A46A-4FE6-D06BA7923A02}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "multi_index_test", "multi_index_test.vcproj", "{9285DFD3-1928-F662-CB73-73518CB53A62}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "file_lock_test", "file_lock_test.vcproj", "{58CCE183-6092-48FE-A4F7-BA0D3A792639}"
+ ProjectSection(ProjectDependencies) = postProject
+ EndProjectSection
+EndProject
 Global
         GlobalSection(SolutionConfiguration) = preSolution
                 Debug = Debug
@@ -839,6 +867,34 @@
                 {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Debug.Build.0 = Debug|Win32
                 {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.ActiveCfg = Release|Win32
                 {5CE11C83-096A-84FE-4FA2-D3A6BA792002}.Release.Build.0 = Release|Win32
+ {6DE178C3-12FE-6032-4FC7-879B63B9F651}.Debug.ActiveCfg = Debug|Win32
+ {6DE178C3-12FE-6032-4FC7-879B63B9F651}.Debug.Build.0 = Debug|Win32
+ {6DE178C3-12FE-6032-4FC7-879B63B9F651}.Release.ActiveCfg = Release|Win32
+ {6DE178C3-12FE-6032-4FC7-879B63B9F651}.Release.Build.0 = Release|Win32
+ {58DE8A13-4FA7-6252-36FE-B3A0A6D92812}.Debug.ActiveCfg = Debug|Win32
+ {58DE8A13-4FA7-6252-36FE-B3A0A6D92812}.Debug.Build.0 = Debug|Win32
+ {58DE8A13-4FA7-6252-36FE-B3A0A6D92812}.Release.ActiveCfg = Release|Win32
+ {58DE8A13-4FA7-6252-36FE-B3A0A6D92812}.Release.Build.0 = Release|Win32
+ {9C185DF3-B75F-1928-8F6D-735108AABE62}.Debug.ActiveCfg = Debug|Win32
+ {9C185DF3-B75F-1928-8F6D-735108AABE62}.Debug.Build.0 = Debug|Win32
+ {9C185DF3-B75F-1928-8F6D-735108AABE62}.Release.ActiveCfg = Release|Win32
+ {9C185DF3-B75F-1928-8F6D-735108AABE62}.Release.Build.0 = Release|Win32
+ {918C5DF3-1928-B73F-F626-7358518CBE62}.Debug.ActiveCfg = Debug|Win32
+ {918C5DF3-1928-B73F-F626-7358518CBE62}.Debug.Build.0 = Debug|Win32
+ {918C5DF3-1928-B73F-F626-7358518CBE62}.Release.ActiveCfg = Release|Win32
+ {918C5DF3-1928-B73F-F626-7358518CBE62}.Release.Build.0 = Release|Win32
+ {C3CE1183-09F2-A46A-4FE6-D06BA7923A02}.Debug.ActiveCfg = Debug|Win32
+ {C3CE1183-09F2-A46A-4FE6-D06BA7923A02}.Debug.Build.0 = Debug|Win32
+ {C3CE1183-09F2-A46A-4FE6-D06BA7923A02}.Release.ActiveCfg = Release|Win32
+ {C3CE1183-09F2-A46A-4FE6-D06BA7923A02}.Release.Build.0 = Release|Win32
+ {9285DFD3-1928-F662-CB73-73518CB53A62}.Debug.ActiveCfg = Debug|Win32
+ {9285DFD3-1928-F662-CB73-73518CB53A62}.Debug.Build.0 = Debug|Win32
+ {9285DFD3-1928-F662-CB73-73518CB53A62}.Release.ActiveCfg = Release|Win32
+ {9285DFD3-1928-F662-CB73-73518CB53A62}.Release.Build.0 = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792639}.Debug.ActiveCfg = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792639}.Debug.Build.0 = Debug|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792639}.Release.ActiveCfg = Release|Win32
+ {58CCE183-6092-48FE-A4F7-BA0D3A792639}.Release.Build.0 = Release|Win32
         EndGlobalSection
         GlobalSection(ExtensibilityGlobals) = postSolution
         EndGlobalSection

Modified: branches/proto/v4/libs/interprocess/proj/vc7ide/interprocesslib.vcproj
==============================================================================
--- branches/proto/v4/libs/interprocess/proj/vc7ide/interprocesslib.vcproj (original)
+++ branches/proto/v4/libs/interprocess/proj/vc7ide/interprocesslib.vcproj 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -316,6 +316,9 @@
                         Filter="h;hpp;hxx;hm;inl;inc;xsd"
                         UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
                         <File
+ RelativePath="..\..\..\..\boost\interprocess\anonymous_shared_memory.hpp">
+ </File>
+ <File
                                 RelativePath="..\..\..\..\boost\interprocess\creation_tags.hpp">
                         </File>
                         <File

Modified: branches/proto/v4/libs/interprocess/test/adaptive_node_pool_test.cpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/adaptive_node_pool_test.cpp (original)
+++ branches/proto/v4/libs/interprocess/test/adaptive_node_pool_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,6 +11,8 @@
 #include "node_pool_test.hpp"
 #include <boost/interprocess/allocators/detail/adaptive_node_pool.hpp>
 
+#include <vector>
+
 int main ()
 {
    using namespace boost::interprocess;

Modified: branches/proto/v4/libs/interprocess/test/adaptive_pool_test.cpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/adaptive_pool_test.cpp (original)
+++ branches/proto/v4/libs/interprocess/test/adaptive_pool_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -41,7 +41,6 @@
 typedef vector<int, shmem_node_allocator_t> MyShmVector;
 typedef vector<int, shmem_node_allocator_v1_t> MyShmVectorV1;
 
-
 int main ()
 {
    if(test::list_test<managed_shared_memory, MyShmList, true>())

Modified: branches/proto/v4/libs/interprocess/test/allocator_v1.hpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/allocator_v1.hpp (original)
+++ branches/proto/v4/libs/interprocess/test/allocator_v1.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -114,17 +114,17 @@
 
    //!Deallocates memory previously allocated. Never throws
    void deallocate(const pointer &ptr, size_type)
- { mp_mngr->deallocate(detail::get_pointer(ptr)); }
-/*
+ { mp_mngr->deallocate((void*)detail::get_pointer(ptr)); }
+
    //!Construct object, calling constructor.
    //!Throws if T(const T&) throws
    void construct(const pointer &ptr, const_reference value)
- { new(detail::get_pointer(ptr)) value_type(value); }
+ { new((void*)detail::get_pointer(ptr)) value_type(value); }
 
    //!Destroys object. Throws if object's destructor throws
    void destroy(const pointer &ptr)
    { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); }
-*/
+
    //!Returns the number of elements that could be allocated. Never throws
    size_type max_size() const
    { return mp_mngr->get_size(); }

Modified: branches/proto/v4/libs/interprocess/test/dummy_test_allocator.hpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/dummy_test_allocator.hpp (original)
+++ branches/proto/v4/libs/interprocess/test/dummy_test_allocator.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -82,26 +82,26 @@
    template<class T2>
    dummy_test_allocator(const dummy_test_allocator<T2> &)
    {}
-/*
+
    pointer address(reference value)
    { return pointer(addressof(value)); }
 
    const_pointer address(const_reference value) const
    { return const_pointer(addressof(value)); }
-*/
+
    pointer allocate(size_type, cvoid_ptr = 0)
    { return 0; }
 
    void deallocate(const pointer &, size_type)
    { }
-/*
+
    template<class Convertible>
    void construct(pointer, const Convertible &)
    {}
 
    void destroy(pointer)
    {}
-*/
+
    size_type max_size() const
    { return 0; }
 

Modified: branches/proto/v4/libs/interprocess/test/expand_bwd_test_allocator.hpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/expand_bwd_test_allocator.hpp (original)
+++ branches/proto/v4/libs/interprocess/test/expand_bwd_test_allocator.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -85,26 +85,26 @@
    expand_bwd_test_allocator(const expand_bwd_test_allocator<T2> &other)
       : mp_buffer(other.mp_buffer), m_size(other.m_size)
       , m_offset(other.m_offset), m_allocations(0){ }
-/*
+
    pointer address(reference value)
    { return pointer(addressof(value)); }
 
    const_pointer address(const_reference value) const
    { return const_pointer(addressof(value)); }
-*/
+
    pointer allocate(size_type , cvoid_ptr hint = 0)
    { (void)hint; return 0; }
 
    void deallocate(const pointer &, size_type)
    {}
-/*
+
    template<class Convertible>
    void construct(pointer ptr, const Convertible &value)
    { new((void*)ptr) value_type(value); }
 
    void destroy(pointer ptr)
    { (*ptr).~value_type(); }
-*/
+
    size_type max_size() const
    { return m_size; }
 

Modified: branches/proto/v4/libs/interprocess/test/expand_bwd_test_template.hpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/expand_bwd_test_template.hpp (original)
+++ branches/proto/v4/libs/interprocess/test/expand_bwd_test_template.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -15,6 +15,7 @@
 #include <vector>
 #include "expand_bwd_test_allocator.hpp"
 #include <algorithm>
+#include <boost/type_traits/remove_volatile.hpp>
 
 namespace boost { namespace interprocess { namespace test {
 
@@ -107,7 +108,8 @@
 bool test_insert_with_expand_bwd()
 {
    typedef typename VectorWithExpandBwdAllocator::value_type value_type;
- typedef std::vector<value_type> Vect;
+ typedef typename boost::remove_volatile<value_type>::type non_volatile_value_type;
+ typedef std::vector<non_volatile_value_type> Vect;
    const int MemorySize = 1000;
 
    //Distance old and new buffer
@@ -131,37 +133,42 @@
 
    for(int iteration = 0; iteration < Iterations; ++iteration)
    {
- Vect memory;
- memory.resize(MemorySize);
-
- Vect initial_data;
- initial_data.resize(InitialSize[iteration]);
- for(int i = 0; i < InitialSize[iteration]; ++i){
- initial_data[i] = value_type(i);
- }
-
- Vect data_to_insert;
- data_to_insert.resize(InsertSize[iteration]);
- for(int i = 0; i < InsertSize[iteration]; ++i){
- data_to_insert[i] = value_type(-i);
- }
-
- expand_bwd_test_allocator<value_type> alloc
- (&memory[0], memory.size(), Offset[iteration]);
- VectorWithExpandBwdAllocator vector(alloc);
- vector.insert( vector.begin()
- , initial_data.begin(), initial_data.end());
- vector.insert( vector.begin() + Position[iteration]
- , data_to_insert.begin(), data_to_insert.end());
- initial_data.insert(initial_data.begin() + Position[iteration]
- , data_to_insert.begin(), data_to_insert.end());
- //Now check that values are equal
- if(!CheckEqualVector(vector, initial_data)){
- std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
- << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
- << " Iteration: " << iteration << std::endl;
- return false;
+ value_type *memory = new value_type[MemorySize];
+ try {
+ std::vector<non_volatile_value_type> initial_data;
+ initial_data.resize(InitialSize[iteration]);
+ for(int i = 0; i < InitialSize[iteration]; ++i){
+ initial_data[i] = i;
+ }
+
+ Vect data_to_insert;
+ data_to_insert.resize(InsertSize[iteration]);
+ for(int i = 0; i < InsertSize[iteration]; ++i){
+ data_to_insert[i] = -i;
+ }
+
+ expand_bwd_test_allocator<value_type> alloc
+ ((value_type*)&memory[0], MemorySize, Offset[iteration]);
+ VectorWithExpandBwdAllocator vector(alloc);
+ vector.insert( vector.begin()
+ , initial_data.begin(), initial_data.end());
+ vector.insert( vector.begin() + Position[iteration]
+ , data_to_insert.begin(), data_to_insert.end());
+ initial_data.insert(initial_data.begin() + Position[iteration]
+ , data_to_insert.begin(), data_to_insert.end());
+ //Now check that values are equal
+ if(!CheckEqualVector(vector, initial_data)){
+ std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
+ << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
+ << " Iteration: " << iteration << std::endl;
+ return false;
+ }
+ }
+ catch(...){
+ delete []((non_volatile_value_type*)memory);
+ throw;
       }
+ delete []((non_volatile_value_type*)memory);
    }
 
    return true;
@@ -173,7 +180,8 @@
 bool test_assign_with_expand_bwd()
 {
    typedef typename VectorWithExpandBwdAllocator::value_type value_type;
- typedef std::vector<value_type> Vect;
+ typedef typename boost::remove_volatile<value_type>::type non_volatile_value_type;
+ typedef std::vector<non_volatile_value_type> Vect;
    const int MemorySize = 200;
 
    const int Offset[] = { 50, 50, 50};
@@ -183,41 +191,46 @@
 
    for(int iteration = 0; iteration <Iterations; ++iteration)
    {
- Vect memory;
- memory.resize(MemorySize);
-
- //Create initial data
- Vect initial_data;
- initial_data.resize(InitialSize[iteration]);
- for(int i = 0; i < InitialSize[iteration]; ++i){
- initial_data[i] = i;
- }
-
- //Create data to assign
- Vect data_to_assign;
- data_to_assign.resize(AssignSize[iteration]);
- for(int i = 0; i < AssignSize[iteration]; ++i){
- data_to_assign[i] = -i;
- }
-
- //Insert initial data to the vector to test
- expand_bwd_test_allocator<value_type> alloc
- (&memory[0], memory.size(), Offset[iteration]);
- VectorWithExpandBwdAllocator vector(alloc);
- vector.insert( vector.begin()
- , initial_data.begin(), initial_data.end());
-
- //Assign data
- vector.assign(data_to_assign.begin(), data_to_assign.end());
- initial_data.assign(data_to_assign.begin(), data_to_assign.end());
-
- //Now check that values are equal
- if(!CheckEqualVector(vector, initial_data)){
- std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
- << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
- << " Iteration: " << iteration << std::endl;
- return false;
+ value_type *memory = new value_type[MemorySize];
+ try {
+ //Create initial data
+ std::vector<non_volatile_value_type> initial_data;
+ initial_data.resize(InitialSize[iteration]);
+ for(int i = 0; i < InitialSize[iteration]; ++i){
+ initial_data[i] = i;
+ }
+
+ //Create data to assign
+ std::vector<non_volatile_value_type> data_to_assign;
+ data_to_assign.resize(AssignSize[iteration]);
+ for(int i = 0; i < AssignSize[iteration]; ++i){
+ data_to_assign[i] = -i;
+ }
+
+ //Insert initial data to the vector to test
+ expand_bwd_test_allocator<value_type> alloc
+ (&memory[0], MemorySize, Offset[iteration]);
+ VectorWithExpandBwdAllocator vector(alloc);
+ vector.insert( vector.begin()
+ , initial_data.begin(), initial_data.end());
+
+ //Assign data
+ vector.assign(data_to_assign.begin(), data_to_assign.end());
+ initial_data.assign(data_to_assign.begin(), data_to_assign.end());
+
+ //Now check that values are equal
+ if(!CheckEqualVector(vector, initial_data)){
+ std::cout << "test_assign_with_expand_bwd::CheckEqualVector failed." << std::endl
+ << " Class: " << typeid(VectorWithExpandBwdAllocator).name() << std::endl
+ << " Iteration: " << iteration << std::endl;
+ return false;
+ }
+ }
+ catch(...){
+ delete []((typename boost::remove_volatile<value_type>::type*)memory);
+ throw;
       }
+ delete []((typename boost::remove_volatile<value_type>::type*)memory);
    }
 
    return true;

Modified: branches/proto/v4/libs/interprocess/test/list_test.cpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/list_test.cpp (original)
+++ branches/proto/v4/libs/interprocess/test/list_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -26,6 +26,9 @@
 typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
 typedef list<int, ShmemAllocator> MyList;
 
+typedef allocator<volatile int, managed_shared_memory::segment_manager> ShmemVolatileAllocator;
+typedef list<volatile int, ShmemVolatileAllocator> MyVolatileList;
+
 typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
 typedef list<test::movable_int, ShmemMoveAllocator> MyMoveList;
 
@@ -37,6 +40,9 @@
    if(test::list_test<managed_shared_memory, MyList, true>())
       return 1;
 
+ if(test::list_test<managed_shared_memory, MyVolatileList, true>())
+ return 1;
+
    if(test::list_test<managed_shared_memory, MyMoveList, true>())
       return 1;
 

Modified: branches/proto/v4/libs/interprocess/test/node_pool_test.hpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/node_pool_test.hpp (original)
+++ branches/proto/v4/libs/interprocess/test/node_pool_test.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -136,7 +136,7 @@
    typedef boost::interprocess::test::test_node_pool<node_pool_t> test_node_pool_t;
    shared_memory_object::remove(test::get_process_id_name());
    {
- managed_shared_memory shm(create_only, test::get_process_id_name(), 16*1024);
+ managed_shared_memory shm(create_only, test::get_process_id_name(), 4*1024*sizeof(void*));
 
       typedef deleter<node_pool_t, segment_manager> deleter_t;
       typedef unique_ptr<node_pool_t, deleter_t> unique_ptr_t;

Modified: branches/proto/v4/libs/interprocess/test/shared_memory_mapping_test.cpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/shared_memory_mapping_test.cpp (original)
+++ branches/proto/v4/libs/interprocess/test/shared_memory_mapping_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,7 @@
 #include <iostream>
 #include <boost/interprocess/shared_memory_object.hpp>
 #include <boost/interprocess/mapped_region.hpp>
+#include <boost/interprocess/anonymous_shared_memory.hpp>
 #include <string>
 #include "get_process_id_name.hpp"
 
@@ -113,6 +114,28 @@
             }
          }
       }
+ {
+ //Now check anonymous mapping
+ mapped_region region(anonymous_shared_memory(FileSize));
+
+ //Write pattern
+ unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize
+ ;++i, ++pattern){
+ *pattern = static_cast<unsigned char>(i);
+ }
+
+ //Check pattern
+ pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize
+ ;++i, ++pattern){
+ if(*pattern != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+ }
    }
    catch(std::exception &exc){
       shared_memory_object::remove(test::get_process_id_name());

Modified: branches/proto/v4/libs/interprocess/test/tree_test.cpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/tree_test.cpp (original)
+++ branches/proto/v4/libs/interprocess/test/tree_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -61,7 +61,7 @@
 //Customize managed_shared_memory class
 typedef basic_managed_shared_memory
    <char,
- simple_seq_fit<mutex_family, void*>,
+ simple_seq_fit<mutex_family, offset_ptr<void> >,
     map_index
> my_managed_shared_memory;
 

Modified: branches/proto/v4/libs/interprocess/test/vector_test.cpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/vector_test.cpp (original)
+++ branches/proto/v4/libs/interprocess/test/vector_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -44,7 +44,16 @@
 
    if(!test::test_all_expand_bwd<int_vector>())
       return 1;
+/*
+ //First raw volatile ints
+ typedef test::expand_bwd_test_allocator<volatile int>
+ volatile_int_allocator_type;
+ typedef vector<volatile int, volatile_int_allocator_type>
+ volatile_int_vector;
 
+ if(!test::test_all_expand_bwd<volatile_int_vector>())
+ return 1;
+*/
    //Now user defined wrapped int
    typedef test::expand_bwd_test_allocator<test::int_holder>
       int_holder_allocator_type;
@@ -72,6 +81,9 @@
    typedef allocator<int, managed_shared_memory::segment_manager> ShmemAllocator;
    typedef vector<int, ShmemAllocator> MyVector;
 
+ //typedef allocator<volatile int, managed_shared_memory::segment_manager> ShmemVolatileAllocator;
+ //typedef vector<volatile int, ShmemVolatileAllocator> MyVolatileVector;
+
    typedef allocator<test::movable_int, managed_shared_memory::segment_manager> ShmemMoveAllocator;
    typedef vector<test::movable_int, ShmemMoveAllocator> MyMoveVector;
 
@@ -81,6 +93,9 @@
    if(test::vector_test<managed_shared_memory, MyVector>())
       return 1;
 
+ //if(test::vector_test<managed_shared_memory, MyVolatileVector>())
+ //return 1;
+
    if(test::vector_test<managed_shared_memory, MyMoveVector>())
       return 1;
 

Modified: branches/proto/v4/libs/interprocess/test/windows_shared_memory_mapping_test.cpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/windows_shared_memory_mapping_test.cpp (original)
+++ branches/proto/v4/libs/interprocess/test/windows_shared_memory_mapping_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -23,98 +23,93 @@
 
 int main ()
 {
- std::string process_name;
- test::get_process_id_name(process_name);
-
    try{
- const std::size_t FileSize = 99999*2;
- //Create shared memory and file mapping
- windows_shared_memory mapping(create_only, process_name.c_str(), read_write, FileSize);
-
+ const char *names[2] = { test::get_process_id_name(), 0 };
+ for(unsigned int i = 0; i < sizeof(names)/sizeof(names[0]); ++i)
       {
+ const std::size_t FileSize = 99999*2;
          //Create a file mapping
- windows_shared_memory mapping(open_only, process_name.c_str(), read_write);
+ windows_shared_memory mapping
+ (create_only, names[i], read_write, FileSize);
 
- //Create two mapped regions, one half of the file each
- mapped_region region (mapping
- ,read_write
- ,0
- ,FileSize/2
- ,0);
-
- mapped_region region2(mapping
- ,read_write
- ,FileSize/2
- ,FileSize - FileSize/2
- ,0);
-
- //Fill two regions with a pattern
- unsigned char *filler = static_cast<unsigned char*>(region.get_address());
- for(std::size_t i = 0
- ;i < FileSize/2
- ;++i){
- *filler++ = static_cast<unsigned char>(i);
- }
+ {
 
- filler = static_cast<unsigned char*>(region2.get_address());
- for(std::size_t i = FileSize/2
- ;i < FileSize
- ;++i){
- *filler++ = static_cast<unsigned char>(i);
- }
- }
+ //Create two mapped regions, one half of the file each
+ mapped_region region (mapping
+ ,read_write
+ ,0
+ ,FileSize/2
+ ,0);
+
+ mapped_region region2(mapping
+ ,read_write
+ ,FileSize/2
+ ,FileSize - FileSize/2
+ ,0);
+
+ //Fill two regions with a pattern
+ unsigned char *filler = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize/2
+ ;++i){
+ *filler++ = static_cast<unsigned char>(i);
+ }
 
- //See if the pattern is correct in the file using two mapped regions
- {
- //Create a file mapping
- windows_shared_memory mapping(open_only, process_name.c_str(), read_write);
- mapped_region region(mapping, read_write, 0, FileSize/2, 0);
- mapped_region region2(mapping, read_write, FileSize/2, 0/*FileSize - FileSize/2*/, 0);
-
- unsigned char *checker = (unsigned char*)region.get_address();
- //Check pattern
- for(std::size_t i = 0
- ;i < FileSize/2
- ;++i){
- if(*checker++ != static_cast<unsigned char>(i)){
- return 1;
+ filler = static_cast<unsigned char*>(region2.get_address());
+ for(std::size_t i = FileSize/2
+ ;i < FileSize
+ ;++i){
+ *filler++ = static_cast<unsigned char>(i);
             }
          }
 
- //Check second half
- checker = (unsigned char *)region2.get_address();
+ //See if the pattern is correct in the file using two mapped regions
+ {
+ mapped_region region (mapping, read_only, 0, FileSize/2, 0);
+ mapped_region region2(mapping, read_only, FileSize/2, FileSize - FileSize/2, 0);
+
+ unsigned char *checker = (unsigned char*)region.get_address();
+ //Check pattern
+ for(std::size_t i = 0
+ ;i < FileSize/2
+ ;++i){
+ if(*checker++ != static_cast<unsigned char>(i)){
+ return 1;
+ }
+ }
+
+ //Check second half
+ checker = (unsigned char *)region2.get_address();
 
- //Check pattern
- for(std::size_t i = FileSize/2
- ;i < FileSize
- ;++i){
- if(*checker++ != static_cast<unsigned char>(i)){
- return 1;
+ //Check pattern
+ for(std::size_t i = FileSize/2
+ ;i < FileSize
+ ;++i){
+ if(*checker++ != static_cast<unsigned char>(i)){
+ return 1;
+ }
             }
          }
- }
-
- //Now check the pattern mapping a single read only mapped_region
- {
- //Create a file mapping
- windows_shared_memory mapping(open_only, process_name.c_str(), read_only);
 
- //Create a single regions, mapping all the file
- mapped_region region (mapping
- ,read_only);
-
- //Check pattern
- unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
- for(std::size_t i = 0
- ;i < FileSize
- ;++i, ++pattern){
- if(*pattern != static_cast<unsigned char>(i)){
- return 1;
+ //Now check the pattern mapping a single read only mapped_region
+ {
+ //Create a single regions, mapping all the file
+ mapped_region region (mapping, read_only);
+
+ //Check pattern
+ unsigned char *pattern = static_cast<unsigned char*>(region.get_address());
+ for(std::size_t i = 0
+ ;i < FileSize
+ ;++i, ++pattern){
+ if(*pattern != static_cast<unsigned char>(i)){
+ return 1;
+ }
             }
          }
       }
    }
    catch(std::exception &exc){
+ //shared_memory_object::remove(test::get_process_id_name());
       std::cout << "Unhandled exception: " << exc.what() << std::endl;
       return 1;
    }

Modified: branches/proto/v4/libs/interprocess/test/windows_shared_memory_test.cpp
==============================================================================
--- branches/proto/v4/libs/interprocess/test/windows_shared_memory_test.cpp (original)
+++ branches/proto/v4/libs/interprocess/test/windows_shared_memory_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -68,6 +68,7 @@
       std::cout << ex.what() << std::endl;
       return 1;
    }
+
    return 0;
 }
 

Modified: branches/proto/v4/libs/intrusive/doc/intrusive.qbk
==============================================================================
--- branches/proto/v4/libs/intrusive/doc/intrusive.qbk (original)
+++ branches/proto/v4/libs/intrusive/doc/intrusive.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -528,7 +528,25 @@
    small for user classes (usually the size of two pointers). Many operations have
    constant time complexity.
 
-* [*set/multiset]: A `std::set/std::multiset` like intrusive associative containers.
+* [*set/multiset/rbtree]: A `std::set/std::multiset` like intrusive associative containers
+ based on red-black trees.
+ The size overhead is moderate for user classes (usually the size of three pointers).
+ Many operations have logarithmic time complexity.
+
+* [*avl_set/avl_multiset/avltree]: A `std::set/std::multiset` like intrusive associative
+ containers based on AVL trees.
+ The size overhead is moderate for user classes (usually the size of three pointers).
+ Many operations have logarithmic time complexity.
+
+* [*splay_set/splay_multiset/splaytree]: A `std::set/std::multiset` like intrusive associative
+ containers based on splay trees. Splay trees have no constant operations, but they
+ have some interesting caching properties.
+ The size overhead is moderate for user classes (usually the size of three pointers).
+ Many operations have logarithmic time complexity.
+
+* [*sg_set/sg_multiset/sgtree]: A `std::set/std::multiset` like intrusive associative
+ containers based on scapegoat trees. Scapegoat can be configured with the desired
+ balance factor to achieve the desised rebalancing frequency/search time compromise.
    The size overhead is moderate for user classes (usually the size of three pointers).
    Many operations have logarithmic time complexity.
 
@@ -539,7 +557,7 @@
    The size overhead is moderate for user classes (an average of two pointers per element).
    Many operations have an amortized constant time complexity.
 
-Each of these intrusive containers can be configured with constant or linear time
+Most of these intrusive containers can be configured with constant or linear time
 size:
 
 * [*Linear time size]: The intrusive container doesn't hold a size member that it's
@@ -753,7 +771,7 @@
 only provides forward iterators.
 
 For most cases, a doubly linked list is preferrable because it offers more
-constant-time functions with a slightly bigger overhead.
+constant-time functions with a slightly bigger size overhead.
 However, for some applications like
 constructing more elaborated containers, singly linked lists are essential
 because of their low size overhead.
@@ -784,7 +802,8 @@
    it [classref boost::intrusive::slist slist]-compatible.
 
 [classref boost::intrusive::slist_base_hook slist_base_hook] and
-[classref boost::intrusive::slist_member_hook slist_member_hook] receive the same options explained in
+[classref boost::intrusive::slist_member_hook slist_member_hook]
+receive the same options explained in
 the section [link intrusive.usage How to use Boost.Intrusive]:
 
 * [*`tag<class Tag>`] (for base hooks only): This argument serves as a tag,
@@ -807,7 +826,7 @@
    template <class T, class ...Options>
    class slist;
 
-[classref boost::intrusive::slist slist] receives the same options explained in
+[classref boost::intrusive::slist slist] receives the options explained in
 the section [link intrusive.usage How to use Boost.Intrusive]:
 
 * [*`base_hook<class Hook>`] / [*`member_hook<class T, class Hook, Hook T::* PtrToMember>`] /
@@ -819,7 +838,23 @@
    Default: `constant_time_size<true>`
 
 * [*`size_type<bool Enabled>`]: To specify the type that will be used to store the size
- of the container. Default: `size_type<std::size_t>`
+ of the container. Default: `size_type<std::size_t>`.
+
+[classref boost::intrusive::slist slist] can receive additional options:
+
+* [*`linear<bool Enable>`]: the singly linked list is implemented as a
+ null-terminated list instead of a circular list. This allows `O(1)` swap,
+ but losses some operations like `container_from_end_iterator`.
+* [*`cache_last<bool Enable>`]: the singly linked also stores a pointer to the
+ last element of the singly linked list. This allows `O(1)` swap,
+ `splice_after(iterator, slist &)` and makes the list offer new functions
+ like `push_back(reference)` and `back()`. Logically, the size an empty list is
+ increased in `sizeof(void_pointer)` and the the cached last node pointer must
+ be updated in every operation, and that might incur in a slight performance impact.
+
+`auto_unlink` hooks are not usable if `linear<true>` and/or `cache_last<true>` options are
+used. If `auto_unlink` hooks are used and those options are specified, a static
+assertion will be raised.
 
 [endsect]
 
@@ -1151,6 +1186,11 @@
    rehashing is frequent or hashing the value is a slow operation.
    Default: `store_hash<false>`.
 
+* [*`optimize_multikey<bool Enabled>`]: This option reserves additional space in
+ the hook that will be used to group equal elements in unordered multisets,
+ improving significantly the performance when many equal values are inserted
+ in these containers. Default: `optimize_multikey<false>`.
+
 [endsect]
 
 [section:unordered_set_unordered_multiset_containers unordered_set and unordered_multiset containers]
@@ -1210,7 +1250,7 @@
 * [*`size_type<bool Enabled>`]: To specify the type that will be used to store the size
    of the container. Default: `size_type<std::size_t>`
 
-And they also can receive two additional options:
+And they also can receive additional options:
 
 * [*`equal<class Equal>`]: Equality function for the objects to be inserted
    in containers. Default: `equal< std::equal_to<T> >`
@@ -1228,7 +1268,14 @@
    modulo operations and for some applications modulo operations can impose
    a considerable overhead. In debug mode an assertion will be raised if the user
    provides a bucket length that is not power of two.
- Default: `constant_time_size<false>`.
+ Default: `power_2_buckets<false>`.
+
+* [*`cache_begin<bool Enabled>`]: Due to its internal structure, finding the first
+ element of an unordered container (`begin()` operation) is
+ amortized constant-time. It's possible to speed up `begin()` and other operations
+ related to it (like `clear()`) if the container caches internally the position
+ of the first element. This imposes the overhead of one pointer to the size
+ of the container. Default: `cache_begin<false>`.
 
 [endsect]
 
@@ -1301,13 +1348,13 @@
 balanced binary trees (such as red-black trees).
 
 The caching effect offered by splay trees comes with a cost: the tree must be
-rebalanced when a element is searched. This disallows const versions of search
+rebalanced when an element is searched. This disallows const versions of search
 functions like `find()`, `lower_bound()`, `upper_bound()`, `equal_range()`,
 `count()`...
 
 Because of this, splay-tree based associative containers are not drop-in
 replacements of [classref boost::intrusive::set set]/
-[classref boost::intrusive::splay_set splay_set].
+[classref boost::intrusive::multiset multiset].
 
 Apart from this, if element searches are randomized, the tree will be rebalanced
 without taking advantage of the cache effect, so splay trees can offer worse
@@ -1565,22 +1612,22 @@
 search tree.
 
 A binary search tree is said to be weight balanced if half the nodes are on the left
-of the root, and half on the right. An α-height-balanced tree is defined with defined
+of the root, and half on the right. An a-height-balanced tree is defined with defined
 with the following equation:
 
-[*['height(tree) <= log1/α(tree.size())]]
+[*['height(tree) <= log1/a(tree.size())]]
 
-* [*['α == 1]]: A tree forming a linked list is considered balanced.
-* [*['α == 0.5]]: Only a perfectly balanced binary is considered balanced.
+* [*['a == 1]]: A tree forming a linked list is considered balanced.
+* [*['a == 0.5]]: Only a perfectly balanced binary is considered balanced.
 
-Scapegoat trees are loosely ['α-height-balanced] so:
+Scapegoat trees are loosely ['a-height-balanced] so:
 
-[*['height(tree) <= log1/α(tree.size()) + 1]]
+[*['height(tree) <= log1/a(tree.size()) + 1]]
 
-Scapegoat trees support any α between 0.5 and 1. If α is higher, the tree is rebalanced
+Scapegoat trees support any a between 0.5 and 1. If a is higher, the tree is rebalanced
 less often, obtaining quicker insertions but slower searches. Lower
-α values improve search times. Scapegoat-trees implemented in [*Boost.Intrusive] offer the possibility of
-[*changing α at run-time] taking advantage of the flexibility of scapegoat trees.
+a values improve search times. Scapegoat-trees implemented in [*Boost.Intrusive] offer the possibility of
+[*changing a at run-time] taking advantage of the flexibility of scapegoat trees.
 For more information on scapegoat trees see [@http://en.wikipedia.org/wiki/Scapegoat_tree Wikipedia entry].
 
 Scapegoat trees also have downsides:
@@ -1591,7 +1638,7 @@
    tree is also considerably increased.
 
 * The operations needed to determine if the tree is unbalanced require floating-point
- operations like ['log1/α]. If the system has no floating point operations (like some
+ operations like ['log1/a]. If the system has no floating point operations (like some
    embedded systems), scapegoat tree operations might become slow.
 
 [*Boost.Intrusive] offers 3 containers based on scapegoat trees:
@@ -1689,9 +1736,9 @@
 
 * [*`floating_point<bool Enable>`]:
    When this option is deactivated, the scapegoat tree loses the ability to change
- the balance factor α at run-time, but the size of an empty container is reduced
+ the balance factor a at run-time, but the size of an empty container is reduced
    and no floating point operations are performed, normally increasing container
- performance. The fixed α factor that is used when this option is activated
+ performance. The fixed a factor that is used when this option is activated
    is ['1/sqrt(2) ~ 0,70711]. Default: `floating_point<true>`
 
 [endsect]
@@ -2523,6 +2570,63 @@
 
 [endsect]
 
+[/
+/
+/[section:sgtree_algorithms Intrusive sg tree algorithms]
+/
+/
+/[classref boost::intrusive::sgtree_algorithms sgtree_algorithms] have the same
+/interface as [classref boost::intrusive::rbtree_algorithms rbtree_algorithms].
+/
+/[c++]
+/
+/ template<class NodeTraits>
+/ struct sgtree_algorithms;
+/
+/[classref boost::intrusive::sgtree_algorithms sgtree_algorithms]
+/is configured with a NodeTraits class, which encapsulates
+/the information about the node to be manipulated. NodeTraits must support the
+/following interface:
+/
+/[*Typedefs]:
+/
+/* `node`: The type of the node that forms the circular sgtree
+/
+/* `node_ptr`: The type of a pointer to a node (usually node*)
+/
+/* `const_node_ptr`: The type of a pointer to a const node (usually const node*)
+/
+/[*Static functions]:
+/
+/* `static node_ptr get_parent(const_node_ptr n);`:
+/ Returns a pointer to the parent node stored in "n".
+/
+/* `static void set_parent(node_ptr n, node_ptr p);`:
+/ Sets the pointer to the parent node stored in "n" to "p".
+/
+/* `static node_ptr get_left(const_node_ptr n);`:
+/ Returns a pointer to the left node stored in "n".
+/
+/* `static void set_left(node_ptr n, node_ptr l);`:
+/ Sets the pointer to the left node stored in "n" to "l".
+/
+/* `static node_ptr get_right(const_node_ptr n);`:
+/ Returns a pointer to the right node stored in "n".
+/
+/* `static void set_right(node_ptr n, node_ptr r);`:
+/ Sets the pointer to the right node stored in "n" to "r".
+/
+/Once we have a node traits configuration we can use [*Boost.Intrusive] algorithms
+/with our nodes:
+/
+/[import ../example/doc_sgtree_algorithms.cpp]
+/[doc_sgtree_algorithms_code]
+/
+/For a complete list of functions see
+/[classref boost::intrusive::sgtree_algorithms sgtree_algorithms reference].
+/
+/[endsect]
+/]
 [endsect]
 
 [section:value_traits Containers with custom ValueTraits]
@@ -3011,7 +3115,7 @@
 `test_list` objects to funtion objects taking pointers to them.
 
 You can find the full test code code in the
-[@../../perf/perf_list.cpp perf_list.cpp] source file.
+[@../../libs/intrusive/perf/perf_list.cpp perf_list.cpp] source file.
 
 [section:performance_results_push_back Back insertion and destruction]
 
@@ -3104,7 +3208,7 @@
 These are the results:
 
 [table Reverse times for Visual C++ 7.1 / Windows XP
- [[Container] [Time in us/iteration (small object / big object)] [Normalized time (small object / big object) (small object / big object)]]
+ [[Container] [Time in us/iteration (small object / big object)] [Normalized time (small object / big object)]]
     [[`normal_link` intrusive list] [2656 / 10625] [1 / 1.83]]
     [[`safe_link` intrusive list] [2812 / 10937] [1.05 / 1.89]]
     [[`auto_unlink` intrusive list] [2710 / 10781] [1.02 / 1.86]]
@@ -3310,18 +3414,18 @@
 
 [endsect]
 
-[section:disabling_exceptions Disabling exceptions support]
+[section:release_notes Release Notes]
+
+[section:release_notes_boost_1_36_00 Boost 1.36 Release]
 
-[*Boost.Intrusive] might be useful in environments where exceptions are not available
-or recommendable (like embedded or real-time systems). [*Boost.Intrusive] uses the
-global Boost mechanism to disable exception handling, so that if the compiler
-configuration disables exceptions, `BOOST_NO_EXCEPTIONS` is defined and exception
-handling is disabled.
-
-This mechanism is a global mechanism to disable exceptions. If for any reason,
-the user wants to disable exception handling [*only] in [*Boost.Intrusive],
-`BOOST_INTRUSIVE_DISABLE_EXCEPTION_HANDLING` can be defined to disable
-exception handling in the library.
+* Added `linear<>` and `cache_last<>` options to singly linked lists.
+* Added `optimize_multikey<>` option to unordered container hooks.
+* Optimized unordered containers when `store_hash` option is used in the hook.
+* Implementation changed to be exception agnostic so that it can be used
+ in environments without exceptions.
+* Added `container_from_iterator` function to tree-based containers.
+
+[endsect]
 
 [endsect]
 
@@ -3331,13 +3435,13 @@
 
 * Visual 7.1/WinXP
 * Visual 8.0/WinXP
+* Visual 9.0/WinXP
 * GCC 4.1.1/MinGW
 * GCC 3.4.4/Cygwin
 * Intel 9.1/WinXP
 * GCC 4.1.2/Linux
 * GCC 3.4.3/Solaris 11
 * GCC 4.0/Mac Os 10.4.1
-* SunCC 5.8/Solaris 11
 
 [endsect]
 

Modified: branches/proto/v4/libs/intrusive/index.html
==============================================================================
--- branches/proto/v4/libs/intrusive/index.html (original)
+++ branches/proto/v4/libs/intrusive/index.html 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -4,6 +4,6 @@
 </head>
 <body>
 Automatic redirection failed, please go to
-../../doc/html/intrusive.html
+../../doc/html/intrusive
 </body>
 </html>

Modified: branches/proto/v4/libs/intrusive/perf/perf_list.cpp
==============================================================================
--- branches/proto/v4/libs/intrusive/perf/perf_list.cpp (original)
+++ branches/proto/v4/libs/intrusive/perf/perf_list.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -23,7 +23,7 @@
 //[perf_list_value_type
 //Iteration and element count defines
 const int NumIter = 100;
-const int NumElements = 100000;
+const int NumElements = 50000;
 
 using namespace boost::intrusive;
 

Modified: branches/proto/v4/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj
==============================================================================
--- branches/proto/v4/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj (original)
+++ branches/proto/v4/libs/intrusive/proj/vc7ide/_intrusivelib/_intrusivelib.vcproj 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -154,10 +154,7 @@
                                 RelativePath="..\..\..\..\..\boost\intrusive\options.hpp">
                         </File>
                         <File
- RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_2_bits.hpp">
- </File>
- <File
- RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bit.hpp">
+ RelativePath="..\..\..\..\..\boost\intrusive\pointer_plus_bits.hpp">
                         </File>
                         <File
                                 RelativePath="..\..\..\..\..\boost\intrusive\rbtree.hpp">
@@ -241,9 +238,6 @@
                                         RelativePath="..\..\..\..\..\boost\intrusive\detail\mpl.hpp">
                                 </File>
                                 <File
- RelativePath="..\..\..\..\..\boost\intrusive\detail\no_exceptions_support.hpp">
- </File>
- <File
                                         RelativePath="..\..\..\..\..\boost\intrusive\detail\parent_from_member.hpp">
                                 </File>
                                 <File

Modified: branches/proto/v4/libs/intrusive/test/avl_set_test.cpp
==============================================================================
--- branches/proto/v4/libs/intrusive/test/avl_set_test.cpp (original)
+++ branches/proto/v4/libs/intrusive/test/avl_set_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -108,7 +108,6 @@
 
 int main( int, char* [] )
 {
-
    test_main_template<void*, false>()();
    test_main_template<boost::intrusive::smart_ptr<void>, false>()();
    test_main_template<void*, true>()();

Modified: branches/proto/v4/libs/intrusive/test/generic_assoc_test.hpp
==============================================================================
--- branches/proto/v4/libs/intrusive/test/generic_assoc_test.hpp (original)
+++ branches/proto/v4/libs/intrusive/test/generic_assoc_test.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -52,9 +52,38 @@
    static void test_rebalance(std::vector<value_type>& values);
    static void test_rebalance(std::vector<value_type>& values, boost::intrusive::detail::true_type);
    static void test_rebalance(std::vector<value_type>& values, boost::intrusive::detail::false_type);
+ static void test_container_from_iterator(std::vector<value_type>& values);
 };
 
 template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
+void test_generic_assoc<ValueTraits, ContainerDefiner>::
+ test_container_from_iterator(std::vector<value_type>& values)
+{
+ typedef typename ContainerDefiner
+ < value_type
+ , value_traits<ValueTraits>
+ , constant_time_size<value_type::constant_time_size>
+ >::type assoc_type;
+
+ assoc_type testset(values.begin(), values.end());
+ typedef typename assoc_type::iterator it_type;
+ typedef typename assoc_type::const_iterator cit_type;
+ typedef typename assoc_type::size_type sz_type;
+ sz_type sz = testset.size();
+ for(it_type b(testset.begin()), e(testset.end()); b != e; ++b)
+ {
+ assoc_type &s = assoc_type::container_from_iterator(b);
+ const assoc_type &cs = assoc_type::container_from_iterator(cit_type(b));
+ BOOST_TEST(&s == &cs);
+ BOOST_TEST(&s == &testset);
+ s.erase(b);
+ BOOST_TEST(testset.size() == (sz-1));
+ s.insert(*b);
+ BOOST_TEST(testset.size() == sz);
+ }
+}
+
+template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
 void test_generic_assoc<ValueTraits, ContainerDefiner>::test_insert_erase_burst()
 {
    typedef typename ValueTraits::value_type value_type;
@@ -103,12 +132,14 @@
 template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
 void test_generic_assoc<ValueTraits, ContainerDefiner>::test_all(std::vector<typename ValueTraits::value_type>& values)
 {
+ typedef typename ValueTraits::value_type value_type;
    test_clone(values);
    test_container_from_end(values);
    test_splay_up(values);
    test_splay_down(values);
    test_rebalance(values);
    test_insert_erase_burst();
+ test_container_from_iterator(values);
 }
 
 template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>

Modified: branches/proto/v4/libs/intrusive/test/generic_set_test.hpp
==============================================================================
--- branches/proto/v4/libs/intrusive/test/generic_set_test.hpp (original)
+++ branches/proto/v4/libs/intrusive/test/generic_set_test.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -35,6 +35,7 @@
    static void test_impl();
 };
 
+
 template<class ValueTraits, template <class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none, class = ::boost::intrusive::none> class ContainerDefiner>
 void test_generic_set<ValueTraits, ContainerDefiner>::test_all()
 {

Modified: branches/proto/v4/libs/intrusive/test/itestvalue.hpp
==============================================================================
--- branches/proto/v4/libs/intrusive/test/itestvalue.hpp (original)
+++ branches/proto/v4/libs/intrusive/test/itestvalue.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -126,20 +126,30 @@
 struct uset_auto_base_hook_type
 {
    typedef unordered_set_base_hook
- < link_mode<auto_unlink>, void_pointer<VoidPointer>
- , tag<my_tag>, store_hash<true> > type;
+ < link_mode<auto_unlink>
+ , void_pointer<VoidPointer>
+ , tag<my_tag>
+ , store_hash<true>
+ > type;
 };
 
 template<class VoidPointer>
 struct uset_member_hook_type
-{ typedef unordered_set_member_hook<void_pointer<VoidPointer> > type; };
+{
+ typedef unordered_set_member_hook
+ < void_pointer<VoidPointer>
+ , optimize_multikey<true>
+ > type;
+};
 
 template<class VoidPointer>
 struct uset_auto_member_hook_type
 {
    typedef unordered_set_member_hook
       < link_mode<auto_unlink>, void_pointer<VoidPointer>
- , store_hash<true> > type;
+ , store_hash<true>
+ , optimize_multikey<true>
+ > type;
 };
 
 template<class VoidPointer, bool ConstantTimeSize>
@@ -318,6 +328,49 @@
       slist_auto_node_.swap_nodes(other.slist_auto_node_);
    }
 
+ bool is_linked() const
+ {
+ //Set
+ return set_base_hook_t::is_linked() ||
+ set_auto_base_hook_t::is_linked() ||
+ set_node_.is_linked() ||
+ set_auto_node_.is_linked() ||
+
+ //SplaySet
+ splay_set_base_hook_t::is_linked() ||
+ splay_set_auto_base_hook_t::is_linked() ||
+ splay_set_node_.is_linked() ||
+ splay_set_auto_node_.is_linked() ||
+
+ //ScapeoatSet
+ bs_set_base_hook_t::is_linked() ||
+ sg_set_node_.is_linked() ||
+
+ //AvlSet
+ avl_set_base_hook_t::is_linked() ||
+ avl_set_auto_base_hook_t::is_linked() ||
+ avl_set_node_.is_linked() ||
+ avl_set_auto_node_.is_linked() ||
+
+ //Unordered set
+ unordered_set_base_hook_t::is_linked() ||
+ unordered_set_auto_base_hook_t::is_linked() ||
+ unordered_set_node_.is_linked() ||
+ unordered_set_auto_node_.is_linked() ||
+
+ //List
+ list_base_hook_t::is_linked() ||
+ list_auto_base_hook_t::is_linked() ||
+ list_node_.is_linked() ||
+ list_auto_node_.is_linked() ||
+
+ //Slist
+ slist_base_hook_t::is_linked() ||
+ slist_auto_base_hook_t::is_linked() ||
+ slist_node_.is_linked() ||
+ slist_auto_node_.is_linked();
+ }
+
    ~testvalue()
    {}
 

Modified: branches/proto/v4/libs/intrusive/test/smart_ptr.hpp
==============================================================================
--- branches/proto/v4/libs/intrusive/test/smart_ptr.hpp (original)
+++ branches/proto/v4/libs/intrusive/test/smart_ptr.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -12,8 +12,7 @@
 #define BOOST_INTRUSIVE_SMART_PTR_HPP
 
 #include <boost/iterator.hpp>
-#include <boost/intrusive/pointer_plus_bit.hpp>
-#include <boost/intrusive/pointer_plus_2_bits.hpp>
+#include <boost/intrusive/pointer_plus_bits.hpp>
 
 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
 # pragma once
@@ -109,7 +108,7 @@
    public: //Public Functions
 
    //!Constructor from raw pointer (allows "0" pointer conversion). Never throws.
- smart_ptr(pointer ptr = 0)
+ explicit smart_ptr(pointer ptr = 0)
       : m_ptr(ptr)
    {}
 
@@ -351,67 +350,34 @@
 //for intrusive containers, saving space
 namespace intrusive {
 
-template<std::size_t N>
-struct has_pointer_plus_bit<smart_ptr<void>, N>
+template<std::size_t Alignment>
+struct max_pointer_plus_bits<smart_ptr<void>, Alignment>
 {
- static const bool value = has_pointer_plus_bit<void*, N>::value;
+ static const std::size_t value = max_pointer_plus_bits<void*, Alignment>::value;
 };
 
-//Specialization
-template<class T>
-struct pointer_plus_bit<smart_ptr<T> >
-{
- typedef smart_ptr<T> pointer;
-
- static pointer get_pointer(const pointer &n)
- { return pointer_plus_bit<T*>::get_pointer(n.get()); }
-
- static void set_pointer(pointer &n, pointer p)
- {
- T *raw_n = n.get();
- pointer_plus_bit<T*>::set_pointer(raw_n, p.get());
- n = raw_n;
- }
-
- static bool get_bit(const pointer &n)
- { return pointer_plus_bit<T*>::get_bit(n.get()); }
-
- static void set_bit(pointer &n, bool c)
- {
- T *raw_n = n.get();
- pointer_plus_bit<T*>::set_bit(raw_n, c);
- n = raw_n;
- }
-};
-
-template<std::size_t N>
-struct has_pointer_plus_2_bits<smart_ptr<void>, N>
-{
- static const bool value = has_pointer_plus_2_bits<void*, N>::value;
-};
-
-template<class T>
-struct pointer_plus_2_bits<smart_ptr<T> >
+template<class T, std::size_t NumBits>
+struct pointer_plus_bits<smart_ptr<T>, NumBits>
 {
    typedef smart_ptr<T> pointer;
 
    static pointer get_pointer(const pointer &n)
- { return pointer_plus_2_bits<T*>::get_pointer(n.get()); }
+ { return pointer_plus_bits<T*, NumBits>::get_pointer(n.get()); }
 
    static void set_pointer(pointer &n, pointer p)
    {
       T *raw_n = n.get();
- pointer_plus_2_bits<T*>::set_pointer(raw_n, p.get());
+ pointer_plus_bits<T*, NumBits>::set_pointer(raw_n, p.get());
       n = raw_n;
    }
 
    static std::size_t get_bits(const pointer &n)
- { return pointer_plus_2_bits<T*>::get_bits(n.get()); }
+ { return pointer_plus_bits<T*, NumBits>::get_bits(n.get()); }
 
    static void set_bits(pointer &n, std::size_t c)
    {
       T *raw_n = n.get();
- pointer_plus_2_bits<T*>::set_bits(raw_n, c);
+ pointer_plus_bits<T*, NumBits>::set_bits(raw_n, c);
       n = raw_n;
    }
 };

Modified: branches/proto/v4/libs/intrusive/test/unordered_multiset_test.cpp
==============================================================================
--- branches/proto/v4/libs/intrusive/test/unordered_multiset_test.cpp (original)
+++ branches/proto/v4/libs/intrusive/test/unordered_multiset_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,6 +18,7 @@
 #include "smart_ptr.hpp"
 #include "common_functors.hpp"
 #include <vector>
+#include <algorithm> //std::sort std::find
 #include <set>
 #include <boost/detail/lightweight_test.hpp>
 #include "test_macros.hpp"
@@ -27,7 +28,7 @@
 
 static const std::size_t BucketSize = 11;
 
-template<class ValueTraits>
+template<class ValueTraits, bool CacheBegin>
 struct test_unordered_multiset
 {
    typedef typename ValueTraits::value_type value_type;
@@ -41,14 +42,15 @@
    static void test_clone(std::vector<value_type>& values);
 };
 
-template<class ValueTraits>
-void test_unordered_multiset<ValueTraits>::test_all (std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_multiset<ValueTraits, CacheBegin>::test_all (std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_multiset
- <value_type
+ < value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_multiset_type;
    {
       typedef typename unordered_multiset_type::bucket_traits bucket_traits;
@@ -76,14 +78,15 @@
 }
 
 //test case due to an error in tree implementation:
-template<class ValueTraits>
-void test_unordered_multiset<ValueTraits>::test_impl()
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_multiset<ValueTraits, CacheBegin>::test_impl()
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_multiset
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_multiset_type;
    typedef typename unordered_multiset_type::bucket_traits bucket_traits;
 
@@ -106,14 +109,15 @@
 }
 
 //test: constructor, iterator, clear, reverse_iterator, front, back, size:
-template<class ValueTraits>
-void test_unordered_multiset<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_multiset<ValueTraits, CacheBegin>::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_multiset
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_multiset_type;
    typedef typename unordered_multiset_type::bucket_traits bucket_traits;
 
@@ -127,104 +131,187 @@
 }
   
 //test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
-template<class ValueTraits>
-void test_unordered_multiset<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_multiset<ValueTraits, CacheBegin>::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_multiset
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_multiset_type;
    typedef typename unordered_multiset_type::bucket_traits bucket_traits;
+ typedef typename unordered_multiset_type::iterator iterator;
+ {
+ typename unordered_multiset_type::bucket_type buckets [BucketSize];
+ unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
 
- typename unordered_multiset_type::bucket_type buckets [BucketSize];
- unordered_multiset_type testset(bucket_traits(buckets, BucketSize));
-
- testset.insert(&values[0] + 2, &values[0] + 5);
-
- const unordered_multiset_type& const_testset = testset;
- { int init_values [] = { 1, 4, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ testset.insert(&values[0] + 2, &values[0] + 5);
 
- typename unordered_multiset_type::iterator i = testset.begin();
- BOOST_TEST (i->value_ == 1);
+ const unordered_multiset_type& const_testset = testset;
+ { int init_values [] = { 1, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+
+ typename unordered_multiset_type::iterator i = testset.begin();
+ BOOST_TEST (i->value_ == 1);
+
+ i = testset.insert (values[0]);
+ BOOST_TEST (&*i == &values[0]);
+
+ i = testset.iterator_to (values[2]);
+ BOOST_TEST (&*i == &values[2]);
+ testset.erase(i);
 
- i = testset.insert (values[0]);
- BOOST_TEST (&*i == &values[0]);
-
- i = testset.iterator_to (values[2]);
- BOOST_TEST (&*i == &values[2]);
- testset.erase(i);
-
- { int init_values [] = { 1, 3, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
- testset.clear();
- testset.insert(&values[0], &values[0] + values.size());
+ { int init_values [] = { 1, 3, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ testset.clear();
+ testset.insert(&values[0], &values[0] + values.size());
 
- { int init_values [] = { 1, 2, 2, 3, 4, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
+ { int init_values [] = { 1, 2, 2, 3, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, const_testset.begin() ); }
 
- BOOST_TEST (testset.erase(1) == 1);
- BOOST_TEST (testset.erase(2) == 2);
- BOOST_TEST (testset.erase(3) == 1);
- BOOST_TEST (testset.erase(4) == 1);
- BOOST_TEST (testset.erase(5) == 1);
- BOOST_TEST (testset.empty() == true);
-
- //Now with a single bucket
- typename unordered_multiset_type::bucket_type single_bucket[1];
- unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
- testset2.insert(&values[0], &values[0] + values.size());
- BOOST_TEST (testset2.erase(5) == 1);
- BOOST_TEST (testset2.erase(2) == 2);
- BOOST_TEST (testset2.erase(1) == 1);
- BOOST_TEST (testset2.erase(4) == 1);
- BOOST_TEST (testset2.erase(3) == 1);
- BOOST_TEST (testset2.empty() == true);
+ BOOST_TEST (testset.erase(1) == 1);
+ BOOST_TEST (testset.erase(2) == 2);
+ BOOST_TEST (testset.erase(3) == 1);
+ BOOST_TEST (testset.erase(4) == 1);
+ BOOST_TEST (testset.erase(5) == 1);
+ BOOST_TEST (testset.empty() == true);
+
+ //Now with a single bucket
+ typename unordered_multiset_type::bucket_type single_bucket[1];
+ unordered_multiset_type testset2(bucket_traits(single_bucket, 1));
+ testset2.insert(&values[0], &values[0] + values.size());
+ BOOST_TEST (testset2.erase(5) == 1);
+ BOOST_TEST (testset2.erase(2) == 2);
+ BOOST_TEST (testset2.erase(1) == 1);
+ BOOST_TEST (testset2.erase(4) == 1);
+ BOOST_TEST (testset2.erase(3) == 1);
+ BOOST_TEST (testset2.empty() == true);
+ }
+ {
+ //Now erase just one per loop
+ const int random_init[] = { 3, 2, 4, 1, 5, 2, 2 };
+ const unsigned int random_size = sizeof(random_init)/sizeof(random_init[0]);
+ typename unordered_multiset_type::bucket_type single_bucket[1];
+ for(unsigned int i = 0, max = random_size; i != max; ++i){
+ std::vector<typename ValueTraits::value_type> data (random_size);
+ for (unsigned int j = 0; j < random_size; ++j)
+ data[j].value_ = random_init[j];
+ unordered_multiset_type testset_new(bucket_traits(single_bucket, 1));
+ testset_new.insert(&data[0], &data[0]+max);
+ testset_new.erase(testset_new.iterator_to(data[i]));
+ BOOST_TEST (testset_new.size() == (max -1));
+ }
+ }
+ {
+ typename unordered_multiset_type::bucket_type buckets [BucketSize];
+ const unsigned int NumBucketSize = BucketSize;
+ const unsigned int LoadFactor = 3;
+ const unsigned int NumIterations = NumBucketSize*LoadFactor;
+ std::vector<value_type> random_init(NumIterations);//Preserve memory
+ std::vector<value_type> set_tester;
+ set_tester.reserve(NumIterations);
+
+ //Initialize values
+ for (unsigned int i = 0; i < NumIterations; ++i){
+ random_init[i].value_ = i*2;//(i/LoadFactor)*LoadFactor;
+ }
+
+ for(unsigned int initial_pos = 0; initial_pos != (NumIterations+1); ++initial_pos){
+ for(unsigned int final_pos = initial_pos; final_pos != (NumIterations+1); ++final_pos){
+
+ //Create intrusive container inserting values
+ unordered_multiset_type testset
+ ( &random_init[0]
+ , &random_init[0] + random_init.size()
+ , bucket_traits(buckets, NumBucketSize));
+
+ BOOST_TEST (testset.size() == random_init.size());
+
+ //Obtain the iterator range to erase
+ iterator it_beg_pos = testset.begin();
+ for(unsigned int it_beg_pos_num = 0; it_beg_pos_num != initial_pos; ++it_beg_pos_num){
+ ++it_beg_pos;
+ }
+ iterator it_end_pos(it_beg_pos);
+ for(unsigned int it_end_pos_num = 0; it_end_pos_num != (final_pos - initial_pos); ++it_end_pos_num){
+ ++it_end_pos;
+ }
+
+ //Erase the same values in both the intrusive and original vector
+ std::size_t erased_cnt = std::distance(it_beg_pos, it_end_pos);
+
+ //Erase values from the intrusive container
+ testset.erase(it_beg_pos, it_end_pos);
+
+ BOOST_TEST (testset.size() == (random_init.size()-(final_pos - initial_pos)));
+
+ //Now test...
+ BOOST_TEST ((random_init.size() - erased_cnt) == testset.size());
+
+ //Create an ordered copy of the intrusive container
+ set_tester.insert(set_tester.end(), testset.begin(), testset.end());
+ std::sort(set_tester.begin(), set_tester.end());
+ {
+ typename std::vector<value_type>::iterator it = set_tester.begin(), itend = set_tester.end();
+ typename std::vector<value_type>::iterator random_init_it(random_init.begin());
+ for( ; it != itend; ++it){
+ while(!random_init_it->is_linked())
+ ++random_init_it;
+ BOOST_TEST(*it == *random_init_it);
+ ++random_init_it;
+ }
+ }
+ set_tester.clear();
+ }
+ }
+ }
 }
 
 //test: insert (seq-version), swap, erase (seq-version), size:
-template<class ValueTraits>
-void test_unordered_multiset<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_multiset<ValueTraits, CacheBegin>::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_multiset
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_multiset_type;
    typedef typename unordered_multiset_type::bucket_traits bucket_traits;
-
    typename unordered_multiset_type::bucket_type buckets [BucketSize];
- typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
- unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
- unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
-
- testset2.insert (&values[0] + 2, &values[0] + 6);
- testset1.swap (testset2);
+ {
+ typename unordered_multiset_type::bucket_type buckets2 [BucketSize];
+ unordered_multiset_type testset1(&values[0], &values[0] + 2, bucket_traits(buckets, BucketSize));
+ unordered_multiset_type testset2(bucket_traits(buckets2, BucketSize));
 
- { int init_values [] = { 1, 2, 4, 5 };
- TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
+ testset2.insert (&values[0] + 2, &values[0] + 6);
+ testset1.swap (testset2);
 
- { int init_values [] = { 2, 3 };
- TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+ { int init_values [] = { 1, 2, 4, 5 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset1.begin() ); }
 
- testset1.erase (testset1.iterator_to(values[5]), testset1.end());
- BOOST_TEST (testset1.size() == 1);
- // BOOST_TEST (&testset1.front() == &values[3]);
- BOOST_TEST (&*testset1.begin() == &values[3]);
+ { int init_values [] = { 2, 3 };
+ TEST_INTRUSIVE_SEQUENCE( init_values, testset2.begin() ); }
+ testset1.erase (testset1.iterator_to(values[5]), testset1.end());
+ BOOST_TEST (testset1.size() == 1);
+ // BOOST_TEST (&testset1.front() == &values[3]);
+ BOOST_TEST (&*testset1.begin() == &values[3]);
+ }
 }
 
 //test: rehash:
-template<class ValueTraits>
-void test_unordered_multiset<ValueTraits>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_multiset<ValueTraits, CacheBegin>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_multiset
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_multiset_type;
    typedef typename unordered_multiset_type::bucket_traits bucket_traits;
 
@@ -261,14 +348,15 @@
 }
 
 //test: find, equal_range (lower_bound, upper_bound):
-template<class ValueTraits>
-void test_unordered_multiset<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_multiset<ValueTraits, CacheBegin>::test_find(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_multiset
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_multiset_type;
    typedef typename unordered_multiset_type::bucket_traits bucket_traits;
 
@@ -293,8 +381,8 @@
 }
 
 
-template<class ValueTraits>
-void test_unordered_multiset<ValueTraits>
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_multiset<ValueTraits, CacheBegin>
    ::test_clone(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -302,6 +390,7 @@
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_multiset_type;
    typedef typename unordered_multiset_type::bucket_traits bucket_traits;
    {
@@ -373,6 +462,7 @@
                   < value_type
                   , typename value_type::unordered_set_base_hook_t
>::type
+ , true
>::test_all(data);
 
       test_unordered_multiset < typename detail::get_member_value_traits
@@ -382,6 +472,7 @@
                                , &value_type::unordered_set_node_
>
>::type
+ , false
>::test_all(data);
 
       return 0;
@@ -404,6 +495,7 @@
                   < value_type
                   , typename value_type::unordered_set_base_hook_t
>::type
+ , true
>::test_all(data);
 
       test_unordered_multiset < typename detail::get_member_value_traits
@@ -413,12 +505,14 @@
                                , &value_type::unordered_set_node_
>
>::type
+ , false
>::test_all(data);
 
       test_unordered_multiset < typename detail::get_base_value_traits
                   < value_type
                   , typename value_type::unordered_set_auto_base_hook_t
>::type
+ , true
>::test_all(data);
 
       test_unordered_multiset < typename detail::get_member_value_traits
@@ -428,6 +522,7 @@
                                , &value_type::unordered_set_auto_node_
>
>::type
+ , false
>::test_all(data);
       return 0;
    }

Modified: branches/proto/v4/libs/intrusive/test/unordered_set_test.cpp
==============================================================================
--- branches/proto/v4/libs/intrusive/test/unordered_set_test.cpp (original)
+++ branches/proto/v4/libs/intrusive/test/unordered_set_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -26,7 +26,7 @@
 
 static const std::size_t BucketSize = 11;
 
-template<class ValueTraits>
+template<class ValueTraits, bool CacheBegin>
 struct test_unordered_set
 {
    typedef typename ValueTraits::value_type value_type;
@@ -40,14 +40,15 @@
    static void test_clone(std::vector<value_type>& values);
 };
 
-template<class ValueTraits>
-void test_unordered_set<ValueTraits>::test_all(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_set<ValueTraits, CacheBegin>::test_all(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_set
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_set_type;
    typedef typename unordered_set_type::bucket_traits bucket_traits;
    {
@@ -75,14 +76,15 @@
 }
 
 //test case due to an error in tree implementation:
-template<class ValueTraits>
-void test_unordered_set<ValueTraits>::test_impl()
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_set<ValueTraits, CacheBegin>::test_impl()
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_set
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_set_type;
    typedef typename unordered_set_type::bucket_traits bucket_traits;
 
@@ -103,14 +105,15 @@
 }
 
 //test: constructor, iterator, clear, reverse_iterator, front, back, size:
-template<class ValueTraits>
-void test_unordered_set<ValueTraits>::test_sort(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_set<ValueTraits, CacheBegin>::test_sort(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_set
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_set_type;
    typedef typename unordered_set_type::bucket_traits bucket_traits;
 
@@ -126,14 +129,15 @@
 }
   
 //test: insert, const_iterator, const_reverse_iterator, erase, iterator_to:
-template<class ValueTraits>
-void test_unordered_set<ValueTraits>::test_insert(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_set<ValueTraits, CacheBegin>::test_insert(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_set
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_set_type;
    typedef typename unordered_set_type::bucket_traits bucket_traits;
 
@@ -161,14 +165,15 @@
 }
 
 //test: insert (seq-version), swap, erase (seq-version), size:
-template<class ValueTraits>
-void test_unordered_set<ValueTraits>::test_swap(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_set<ValueTraits, CacheBegin>::test_swap(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_set
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_set_type;
    typedef typename unordered_set_type::bucket_traits bucket_traits;
 
@@ -192,14 +197,15 @@
 }
 
 //test: rehash:
-template<class ValueTraits>
-void test_unordered_set<ValueTraits>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_set<ValueTraits, CacheBegin>::test_rehash(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_set
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_set_type;
    typedef typename unordered_set_type::bucket_traits bucket_traits;
 
@@ -237,14 +243,15 @@
 
 
 //test: find, equal_range (lower_bound, upper_bound):
-template<class ValueTraits>
-void test_unordered_set<ValueTraits>::test_find(std::vector<typename ValueTraits::value_type>& values)
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_set<ValueTraits, CacheBegin>::test_find(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
    typedef unordered_set
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_set_type;
    typedef typename unordered_set_type::bucket_traits bucket_traits;
 
@@ -267,8 +274,8 @@
    BOOST_TEST (testset.find (cmp_val) == testset.end());
 }
 
-template<class ValueTraits>
-void test_unordered_set<ValueTraits>
+template<class ValueTraits, bool CacheBegin>
+void test_unordered_set<ValueTraits, CacheBegin>
    ::test_clone(std::vector<typename ValueTraits::value_type>& values)
 {
    typedef typename ValueTraits::value_type value_type;
@@ -276,6 +283,7 @@
       <value_type
       , value_traits<ValueTraits>
       , constant_time_size<value_type::constant_time_size>
+ , cache_begin<CacheBegin>
> unordered_set_type;
    typedef typename unordered_set_type::bucket_traits bucket_traits;
    {
@@ -347,6 +355,7 @@
                   < value_type
                   , typename value_type::unordered_set_base_hook_t
>::type
+ , true
>::test_all(data);
       test_unordered_set < typename detail::get_member_value_traits
                   < value_type
@@ -355,6 +364,7 @@
                                , &value_type::unordered_set_node_
>
>::type
+ , false
>::test_all(data);
 
       return 0;
@@ -377,6 +387,7 @@
                   < value_type
                   , typename value_type::unordered_set_base_hook_t
>::type
+ , true
>::test_all(data);
 
       test_unordered_set < typename detail::get_member_value_traits
@@ -386,12 +397,14 @@
                                , &value_type::unordered_set_node_
>
>::type
+ , false
>::test_all(data);
 
       test_unordered_set < typename detail::get_base_value_traits
                   < value_type
                   , typename value_type::unordered_set_auto_base_hook_t
>::type
+ , true
>::test_all(data);
 
       test_unordered_set < typename detail::get_member_value_traits
@@ -401,6 +414,7 @@
                                , &value_type::unordered_set_auto_node_
>
>::type
+ , false
>::test_all(data);
       return 0;
    }

Modified: branches/proto/v4/libs/math/test/common_factor_test.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/common_factor_test.cpp (original)
+++ branches/proto/v4/libs/math/test/common_factor_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -113,7 +113,7 @@
 // Various types to test with each GCD/LCM
 typedef ::boost::mpl::list<signed char, short, int, long,
 #ifdef BOOST_HAS_LONG_LONG
- long long,
+ boost::long_long_type,
 #elif defined(BOOST_HAS_MS_INT64)
  __int64,
 #endif
@@ -121,7 +121,7 @@
 typedef ::boost::mpl::list<unsigned char, unsigned short, unsigned,
  unsigned long,
 #ifdef BOOST_HAS_LONG_LONG
- unsigned long long,
+ boost::ulong_long_type,
 #elif defined(BOOST_HAS_MS_INT64)
  unsigned __int64,
 #endif

Modified: branches/proto/v4/libs/math/test/compile_test/instantiate.hpp
==============================================================================
--- branches/proto/v4/libs/math/test/compile_test/instantiate.hpp (original)
+++ branches/proto/v4/libs/math/test/compile_test/instantiate.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -16,6 +16,8 @@
 #include <boost/math/special_functions.hpp>
 #include <boost/math/concepts/distributions.hpp>
 
+#ifndef BOOST_MATH_INSTANTIATE_MINIMUM
+
 typedef boost::math::policies::policy<> test_policy;
 
 namespace test{
@@ -29,6 +31,7 @@
 BOOST_MATH_DECLARE_DISTRIBUTIONS(double, test_policy)
 
 }
+#endif
 
 namespace boost{ namespace math{
 //
@@ -79,7 +82,7 @@
    function_requires<DistributionConcept<non_central_beta_distribution<RealType> > >();
    function_requires<DistributionConcept<non_central_f_distribution<RealType> > >();
    function_requires<DistributionConcept<non_central_t_distribution<RealType> > >();
-
+#ifndef BOOST_MATH_INSTANTIATE_MINIMUM
    function_requires<DistributionConcept<bernoulli_distribution<RealType, test_policy> > >();
    function_requires<DistributionConcept<beta_distribution<RealType, test_policy> > >();
    function_requires<DistributionConcept<binomial_distribution<RealType, test_policy> > >();
@@ -128,7 +131,7 @@
    function_requires<DistributionConcept<dist_test::non_central_beta > >();
    function_requires<DistributionConcept<dist_test::non_central_f > >();
    function_requires<DistributionConcept<dist_test::non_central_t > >();
-
+#endif
    int i;
    RealType v1(0.5), v2(0.5), v3(0.5);
    boost::math::tgamma(v1);
@@ -242,10 +245,11 @@
 #ifdef BOOST_HAS_LONG_LONG
    boost::math::lltrunc(v1);
    boost::math::llround(v1);
- long long ll;
+ boost::long_long_type ll;
    boost::math::modf(v1, &ll);
 #endif
    boost::math::pow<2>(v1);
+#ifndef BOOST_MATH_INSTANTIATE_MINIMUM
    //
    // All over again, with a policy this time:
    //
@@ -483,6 +487,7 @@
    test::modf(v1, &ll);
 #endif
    test::pow<2>(v1);
+#endif
 }
 
 template <class RealType>
@@ -490,7 +495,7 @@
 {
    using namespace boost;
    using namespace boost::math;
-
+#ifndef BOOST_MATH_INSTANTIATE_MINIMUM
    int i = 1;
    long l = 1;
    short s = 1;
@@ -839,6 +844,7 @@
    test::sph_bessel(i, 1);
    test::sph_neumann(i, lr);
    test::sph_neumann(i, i);
+#endif
 }
 
 

Modified: branches/proto/v4/libs/math/test/compile_test/sf_modf_incl_test.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/compile_test/sf_modf_incl_test.cpp (original)
+++ branches/proto/v4/libs/math/test/compile_test/sf_modf_incl_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -20,7 +20,7 @@
 int ii;
 long ll;
 #ifdef BOOST_HAS_LONG_LONG
-long long llll;
+boost::long_long_type llll;
 #endif
 
 void check()

Modified: branches/proto/v4/libs/math/test/compile_test/sf_round_incl_test.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/compile_test/sf_round_incl_test.cpp (original)
+++ branches/proto/v4/libs/math/test/compile_test/sf_round_incl_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -31,10 +31,10 @@
    check_result<long>(boost::math::lround<long double>(l));
 #endif
 #ifdef BOOST_HAS_LONG_LONG
- check_result<long long>(boost::math::llround<float>(f));
- check_result<long long>(boost::math::llround<double>(d));
+ check_result<boost::long_long_type>(boost::math::llround<float>(f));
+ check_result<boost::long_long_type>(boost::math::llround<double>(d));
 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
- check_result<long long>(boost::math::llround<long double>(l));
+ check_result<boost::long_long_type>(boost::math::llround<long double>(l));
 #endif
 #endif
 }

Modified: branches/proto/v4/libs/math/test/compile_test/sf_trunc_incl_test.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/compile_test/sf_trunc_incl_test.cpp (original)
+++ branches/proto/v4/libs/math/test/compile_test/sf_trunc_incl_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -31,10 +31,10 @@
    check_result<long>(boost::math::ltrunc<long double>(l));
 #endif
 #ifdef BOOST_HAS_LONG_LONG
- check_result<long long>(boost::math::lltrunc<float>(f));
- check_result<long long>(boost::math::lltrunc<double>(d));
+ check_result<boost::long_long_type>(boost::math::lltrunc<float>(f));
+ check_result<boost::long_long_type>(boost::math::lltrunc<double>(d));
 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
- check_result<long long>(boost::math::lltrunc<long double>(l));
+ check_result<boost::long_long_type>(boost::math::lltrunc<long double>(l));
 #endif
 #endif
 }

Modified: branches/proto/v4/libs/math/test/compile_test/test_compile_result.hpp
==============================================================================
--- branches/proto/v4/libs/math/test/compile_test/test_compile_result.hpp (original)
+++ branches/proto/v4/libs/math/test/compile_test/test_compile_result.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -24,7 +24,7 @@
 inline void check_result_imp(int, int){}
 inline void check_result_imp(long, long){}
 #ifdef BOOST_HAS_LONG_LONG
-inline void check_result_imp(long long, long long){}
+inline void check_result_imp(boost::long_long_type, boost::long_long_type){}
 #endif
 inline void check_result_imp(bool, bool){}
 

Modified: branches/proto/v4/libs/math/test/pow_test.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/pow_test.cpp (original)
+++ branches/proto/v4/libs/math/test/pow_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -109,7 +109,7 @@
 #ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
     BOOST_STATIC_ASSERT((is_same<BOOST_TYPEOF(pow<2>(7.0l)), long double>::value));
 #endif
-};
+}
 
 
 namespace boost { namespace math { namespace policies {

Modified: branches/proto/v4/libs/math/test/test_rational_instances/test_rational_double4.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/test_rational_instances/test_rational_double4.cpp (original)
+++ branches/proto/v4/libs/math/test/test_rational_instances/test_rational_double4.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,5 +6,5 @@
 #include "test_rational.hpp"
 
 #ifdef BOOST_HAS_LONG_LONG
-template void do_test_spots<double, unsigned long long>(double, unsigned long long);
+template void do_test_spots<double, boost::ulong_long_type>(double, boost::ulong_long_type);
 #endif

Modified: branches/proto/v4/libs/math/test/test_rational_instances/test_rational_float4.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/test_rational_instances/test_rational_float4.cpp (original)
+++ branches/proto/v4/libs/math/test/test_rational_instances/test_rational_float4.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,5 +7,5 @@
 #include "test_rational.hpp"
 
 #ifdef BOOST_HAS_LONG_LONG
-template void do_test_spots<float, unsigned long long>(float, unsigned long long);
+template void do_test_spots<float, boost::ulong_long_type>(float, boost::ulong_long_type);
 #endif

Modified: branches/proto/v4/libs/math/test/test_rational_instances/test_rational_ldouble4.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/test_rational_instances/test_rational_ldouble4.cpp (original)
+++ branches/proto/v4/libs/math/test/test_rational_instances/test_rational_ldouble4.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,5 +7,5 @@
 #include "test_rational.hpp"
 
 #ifdef BOOST_HAS_LONG_LONG
-template void do_test_spots<long double, unsigned long long>(long double, unsigned long long);
+template void do_test_spots<long double, boost::ulong_long_type>(long double, boost::ulong_long_type);
 #endif

Modified: branches/proto/v4/libs/math/test/test_rational_instances/test_rational_real_concept4.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/test_rational_instances/test_rational_real_concept4.cpp (original)
+++ branches/proto/v4/libs/math/test/test_rational_instances/test_rational_real_concept4.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,6 +11,6 @@
 #include <boost/math/concepts/real_concept.hpp>
 
 #ifdef BOOST_HAS_LONG_LONG
-template void do_test_spots<boost::math::concepts::real_concept, unsigned long long>(boost::math::concepts::real_concept, unsigned long long);
+template void do_test_spots<boost::math::concepts::real_concept, boost::ulong_long_type>(boost::math::concepts::real_concept, boost::ulong_long_type);
 #endif
 #endif

Modified: branches/proto/v4/libs/math/test/test_rationals.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/test_rationals.cpp (original)
+++ branches/proto/v4/libs/math/test/test_rationals.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -20,7 +20,7 @@
    do_test_spots(t, int(0));
    do_test_spots(t, unsigned(0));
 #ifdef BOOST_HAS_LONG_LONG
- do_test_spots(t, (unsigned long long)(0));
+ do_test_spots(t, (boost::ulong_long_type)(0));
 #endif
    do_test_spots(t, float(0));
    do_test_spots(t, T(0));

Modified: branches/proto/v4/libs/math/test/test_round.cpp
==============================================================================
--- branches/proto/v4/libs/math/test/test_round.cpp (original)
+++ branches/proto/v4/libs/math/test/test_round.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -141,9 +141,9 @@
       }
 
 #ifdef BOOST_HAS_LONG_LONG
- if(abs(r) < (std::numeric_limits<long long>::max)())
+ if(abs(r) < (std::numeric_limits<boost::long_long_type>::max)())
       {
- long long ll = boost::math::llround(arg);
+ boost::long_long_type ll = boost::math::llround(arg);
          check_within_half(arg, ll);
          ll = boost::math::lltrunc(arg);
          check_trunc_result(arg, ll);

Modified: branches/proto/v4/libs/math/vc71_fix/instantiate_all.cpp
==============================================================================
--- branches/proto/v4/libs/math/vc71_fix/instantiate_all.cpp (original)
+++ branches/proto/v4/libs/math/vc71_fix/instantiate_all.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -14,8 +14,10 @@
 // as that would lead to recursive project dependencies...
 //
 
-#include "../test/compile_test/instantiate.hpp"
+#define BOOST_MATH_ASSERT_UNDEFINED_POLICY false
+#define BOOST_MATH_INSTANTIATE_MINIMUM
 #include <boost/math/concepts/real_concept.hpp>
+#include "../test/compile_test/instantiate.hpp"
 
 void some_proc()
 {

Modified: branches/proto/v4/libs/mpi/doc/mpi.qbk
==============================================================================
--- branches/proto/v4/libs/mpi/doc/mpi.qbk (original)
+++ branches/proto/v4/libs/mpi/doc/mpi.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -2004,7 +2004,7 @@
 [@http://www.open-mpi.org/ Open MPI] version 1.1. The NetPIPE results
 follow:
 
-[$../../../libs/mpi/doc/netpipe.png]
+[$../../libs/mpi/doc/netpipe.png]
 
 There are a some observations we can make about these NetPIPE
 results. First of all, the top two plots show that Boost.MPI performs

Modified: branches/proto/v4/libs/numeric/conversion/doc/conversion.qbk
==============================================================================
--- branches/proto/v4/libs/numeric/conversion/doc/conversion.qbk (original)
+++ branches/proto/v4/libs/numeric/conversion/doc/conversion.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -21,7 +21,7 @@
 
 [/ Cited Boost resources ]
 
-[def __MPL_INTEGRAL_CONSTANT__ [@../../../../mpl/refmanual/integral-constant.html MPL's Integral Constant] ]
+[def __MPL_INTEGRAL_CONSTANT__ [@../../../../mpl/doc/refmanual/integral-constant.html MPL's Integral Constant] ]
 
 
 

Modified: branches/proto/v4/libs/optional/doc/optional.qbk
==============================================================================
--- branches/proto/v4/libs/optional/doc/optional.qbk (original)
+++ branches/proto/v4/libs/optional/doc/optional.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -22,7 +22,7 @@
 [/ Cited Boost resources ]
 
 [def __BOOST_VARIANT__ [@../../../variant/index.html Boost.Variant]]
-[def __BOOST_TRIBOOL__ [@../../../tribool/index.html boost::tribool]]
+[def __BOOST_TRIBOOL__ [@../../../../doc/html/tribool.html boost::tribool]]
 
 [def __OPTIONAL_POINTEE__ [@../../../utility/OptionalPointee.html OptionalPointee]]
 [def __COPY_CONSTRUCTIBLE__ [@../../../utility/CopyConstructible.html Copy Constructible]]

Modified: branches/proto/v4/libs/optional/index.html
==============================================================================
--- branches/proto/v4/libs/optional/index.html (original)
+++ branches/proto/v4/libs/optional/index.html 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -4,10 +4,10 @@
 </head>
 <body>
 Automatic redirection failed, please go to
-doc/html/index.html.&nbsp;<hr>
+doc/html/index.html.&nbsp;<hr>
 <p>� Copyright Beman Dawes, 2001</p>
 <p>Distributed under the Boost Software License, Version 1.0. (See accompanying
 file LICENSE_1_0.txt or copy
 at www.boost.org/LICENSE_1_0.txt)</p>
 </body>
-</html>
\ No newline at end of file
+</html>

Modified: branches/proto/v4/libs/optional/test/optional_test.cpp
==============================================================================
--- branches/proto/v4/libs/optional/test/optional_test.cpp (original)
+++ branches/proto/v4/libs/optional/test/optional_test.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1,4 +1,4 @@
-// Copyright (C) 2003, Fernando Luis Cacciola Carballal.
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
 //
 // Use, modification, and distribution is subject to the Boost Software
 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@@ -9,6 +9,9 @@
 // You are welcome to contact the author at:
 // fernando_cacciola_at_[hidden]
 //
+// Revisions:
+// 25 Apr 2008 (added more swap tests)
+//
 #include<iostream>
 #include<stdexcept>
 #include<string>
@@ -16,6 +19,8 @@
 #define BOOST_ENABLE_ASSERT_HANDLER
 
 #include "boost/bind/apply.hpp" // Included just to test proper interaction with boost::apply<> as reported by Daniel Wallin
+#include "boost/mpl/bool.hpp"
+#include "boost/mpl/bool_fwd.hpp" // For mpl::true_ and mpl::false_
 
 #include "boost/optional/optional.hpp"
 
@@ -927,6 +932,185 @@
   BOOST_CHECK(*get(&opt1) == static_cast<double>(f));
 }
 
+
+namespace optional_swap_test
+{
+ class default_ctor_exception : public std::exception {} ;
+ class copy_ctor_exception : public std::exception {} ;
+ class assignment_exception : public std::exception {} ;
+
+ //
+ // Base class for swap test classes. Its assignment should not be called, when swapping
+ // optional<T> objects. (The default std::swap would do so.)
+ //
+ class base_class_with_forbidden_assignment
+ {
+ public:
+ base_class_with_forbidden_assignment & operator=(const base_class_with_forbidden_assignment &)
+ {
+ BOOST_CHECK(!"The assignment should not be used while swapping!");
+ throw assignment_exception();
+ }
+
+ virtual ~base_class_with_forbidden_assignment() {}
+ };
+
+ //
+ // Class without default constructor
+ //
+ class class_without_default_ctor : public base_class_with_forbidden_assignment
+ {
+ public:
+ char data;
+ explicit class_without_default_ctor(char arg) : data(arg) {}
+ };
+
+ //
+ // Class whose default constructor should not be used by optional::swap!
+ //
+ class class_whose_default_ctor_should_not_be_used : public base_class_with_forbidden_assignment
+ {
+ public:
+ char data;
+ explicit class_whose_default_ctor_should_not_be_used(char arg) : data(arg) {}
+
+ class_whose_default_ctor_should_not_be_used()
+ {
+ BOOST_CHECK(!"This default constructor should not be used while swapping!");
+ throw default_ctor_exception();
+ }
+ };
+
+ //
+ // Class whose default constructor should be used by optional::swap.
+ // Its copy constructor should be avoided!
+ //
+ class class_whose_default_ctor_should_be_used : public base_class_with_forbidden_assignment
+ {
+ public:
+ char data;
+ explicit class_whose_default_ctor_should_be_used(char arg) : data(arg) { }
+
+ class_whose_default_ctor_should_be_used() : data('\0') { }
+
+ class_whose_default_ctor_should_be_used(const class_whose_default_ctor_should_be_used &)
+ {
+ BOOST_CHECK(!"This copy constructor should not be used while swapping!");
+ throw copy_ctor_exception();
+ }
+ };
+
+ void swap(class_whose_default_ctor_should_not_be_used & lhs, class_whose_default_ctor_should_not_be_used & rhs)
+ {
+ std::swap(lhs.data, rhs.data);
+ }
+
+ void swap(class_whose_default_ctor_should_be_used & lhs, class_whose_default_ctor_should_be_used & rhs)
+ {
+ std::swap(lhs.data, rhs.data);
+ }
+
+ void swap(class_without_default_ctor & lhs, class_without_default_ctor & rhs)
+ {
+ std::swap(lhs.data, rhs.data);
+ }
+
+} // End of namespace optional_swap_test.
+
+namespace boost {
+
+ //
+ // Compile time tweaking on whether or not swap should use the default constructor:
+ //
+ template <> struct optional_swap_should_use_default_constructor<
+ ::optional_swap_test::class_whose_default_ctor_should_be_used> : mpl::true_ {} ;
+
+ template <> struct optional_swap_should_use_default_constructor<
+ ::optional_swap_test::class_whose_default_ctor_should_not_be_used> : mpl::false_ {} ;
+}
+
+
+//
+// Tests whether the swap function works properly for optional<T>.
+// Assumes that T has one data member, of type char.
+// Returns true iff the test is passed.
+//
+template <class T>
+bool test_swap_function( T const* )
+{
+ const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
+ try
+ {
+ optional<T> obj1;
+ optional<T> obj2('a');
+
+ // Test if obj1 and obj2 are properly initialized.
+ BOOST_CHECK(!obj1);
+ BOOST_CHECK(!!obj2 && obj2->data == 'a');
+
+ // Call non-member swap
+ swap(obj1, obj2);
+
+ // Test if obj1 and obj2 are really swapped
+ BOOST_CHECK(!!obj1 && obj1->data == 'a');
+ BOOST_CHECK(!obj2);
+ }
+ catch(const std::exception &)
+ {
+ // The swap function should not throw, for our test cases.
+ return false ;
+ }
+ return boost::minimal_test::errors_counter() == counter_before_test ;
+}
+
+//
+// Tests whether the optional<T>::swap member function works properly.
+// Assumes that T has one data member, of type char.
+// Returns true iff the test is passed.
+//
+template <class T>
+bool test_swap_member_function( T const* )
+{
+ const boost::unit_test::counter_t counter_before_test = boost::minimal_test::errors_counter();
+ try
+ {
+ optional<T> obj1;
+ optional<T> obj2('a');
+
+ // Test if obj1 and obj2 are properly initialized.
+ BOOST_CHECK(!obj1);
+ BOOST_CHECK(!!obj2 && obj2->data == 'a');
+
+ // Call member swap
+ obj1.swap(obj2);
+
+ // Test if obj1 and obj2 are really swapped
+ BOOST_CHECK(!!obj1 && obj1->data == 'a');
+ BOOST_CHECK(!obj2);
+ }
+ catch(const std::exception &)
+ {
+ // The optional<T>::swap member function should not throw, for our test cases.
+ return false ;
+ }
+ return boost::minimal_test::errors_counter() == counter_before_test ;
+}
+
+
+//
+// Tests compile time tweaking of swap, by means of
+// optional_swap_should_use_default_constructor.
+//
+void test_swap_tweaking()
+{
+ BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_without_default_ctor) ) );
+ BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
+ BOOST_CHECK( test_swap_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
+ BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_without_default_ctor) ) );
+ BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_be_used) ) );
+ BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::class_whose_default_ctor_should_not_be_used) ) );
+}
+
 int test_main( int, char* [] )
 {
   try
@@ -936,6 +1120,7 @@
     test_no_implicit_conversions();
     test_conversions1();
     test_conversions2();
+ test_swap_tweaking();
   }
   catch ( ... )
   {

Modified: branches/proto/v4/libs/python/doc/building.rst
==============================================================================
--- branches/proto/v4/libs/python/doc/building.rst (original)
+++ branches/proto/v4/libs/python/doc/building.rst 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,7 +11,7 @@
    :alt: Boost C++ Libraries:
    :class: boost-logo
 
-__ ../index.htm
+__ ../index.html
 
 
 .. section-numbering::

Modified: branches/proto/v4/libs/python/doc/tutorial/doc/tutorial.qbk
==============================================================================
--- branches/proto/v4/libs/python/doc/tutorial/doc/tutorial.qbk (original)
+++ branches/proto/v4/libs/python/doc/tutorial/doc/tutorial.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1381,9 +1381,9 @@
 [section Using the interpreter]
 
 As you probably already know, objects in Python are reference-counted.
-Naturally, the [^PyObject]s of the Python/C API are also reference-counted.
+Naturally, the [^PyObject]s of the Python\/C API are also reference-counted.
 There is a difference however. While the reference-counting is fully
-automatic in Python, the Python/C API requires you to do it
+automatic in Python, the Python\/C API requires you to do it
 [@http://www.python.org/doc/current/api/refcounts.html by hand]. This is
 messy and especially hard to get right in the presence of C++ exceptions.
 Fortunately Boost.Python provides the [@../../../v2/handle.html handle] and

Modified: branches/proto/v4/libs/python/doc/tutorial/index.html
==============================================================================
--- branches/proto/v4/libs/python/doc/tutorial/index.html (original)
+++ branches/proto/v4/libs/python/doc/tutorial/index.html 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,8 +11,8 @@
     <a href="doc/html/index.html">link</a> &nbsp;<hr>
     <p>© Copyright Beman Dawes, 2001</p>
     <p>Distributed under the Boost Software License, Version 1.0. (See
- accompanying file <a href="../../../LICENSE_1_0.txt">
+ accompanying file <a href="../../../../LICENSE_1_0.txt">
     LICENSE_1_0.txt</a> or copy at
     <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
   </body>
-</html>
\ No newline at end of file
+</html>

Modified: branches/proto/v4/libs/regex/src/usinstances.cpp
==============================================================================
--- branches/proto/v4/libs/regex/src/usinstances.cpp (original)
+++ branches/proto/v4/libs/regex/src/usinstances.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -49,6 +49,9 @@
 #if BOOST_WORKAROUND(BOOST_MSVC, > 1300) && BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
 template<> _CRTIMP2 std::size_t __cdecl char_traits<unsigned short>::length(unsigned short const*);
 #endif
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+template _CRTIMP2 allocator<unsigned short>::allocator();
+#endif
 }
 #endif
 

Modified: branches/proto/v4/libs/regex/src/wc_regex_traits.cpp
==============================================================================
--- branches/proto/v4/libs/regex/src/wc_regex_traits.cpp (original)
+++ branches/proto/v4/libs/regex/src/wc_regex_traits.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,9 +19,40 @@
 
 #define BOOST_REGEX_SOURCE
 
-#include <boost/config.hpp>
+#include <boost/regex/config.hpp>
 #include <boost/detail/workaround.hpp>
 
+#ifdef _DLL_CPPLIB
+//
+// This is a horrible workaround, without declaring these symbols extern we get
+// duplicate symbol errors when linking if the application is built without
+// /Zc:wchar_t
+//
+namespace std{
+template _CRTIMP2 bool __cdecl operator==(
+ const basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short> >&,
+ const basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short> >&);
+template _CRTIMP2 bool __cdecl operator==(
+ const unsigned short *,
+ const basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short> >&);
+template _CRTIMP2 bool __cdecl operator==(
+ const basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short> >&,
+ const unsigned short *);
+template _CRTIMP2 bool __cdecl operator<(
+ const basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short> >&,
+ const basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short> >&);
+template _CRTIMP2 bool __cdecl operator>(
+ const basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short> >&,
+ const basic_string<unsigned short, char_traits<unsigned short>, allocator<unsigned short> >&);
+#if BOOST_WORKAROUND(BOOST_MSVC, > 1300) && BOOST_WORKAROUND(BOOST_MSVC, BOOST_TESTED_AT(1400))
+template<> _CRTIMP2 std::size_t __cdecl char_traits<unsigned short>::length(unsigned short const*);
+#endif
+#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400)
+template _CRTIMP2 allocator<unsigned short>::allocator();
+#endif
+}
+#endif
+
 #if !BOOST_WORKAROUND(__BORLANDC__, < 0x560)
 
 #include <boost/regex/v4/c_regex_traits.hpp>

Modified: branches/proto/v4/libs/smart_ptr/test/Jamfile.v2
==============================================================================
--- branches/proto/v4/libs/smart_ptr/test/Jamfile.v2 (original)
+++ branches/proto/v4/libs/smart_ptr/test/Jamfile.v2 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -45,5 +45,6 @@
           [ run spinlock_pool_test.cpp ]
           [ run sp_accept_owner_test.cpp ]
           [ run sp_atomic_test.cpp ]
+ [ run make_shared_test.cpp ]
         ;
 }

Modified: branches/proto/v4/libs/smart_ptr/test/esft_regtest.cpp
==============================================================================
--- branches/proto/v4/libs/smart_ptr/test/esft_regtest.cpp (original)
+++ branches/proto/v4/libs/smart_ptr/test/esft_regtest.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -160,6 +160,7 @@
     V * p = new W;
     boost::shared_ptr<void> pv( p );
     BOOST_TEST( pv.get() == p );
+ BOOST_TEST( pv.use_count() == 1 );
 }
 
 struct null_deleter
@@ -171,6 +172,41 @@
 {
     boost::shared_ptr<V> pv( new V );
     boost::shared_ptr<V> pv2( pv.get(), null_deleter() );
+ BOOST_TEST( pv2.get() == pv.get() );
+ BOOST_TEST( pv2.use_count() == 1 );
+}
+
+void test5()
+{
+ V v;
+
+ boost::shared_ptr<V> p1( &v, null_deleter() );
+ BOOST_TEST( p1.get() == &v );
+ BOOST_TEST( p1.use_count() == 1 );
+
+ try
+ {
+ p1->shared_from_this();
+ }
+ catch( ... )
+ {
+ BOOST_ERROR( "p1->shared_from_this() failed" );
+ }
+
+ p1.reset();
+
+ boost::shared_ptr<V> p2( &v, null_deleter() );
+ BOOST_TEST( p2.get() == &v );
+ BOOST_TEST( p2.use_count() == 1 );
+
+ try
+ {
+ p2->shared_from_this();
+ }
+ catch( ... )
+ {
+ BOOST_ERROR( "p2->shared_from_this() failed" );
+ }
 }
 
 int main()
@@ -179,6 +215,7 @@
     test2();
     test3();
     test4();
+ test5();
 
     return boost::report_errors();
 }

Modified: branches/proto/v4/libs/spirit/doc/notes/style_guide.qbk
==============================================================================
--- branches/proto/v4/libs/spirit/doc/notes/style_guide.qbk (original)
+++ branches/proto/v4/libs/spirit/doc/notes/style_guide.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,7 +11,7 @@
 keep an easy-to-read, consistent en aesthetically pleasing look to the Spirit
 code, the following coding styleguide is advised.
 
-This coding style is adapted and extended from the ANTLR/PCCTS style (Terrence
+This coding style is adapted and extended from the ANTLR\/PCCTS style (Terrence
 Parr) and [@http://groups.yahoo.com/group/boost/files/coding_guidelines.html
 Boost coding guidelines] (David Abrahams and Nathan Myers) and is the
 combined work of Joel de Guzman, Chris Uzdavinis and Hartmut Kaiser.

Modified: branches/proto/v4/libs/spirit/doc/what_s_new.qbk
==============================================================================
--- branches/proto/v4/libs/spirit/doc/what_s_new.qbk (original)
+++ branches/proto/v4/libs/spirit/doc/what_s_new.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -35,7 +35,7 @@
 corrected as described above. As an alternative you can define the preprocessor
 constant `BOOST_SPIRIT_USE_OLD_NAMESPACE`, which will force the Spirit Classic
 code to be in the namespace `boost::spirit` as before. This is not recommended,
-though, as it maz result in naming clashs
+though, as it may result in naming clashes.
 
 The change of the namespace will be automatically deactivated whenever the
 deprecated include files are being used. This ensures full backwards

Modified: branches/proto/v4/libs/spirit/example/karma/Jamfile
==============================================================================
--- branches/proto/v4/libs/spirit/example/karma/Jamfile (original)
+++ branches/proto/v4/libs/spirit/example/karma/Jamfile 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,7 +7,10 @@
 #==============================================================================
 project spirit-karma-example ;
 
-exe quick_start1 : quick_start1.cpp ;
-exe basic_facilities : basic_facilities.cpp ;
+exe quick_start1 : quick_start1.cpp ;
+exe actions : actions.cpp ;
+exe basic_facilities : basic_facilities.cpp ;
 exe functor_facilities : functor_facilities.cpp ;
+exe calc2_ast_dump : calc2_ast_dump.cpp ;
+exe calc2_ast_rpn : calc2_ast_rpn.cpp ;
 

Modified: branches/proto/v4/libs/spirit/example/karma/actions.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/karma/actions.cpp (original)
+++ branches/proto/v4/libs/spirit/example/karma/actions.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,14 +6,15 @@
     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 
-#include <iostream>
-#include <strstream>
-
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/karma.hpp>
 #include <boost/lambda/lambda.hpp>
 #include <boost/bind.hpp>
 #include <boost/function_output_iterator.hpp>
 
+#include <iostream>
+#include <strstream>
+
 // Presented are various ways to attach semantic actions
 // * Using plain function pointer
 // * Using simple function object

Modified: branches/proto/v4/libs/spirit/example/karma/basic_facilities.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/karma/basic_facilities.cpp (original)
+++ branches/proto/v4/libs/spirit/example/karma/basic_facilities.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -15,6 +15,7 @@
 // use a larger value for the alignment field width (default is 10)
 #define BOOST_KARMA_DEFAULT_FIELD_LENGTH 25
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/karma.hpp>
 #include <boost/spirit/include/karma_stream.hpp>
 

Modified: branches/proto/v4/libs/spirit/example/karma/functor_facilities.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/karma/functor_facilities.cpp (original)
+++ branches/proto/v4/libs/spirit/example/karma/functor_facilities.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,6 +6,7 @@
 // This examples demonstrate how to write functor based generators for special
 // purposes.
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/karma.hpp>
 #include <boost/spirit/include/karma_stream.hpp>
 

Modified: branches/proto/v4/libs/spirit/example/karma/quick_start1.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/karma/quick_start1.cpp (original)
+++ branches/proto/v4/libs/spirit/example/karma/quick_start1.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,6 +6,7 @@
 // The main purpose of this example is to show how a single container type can
 // be formatted using different output grammars.
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/karma.hpp>
 #include <boost/spirit/include/karma_stream.hpp>
 

Modified: branches/proto/v4/libs/spirit/example/lex/example1.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/example1.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/example1.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -20,6 +20,7 @@
 // Any number of simple sentences (optionally comma separated) inside a pair
 // of curly braces will be matched.
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 

Modified: branches/proto/v4/libs/spirit/example/lex/example2.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/example2.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/example2.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -20,6 +20,7 @@
 // #define BOOST_SPIRIT_DEBUG
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/example3.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/example3.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/example3.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -22,6 +22,7 @@
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 // #define BOOST_SPIRIT_DEBUG
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 

Modified: branches/proto/v4/libs/spirit/example/lex/example4.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/example4.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/example4.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -22,6 +22,7 @@
 // assignment statements and if and while control structures. Look at the file
 // example4.input for an example.
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/example5.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/example5.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/example5.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -24,6 +24,7 @@
 // assignment statements and if and while control structures. Look at the file
 // example5.input for an example.
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/example6.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/example6.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/example6.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -26,6 +26,7 @@
 // is that we use the self.add() syntax to define tokens and to associate them
 // with the lexer.
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/print_numbers.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/print_numbers.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/print_numbers.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,6 +19,7 @@
 //
 // Its purpose is to print all the (integer) numbers found in a file
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/static_lexer/word_count_generate.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/static_lexer/word_count_generate.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/static_lexer/word_count_generate.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,7 @@
 
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/home/lex/lexer/lexertl/lexertl_generate_static.hpp>
 

Modified: branches/proto/v4/libs/spirit/example/lex/static_lexer/word_count_static.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/static_lexer/word_count_static.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/static_lexer/word_count_static.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -14,6 +14,7 @@
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 #define BOOST_VARIANT_MINIMIZE_SIZE
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 //[wc_static_include
 #include <boost/spirit/include/lex_lexer_static_lexertl.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/strip_comments.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/strip_comments.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/strip_comments.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -33,6 +33,7 @@
 
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/strip_comments_lexer.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/strip_comments_lexer.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/strip_comments_lexer.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -33,6 +33,7 @@
 
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/lex/lexer/lexer_actions.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/word_count.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/word_count.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/word_count.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -34,6 +34,7 @@
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 #define BOOST_VARIANT_MINIMIZE_SIZE
 
+#include <boost/config/warning_disable.hpp>
 //[wcp_includes
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/word_count_functor.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/word_count_functor.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/word_count_functor.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -49,6 +49,7 @@
 
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 
+#include <boost/config/warning_disable.hpp>
 //[wcf_includes
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/bind.hpp>

Modified: branches/proto/v4/libs/spirit/example/lex/word_count_lexer.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/lex/word_count_lexer.cpp (original)
+++ branches/proto/v4/libs/spirit/example/lex/word_count_lexer.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -32,6 +32,7 @@
 
 // #define BOOST_SPIRIT_LEXERTL_DEBUG
 
+#include <boost/config/warning_disable.hpp>
 //[wcl_includes
 #include <boost/spirit/include/support_argument.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/actions.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/actions.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/actions.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -5,11 +5,13 @@
     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/
 
-#include <iostream>
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/lambda/lambda.hpp>
 #include <boost/bind.hpp>
 
+#include <iostream>
+
 // Presented are various ways to attach semantic actions
 // * Using plain function pointer
 // * Using simple function object

Modified: branches/proto/v4/libs/spirit/example/qi/calc1.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc1.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc1.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,8 @@
 // [ JDG March 4, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <iostream>
 #include <string>

Modified: branches/proto/v4/libs/spirit/example/qi/calc2.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc2.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc2.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,15 +7,16 @@
 ///////////////////////////////////////////////////////////////////////////////
 //
 // A Calculator example demonstrating the grammar and semantic actions
-// using phoenix to "bind" plain functions. The parser prints code suitable
-// for a stack based virtual machine.
+// using plain functions. The parser prints code suitable for a stack
+// based virtual machine.
 //
 // [ JDG May 10, 2002 ] spirit1
 // [ JDG March 4, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
-#include <boost/spirit/include/phoenix_bind.hpp>
 
 #include <iostream>
 #include <string>
@@ -23,9 +24,6 @@
 using namespace boost::spirit;
 using namespace boost::spirit::qi;
 using namespace boost::spirit::ascii;
-using namespace boost::spirit::arg_names;
-
-using boost::phoenix::bind;
 
 ///////////////////////////////////////////////////////////////////////////////
 // Semantic actions
@@ -50,22 +48,22 @@
     {
         expression =
             term
- >> *( ('+' >> term [bind(&do_add)])
- | ('-' >> term [bind(&do_subt)])
+ >> *( ('+' >> term [&do_add])
+ | ('-' >> term [&do_subt])
                 )
             ;
 
         term =
             factor
- >> *( ('*' >> factor [bind(&do_mult)])
- | ('/' >> factor [bind(&do_div)])
+ >> *( ('*' >> factor [&do_mult])
+ | ('/' >> factor [&do_div])
                 )
             ;
 
         factor =
- uint_ [bind(&do_int, _1)]
+ uint_ [&do_int]
             | '(' >> expression >> ')'
- | ('-' >> factor [bind(&do_neg)])
+ | ('-' >> factor [&do_neg])
             | ('+' >> factor)
             ;
     }

Modified: branches/proto/v4/libs/spirit/example/qi/calc3.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc3.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc3.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -14,6 +14,8 @@
 // [ JDG March 5, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
 

Modified: branches/proto/v4/libs/spirit/example/qi/calc3_lexer.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc3_lexer.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc3_lexer.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -25,6 +25,8 @@
 // [ JDG March 5, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/lex_lexer_lexertl.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/calc4.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc4.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc4.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -12,6 +12,8 @@
 // [ JDG March 5, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
 #include <boost/spirit/include/phoenix_object.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/calc5.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc5.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc5.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -15,6 +15,8 @@
 // [ JDG April 8, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_container.hpp>
@@ -60,7 +62,7 @@
     }
 
     int top() const { return stack_ptr[-1]; };
- void execute(std::vector<int>& code);
+ void execute(std::vector<int> const& code);
 
 private:
 
@@ -68,9 +70,9 @@
     std::vector<int>::iterator stack_ptr;
 };
 
-void vmachine::execute(std::vector<int>& code)
+void vmachine::execute(std::vector<int> const& code)
 {
- std::vector<int>::iterator pc = code.begin();
+ std::vector<int>::const_iterator pc = code.begin();
     stack_ptr = stack.begin();
 
     while (pc != code.end())

Modified: branches/proto/v4/libs/spirit/example/qi/calc6/calc6.hpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc6/calc6.hpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc6/calc6.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,6 +7,7 @@
 #if !defined(BOOST_SPIRIT_CALC6)
 #define BOOST_SPIRIT_CALC6
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_container.hpp>
@@ -52,7 +53,7 @@
     }
 
     std::vector<int> const& get_stack() const { return stack; };
- void execute(std::vector<int>& code, int nvars);
+ void execute(std::vector<int> const& code, int nvars);
 
 private:
 

Modified: branches/proto/v4/libs/spirit/example/qi/calc6/calc6a.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc6/calc6a.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc6/calc6a.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,9 +6,9 @@
 =============================================================================*/
 #include "calc6.hpp"
 
-void vmachine::execute(std::vector<int>& code, int nvars)
+void vmachine::execute(std::vector<int> const& code, int nvars)
 {
- std::vector<int>::iterator pc = code.begin();
+ std::vector<int>::const_iterator pc = code.begin();
     std::vector<int>::iterator locals = stack.begin();
     stack_ptr = stack.begin() + nvars;
 

Modified: branches/proto/v4/libs/spirit/example/qi/calc7/calc7.hpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc7/calc7.hpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc7/calc7.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,6 +7,7 @@
 #if !defined(BOOST_SPIRIT_CALC7)
 #define BOOST_SPIRIT_CALC7
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_container.hpp>
@@ -71,7 +72,7 @@
     }
 
     std::vector<int> const& get_stack() const { return stack; };
- void execute(std::vector<int>& code, int nvars);
+ void execute(std::vector<int> const& code, int nvars);
 
 private:
 

Modified: branches/proto/v4/libs/spirit/example/qi/calc7/calc7a.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/calc7/calc7a.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/calc7/calc7a.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -9,9 +9,9 @@
 # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
                                 // (performance warning)
 
-void vmachine::execute(std::vector<int>& code, int nvars)
+void vmachine::execute(std::vector<int> const& code, int nvars)
 {
- std::vector<int>::iterator pc = code.begin();
+ std::vector<int>::const_iterator pc = code.begin();
     std::vector<int>::iterator locals = stack.begin();
     stack_ptr = stack.begin() + nvars;
 

Modified: branches/proto/v4/libs/spirit/example/qi/complex_number.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/complex_number.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/complex_number.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -12,6 +12,8 @@
 // [ JDG May 9, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/employee.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/employee.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/employee.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -12,6 +12,8 @@
 // [ JDG May 9, 2007 ]
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/mini_c/mini_c.hpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/mini_c/mini_c.hpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/mini_c/mini_c.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,6 +7,7 @@
 #if !defined(BOOST_SPIRIT_MINI_C)
 #define BOOST_SPIRIT_MINI_C
 
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_container.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/mini_xml1.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/mini_xml1.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/mini_xml1.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,6 +11,8 @@
 // [ JDG March 25, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/mini_xml2.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/mini_xml2.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/mini_xml2.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,6 +11,8 @@
 // [ JDG March 25, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/mini_xml_karma.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/mini_xml_karma.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/mini_xml_karma.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,8 @@
 // [ HK April 02, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/karma.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/num_list.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/num_list.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/num_list.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,8 @@
 // [ JDG March 24, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/num_list2.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/num_list2.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/num_list2.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,8 @@
 // [ JDG March 24, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/num_list3.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/num_list3.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/num_list3.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,8 @@
 // [ JDG March 24, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/example/qi/roman.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/roman.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/roman.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -13,6 +13,8 @@
 // [ JDG March 13, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
 

Modified: branches/proto/v4/libs/spirit/example/qi/sum.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/example/qi/sum.cpp (original)
+++ branches/proto/v4/libs/spirit/example/qi/sum.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -12,6 +12,8 @@
 // [ JDG March 24, 2007 ] spirit2
 //
 ///////////////////////////////////////////////////////////////////////////////
+
+#include <boost/config/warning_disable.hpp>
 #include <boost/spirit/include/qi.hpp>
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>

Modified: branches/proto/v4/libs/spirit/test/karma/actions.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/karma/actions.cpp (original)
+++ branches/proto/v4/libs/spirit/test/karma/actions.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -75,14 +75,15 @@
     }
 
     {
- using boost::lambda::_1;
+ namespace lambda = boost::lambda;
         {
             std::stringstream strm("42");
- BOOST_TEST(test("{42}", '{' << int_[strm >> _1] << '}'));
+ BOOST_TEST(test("{42}", '{' << int_[strm >> lambda::_1] << '}'));
         }
         {
             std::stringstream strm("42");
- BOOST_TEST(test_delimited("{ 42 } ", '{' << int_[strm >> _1] << '}', space));
+ BOOST_TEST(test_delimited("{ 42 } ",
+ '{' << int_[strm >> lambda::_1] << '}', space));
         }
     }
 

Modified: branches/proto/v4/libs/spirit/test/karma/lazy.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/karma/lazy.cpp (original)
+++ branches/proto/v4/libs/spirit/test/karma/lazy.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -25,16 +25,16 @@
     using spirit_test::test;
     using namespace boost::spirit;
     using namespace boost::spirit::karma;
- using namespace boost::phoenix;
     using namespace boost::spirit::arg_names;
+ namespace phx = boost::phoenix;
 
     {
- BOOST_TEST(test("123", lazy(val(int_)), 123));
+ BOOST_TEST(test("123", lazy(phx::val(int_)), 123));
     }
 
     {
         int result = 123;
- BOOST_TEST(test("123", lazy(val(int_))[_1 = ref(result)]));
+ BOOST_TEST(test("123", lazy(phx::val(int_))[_1 = phx::ref(result)]));
     }
 
     {
@@ -44,8 +44,8 @@
         r = char_('<') << lazy(_r1) << '>' << "</" << lazy(_r1) << '>';
 
         std::string tag("tag"), foo("foo");
- BOOST_TEST(test("<tag></tag>", r (ref(tag))));
- BOOST_TEST(!test("<foo></bar>", r (ref(foo))));
+ BOOST_TEST(test("<tag></tag>", r (phx::ref(tag))));
+ BOOST_TEST(!test("<foo></bar>", r (phx::ref(foo))));
     }
 
     return boost::report_errors();

Modified: branches/proto/v4/libs/spirit/test/karma/list.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/karma/list.cpp (original)
+++ branches/proto/v4/libs/spirit/test/karma/list.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -35,7 +35,7 @@
     using namespace boost::spirit::ascii;
 
     using namespace boost::assign;
-
+
     std::vector<char> v;
     v += 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h';
     
@@ -53,12 +53,12 @@
     }
 
     { // actions
- using namespace boost::phoenix;
+ namespace phx = boost::phoenix;
         using boost::spirit::arg_names::_1;
 
- BOOST_TEST(test("a,b,c,d,e,f,g,h", (char_ % ',')[_1 = ref(v)]));
+ BOOST_TEST(test("a,b,c,d,e,f,g,h", (char_ % ',')[_1 = phx::ref(v)]));
         BOOST_TEST(test_delimited("a , b , c , d , e , f , g , h ",
- (char_ % ',')[_1 = ref(v)], space));
+ (char_ % ',')[_1 = phx::ref(v)], space));
     }
 
     return boost::report_errors();

Modified: branches/proto/v4/libs/spirit/test/karma/pattern.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/karma/pattern.cpp (original)
+++ branches/proto/v4/libs/spirit/test/karma/pattern.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -19,6 +19,7 @@
 #include <boost/spirit/include/phoenix_core.hpp>
 #include <boost/spirit/include/phoenix_operator.hpp>
 #include <boost/spirit/include/phoenix_statement.hpp>
+#include <boost/spirit/include/phoenix_fusion.hpp>
 
 #include "test.hpp"
 
@@ -57,29 +58,27 @@
     // basic tests involving a direct parameter
     {
         typedef variant<char, int, double> var_type;
- fusion::vector<unused_type, var_type> v (unused, 'a');
+ var_type v ('a');
 
- rule<outiter_type, void(var_type)> start;
+ rule<outiter_type, var_type()> start;
 
- start = (char_ | int_ | double_)[_1 = _r1];
+ start = (char_ | int_ | double_)[_1 = _r0];
         BOOST_TEST(test("a", start, v));
 
- v = fusion::vector<unused_type, var_type>(unused, 10);
+ v = 10;
         BOOST_TEST(test("10", start, v));
- v = fusion::vector<unused_type, var_type>(unused, 12.4);
+ v = 12.4;
         BOOST_TEST(test("12.4", start, v));
     }
 
     {
         rule<outiter_type, void(char, int, double)> start;
- fusion::vector<unused_type, char, int, double> vec(unused, 'a', 10, 12.4);
+ fusion::vector<char, int, double> vec('a', 10, 12.4);
 
         start = char_[_1 = _r1] << int_[_1 = _r2] << double_[_1 = _r3];
- BOOST_TEST(test("a1012.4", start, vec));
         BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
 
         start = (char_ << int_ << double_)[_1 = _r1, _2 = _r2, _3 = _r3];
- BOOST_TEST(test("a1012.4", start, vec));
         BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
 
         rule<outiter_type, void(char)> a;
@@ -90,29 +89,34 @@
         b = int_[_1 = _r1];
         c = double_[_1 = _r1];
         start = a(_r1) << b(_r2) << c(_r3);
- BOOST_TEST(test("a1012.4", start, vec));
         BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
     }
 
     // test rule parameter propagation
     {
- rule<outiter_type, void(char, int, double)> start;
- fusion::vector<unused_type, char, int, double> vec(unused, 'a', 10, 12.4);
+ using boost::phoenix::at_c;
+
+ rule<outiter_type, fusion::vector<char, int, double>()> start;
+ fusion::vector<char, int, double> vec('a', 10, 12.4);
 
         start %= char_ << int_ << double_;
         BOOST_TEST(test("a1012.4", start, vec));
- BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
 
- rule<outiter_type, void(char)> a;
- rule<outiter_type, void(int)> b;
- rule<outiter_type, void(double)> c;
+ rule<outiter_type, char()> a;
+ rule<outiter_type, int()> b;
+ rule<outiter_type, double()> c;
 
         a %= char_ << eps;
         b %= int_;
         c %= double_;
- start = a(_r1) << b(_r2) << c(_r3);
+ start = a[_1 = at_c<0>(_r0)] << b[_1 = at_c<1>(_r0)] << c[_1 = at_c<2>(_r0)];
+ BOOST_TEST(test("a1012.4", start, vec));
+
+ start = (a << b << c)[_1 = at_c<0>(_r0), _2 = at_c<1>(_r0), _3 = at_c<2>(_r0)];
+ BOOST_TEST(test("a1012.4", start, vec));
+
+ start %= a << b << c;
         BOOST_TEST(test("a1012.4", start, vec));
- BOOST_TEST(test("a1012.4", start('a', 10, 12.4)));
     }
 
     // basic tests with delimiter

Modified: branches/proto/v4/libs/spirit/test/karma/real_numerics.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/karma/real_numerics.cpp (original)
+++ branches/proto/v4/libs/spirit/test/karma/real_numerics.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -26,7 +26,7 @@
 {
     // we want the numbers always to be in scientific format
     typedef boost::spirit::karma::real_generator_policies<T> base_type;
- static int floatfield(T n) { return base_type::scientific; }
+ static int floatfield(T) { return base_type::scientific; }
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -37,7 +37,7 @@
     typedef boost::spirit::karma::real_generator_policies<T> base_type;
 
     // we want the numbers always to be in scientific format
- static int floatfield(T n) { return base_type::fixed; }
+ static int floatfield(T) { return base_type::fixed; }
 };
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -52,7 +52,7 @@
     static bool const trailing_zeros = true;
     
     // we want to generate up to 4 fractional digits
- static unsigned int precision(T n) { return 4; }
+ static unsigned int precision(T) { return 4; }
 };
 
 ///////////////////////////////////////////////////////////////////////////////

Modified: branches/proto/v4/libs/spirit/test/karma/test.hpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/karma/test.hpp (original)
+++ branches/proto/v4/libs/spirit/test/karma/test.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -10,6 +10,7 @@
 #include <string>
 #include <iterator>
 #include <iostream>
+#include <typeinfo>
 
 #include <boost/function_output_iterator.hpp>
 #include <boost/spirit/include/karma_generate.hpp>
@@ -51,6 +52,9 @@
         }
 
         String& str;
+
+ // suppress warning about assignment operator not being generated
+ string_appender& operator=(string_appender const&);
     };
 
     template <typename String>

Modified: branches/proto/v4/libs/spirit/test/lex/lexertl3.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/lex/lexertl3.cpp (original)
+++ branches/proto/v4/libs/spirit/test/lex/lexertl3.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -31,7 +31,6 @@
     typedef lexer_type::token_set token_set;
     typedef lex::lexer_def<lexer_type> lexer_def;
 
- token_set s;
     lexer_def def;
     
     {

Modified: branches/proto/v4/libs/spirit/test/lex/lexertl4.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/lex/lexertl4.cpp (original)
+++ branches/proto/v4/libs/spirit/test/lex/lexertl4.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -35,7 +35,6 @@
     typedef lexer_type::token_set token_set;
     typedef lex::lexer_def<lexer_type> lexer_def;
 
- token_set s;
     std::string str("def");
 
     {

Modified: branches/proto/v4/libs/spirit/test/lex/lexertl5.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/lex/lexertl5.cpp (original)
+++ branches/proto/v4/libs/spirit/test/lex/lexertl5.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -32,7 +32,6 @@
     typedef lexer_type::token_set token_set;
     typedef lex::lexer_def<lexer_type> lexer_def;
 
- token_set s;
     std::string str("def");
 
     {

Modified: branches/proto/v4/libs/spirit/test/qi/debug.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/qi/debug.cpp (original)
+++ branches/proto/v4/libs/spirit/test/qi/debug.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -28,6 +28,7 @@
 int
 main()
 {
+ using namespace boost::spirit;
     using namespace boost::spirit::qi;
     using namespace boost::spirit::ascii;
 
@@ -215,7 +216,7 @@
         using boost::spirit::qi::fail;
 
         rule<char const*> r;
- r = '(' > int_ > ',' > int_ > ')';
+ r = char_('(') > int_ > ',' > int_ > ')';
 
         on_error<fail>
         (

Modified: branches/proto/v4/libs/spirit/test/qi/difference.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/qi/difference.cpp (original)
+++ branches/proto/v4/libs/spirit/test/qi/difference.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -54,20 +54,21 @@
     }
 
     {
- using namespace boost::phoenix;
         using boost::spirit::arg_names::_1;
+ namespace phx = boost::phoenix;
+
         std::string s;
 
         BOOST_TEST(test(
             "/*abcdefghijk*/"
- , "/*" >> *(char_ - "*/")[ref(s) += _1] >> "*/"
+ , "/*" >> *(char_ - "*/")[phx::ref(s) += _1] >> "*/"
         ));
         BOOST_TEST(s == "abcdefghijk");
         s.clear();
 
         BOOST_TEST(test(
             " /*abcdefghijk*/ "
- , "/*" >> *(char_ - "*/")[ref(s) += _1] >> "*/"
+ , "/*" >> *(char_ - "*/")[phx::ref(s) += _1] >> "*/"
           , space
         ));
         BOOST_TEST(s == "abcdefghijk");

Modified: branches/proto/v4/libs/spirit/test/qi/grammar.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/qi/grammar.cpp (original)
+++ branches/proto/v4/libs/spirit/test/qi/grammar.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -24,9 +24,9 @@
 using namespace boost::spirit::ascii;
 using namespace boost::spirit::arg_names;
 
-struct num_list : grammar_def<char const*, space_type>
+struct num_list : grammar_<char const*, space_type>
 {
- num_list()
+ num_list() : base_type(start)
     {
         using boost::spirit::int_;
         num = int_;
@@ -68,13 +68,26 @@
     rule<char const*, grammar<my_skipper> > start, num;
 };
 
+template <typename Iterator, typename Skipper>
+struct num_list3 : grammar_def<Iterator, Skipper>
+{
+ template <typename Class>
+ num_list3(Class& self)
+ {
+ using boost::spirit::int_;
+ num = int_;
+ start = num >> *(',' >> num);
+ }
+
+ rule<Iterator, Skipper> start, num;
+};
+
 int
 main()
 {
     { // simple grammar test
 
- num_list def;
- grammar<num_list> nlist(def);
+ num_list nlist;
         BOOST_TEST(test("123, 456, 789", nlist, space));
     }
 
@@ -104,6 +117,29 @@
         BOOST_TEST(test_attr("inherited", g(123), n, space)); // using the grammar
         BOOST_TEST(n == 123);
     }
+
+ { // grammar_class test (no skipper)
+
+ grammar_class<num_list3> nlist;
+
+ char const* first = "123,456,789";
+ char const* last = first;
+ while (*last)
+ last++;
+ BOOST_TEST(parse(first, last, nlist) && (first == last));
+ }
+
+ { // grammar_class test (w/skipper)
+
+ grammar_class<num_list3> nlist;
+
+ char const* first = "123, 456, 789";
+ char const* last = first;
+ while (*last)
+ last++;
+ BOOST_TEST(phrase_parse(first, last, nlist, space)
+ && (first == last));
+ }
     return boost::report_errors();
 }
 

Modified: branches/proto/v4/libs/spirit/test/qi/kleene.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/qi/kleene.cpp (original)
+++ branches/proto/v4/libs/spirit/test/qi/kleene.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -91,20 +91,20 @@
     }
 
     { // actions
- using namespace boost::phoenix;
+ namespace phx = boost::phoenix;
         using boost::spirit::arg_names::_1;
 
         std::vector<char> v;
- BOOST_TEST(test("bbbb", (*char_)[ref(v) = _1]) && 4 == v.size() &&
+ BOOST_TEST(test("bbbb", (*char_)[phx::ref(v) = _1]) && 4 == v.size() &&
             v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b');
     }
 
     { // more actions
- using namespace boost::phoenix;
+ namespace phx = boost::phoenix;
         using boost::spirit::arg_names::_1;
 
         std::vector<int> v;
- BOOST_TEST(test("123 456 789", (*int_)[ref(v) = _1], space) && 3 == v.size() &&
+ BOOST_TEST(test("123 456 789", (*int_)[phx::ref(v) = _1], space) && 3 == v.size() &&
             v[0] == 123 && v[1] == 456 && v[2] == 789);
     }
 

Modified: branches/proto/v4/libs/spirit/test/qi/plus.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/qi/plus.cpp (original)
+++ branches/proto/v4/libs/spirit/test/qi/plus.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -76,20 +76,20 @@
     }
 
     { // actions
- using namespace boost::phoenix;
+ namespace phx = boost::phoenix;
         using boost::spirit::arg_names::_1;
 
         std::vector<char> v;
- BOOST_TEST(test("bbbb", (+char_)[ref(v) = _1]) && 4 == v.size() &&
+ BOOST_TEST(test("bbbb", (+char_)[phx::ref(v) = _1]) && 4 == v.size() &&
             v[0] == 'b' && v[1] == 'b' && v[2] == 'b' && v[3] == 'b');
     }
 
     { // more actions
- using namespace boost::phoenix;
+ namespace phx = boost::phoenix;
         using boost::spirit::arg_names::_1;
 
         std::vector<int> v;
- BOOST_TEST(test("1 2 3", (+int_)[ref(v) = _1], space) && 3 == v.size() &&
+ BOOST_TEST(test("1 2 3", (+int_)[phx::ref(v) = _1], space) && 3 == v.size() &&
             v[0] == 1 && v[1] == 2 && v[2] == 3);
     }
 

Modified: branches/proto/v4/libs/spirit/test/qi/range_run.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/qi/range_run.cpp (original)
+++ branches/proto/v4/libs/spirit/test/qi/range_run.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -28,7 +28,7 @@
     int const test_size = 1000;
 
     boost::mt19937 rng;
- boost::uniform_int<> char_(const_min, const_max);
+ boost::uniform_int<> char_(int(const_min), int(const_max));
     boost::variate_generator<boost::mt19937&, boost::uniform_int<> >
        gen(rng, char_);
     boost::uniform_int<> _1of10(1, 10);
@@ -36,7 +36,7 @@
        on_or_off(rng, _1of10);
 
     range_run<Char> rr;
- boost::dynamic_bitset<> bset(const_max-const_min+1);
+ boost::dynamic_bitset<> bset(int(const_max)-int(const_min)+1);
 
     for (int i = 0; i < test_size; ++i)
     {

Modified: branches/proto/v4/libs/spirit/test/qi/real.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/qi/real.cpp (original)
+++ branches/proto/v4/libs/spirit/test/qi/real.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -38,7 +38,7 @@
     // No exponent
     template <typename Iterator>
     static bool
- parse_exp(Iterator& first, Iterator const& last)
+ parse_exp(Iterator&, Iterator const&)
     {
         return false;
     }
@@ -46,7 +46,7 @@
     // No exponent
     template <typename Iterator, typename Attribute>
     static bool
- parse_exp_n(Iterator& first, Iterator const& last, Attribute& attr)
+ parse_exp_n(Iterator&, Iterator const&, Attribute&)
     {
         return false;
     }

Modified: branches/proto/v4/libs/spirit/test/support/hold_any.cpp
==============================================================================
--- branches/proto/v4/libs/spirit/test/support/hold_any.cpp (original)
+++ branches/proto/v4/libs/spirit/test/support/hold_any.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -36,9 +36,9 @@
     {
         o << any_cast<double>(a);
     }
- else if (a.type() == typeid(complex<int>))
+ else if (a.type() == typeid(std::complex<int>))
     {
- o << any_cast<complex<int> >(a);
+ o << any_cast<std::complex<int> >(a);
     }
     else
     {
@@ -61,12 +61,12 @@
     BOOST_TEST(output_any(42, "42"));
     BOOST_TEST(output_any('q', "q"));
     BOOST_TEST(output_any(3.14, "3.14"));
- BOOST_TEST(output_any(complex<int>(1, 2), "(1,2)"));
+ BOOST_TEST(output_any(std::complex<int>(1, 2), "(1,2)"));
 
     int n = 42; BOOST_TEST(output_any(n, "42"));
     char c = 'q'; BOOST_TEST(output_any(c, "q"));
     double d = 3.14; BOOST_TEST(output_any(d, "3.14"));
- complex<int> x(1, 2); BOOST_TEST(output_any(x, "(1,2)"));
+ std::complex<int> x(1, 2); BOOST_TEST(output_any(x, "(1,2)"));
   
     hold_any a;
     BOOST_TEST(output_any(a = n, "42"));
@@ -79,13 +79,13 @@
     BOOST_TEST(output_any_direct(n = hold_any(42), "42"));
     BOOST_TEST(output_any_direct(c = hold_any('q'), "q"));
     BOOST_TEST(output_any_direct(d = hold_any(3.14), "3.14"));
- BOOST_TEST(output_any_direct(x = complex<int>(hold_any(complex<int>(1, 2))), "(1,2)"));
+ BOOST_TEST(output_any_direct(x = std::complex<int>(hold_any(std::complex<int>(1, 2))), "(1,2)"));
 #endif
   
     BOOST_TEST(output_any_direct(hold_any(42), "42"));
     BOOST_TEST(output_any_direct(hold_any('q'), "q"));
     BOOST_TEST(output_any_direct(hold_any(3.14), "3.14"));
- BOOST_TEST(output_any_direct(hold_any(complex<int>(1, 2)), "(1,2)"));
+ BOOST_TEST(output_any_direct(hold_any(std::complex<int>(1, 2)), "(1,2)"));
 
     BOOST_TEST(!a.empty());
     a = 0;
@@ -118,7 +118,7 @@
 struct small_object
 {
     small_object() {}
- small_object(small_object const& fb) { state = 1; }
+ small_object(small_object const&) { state = 1; }
     ~small_object() { state = 2; }
 };
 
@@ -138,7 +138,7 @@
 struct large_object
 {
     large_object() {}
- large_object(large_object const& fb) { state = 3; }
+ large_object(large_object const&) { state = 3; }
     ~large_object() { state = 4; }
     
     int data0;

Modified: branches/proto/v4/libs/thread/doc/changes.qbk
==============================================================================
--- branches/proto/v4/libs/thread/doc/changes.qbk (original)
+++ branches/proto/v4/libs/thread/doc/changes.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -46,7 +46,10 @@
 
 * The `locked()` member function of the `scoped_lock` types has been renamed to __owns_lock_ref__.
 
-* The broken `boost::read_write_mutex` has been replaced with __shared_mutex__.
+* You can no longer obtain a __thread__ instance representing the current thread: a default-constructed __thread__ object is not
+associated with any thread. The only use for such a thread object was to support the comparison operators: this functionality has
+been moved to __thread_id__.
 
+* The broken `boost::read_write_mutex` has been replaced with __shared_mutex__.
 
 [endsect]

Modified: branches/proto/v4/libs/thread/test/test_lock_concept.cpp
==============================================================================
--- branches/proto/v4/libs/thread/test/test_lock_concept.cpp (original)
+++ branches/proto/v4/libs/thread/test/test_lock_concept.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,7 +7,9 @@
 #include <boost/test/test_case_template.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/thread/mutex.hpp>
+#include <boost/thread/thread.hpp>
 #include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/condition_variable.hpp>
 
 template<typename Mutex,typename Lock>
 struct test_initially_locked
@@ -23,6 +25,64 @@
 };
 
 template<typename Mutex,typename Lock>
+struct test_initially_unlocked_if_other_thread_has_lock
+{
+ Mutex m;
+ boost::mutex done_mutex;
+ bool done;
+ bool locked;
+ boost::condition_variable done_cond;
+
+ test_initially_unlocked_if_other_thread_has_lock():
+ done(false),locked(false)
+ {}
+
+ void locking_thread()
+ {
+ Lock lock(m);
+
+ boost::lock_guard<boost::mutex> lk(done_mutex);
+ locked=lock.owns_lock();
+ done=true;
+ done_cond.notify_one();
+ }
+
+ bool is_done() const
+ {
+ return done;
+ }
+
+
+ void operator()()
+ {
+ Lock lock(m);
+
+ typedef test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock> this_type;
+
+ boost::thread t(&this_type::locking_thread,this);
+
+ try
+ {
+ {
+ boost::mutex::scoped_lock lk(done_mutex);
+ BOOST_CHECK(done_cond.timed_wait(lk,boost::posix_time::seconds(2),
+ boost::bind(&this_type::is_done,this)));
+ BOOST_CHECK(!locked);
+ }
+
+ lock.unlock();
+ t.join();
+ }
+ catch(...)
+ {
+ lock.unlock();
+ t.join();
+ throw;
+ }
+ }
+};
+
+template<typename Mutex,typename Lock>
 struct test_initially_unlocked_with_defer_lock_parameter
 {
     void operator()() const
@@ -144,6 +204,7 @@
     typedef typename Mutex::scoped_try_lock Lock;
     
     test_initially_locked<Mutex,Lock>()();
+ test_initially_unlocked_if_other_thread_has_lock<Mutex,Lock>()();
     test_initially_unlocked_with_defer_lock_parameter<Mutex,Lock>()();
     test_initially_locked_with_adopt_lock_parameter<Mutex,Lock>()();
     test_unlocked_after_unlock_called<Mutex,Lock>()();

Modified: branches/proto/v4/libs/unordered/doc/ref.xml
==============================================================================
--- branches/proto/v4/libs/unordered/doc/ref.xml (original)
+++ branches/proto/v4/libs/unordered/doc/ref.xml 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -262,6 +262,60 @@
             </method>
           </method-group>
           <method-group name="modifiers">
+ <method name="emplace">
+ <template>
+ <template-type-parameter name="Args">
+ </template-type-parameter>
+ <template-varargs></template-varargs>
+ </template>
+ <parameter name="args">
+ <paramtype>Args&amp;&amp;...</paramtype>
+ </parameter>
+ <type>std::pair&lt;iterator, bool&gt;</type>
+ <description>
+ <para>Inserts an object, constructed with the arguments <code>args</code>, in the container if and only if there is no element in the container with an equivalent value.</para>
+ </description>
+ <returns>
+ <para>The bool component of the return type is true if an insert took place.</para>
+ <para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent value.</para>
+ </returns>
+ <throws>
+ <para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
+ </throws>
+ <notes>
+ <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
+ </notes>
+ </method>
+ <method name="emplace">
+ <template>
+ <template-type-parameter name="Args">
+ </template-type-parameter>
+ <template-varargs></template-varargs>
+ </template>
+ <parameter name="hint">
+ <paramtype>const_iterator</paramtype>
+ </parameter>
+ <parameter name="args">
+ <paramtype>Args&amp;&amp;...</paramtype>
+ </parameter>
+ <type>iterator</type>
+ <description>
+ <para>Inserts an object, constructed with the arguments <code>args</code>, in the container if and only if there is no element in the container with an equivalent value.</para>
+ <para>hint is a suggestion to where the element should be inserted.</para>
+ </description>
+ <returns>
+ <para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent value.</para>
+ </returns>
+ <throws>
+ <para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
+ </throws>
+ <notes>
+ <para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. </para>
+ <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
+ </notes>
+ </method>
             <method name="insert">
               <parameter name="obj">
                 <paramtype>value_type const&amp;</paramtype>
@@ -603,6 +657,71 @@
               </throws>
             </method>
           </method-group>
+ <free-function-group name="Equality Comparisons">
+ <function name="operator==">
+ <template>
+ <template-type-parameter name="Value">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <parameter name="y">
+ <paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>bool</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ <function name="operator!=">
+ <template>
+ <template-type-parameter name="Value">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <parameter name="y">
+ <paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>bool</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ <function name="hash_value">
+ <template>
+ <template-type-parameter name="Value">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_set&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>std::size_t</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ </free-function-group>
           <free-function-group name="swap">
             <function name="swap">
               <template>
@@ -892,6 +1011,59 @@
             </method>
           </method-group>
           <method-group name="modifiers">
+ <method name="emplace">
+ <template>
+ <template-type-parameter name="Args">
+ </template-type-parameter>
+ <template-varargs></template-varargs>
+ </template>
+ <parameter name="args">
+ <paramtype>Args&amp;&amp;...</paramtype>
+ </parameter>
+ <type>iterator</type>
+ <description>
+ <para>Inserts an object, constructed with the arguments <code>args</code>, in the container.</para>
+ </description>
+ <returns>
+ <para>An iterator pointing to the inserted element.</para>
+ </returns>
+ <throws>
+ <para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
+ </throws>
+ <notes>
+ <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
+ </notes>
+ </method>
+ <method name="emplace">
+ <template>
+ <template-type-parameter name="Args">
+ </template-type-parameter>
+ <template-varargs></template-varargs>
+ </template>
+ <parameter name="hint">
+ <paramtype>const_iterator</paramtype>
+ </parameter>
+ <parameter name="args">
+ <paramtype>Args&amp;&amp;...</paramtype>
+ </parameter>
+ <type>iterator</type>
+ <description>
+ <para>Inserts an object, constructed with the arguments <code>args</code>, in the container.</para>
+ <para>hint is a suggestion to where the element should be inserted.</para>
+ </description>
+ <returns>
+ <para>An iterator pointing to the inserted element.</para>
+ </returns>
+ <throws>
+ <para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
+ </throws>
+ <notes>
+ <para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same value. </para>
+ <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
+ </notes>
+ </method>
             <method name="insert">
               <parameter name="obj">
                 <paramtype>value_type const&amp;</paramtype>
@@ -1232,6 +1404,71 @@
               </throws>
             </method>
           </method-group>
+ <free-function-group name="Equality Comparisons">
+ <function name="operator==">
+ <template>
+ <template-type-parameter name="Value">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <parameter name="y">
+ <paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>bool</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ <function name="operator!=">
+ <template>
+ <template-type-parameter name="Value">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <parameter name="y">
+ <paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>bool</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ <function name="hash_value">
+ <template>
+ <template-type-parameter name="Value">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_multiset&lt;Value, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>std::size_t</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ </free-function-group>
           <free-function-group name="swap">
             <function name="swap">
               <template>
@@ -1533,6 +1770,60 @@
             </method>
           </method-group>
           <method-group name="modifiers">
+ <method name="emplace">
+ <template>
+ <template-type-parameter name="Args">
+ </template-type-parameter>
+ <template-varargs></template-varargs>
+ </template>
+ <parameter name="args">
+ <paramtype>Args&amp;&amp;...</paramtype>
+ </parameter>
+ <type>std::pair&lt;iterator, bool&gt;</type>
+ <description>
+ <para>Inserts an object, constructed with the arguments <code>args</code>, in the container if and only if there is no element in the container with an equivalent key.</para>
+ </description>
+ <returns>
+ <para>The bool component of the return type is true if an insert took place.</para>
+ <para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.</para>
+ </returns>
+ <throws>
+ <para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
+ </throws>
+ <notes>
+ <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
+ </notes>
+ </method>
+ <method name="emplace">
+ <template>
+ <template-type-parameter name="Args">
+ </template-type-parameter>
+ <template-varargs></template-varargs>
+ </template>
+ <parameter name="hint">
+ <paramtype>const_iterator</paramtype>
+ </parameter>
+ <parameter name="args">
+ <paramtype>Args&amp;&amp;...</paramtype>
+ </parameter>
+ <type>iterator</type>
+ <description>
+ <para>Inserts an object, constructed with the arguments <code>args</code>, in the container if and only if there is no element in the container with an equivalent key.</para>
+ <para>hint is a suggestion to where the element should be inserted.</para>
+ </description>
+ <returns>
+ <para>If an insert took place, then the iterator points to the newly inserted element. Otherwise, it points to the element with equivalent key.</para>
+ </returns>
+ <throws>
+ <para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
+ </throws>
+ <notes>
+ <para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. </para>
+ <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
+ </notes>
+ </method>
             <method name="insert">
               <parameter name="obj">
                 <paramtype>value_type const&amp;</paramtype>
@@ -1909,6 +2200,77 @@
               </throws>
             </method>
           </method-group>
+ <free-function-group name="Equality Comparisons">
+ <function name="operator==">
+ <template>
+ <template-type-parameter name="Key">
+ </template-type-parameter>
+ <template-type-parameter name="Mapped">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <parameter name="y">
+ <paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>bool</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ <function name="operator!=">
+ <template>
+ <template-type-parameter name="Key">
+ </template-type-parameter>
+ <template-type-parameter name="Mapped">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <parameter name="y">
+ <paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>bool</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ <function name="hash_value">
+ <template>
+ <template-type-parameter name="Key">
+ </template-type-parameter>
+ <template-type-parameter name="Mapped">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_map&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>std::size_t</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ </free-function-group>
           <free-function-group name="swap">
             <function name="swap">
               <template>
@@ -2208,6 +2570,59 @@
             </method>
           </method-group>
           <method-group name="modifiers">
+ <method name="emplace">
+ <template>
+ <template-type-parameter name="Args">
+ </template-type-parameter>
+ <template-varargs></template-varargs>
+ </template>
+ <parameter name="args">
+ <paramtype>Args&amp;&amp;...</paramtype>
+ </parameter>
+ <type>iterator</type>
+ <description>
+ <para>Inserts an object, constructed with the arguments <code>args</code>, in the container.</para>
+ </description>
+ <returns>
+ <para>An iterator pointing to the inserted element.</para>
+ </returns>
+ <throws>
+ <para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
+ </throws>
+ <notes>
+ <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
+ </notes>
+ </method>
+ <method name="emplace">
+ <template>
+ <template-type-parameter name="Args">
+ </template-type-parameter>
+ <template-varargs></template-varargs>
+ </template>
+ <parameter name="hint">
+ <paramtype>const_iterator</paramtype>
+ </parameter>
+ <parameter name="args">
+ <paramtype>Args&amp;&amp;...</paramtype>
+ </parameter>
+ <type>iterator</type>
+ <description>
+ <para>Inserts an object, constructed with the arguments <code>args</code>, in the container.</para>
+ <para>hint is a suggestion to where the element should be inserted.</para>
+ </description>
+ <returns>
+ <para>An iterator pointing to the inserted element.</para>
+ </returns>
+ <throws>
+ <para>If an exception is thrown by an operation other than a call to <code>hasher</code> the function has no effect.</para>
+ </throws>
+ <notes>
+ <para>The standard is fairly vague on the meaning of the hint. But the only practical way to use it, and the only way that Boost.Unordered supports is to point to an existing element with the same key. </para>
+ <para>Can invalidate iterators, but only if the insert causes the load factor to be greater to or equal to the maximum load factor.</para>
+ <para>Pointers and references to elements are never invalidated.</para>
+ </notes>
+ </method>
             <method name="insert">
               <parameter name="obj">
                 <paramtype>value_type const&amp;</paramtype>
@@ -2548,6 +2963,77 @@
               </throws>
             </method>
           </method-group>
+ <free-function-group name="Equality Comparisons">
+ <function name="operator==">
+ <template>
+ <template-type-parameter name="Key">
+ </template-type-parameter>
+ <template-type-parameter name="Mapped">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <parameter name="y">
+ <paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>bool</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ <function name="operator!=">
+ <template>
+ <template-type-parameter name="Key">
+ </template-type-parameter>
+ <template-type-parameter name="Mapped">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <parameter name="y">
+ <paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>bool</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ <function name="hash_value">
+ <template>
+ <template-type-parameter name="Key">
+ </template-type-parameter>
+ <template-type-parameter name="Mapped">
+ </template-type-parameter>
+ <template-type-parameter name="Hash">
+ </template-type-parameter>
+ <template-type-parameter name="Pred">
+ </template-type-parameter>
+ <template-type-parameter name="Alloc">
+ </template-type-parameter>
+ </template>
+ <parameter name="x">
+ <paramtype>unordered_multimap&lt;Key, Mapped, Hash, Pred, Alloc&gt; const&amp;</paramtype>
+ </parameter>
+ <type>std::size_t</type>
+ <notes>
+ <para>This is a boost extension.</para>
+ </notes>
+ </function>
+ </free-function-group>
           <free-function-group name="swap">
             <function name="swap">
               <template>

Modified: branches/proto/v4/libs/unordered/test/exception/insert_exception_tests.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/exception/insert_exception_tests.cpp (original)
+++ branches/proto/v4/libs/unordered/test/exception/insert_exception_tests.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -36,6 +36,25 @@
     }
 };
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+
+template <class T>
+struct emplace_test1 : public insert_test_base<T>
+{
+ typedef BOOST_DEDUCED_TYPENAME insert_test_base<T>::strong_type strong_type;
+
+ void run(T& x, strong_type& strong) const {
+ for(BOOST_DEDUCED_TYPENAME test::random_values<T>::const_iterator
+ it = this->values.begin(), end = this->values.end(); it != end; ++it)
+ {
+ strong.store(x);
+ x.emplace(*it);
+ }
+ }
+};
+
+#endif
+
 template <class T>
 struct insert_test1 : public insert_test_base<T>
 {
@@ -204,7 +223,15 @@
     }
 };
 
-RUN_EXCEPTION_TESTS(
- (insert_test1)(insert_test2)(insert_test3)(insert_test4)
- (insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3),
- CONTAINER_SEQ)
+#define BASIC_TESTS \
+ (insert_test1)(insert_test2)(insert_test3)(insert_test4) \
+ (insert_test_rehash1)(insert_test_rehash2)(insert_test_rehash3)
+
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+#define ALL_TESTS (emplace_test1)BASIC_TESTS
+#else
+#define ALL_TESTS BASIC_TESTS
+#endif
+
+
+RUN_EXCEPTION_TESTS(ALL_TESTS, CONTAINER_SEQ)

Modified: branches/proto/v4/libs/unordered/test/helpers/equivalent.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/helpers/equivalent.hpp (original)
+++ branches/proto/v4/libs/unordered/test/helpers/equivalent.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -8,10 +8,10 @@
 
 #include <boost/unordered_map.hpp>
 #include <boost/unordered_set.hpp>
-#include <vector>
 #include <algorithm>
 #include "./metafunctions.hpp"
 #include "./fwd.hpp"
+#include "./list.hpp"
 
 namespace test
 {
@@ -56,20 +56,17 @@
         BOOST_DEDUCED_TYPENAME Container::key_equal key_equal_;
         float max_load_factor_;
 
- typedef BOOST_DEDUCED_TYPENAME non_const_value_type<Container>::type value_type;
- std::vector<value_type> values_;
+ typedef test::list<BOOST_DEDUCED_TYPENAME Container::value_type>
+ value_list;
+ value_list values_;
     public:
         unordered_equivalence_tester(Container const &x)
             : size_(x.size()),
             hasher_(x.hash_function()), key_equal_(x.key_eq()),
             max_load_factor_(x.max_load_factor()),
- values_()
+ values_(x.begin(), x.end())
         {
- // Can't initialise values_ straight from x because of Visual C++ 6
- values_.reserve(x.size());
- std::copy(x.begin(), x.end(), std::back_inserter(values_));
-
- std::sort(values_.begin(), values_.end());
+ values_.sort();
         }
 
         bool operator()(Container const& x) const
@@ -80,11 +77,9 @@
                 (max_load_factor_ == x.max_load_factor()) &&
                 (values_.size() == x.size()))) return false;
 
- std::vector<value_type> copy;
- copy.reserve(x.size());
- std::copy(x.begin(), x.end(), std::back_inserter(copy));
- std::sort(copy.begin(), copy.end());
- return(std::equal(values_.begin(), values_.end(), copy.begin()));
+ value_list copy(x.begin(), x.end());
+ copy.sort();
+ return values_ == copy;
         }
     private:
         unordered_equivalence_tester();

Modified: branches/proto/v4/libs/unordered/test/helpers/metafunctions.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/helpers/metafunctions.hpp (original)
+++ branches/proto/v4/libs/unordered/test/helpers/metafunctions.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -75,35 +75,6 @@
             sizeof(has_unique_key_impl((Container const*)0))
                 == sizeof(no_type));
     };
-
- // Non Const Value Type
-
- template <bool IsMap>
- struct non_const_value_type_impl
- {
- template <class Container>
- struct apply {
- typedef std::pair<
- BOOST_DEDUCED_TYPENAME Container::key_type,
- BOOST_DEDUCED_TYPENAME Container::mapped_type> type;
- };
- };
-
- template<>
- struct non_const_value_type_impl<false>
- {
- template <class Container>
- struct apply {
- typedef BOOST_DEDUCED_TYPENAME Container::value_type type;
- };
- };
-
- template <class Container>
- struct non_const_value_type
- : non_const_value_type_impl< ::test::is_map<Container>::value>::
- BOOST_NESTED_TEMPLATE apply<Container>
- {
- };
 }
 
 #endif

Modified: branches/proto/v4/libs/unordered/test/helpers/random_values.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/helpers/random_values.hpp (original)
+++ branches/proto/v4/libs/unordered/test/helpers/random_values.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,7 +6,7 @@
 #if !defined(BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER)
 #define BOOST_UNORDERED_TEST_HELPERS_RANDOM_VALUES_HEADER
 
-#include <list>
+#include "./list.hpp"
 #include <algorithm>
 #include <boost/mpl/if.hpp>
 #include "./generators.hpp"
@@ -97,7 +97,7 @@
 
     template <class X>
     struct random_values
- : public std::list<BOOST_DEDUCED_TYPENAME X::value_type>
+ : public test::list<BOOST_DEDUCED_TYPENAME X::value_type>
     {
         random_values(int count, test::random_generator const& generator =
             test::default_generator)

Modified: branches/proto/v4/libs/unordered/test/helpers/strong.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/helpers/strong.hpp (original)
+++ branches/proto/v4/libs/unordered/test/helpers/strong.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -7,10 +7,10 @@
 #define BOOST_UNORDERED_TEST_HELPERS_STRONG_HEADER
 
 #include <boost/config.hpp>
-#include <vector>
 #include <iterator>
 #include "./metafunctions.hpp"
 #include "./equivalent.hpp"
+#include "./list.hpp"
 #include "../objects/exception.hpp"
 
 namespace test
@@ -18,19 +18,19 @@
     template <class X>
     class strong
     {
- typedef std::vector<BOOST_DEDUCED_TYPENAME non_const_value_type<X>::type> values_type;
+ typedef test::list<BOOST_DEDUCED_TYPENAME X::value_type> values_type;
         values_type values_;
     public:
         void store(X const& x) {
             DISABLE_EXCEPTIONS;
             values_.clear();
- values_.reserve(x.size());
- std::copy(x.cbegin(), x.cend(), std::back_inserter(values_));
+ values_.insert(x.cbegin(), x.cend());
         }
 
         void test(X const& x) const {
             if(!(x.size() == values_.size() &&
- std::equal(x.cbegin(), x.cend(), values_.begin(), test::equivalent)))
+ std::equal(x.cbegin(), x.cend(), values_.begin(),
+ test::equivalent)))
                 BOOST_ERROR("Strong exception safety failure.");
         }
     };

Modified: branches/proto/v4/libs/unordered/test/helpers/test.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/helpers/test.hpp (original)
+++ branches/proto/v4/libs/unordered/test/helpers/test.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -61,7 +61,7 @@
             for(registered_test_base* i = first(); i; i = i->next)
                 i->run();
         }
- };
+ }
 }
 
 #endif

Modified: branches/proto/v4/libs/unordered/test/helpers/tracker.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/helpers/tracker.hpp (original)
+++ branches/proto/v4/libs/unordered/test/helpers/tracker.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,7 +11,6 @@
 
 #include <set>
 #include <map>
-#include <vector>
 #include <iterator>
 #include <algorithm>
 #include <boost/mpl/if.hpp>
@@ -22,6 +21,7 @@
 #include "./metafunctions.hpp"
 #include "./helpers.hpp"
 #include "./equivalent.hpp"
+#include "./list.hpp"
 
 namespace test
 {
@@ -44,27 +44,23 @@
     template <class X1, class X2>
     void compare_range(X1 const& x1, X2 const& x2)
     {
- std::vector<BOOST_DEDUCED_TYPENAME non_const_value_type<X1>::type> values1, values2;
- values1.reserve(x1.size());
- values2.reserve(x2.size());
- std::copy(x1.begin(), x1.end(), std::back_inserter(values1));
- std::copy(x2.begin(), x2.end(), std::back_inserter(values2));
- std::sort(values1.begin(), values1.end());
- std::sort(values2.begin(), values2.end());
+ typedef test::list<BOOST_DEDUCED_TYPENAME X1::value_type> value_list;
+ value_list values1(x1.begin(), x1.end());
+ value_list values2(x2.begin(), x2.end());
+ values1.sort();
+ values2.sort();
         BOOST_CHECK(values1.size() == values2.size() &&
- std::equal(values1.begin(), values1.end(), values2.begin(), test::equivalent));
+ std::equal(values1.begin(), values1.end(), values2.begin(),
+ test::equivalent));
     }
 
     template <class X1, class X2, class T>
     void compare_pairs(X1 const& x1, X2 const& x2, T*)
     {
- std::vector<T> values1, values2;
- values1.reserve(std::distance(x1.first, x1.second));
- values2.reserve(std::distance(x2.first, x2.second));
- std::copy(x1.first, x1.second, std::back_inserter(values1));
- std::copy(x2.first, x2.second, std::back_inserter(values2));
- std::sort(values1.begin(), values1.end());
- std::sort(values2.begin(), values2.end());
+ test::list<T> values1(x1.first, x1.second);
+ test::list<T> values2(x2.first, x2.second);
+ values1.sort();
+ values2.sort();
         BOOST_CHECK(values1.size() == values2.size() &&
                 std::equal(values1.begin(), values1.end(), values2.begin(), test::equivalent));
     }
@@ -123,8 +119,7 @@
             compare_pairs(
                 x.equal_range(get_key<X>(val)),
                 this->equal_range(get_key<X>(val)),
- (BOOST_DEDUCED_TYPENAME non_const_value_type<X>::type*) 0
- );
+ (BOOST_DEDUCED_TYPENAME X::value_type*) 0);
         }
 
         template <class It>

Modified: branches/proto/v4/libs/unordered/test/objects/exception.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/objects/exception.hpp (original)
+++ branches/proto/v4/libs/unordered/test/objects/exception.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -347,6 +347,16 @@
             detail::tracker.track_construct((void*) p, sizeof(T), tag_);
         }
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template<class... Args> void construct(pointer p, Args&&... args) {
+ UNORDERED_SCOPE(allocator::construct(pointer, Args&&...)) {
+ UNORDERED_EPOINT("Mock allocator construct function.");
+ new(p) T(std::forward<Args>(args)...);
+ }
+ detail::tracker.track_construct((void*) p, sizeof(T), tag_);
+ }
+#endif
+
         void destroy(pointer p) {
             detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
             p->~T();

Modified: branches/proto/v4/libs/unordered/test/objects/minimal.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/objects/minimal.hpp (original)
+++ branches/proto/v4/libs/unordered/test/objects/minimal.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -22,8 +22,10 @@
 namespace minimal
 {
     class copy_constructible;
+ class copy_constructible_equality_comparable;
     class default_copy_constructible;
     class assignable;
+
     template <class T> class hash;
     template <class T> class equal_to;
     template <class T> class ptr;
@@ -41,6 +43,25 @@
         copy_constructible() {}
     };
 
+ class copy_constructible_equality_comparable
+ {
+ public:
+ static copy_constructible_equality_comparable create() { return copy_constructible_equality_comparable(); }
+ copy_constructible_equality_comparable(copy_constructible_equality_comparable const&) {}
+ ~copy_constructible_equality_comparable() {}
+ private:
+ copy_constructible_equality_comparable& operator=(copy_constructible_equality_comparable const&);
+ copy_constructible_equality_comparable() {}
+ };
+
+ bool operator==(copy_constructible_equality_comparable, copy_constructible_equality_comparable) {
+ return true;
+ }
+
+ bool operator!=(copy_constructible_equality_comparable, copy_constructible_equality_comparable) {
+ return false;
+ }
+
     class default_copy_constructible
     {
     public:
@@ -207,6 +228,13 @@
         }
 
         void construct(pointer p, T const& t) { new((void*)p.ptr_) T(t); }
+
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template<class... Args> void construct(pointer p, Args&&... args) {
+ new((void*)p.ptr_) T(std::forward<Args>(args)...);
+ }
+#endif
+
         void destroy(pointer p) { ((T*)p.ptr_)->~T(); }
 
         size_type max_size() const { return 1000; }
@@ -238,6 +266,22 @@
 }
 }
 
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+namespace boost {
+#else
+namespace test {
+namespace minimal {
+#endif
+ std::size_t hash_value(test::minimal::copy_constructible_equality_comparable) {
+ return 1;
+ }
+#if !defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+}}
+#else
+}
+#endif
+
+
 #if defined(BOOST_MSVC)
 #pragma warning(pop)
 #endif

Modified: branches/proto/v4/libs/unordered/test/objects/test.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/objects/test.hpp (original)
+++ branches/proto/v4/libs/unordered/test/objects/test.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -212,6 +212,13 @@
             new(p) T(t);
         }
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template<class... Args> void construct(pointer p, Args&&... args) {
+ detail::tracker.track_construct((void*) p, sizeof(T), tag_);
+ new(p) T(std::forward<Args>(args)...);
+ }
+#endif
+
         void destroy(pointer p) {
             detail::tracker.track_destroy((void*) p, sizeof(T), tag_);
             p->~T();

Modified: branches/proto/v4/libs/unordered/test/unordered/Jamfile.v2
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/Jamfile.v2 (original)
+++ branches/proto/v4/libs/unordered/test/unordered/Jamfile.v2 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -33,5 +33,6 @@
         [ run bucket_tests.cpp ]
         [ run load_factor_tests.cpp ]
         [ run rehash_tests.cpp ]
+ [ run equality_tests.cpp ]
         [ run swap_tests.cpp : : : <define>BOOST_UNORDERED_SWAP_METHOD=2 ]
     ;

Modified: branches/proto/v4/libs/unordered/test/unordered/compile_map.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/compile_map.cpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/compile_map.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -22,6 +22,9 @@
             test::minimal::copy_constructible::create());
 
     std::cout<<"Test unordered_map.\n";
+
+ boost::unordered_map<int, int> int_map;
+
     boost::unordered_map<
         test::minimal::assignable,
         test::minimal::copy_constructible,
@@ -29,9 +32,13 @@
         test::minimal::equal_to<test::minimal::assignable>,
         test::minimal::allocator<value_type> > map;
 
+ container_test(int_map, std::pair<int const, int>(0, 0));
     container_test(map, value);
 
     std::cout<<"Test unordered_multimap.\n";
+
+ boost::unordered_multimap<int, int> int_multimap;
+
     boost::unordered_multimap<
         test::minimal::assignable,
         test::minimal::copy_constructible,
@@ -39,9 +46,39 @@
         test::minimal::equal_to<test::minimal::assignable>,
         test::minimal::allocator<value_type> > multimap;
 
+ container_test(int_multimap, std::pair<int const, int>(0, 0));
     container_test(multimap, value);
 }
 
+UNORDERED_AUTO_TEST(equality_tests) {
+ typedef std::pair<test::minimal::assignable const,
+ test::minimal::copy_constructible> value_type;
+
+ boost::unordered_map<int, int> int_map;
+
+ boost::unordered_map<
+ test::minimal::assignable,
+ test::minimal::copy_constructible_equality_comparable,
+ test::minimal::hash<test::minimal::assignable>,
+ test::minimal::equal_to<test::minimal::assignable>,
+ test::minimal::allocator<value_type> > map;
+
+ equality_test(int_map);
+ equality_test(map);
+
+ boost::unordered_multimap<int, int> int_multimap;
+
+ boost::unordered_multimap<
+ test::minimal::assignable,
+ test::minimal::copy_constructible_equality_comparable,
+ test::minimal::hash<test::minimal::assignable>,
+ test::minimal::equal_to<test::minimal::assignable>,
+ test::minimal::allocator<value_type> > multimap;
+
+ equality_test(int_multimap);
+ equality_test(multimap);
+}
+
 UNORDERED_AUTO_TEST(test1) {
     boost::hash<int> hash;
     std::equal_to<int> equal_to;

Modified: branches/proto/v4/libs/unordered/test/unordered/compile_set.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/compile_set.cpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/compile_set.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,24 +18,54 @@
     test::minimal::assignable assignable = test::minimal::assignable::create();
 
     std::cout<<"Test unordered_set.\n";
+ boost::unordered_set<int> int_set;
     boost::unordered_set<
         test::minimal::assignable,
         test::minimal::hash<test::minimal::assignable>,
         test::minimal::equal_to<test::minimal::assignable>,
         test::minimal::allocator<test::minimal::assignable> > set;
 
+ container_test(int_set, 0);
     container_test(set, assignable);
 
     std::cout<<"Test unordered_multiset.\n";
+ boost::unordered_multiset<int> int_multiset;
     boost::unordered_multiset<
         test::minimal::assignable,
         test::minimal::hash<test::minimal::assignable>,
         test::minimal::equal_to<test::minimal::assignable>,
         test::minimal::allocator<test::minimal::assignable> > multiset;
 
+ container_test(int_multiset, 0);
     container_test(multiset, assignable);
 }
 
+UNORDERED_AUTO_TEST(equality_tests) {
+ typedef test::minimal::assignable value_type;
+
+ boost::unordered_set<int> int_set;
+
+ boost::unordered_set<
+ test::minimal::assignable,
+ test::minimal::hash<test::minimal::assignable>,
+ test::minimal::equal_to<test::minimal::assignable>,
+ test::minimal::allocator<value_type> > set;
+
+ equality_test(int_set);
+ equality_test(set);
+
+ boost::unordered_multiset<int> int_multiset;
+
+ boost::unordered_multiset<
+ test::minimal::assignable,
+ test::minimal::hash<test::minimal::assignable>,
+ test::minimal::equal_to<test::minimal::assignable>,
+ test::minimal::allocator<value_type> > multiset;
+
+ equality_test(int_multiset);
+ equality_test(multiset);
+}
+
 UNORDERED_AUTO_TEST(test1)
 {
     boost::hash<int> hash;

Modified: branches/proto/v4/libs/unordered/test/unordered/compile_tests.hpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/compile_tests.hpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/compile_tests.hpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -25,9 +25,10 @@
 typedef long double comparison_type;
 
 template <class T> void sink(T const&) {}
+template <class T> T rvalue(T const& v) { return v; }
 
 template <class X, class T>
-void container_test(X& r, T&)
+void container_test(X& r, T const&)
 {
     typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
     typedef BOOST_DEDUCED_TYPENAME X::const_iterator const_iterator;
@@ -120,8 +121,6 @@
     test::check_return_type<const_iterator>::equals(a.cend());
     test::check_return_type<const_iterator>::equals(a_const.cend());
 
- // No tests for ==, != since they're not required for unordered containers.
-
     a.swap(b);
     test::check_return_type<X>::equals_ref(r = a);
     test::check_return_type<size_type>::equals(a.size());
@@ -144,11 +143,34 @@
 }
 
 template <class X, class Key, class T>
-void unordered_map_test(X&, Key const&, T const&)
+void unordered_map_test(X& r, Key const& k, T const& v)
 {
     typedef BOOST_DEDUCED_TYPENAME X::value_type value_type;
     typedef BOOST_DEDUCED_TYPENAME X::key_type key_type;
     BOOST_MPL_ASSERT((boost::is_same<value_type, std::pair<key_type const, T> >));
+
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ Key k_lvalue(k);
+ T v_lvalue(v);
+
+ r.emplace(k, v);
+ r.emplace(k_lvalue, v_lvalue);
+ r.emplace(rvalue(k), rvalue(v));
+#endif
+}
+
+template <class X>
+void equality_test(X& r)
+{
+ X const a = r, b = r;
+
+ test::check_return_type<bool>::equals(a == b);
+ test::check_return_type<bool>::equals(a != b);
+#if defined(BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP)
+ test::check_return_type<std::size_t>::equals(boost::hash_value(a));
+#else
+ test::check_return_type<std::size_t>::equals(hash_value(a));
+#endif
 }
 
 template <class X, class T>
@@ -156,6 +178,9 @@
 {
     typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
     test::check_return_type<std::pair<iterator, bool> >::equals(r.insert(t));
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ test::check_return_type<std::pair<iterator, bool> >::equals(r.emplace(t));
+#endif
 }
 
 template <class X, class T>
@@ -163,6 +188,9 @@
 {
     typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
     test::check_return_type<iterator>::equals(r.insert(t));
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ test::check_return_type<iterator>::equals(r.emplace(t));
+#endif
 }
 
 template <class X, class Key, class T>
@@ -264,6 +292,9 @@
 
     const_iterator q = a.cbegin();
     test::check_return_type<iterator>::equals(a.insert(q, t));
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ test::check_return_type<iterator>::equals(a.emplace(q, t));
+#endif
 
     a.insert(i, j);
     test::check_return_type<size_type>::equals(a.erase(k));

Modified: branches/proto/v4/libs/unordered/test/unordered/constructor_tests.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/constructor_tests.cpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/constructor_tests.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -257,11 +257,9 @@
 {
     std::cerr<<"map_constructor_test\n";
 
- typedef std::list<std::pair<BOOST_DEDUCED_TYPENAME T::key_type, BOOST_DEDUCED_TYPENAME T::mapped_type> > list;
+ typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME T::key_type, BOOST_DEDUCED_TYPENAME T::mapped_type> > list;
     test::random_values<T> v(1000);
- list l;
- std::copy(v.begin(), v.end(), std::back_inserter(l));
-
+ list l(v.begin(), v.end());
     T x(l.begin(), l.end());
 
     test::check_container(x, v);

Modified: branches/proto/v4/libs/unordered/test/unordered/equivalent_keys_tests.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/equivalent_keys_tests.cpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/equivalent_keys_tests.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -8,7 +8,7 @@
 #include "../helpers/test.hpp"
 #include <algorithm>
 #include <map>
-#include <list>
+#include "../helpers/list.hpp"
 #include "../helpers/tracker.hpp"
 #include "../helpers/invariants.hpp"
 
@@ -57,7 +57,7 @@
 
 UNORDERED_AUTO_TEST(map_tests)
 {
- typedef std::list<std::pair<int const, int> > values_type;
+ typedef test::list<std::pair<int const, int> > values_type;
     values_type v[5];
     v[0].push_back(std::pair<int const, int>(1,1));
     v[1].push_back(std::pair<int const, int>(28,34));

Modified: branches/proto/v4/libs/unordered/test/unordered/erase_equiv_tests.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/erase_equiv_tests.cpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/erase_equiv_tests.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -8,7 +8,7 @@
 
 #include <boost/unordered_map.hpp>
 #include "../helpers/test.hpp"
-#include <list>
+#include "../helpers/list.hpp"
 #include <set>
 #include <iostream>
 #include <iterator>
@@ -50,7 +50,7 @@
     collision2_hash, std::equal_to<int>,
     test::allocator<std::pair<int const, int> > > collide_map2;
 typedef collide_map::value_type collide_value;
-typedef std::list<collide_value> collide_list;
+typedef test::list<collide_value> collide_list;
 
 UNORDERED_AUTO_TEST(empty_range_tests)
 {
@@ -108,10 +108,8 @@
 template<class Range1, class Range2>
 bool compare(Range1 const& x, Range2 const& y)
 {
- collide_list a;
- collide_list b;
- std::copy(x.begin(), x.end(), std::back_inserter(a));
- std::copy(y.begin(), y.end(), std::back_inserter(b));
+ collide_list a(x.begin(), x.end());
+ collide_list b(y.begin(), y.end());
     a.sort();
     b.sort();
     return a == b;
@@ -120,8 +118,7 @@
 template <class Container>
 bool general_erase_range_test(Container& x, int start, int end)
 {
- collide_list l;
- std::copy(x.begin(), x.end(), std::back_inserter(l));
+ collide_list l(x.begin(), x.end());
     l.erase(boost::next(l.begin(), start), boost::next(l.begin(), end));
     x.erase(boost::next(x.begin(), start), boost::next(x.begin(), end));
     return compare(l, x);
@@ -133,8 +130,7 @@
     for(std::size_t length = 0; length < x.size(); ++length) {
         for(std::size_t position = 0; position < x.size() - length; ++position) {
             Container y(x);
- collide_list init;
- std::copy(y.begin(), y.end(), std::back_inserter(init));
+ collide_list init(y.begin(), y.end());
             if(!general_erase_range_test(y, position, position + length)) {
                 BOOST_ERROR("general_erase_range_test failed.");
                 std::cout<<"Erase: ["<<position<<","<<position + length<<")\n";

Modified: branches/proto/v4/libs/unordered/test/unordered/find_tests.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/find_tests.cpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/find_tests.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -43,10 +43,10 @@
 
             test::compare_pairs(x.equal_range(key),
                     tracker.equal_range(key),
- (BOOST_DEDUCED_TYPENAME test::non_const_value_type<X>::type*) 0);
+ (BOOST_DEDUCED_TYPENAME X::value_type*) 0);
             test::compare_pairs(x_const.equal_range(key),
                     tracker.equal_range(key),
- (BOOST_DEDUCED_TYPENAME test::non_const_value_type<X>::type*) 0);
+ (BOOST_DEDUCED_TYPENAME X::value_type*) 0);
         }
 
         test::random_values<X> v2(500, generator);

Modified: branches/proto/v4/libs/unordered/test/unordered/insert_tests.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/insert_tests.cpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/insert_tests.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -218,6 +218,74 @@
     }
 }
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+
+template <class X>
+void unique_emplace_tests1(X*, test::random_generator generator = test::default_generator)
+{
+ typedef BOOST_DEDUCED_TYPENAME X::iterator iterator;
+ typedef test::ordered<X> ordered;
+
+ std::cerr<<"emplace(value) tests for containers with unique keys.\n";
+
+ X x;
+ test::ordered<X> tracker = test::create_ordered(x);
+
+ test::random_values<X> v(1000, generator);
+
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
+ it != v.end(); ++it)
+ {
+
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
+ float b = x.max_load_factor();
+
+ std::pair<iterator, bool> r1 = x.emplace(*it);
+ std::pair<BOOST_DEDUCED_TYPENAME ordered::iterator, bool> r2 = tracker.insert(*it);
+
+ BOOST_CHECK(r1.second == r2.second);
+ BOOST_CHECK(*r1.first == *r2.first);
+
+ tracker.compare_key(x, *it);
+
+ if(x.size() < b * old_bucket_count)
+ BOOST_CHECK(x.bucket_count() == old_bucket_count);
+ }
+
+ test::check_equivalent_keys(x);
+}
+
+template <class X>
+void equivalent_emplace_tests1(X*, test::random_generator generator = test::default_generator)
+{
+ std::cerr<<"emplace(value) tests for containers with equivalent keys.\n";
+
+ X x;
+ test::ordered<X> tracker = test::create_ordered(x);
+
+ test::random_values<X> v(1000, generator);
+ for(BOOST_DEDUCED_TYPENAME test::random_values<X>::iterator it = v.begin();
+ it != v.end(); ++it)
+ {
+ BOOST_DEDUCED_TYPENAME X::size_type old_bucket_count = x.bucket_count();
+ float b = x.max_load_factor();
+
+ BOOST_DEDUCED_TYPENAME X::iterator r1 = x.emplace(*it);
+ BOOST_DEDUCED_TYPENAME test::ordered<X>::iterator r2 = tracker.insert(*it);
+
+ BOOST_CHECK(*r1 == *r2);
+
+ tracker.compare_key(x, *it);
+
+ if(x.size() < b * old_bucket_count)
+ BOOST_CHECK(x.bucket_count() == old_bucket_count);
+ }
+
+ test::check_equivalent_keys(x);
+}
+
+#endif
+
 template <class X>
 void map_tests(X*, test::random_generator generator = test::default_generator)
 {
@@ -250,10 +318,9 @@
 {
     std::cerr<<"associative_insert_range_test\n";
 
- typedef std::list<std::pair<BOOST_DEDUCED_TYPENAME X::key_type, BOOST_DEDUCED_TYPENAME X::mapped_type> > list;
+ typedef test::list<std::pair<BOOST_DEDUCED_TYPENAME X::key_type, BOOST_DEDUCED_TYPENAME X::mapped_type> > list;
     test::random_values<X> v(1000, generator);
- list l;
- std::copy(v.begin(), v.end(), std::back_inserter(l));
+ list l(v.begin(), v.end());
 
     X x; x.insert(l.begin(), l.end());
 
@@ -283,6 +350,18 @@
     ((default_generator)(generate_collisions))
 )
 
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+UNORDERED_TEST(unique_emplace_tests1,
+ ((test_set)(test_map))
+ ((default_generator)(generate_collisions))
+)
+
+UNORDERED_TEST(equivalent_emplace_tests1,
+ ((test_multiset)(test_multimap))
+ ((default_generator)(generate_collisions))
+)
+#endif
+
 UNORDERED_TEST(map_tests,
     ((test_map))
     ((default_generator)(generate_collisions))

Modified: branches/proto/v4/libs/unordered/test/unordered/unnecessary_copy_tests.cpp
==============================================================================
--- branches/proto/v4/libs/unordered/test/unordered/unnecessary_copy_tests.cpp (original)
+++ branches/proto/v4/libs/unordered/test/unordered/unnecessary_copy_tests.cpp 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -11,15 +11,34 @@
 {
     struct count_copies
     {
- static int count;
- count_copies() { ++count; }
- count_copies(count_copies const&) { ++count; }
+ static int copies;
+ static int moves;
+ count_copies() : tag_(0) { ++copies; }
+ explicit count_copies(int tag) : tag_(tag) { ++copies; }
+ count_copies(count_copies const&, count_copies const& x) : tag_(x.tag_) { ++copies; }
+ count_copies(count_copies const& x) : tag_(x.tag_) { ++copies; }
+#if defined(BOOST_HAS_RVALUE_REFS)
+ count_copies(count_copies&& x) : tag_(x.tag_) {
+ x.tag_ = -1; ++moves;
+ }
+#endif
+ int tag_;
     private:
        count_copies& operator=(count_copies const&);
     };
 
- bool operator==(count_copies const&, count_copies const&) {
- return true;
+ bool operator==(count_copies const& x, count_copies const& y) {
+ return x.tag_ == y.tag_;
+ }
+
+ template <class T>
+ T source() {
+ return T();
+ }
+
+ void reset() {
+ count_copies::copies = 0;
+ count_copies::moves = 0;
     }
 }
 
@@ -29,29 +48,36 @@
 namespace unnecessary_copy_tests
 #endif
 {
- std::size_t hash_value(unnecessary_copy_tests::count_copies const&) {
- return 0;
+ std::size_t hash_value(unnecessary_copy_tests::count_copies const& x) {
+ return x.tag_;
     }
 }
 
+#define COPY_COUNT(n) \
+ if(count_copies::copies != n) { \
+ BOOST_ERROR("Wrong number of copies."); \
+ std::cerr<<"Number of copies: "<<count_copies::copies<<std::endl; \
+ }
+#define MOVE_COUNT(n) \
+ if(count_copies::moves != n) { \
+ BOOST_ERROR("Wrong number of moves."); \
+ std::cerr<<"Number of moves: "<<count_copies::moves<<std::endl; \
+ }
+
 namespace unnecessary_copy_tests
 {
- int count_copies::count;
+ int count_copies::copies;
+ int count_copies::moves;
 
     template <class T>
- void unnecessary_copy_test(T*)
+ void unnecessary_copy_insert_test(T*)
     {
- count_copies::count = 0;
+ reset();
         T x;
         BOOST_DEDUCED_TYPENAME T::value_type a;
- BOOST_CHECK(count_copies::count == 1);
- if(count_copies::count != 1)
- std::cerr<<count_copies::count<<" copies.\n";
-
+ COPY_COUNT(1);
         x.insert(a);
- BOOST_CHECK(count_copies::count == 2);
- if(count_copies::count != 1)
- std::cerr<<count_copies::count<<" copies.\n";
+ COPY_COUNT(2);
     }
 
     boost::unordered_set<count_copies>* set;
@@ -59,7 +85,181 @@
     boost::unordered_map<int, count_copies>* map;
     boost::unordered_multimap<int, count_copies>* multimap;
 
- UNORDERED_TEST(unnecessary_copy_test, ((set)(multiset)(map)(multimap)))
+ UNORDERED_TEST(unnecessary_copy_insert_test,
+ ((set)(multiset)(map)(multimap)))
+
+#if defined(BOOST_HAS_RVALUE_REFS) && defined(BOOST_HAS_VARIADIC_TMPL)
+ template <class T>
+ void unnecessary_copy_emplace_test(T*)
+ {
+ reset();
+ T x;
+ BOOST_DEDUCED_TYPENAME T::value_type a;
+ COPY_COUNT(1);
+ x.emplace(a);
+ COPY_COUNT(2);
+ }
+
+ template <class T>
+ void unnecessary_copy_emplace_rvalue_test(T*)
+ {
+ reset();
+ T x;
+ x.emplace(source<BOOST_DEDUCED_TYPENAME T::value_type>());
+ COPY_COUNT(1);
+ }
+
+ template <class T>
+ void unnecessary_copy_emplace_move_test(T*)
+ {
+ reset();
+ T x;
+ BOOST_DEDUCED_TYPENAME T::value_type a;
+ COPY_COUNT(1); MOVE_COUNT(0);
+ x.emplace(std::move(a));
+ COPY_COUNT(1); MOVE_COUNT(1);
+ }
+
+ UNORDERED_TEST(unnecessary_copy_emplace_test,
+ ((set)(multiset)(map)(multimap)))
+ UNORDERED_TEST(unnecessary_copy_emplace_rvalue_test,
+ ((set)(multiset)(map)(multimap)))
+ UNORDERED_TEST(unnecessary_copy_emplace_move_test,
+ ((set)(multiset)(map)(multimap)))
+
+ UNORDERED_AUTO_TEST(unnecessary_copy_emplace_set_test)
+ {
+ reset();
+ boost::unordered_set<count_copies> x;
+ count_copies a;
+ x.insert(a);
+ COPY_COUNT(2); MOVE_COUNT(0);
+
+ //
+ // 0 arguments
+ //
+
+ // The container will have to create a copy in order to compare with
+ // the existing element.
+ reset();
+ x.emplace();
+ COPY_COUNT(1); MOVE_COUNT(0);
+
+ //
+ // 1 argument
+ //
+
+ // Emplace should be able to tell that there already is an element
+ // without creating a new one.
+ reset();
+ x.emplace(a);
+ COPY_COUNT(0); MOVE_COUNT(0);
+
+ // A new object is created by source, but it shouldn't be moved or
+ // copied.
+ reset();
+ x.emplace(source<count_copies>());
+ COPY_COUNT(1); MOVE_COUNT(0);
+
+ // No move should take place.
+ reset();
+ x.emplace(std::move(a));
+ COPY_COUNT(0); MOVE_COUNT(0);
+
+ // Just in case a did get moved...
+ count_copies b;
+
+ // The container will have to create a copy in order to compare with
+ // the existing element.
+ reset();
+ x.emplace(b.tag_);
+ COPY_COUNT(1); MOVE_COUNT(0);
+
+ //
+ // 2 arguments
+ //
+
+ // The container will have to create b copy in order to compare with
+ // the existing element.
+
+ reset();
+ x.emplace(b, b);
+ COPY_COUNT(1); MOVE_COUNT(0);
+ }
+
+ UNORDERED_AUTO_TEST(unnecessary_copy_emplace_map_test)
+ {
+ reset();
+ boost::unordered_map<count_copies, count_copies> x;
+ // TODO: Run tests for pairs without const etc.
+ std::pair<count_copies const, count_copies> a;
+ x.emplace(a);
+ COPY_COUNT(4); MOVE_COUNT(0);
+
+ //
+ // 0 arguments
+ //
+
+ // COPY_COUNT(1) would be okay here.
+ reset();
+ x.emplace();
+ COPY_COUNT(2); MOVE_COUNT(0);
+
+ //
+ // 1 argument
+ //
+
+ reset();
+ x.emplace(a);
+ COPY_COUNT(0); MOVE_COUNT(0);
+
+ // A new object is created by source, but it shouldn't be moved or
+ // copied.
+ reset();
+ x.emplace(source<std::pair<count_copies, count_copies> >());
+ COPY_COUNT(2); MOVE_COUNT(0);
+
+ count_copies part;
+ reset();
+ std::pair<count_copies const&, count_copies const&> a_ref(part, part);
+ x.emplace(a_ref);
+ COPY_COUNT(0); MOVE_COUNT(0);
+
+ // No move should take place.
+ reset();
+ x.emplace(std::move(a));
+ COPY_COUNT(0); MOVE_COUNT(0);
+
+ // Just in case a did get moved
+ std::pair<count_copies const, count_copies> b;
+
+ // This test requires a C++0x std::pair. Which gcc hasn't got yet.
+ //reset();
+ //x.emplace(b.first.tag_);
+ //COPY_COUNT(2); MOVE_COUNT(0);
+
+ //
+ // 2 arguments
+ //
+
+ reset();
+ x.emplace(b.first, b.second);
+ COPY_COUNT(0); MOVE_COUNT(0);
+
+ reset();
+ x.emplace(source<count_copies>(), source<count_copies>());
+ COPY_COUNT(2); MOVE_COUNT(0);
+
+ // source<count_copies> creates a single copy.
+ reset();
+ x.emplace(b.first, source<count_copies>());
+ COPY_COUNT(1); MOVE_COUNT(0);
+
+ reset();
+ x.emplace(b.first.tag_, b.second.tag_);
+ COPY_COUNT(2); MOVE_COUNT(0);
+ }
+#endif
 }
 
 RUN_TESTS()

Modified: branches/proto/v4/libs/utility/shared_container_iterator.html
==============================================================================
--- branches/proto/v4/libs/utility/shared_container_iterator.html (original)
+++ branches/proto/v4/libs/utility/shared_container_iterator.html 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -315,7 +315,7 @@
 <p>© Copyright 2003 The Trustees of Indiana University.
  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)</p>
+ http://www.boost.org/LICENSE_1_0.txt)</p>
 
 </body>
 

Modified: branches/proto/v4/libs/wave/test/testwave/testfiles/test.cfg
==============================================================================
--- branches/proto/v4/libs/wave/test/testwave/testfiles/test.cfg (original)
+++ branches/proto/v4/libs/wave/test/testwave/testfiles/test.cfg 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1,228 +1,228 @@
-#
-# Boost.Wave: A Standard compliant C++ preprocessor library
-# http://www.boost.org/
-#
-# Copyright (c) 2003-2008 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)
-#
-
-#
-# t_1: Macro expansion
-#
-t_1_001.cpp
-t_1_002.cpp
-t_1_003.cpp
-t_1_004.cpp
-t_1_005.cpp
-t_1_006.cpp
-t_1_007.cpp
-t_1_008.cpp
-t_1_009.cpp
-t_1_010.cpp
-t_1_011.cpp
-t_1_012.cpp
-t_1_013.cpp
-# t_1_014 currently disabled because of a known problem in the Wave library
-#t_1_014.cpp
-t_1_015.cpp
-t_1_016.cpp
-t_1_017.cpp
-t_1_018.cpp
-t_1_019.cpp
-t_1_020.cpp
-t_1_021.cpp
-t_1_022.cpp
-t_1_023.cpp
-t_1_024.cpp
-t_1_025.cpp
-t_1_026.cpp
-t_1_027.cpp
-t_1_028.cpp
-t_1_029.cpp
-t_1_030.cpp
-t_1_031.cpp
-t_1_032.cpp
-t_1_033.cpp
-t_1_034.cpp
-t_1_035.cpp
-t_1_036.cpp
-t_1_037.cpp
-t_1_038.cpp
-
-#
-# t_2: Preprocessing directives
-#
-t_2_001.cpp
-t_2_002.cpp
-t_2_003.cpp
-t_2_004.cpp
-t_2_005.cpp
-t_2_006.cpp
-t_2_007.cpp
-t_2_008.cpp
-t_2_009.cpp
-t_2_010.cpp
-t_2_011.cpp
-t_2_012.cpp
-t_2_013.cpp
-t_2_014.cpp
-t_2_015.cpp
-t_2_016.cpp
-t_2_017.cpp
-t_2_018.cpp
-
-#
-# t_3: Predefined macros
-#
-t_3_001.cpp
-t_3_002.cpp
-t_3_003.cpp
-t_3_004.cpp
-
-#
-# Preprocessing expressions
-#
-t_4_001.cpp
-t_4_002.cpp
-t_4_003.cpp
-t_4_004.cpp
-
-#
-# unit tests from the mcpp preprocessor validation suite
-# (general functionality)
-#
-t_5_001.cpp
-t_5_002.cpp
-t_5_003.cpp
-# t_5_004 is currently disabled because of a known problem in the Wave library
-#t_5_004.cpp
-t_5_005.cpp
-t_5_006.cpp
-t_5_007.cpp
-t_5_008.cpp
-t_5_009.cpp
-t_5_010.cpp
-t_5_011.cpp
-t_5_012.cpp
-t_5_013.cpp
-t_5_014.cpp
-t_5_015.cpp
-t_5_016.cpp
-t_5_017.cpp
-t_5_018.cpp
-t_5_019.cpp
-t_5_020.cpp
-t_5_021.cpp
-t_5_022.cpp
-t_5_023.cpp
-t_5_024.cpp
-t_5_025.cpp
-t_5_026.cpp
-t_5_027.cpp
-t_5_028.cpp
-t_5_029.cpp
-# t_5_030 contains one disabled test
-t_5_030.cpp
-t_5_031.cpp
-t_5_032.cpp
-t_5_033.cpp
-t_5_034.cpp
-t_5_035.cpp
-
-#
-# unit tests from the mcpp preprocessor validation suite
-# (error reporting)
-#
-t_6_001.cpp
-t_6_002.cpp
-t_6_003.cpp
-t_6_004.cpp
-t_6_005.cpp
-t_6_006.cpp
-t_6_007.cpp
-t_6_008.cpp
-t_6_009.cpp
-t_6_010.cpp
-t_6_011.cpp
-t_6_012.cpp
-t_6_013.cpp
-t_6_014.cpp
-t_6_015.cpp
-t_6_016.cpp
-t_6_017.cpp
-t_6_018.cpp
-t_6_019.cpp
-t_6_020.cpp
-t_6_021.cpp
-t_6_022.cpp
-t_6_023.cpp
-t_6_024.cpp
-t_6_025.cpp
-t_6_026.cpp
-t_6_027.cpp
-t_6_028.cpp
-t_6_029.cpp
-t_6_030.cpp
-t_6_031.cpp
-t_6_032.cpp
-t_6_033.cpp
-t_6_034.cpp
-t_6_035.cpp
-t_6_036.cpp
-t_6_037.cpp
-t_6_038.cpp
-t_6_039.cpp
-t_6_040.cpp
-t_6_041.cpp
-t_6_042.cpp
-t_6_043.cpp
-t_6_044.cpp
-t_6_045.cpp
-t_6_046.cpp
-t_6_047.cpp
-t_6_048.cpp
-t_6_049.cpp
-t_6_050.cpp
-t_6_051.cpp
-t_6_052.cpp
-t_6_053.cpp
-t_6_054.cpp
-t_6_055.cpp
-t_6_056.cpp
-t_6_057.cpp
-t_6_058.cpp
-t_6_059.cpp
-t_6_060.cpp
-t_6_061.cpp
-t_6_062.cpp
-t_6_063.cpp
-t_6_064.cpp
-t_6_065.cpp
-t_6_066.cpp
-t_6_067.cpp
-t_6_068.cpp
-t_6_069.cpp
-
-#
-# t_9: General preprocessing problems
-#
-t_9_001.cpp
-t_9_002.cpp
-t_9_003.cpp
-t_9_004.cpp
-t_9_005.cpp
-t_9_006.cpp
-t_9_007.cpp
-t_9_008.cpp
-t_9_009.cpp
-t_9_010.cpp
-t_9_011.cpp
-t_9_012.cpp
-t_9_013.cpp
-t_9_014.cpp
-t_9_015.cpp
-t_9_016.cpp
-t_9_017.cpp
-t_9_018.cpp
-t_9_019.cpp
+#
+# Boost.Wave: A Standard compliant C++ preprocessor library
+# http://www.boost.org/
+#
+# Copyright (c) 2003-2008 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)
+#
+
+#
+# t_1: Macro expansion
+#
+t_1_001.cpp
+t_1_002.cpp
+t_1_003.cpp
+t_1_004.cpp
+t_1_005.cpp
+t_1_006.cpp
+t_1_007.cpp
+t_1_008.cpp
+t_1_009.cpp
+t_1_010.cpp
+t_1_011.cpp
+t_1_012.cpp
+t_1_013.cpp
+# t_1_014 currently disabled because of a known problem in the Wave library
+#t_1_014.cpp
+t_1_015.cpp
+t_1_016.cpp
+t_1_017.cpp
+t_1_018.cpp
+t_1_019.cpp
+t_1_020.cpp
+t_1_021.cpp
+t_1_022.cpp
+t_1_023.cpp
+t_1_024.cpp
+t_1_025.cpp
+t_1_026.cpp
+t_1_027.cpp
+t_1_028.cpp
+t_1_029.cpp
+t_1_030.cpp
+t_1_031.cpp
+t_1_032.cpp
+t_1_033.cpp
+t_1_034.cpp
+t_1_035.cpp
+t_1_036.cpp
+t_1_037.cpp
+t_1_038.cpp
+
+#
+# t_2: Preprocessing directives
+#
+t_2_001.cpp
+t_2_002.cpp
+t_2_003.cpp
+t_2_004.cpp
+t_2_005.cpp
+t_2_006.cpp
+t_2_007.cpp
+t_2_008.cpp
+t_2_009.cpp
+t_2_010.cpp
+t_2_011.cpp
+t_2_012.cpp
+t_2_013.cpp
+t_2_014.cpp
+t_2_015.cpp
+t_2_016.cpp
+t_2_017.cpp
+t_2_018.cpp
+
+#
+# t_3: Predefined macros
+#
+t_3_001.cpp
+t_3_002.cpp
+t_3_003.cpp
+t_3_004.cpp
+
+#
+# Preprocessing expressions
+#
+t_4_001.cpp
+t_4_002.cpp
+t_4_003.cpp
+t_4_004.cpp
+
+#
+# unit tests from the mcpp preprocessor validation suite
+# (general functionality)
+#
+t_5_001.cpp
+t_5_002.cpp
+t_5_003.cpp
+# t_5_004 is currently disabled because of a known problem in the Wave library
+#t_5_004.cpp
+t_5_005.cpp
+t_5_006.cpp
+t_5_007.cpp
+t_5_008.cpp
+t_5_009.cpp
+t_5_010.cpp
+t_5_011.cpp
+t_5_012.cpp
+t_5_013.cpp
+t_5_014.cpp
+t_5_015.cpp
+t_5_016.cpp
+t_5_017.cpp
+t_5_018.cpp
+t_5_019.cpp
+t_5_020.cpp
+t_5_021.cpp
+t_5_022.cpp
+t_5_023.cpp
+t_5_024.cpp
+t_5_025.cpp
+t_5_026.cpp
+t_5_027.cpp
+t_5_028.cpp
+t_5_029.cpp
+# t_5_030 contains one disabled test
+t_5_030.cpp
+t_5_031.cpp
+t_5_032.cpp
+t_5_033.cpp
+t_5_034.cpp
+t_5_035.cpp
+
+#
+# unit tests from the mcpp preprocessor validation suite
+# (error reporting)
+#
+t_6_001.cpp
+t_6_002.cpp
+t_6_003.cpp
+t_6_004.cpp
+t_6_005.cpp
+t_6_006.cpp
+t_6_007.cpp
+t_6_008.cpp
+t_6_009.cpp
+t_6_010.cpp
+t_6_011.cpp
+t_6_012.cpp
+t_6_013.cpp
+t_6_014.cpp
+t_6_015.cpp
+t_6_016.cpp
+t_6_017.cpp
+t_6_018.cpp
+t_6_019.cpp
+t_6_020.cpp
+t_6_021.cpp
+t_6_022.cpp
+t_6_023.cpp
+t_6_024.cpp
+t_6_025.cpp
+t_6_026.cpp
+t_6_027.cpp
+t_6_028.cpp
+t_6_029.cpp
+t_6_030.cpp
+t_6_031.cpp
+t_6_032.cpp
+t_6_033.cpp
+t_6_034.cpp
+t_6_035.cpp
+t_6_036.cpp
+t_6_037.cpp
+t_6_038.cpp
+t_6_039.cpp
+t_6_040.cpp
+t_6_041.cpp
+t_6_042.cpp
+t_6_043.cpp
+t_6_044.cpp
+t_6_045.cpp
+t_6_046.cpp
+t_6_047.cpp
+t_6_048.cpp
+t_6_049.cpp
+t_6_050.cpp
+t_6_051.cpp
+t_6_052.cpp
+t_6_053.cpp
+t_6_054.cpp
+t_6_055.cpp
+t_6_056.cpp
+t_6_057.cpp
+t_6_058.cpp
+t_6_059.cpp
+t_6_060.cpp
+t_6_061.cpp
+t_6_062.cpp
+t_6_063.cpp
+t_6_064.cpp
+t_6_065.cpp
+t_6_066.cpp
+t_6_067.cpp
+t_6_068.cpp
+t_6_069.cpp
+
+#
+# t_9: General preprocessing problems
+#
+t_9_001.cpp
+t_9_002.cpp
+t_9_003.cpp
+t_9_004.cpp
+t_9_005.cpp
+t_9_006.cpp
+t_9_007.cpp
+t_9_008.cpp
+t_9_009.cpp
+t_9_010.cpp
+t_9_011.cpp
+t_9_012.cpp
+t_9_013.cpp
+t_9_014.cpp
+t_9_015.cpp
+t_9_016.cpp
+t_9_017.cpp
+t_9_018.cpp
+t_9_019.cpp

Modified: branches/proto/v4/status/Jamfile.v2
==============================================================================
--- branches/proto/v4/status/Jamfile.v2 (original)
+++ branches/proto/v4/status/Jamfile.v2 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,89 +18,114 @@
     ;
 
 import testing ;
+import modules ;
+
+local rule run-tests ( tests * )
+{
+ local limit-tests = [ MATCH "^--limit-tests=(.*)" : [ modules.peek : ARGV ] ] ;
+ for local test in $(tests)
+ {
+ if $(limit-tests)
+ {
+ if [ MATCH "^($(limit-tests))" : $(test) ]
+ {
+ build-project ../libs/$(test) ;
+ }
+ else
+ {
+ use-project /boost/$(test) : ../libs/$(test) ;
+ }
+ }
+ else
+ {
+ build-project ../libs/$(test) ;
+ }
+ }
+}
 
 # Tests from Jamfiles in individual library test subdirectories
 # Please keep these in alphabetic order by test-suite name
-build-project ../libs/accumulators/test ; # test-suite accumulators
-build-project ../libs/algorithm/minmax/test ; # test-suite algorith/minmax
-build-project ../libs/algorithm/string/test ; # test-suite algorithm/string
-build-project ../libs/array/test ; # test-suite array
-build-project ../libs/asio/test ; # test-suite asio
-build-project ../libs/assign/test ; # test-suite assign
-build-project ../libs/any/test ; # test-suite any
-build-project ../libs/bimap/test ; # test-suite bimap
-build-project ../libs/bind/test ; # test-suite bind
-build-project ../libs/circular_buffer/test ; # test-suite circular_buffer
-build-project ../libs/concept_check ; # test-suite concept_check
-build-project ../libs/config/test ; # test-suite config
-build-project ../libs/conversion/test ; # test-suite conversion
-build-project ../libs/crc/test ; # test-suite crc
-build-project ../libs/date_time/test ; # test-suite date_time
-build-project ../libs/disjoint_sets ; # test-suite disjoint_sets
-build-project ../libs/dynamic_bitset ; # test-suite dynamic_bitset
-build-project ../libs/exception/test ;
-build-project ../libs/filesystem/test ; # test-suite filesystem
-build-project ../libs/foreach/test ; # test-suite foreach
-build-project ../libs/format/test ; # test-suite format
-build-project ../libs/function/test ; # test-suite function
-build-project ../libs/functional/test ; # test-suite functional
-build-project ../libs/functional/hash/test ; # test-suite functional/hash
-build-project ../libs/function_types/test ; # test-suite function_types
-build-project ../libs/fusion/test ; # test-suite fusion
-build-project ../libs/gil/test ; # test-suite gil
-build-project ../libs/graph/test ; # test-suite graph
-build-project ../libs/io/test ; # test-suite io
-build-project ../libs/integer/test ; # test-suite integer
-build-project ../libs/interprocess/example ; # test-suite interprocess_example
-build-project ../libs/interprocess/test ; # test-suite interprocess_test
-build-project ../libs/intrusive/example ; # test-suite intrusive_example
-build-project ../libs/intrusive/test ; # test-suite intrusive_test
-build-project ../libs/iostreams/test ; # test-suite iostreams
-build-project ../libs/iterator/test ; # test-suite iterator
-build-project ../libs/lambda/test ; # test-suite lambda
-build-project ../libs/logic/test ; # test-suite logic
-build-project ../libs/math/test ; # test-suite math
-build-project ../libs/mpi/test ; # test-suite mpi
-build-project ../libs/mpl/test ; # test-suite mpl
-build-project ../libs/numeric/conversion/test ; # test-suite numeric/conversion
-build-project ../libs/numeric/interval/test ; # test-suite numeric/interval
-build-project ../libs/numeric/ublas/test ; # test-suite numeirc/uBLAS
-build-project ../libs/multi_array/test ; # test-suite multi_array
-build-project ../libs/multi_index/test ; # test-suite multi_index
-build-project ../libs/optional/test ; # test-suite optional
-build-project ../libs/parameter/test ; # test-suite parameter
-build-project ../libs/pool/test ; # test-suite pool
-build-project ../libs/preprocessor/test ; # test-suite preprocessor
-build-project ../libs/program_options/test ; # test-suite program_options
-build-project ../libs/property_map/test ; # test-suite property_map
-build-project ../libs/ptr_container/test ; # test-suite ptr_container
-build-project ../libs/python/test ; # test-suite python
-build-project ../libs/random/test ; # test-suite random
-build-project ../libs/range/test ; # test-suite range
-build-project ../libs/rational/test ; # test-suite rational
-build-project ../libs/regex/test ; # test-suite regex
-build-project ../libs/regex/example ; # test-suite regex-examples
-build-project ../libs/serialization/test ; # test-suite serialization
-build-project ../libs/signals/test ; # test-suite signals
-build-project ../libs/smart_ptr/test ; # test-suite smart_ptr
-build-project ../libs/spirit/classic/test ; # test-suite classic spirit
-build-project ../libs/spirit/test ; # test-suite spirit_v2
-build-project ../libs/statechart/test ; # test-suite statechart
-build-project ../libs/static_assert ; # test-suite static_assert
-build-project ../libs/system/test ; # test-suite system
-build-project ../libs/test/test ; # test-suite test
-build-project ../libs/thread/test ; # test-suite thread
-build-project ../libs/timer/test ; # test-suite timer
-build-project ../libs/tokenizer/test ; # test-suite tokenizer
-build-project ../libs/tr1/test ; # test-suite tr1
-build-project ../libs/tuple/test ; # test-suite tuple
-build-project ../libs/type_traits/test ; # test-suite type_traits
-build-project ../libs/typeof/test ; # test-suite typeof
-build-project ../libs/unordered/test/unordered ; # test-suite unordered
-build-project ../libs/unordered/test/exception ; # test-suite unordered-exception
-build-project ../libs/utility/enable_if/test ; # test-suite utility/enable_if
-build-project ../libs/utility/test ; # test-suite utility
-build-project ../libs/variant/test ; # test-suite variant
-build-project ../libs/wave/test/build ; # test-suite wave
-build-project ../libs/xpressive/test ; # test-suite xpressive
-
+run-tests
+ accumulators/test # test-suite accumulators
+ algorithm/minmax/test # test-suite algorith/minmax
+ algorithm/string/test # test-suite algorithm/string
+ array/test # test-suite array
+ asio/test # test-suite asio
+ assign/test # test-suite assign
+ any/test # test-suite any
+ bimap/test # test-suite bimap
+ bind/test # test-suite bind
+ circular_buffer/test # test-suite circular_buffer
+ concept_check # test-suite concept_check
+ config/test # test-suite config
+ conversion/test # test-suite conversion
+ crc/test # test-suite crc
+ date_time/test # test-suite date_time
+ disjoint_sets # test-suite disjoint_sets
+ dynamic_bitset # test-suite dynamic_bitset
+ exception/test
+ filesystem/test # test-suite filesystem
+ foreach/test # test-suite foreach
+ format/test # test-suite format
+ function/test # test-suite function
+ functional/test # test-suite functional
+ functional/hash/test # test-suite functional/hash
+ function_types/test # test-suite function_types
+ fusion/test # test-suite fusion
+ gil/test # test-suite gil
+ graph/test # test-suite graph
+ io/test # test-suite io
+ integer/test # test-suite integer
+ interprocess/example # test-suite interprocess_example
+ interprocess/test # test-suite interprocess_test
+ intrusive/example # test-suite intrusive_example
+ intrusive/test # test-suite intrusive_test
+ iostreams/test # test-suite iostreams
+ iterator/test # test-suite iterator
+ lambda/test # test-suite lambda
+ logic/test # test-suite logic
+ math/test # test-suite math
+ mpi/test # test-suite mpi
+ mpl/test # test-suite mpl
+ numeric/conversion/test # test-suite numeric/conversion
+ numeric/interval/test # test-suite numeric/interval
+ numeric/ublas/test # test-suite numeirc/uBLAS
+ multi_array/test # test-suite multi_array
+ multi_index/test # test-suite multi_index
+ optional/test # test-suite optional
+ parameter/test # test-suite parameter
+ pool/test # test-suite pool
+ preprocessor/test # test-suite preprocessor
+ program_options/test # test-suite program_options
+ property_map/test # test-suite property_map
+ ptr_container/test # test-suite ptr_container
+ python/test # test-suite python
+ random/test # test-suite random
+ range/test # test-suite range
+ rational/test # test-suite rational
+ regex/test # test-suite regex
+ regex/example # test-suite regex-examples
+ serialization/test # test-suite serialization
+ signals/test # test-suite signals
+ smart_ptr/test # test-suite smart_ptr
+ spirit/classic/test # test-suite classic spirit
+ spirit/test # test-suite spirit_v2
+ statechart/test # test-suite statechart
+ static_assert # test-suite static_assert
+ system/test # test-suite system
+ test/test # test-suite test
+ thread/test # test-suite thread
+ timer/test # test-suite timer
+ tokenizer/test # test-suite tokenizer
+ tr1/test # test-suite tr1
+ tuple/test # test-suite tuple
+ type_traits/test # test-suite type_traits
+ typeof/test # test-suite typeof
+ unordered/test/unordered # test-suite unordered
+ unordered/test/exception # test-suite unordered-exception
+ utility/enable_if/test # test-suite utility/enable_if
+ utility/test # test-suite utility
+ variant/test # test-suite variant
+ wave/test/build # test-suite wave
+ xpressive/test # test-suite xpressive
+ ;

Modified: branches/proto/v4/status/explicit-failures-markup.xml
==============================================================================
--- branches/proto/v4/status/explicit-failures-markup.xml (original)
+++ branches/proto/v4/status/explicit-failures-markup.xml 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -2516,6 +2516,15 @@
             <toolset name="gcc-3_3-darwin"/>
             <note author="Fernando Cacciola" refid="2"/>
         </mark-expected-failures>
+ <mark-expected-failures>
+ <test name="optional_test"/>
+ <toolset name="msvc-7.1"/>
+ <note author="Niels Dekker" date="2008-04-28">
+ MSVC 2003 (7.1) does not always do argument-dependent lookup (ADL), when it should.
+ This causes test failures when swapping boost::optional&lt;T&gt;, for
+ T = optional_swap_test::class_whose_default_ctor_should_be_used.
+ </note>
+ </mark-expected-failures>
     </library>
 
     <library name="pool">

Modified: branches/proto/v4/tools/build/v2/build/alias.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/build/alias.jam (original)
+++ branches/proto/v4/tools/build/v2/build/alias.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -2,27 +2,26 @@
 # Distributed under the Boost Software License, Version 1.0.
 # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 
-# This module defines the 'alias' rule and the associated target class.
+# This module defines the 'alias' rule and the associated target class.
 #
-# Alias is just a main target which returns its source targets without any
-# processing. For example:
+# Alias is just a main target which returns its source targets without any
+# processing. For example:
 #
-# alias bin : hello test_hello ;
-# alias lib : helpers xml_parser ;
+# alias bin : hello test_hello ;
+# alias lib : helpers xml_parser ;
 #
-# Another important use of 'alias' is to conveniently group source files:
+# Another important use of 'alias' is to conveniently group source files:
 #
-# alias platform-src : win.cpp : <os>NT ;
-# alias platform-src : linux.cpp : <os>LINUX ;
-# exe main : main.cpp platform-src ;
+# alias platform-src : win.cpp : <os>NT ;
+# alias platform-src : linux.cpp : <os>LINUX ;
+# exe main : main.cpp platform-src ;
 #
-# Lastly, it's possible to create local alias for some target, with different
-# properties::
+# Lastly, it is possible to create a local alias for some target, with different
+# properties:
 #
-# alias big_lib : : @/external_project/big_lib/<link>static ;
+# alias big_lib : : @/external_project/big_lib/<link>static ;
 #
 
-
 import "class" : new ;
 import project ;
 import property-set ;
@@ -47,12 +46,13 @@
     {
         local base = [ basic-target.compute-usage-requirements $(subvariant) ] ;
         # Add source's usage requirement. If we don't do this, "alias" does not
- # look like 100% alias.
+ # look like a 100% alias.
         return [ $(base).add [ $(subvariant).sources-usage-requirements ] ] ;
     }
 }
 
 # Declares the 'alias' target. It will build sources, and return them unaltered.
+#
 rule alias ( name : sources * : requirements * : default-build * : usage-requirements * )
 {
     local project = [ project.current ] ;
@@ -67,6 +67,3 @@
 }
 
 IMPORT $(__name__) : alias : : alias ;
-
-
-

Modified: branches/proto/v4/tools/build/v2/build/generators.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/build/generators.jam (original)
+++ branches/proto/v4/tools/build/v2/build/generators.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -93,8 +93,8 @@
 
 
 # Takes a vector of 'virtual-target' instances and makes a normalized
-# representation, which is the same for given set of targets,
-# regardless of their order.
+# representation, which is the same for given set of targets, regardless of
+# their order.
 #
 rule normalize-target-list ( targets )
 {
@@ -183,19 +183,19 @@
         return $(self.source-types) ;
     }
 
- # Returns the list of target types that this generator produces.
- # It is assumed to be always the same -- i.e. it cannot change depending
- # list of sources.
+ # Returns the list of target types that this generator produces. It is
+ # assumed to be always the same -- i.e. it cannot change depending list of
+ # sources.
     #
     rule target-types ( )
     {
         return $(self.target-types) ;
     }
 
- # Returns the required properties for this generator. Properties
- # in returned set must be present in build properties if this
- # generator is to be used. If result has grist-only element,
- # that build properties must include some value of that feature.
+ # Returns the required properties for this generator. Properties in returned
+ # set must be present in build properties if this generator is to be used.
+ # If result has grist-only element, that build properties must include some
+ # value of that feature.
     # XXX: remove this method?
     #
     rule requirements ( )
@@ -208,10 +208,9 @@
     #
     rule match-rank ( property-set-to-match )
     {
- # See if generator's requirements are satisfied by
- # 'properties'. Treat a feature name in requirements
- # (i.e. grist-only element), as matching any value of the
- # feature.
+ # See if generator's requirements are satisfied by 'properties'. Treat a
+ # feature name in requirements (i.e. grist-only element), as matching
+ # any value of the feature.
         local all-requirements = [ requirements ] ;
 
         local property-requirements feature-requirements ;
@@ -239,9 +238,9 @@
         }
     }
 
- # Returns another generator which differers from $(self) in
- # - id
- # - value to <toolset> feature in properties
+ # Returns another generator which differs from $(self) in
+ # - id
+ # - value to <toolset> feature in properties
     #
     rule clone ( new-id : new-toolset-properties + )
     {
@@ -287,8 +286,8 @@
     # run indicates that the generator was unable to create the target.
     #
     rule run ( project # Project for which the targets are generated
- name ? # Determines the name of 'name' attribute for
- # all generated targets. See 'generated-targets' method.
+ name ? # Determines the name of 'name' attribute for all
+ # generated targets. See 'generated-targets' method.
                : property-set # Desired properties for generated targets.
                : sources + # Source targets.
             )
@@ -360,15 +359,16 @@
     rule construct-result (
         consumed + # Already prepared list of consumable targets
                    # If generator requires several source files will contain
- # exactly len $(self.source-types) targets with matching types
- # Otherwise, might contain several targets with the type of
- # $(self.source-types[1])
+ # exactly len $(self.source-types) targets with matching
+ # types. Otherwise, might contain several targets with the
+ # type of $(self.source-types[1]).
         : project name ?
         : property-set # Properties to be used for all actions create here.
     )
     {
         local result ;
- # If this is 1->1 transformation, apply it to all consumed targets in order.
+ # If this is 1->1 transformation, apply it to all consumed targets in
+ # order.
         if ! $(self.source-types[2]) && ! $(self.composing)
         {
             for local r in $(consumed)
@@ -391,15 +391,14 @@
     #
     rule determine-output-name ( sources + )
     {
- # The simple case if when a name
- # of source has single dot. Then, we take the part before
- # dot. Several dots can be caused by:
- # - Using source file like a.host.cpp
- # - A type which suffix has a dot. Say, we can
- # type 'host_cpp' with extension 'host.cpp'.
- # In the first case, we want to take the part till the last
- # dot. In the second case -- no sure, but for now take
- # the part till the last dot too.
+ # The simple case if when a name of source has single dot. Then, we take
+ # the part before dot. Several dots can be caused by:
+ # - Using source file like a.host.cpp
+ # - A type which suffix has a dot. Say, we can type 'host_cpp' with
+ # extension 'host.cpp'.
+ # In the first case, we want to take the part up to the last dot. In the
+ # second case -- no sure, but for now take the part up to the last dot
+ # too.
         name = [ utility.basename [ $(sources[1]).name ] ] ;
 
         for local s in $(sources[2])
@@ -467,9 +466,9 @@
         return [ sequence.transform virtual-target.register : $(targets) ] ;
     }
 
- # Attempts to convert 'source' to the types that this generator can
- # handle. The intention is to produce the set of targets can should be
- # used when generator is run.
+ # Attempts to convert 'source' to the types that this generator can handle.
+ # The intention is to produce the set of targets can should be used when
+ # generator is run.
     #
     rule convert-to-consumable-types ( project name ? :
         property-set : sources +
@@ -481,16 +480,16 @@
                        # cannot be consumed
     )
     {
- # We're likely to be passed 'consumed' and 'bypassed'
- # var names. Use "_" to avoid name conflicts.
+ # We're likely to be passed 'consumed' and 'bypassed' var names. Use "_"
+ # to avoid name conflicts.
         local _consumed ;
         local _bypassed ;
         local missing-types ;
 
         if $(sources[2])
         {
- # Don't know how to handle several sources yet. Just try
- # to pass the request to other generator
+ # Don't know how to handle several sources yet. Just try to pass the
+ # request to other generator
             missing-types = $(self.source-types) ;
         }
         else
@@ -498,18 +497,17 @@
             consume-directly $(sources) : _consumed : missing-types ;
         }
 
- # No need to search for transformation if
- # some source type has consumed source and
- # no more source types are needed.
+ # No need to search for transformation if some source type has consumed
+ # source and no more source types are needed.
         if $(only-one) && $(_consumed)
         {
             missing-types = ;
         }
 
- #TODO: we should check that only one source type
- #if create of 'only-one' is true.
- # TODO: consider if consuned/bypassed separation should
- # be done by 'construct-types'.
+ # TODO: we should check that only one source type if create of
+ # 'only-one' is true.
+ # TODO: consider if consumed/bypassed separation should be done by
+ # 'construct-types'.
 
         if $(missing-types)
         {
@@ -538,15 +536,14 @@
         _consumed = [ sequence.unique $(_consumed) ] ;
         _bypassed = [ sequence.unique $(_bypassed) ] ;
 
- # remove elements of '_bypassed' that are in '_consumed'
+ # Remove elements of '_bypassed' that are in '_consumed'.
 
- # Suppose the target type of current generator, X is produced from
- # X_1 and X_2, which are produced from Y by one generator.
- # When creating X_1 from Y, X_2 will be added to 'bypassed'
- # Likewise, when creating X_2 from Y, X_1 will be added to 'bypassed'
- # But they are also in 'consumed'. We have to remove them from
- # bypassed, so that generators up the call stack don't try to convert
- # them.
+ # Suppose the target type of current generator, X is produced from X_1
+ # and X_2, which are produced from Y by one generator. When creating X_1
+ # from Y, X_2 will be added to 'bypassed'. Likewise, when creating X_2
+ # from Y, X_1 will be added to 'bypassed', but they are also in
+ # 'consumed'. We have to remove them from bypassed, so that generators
+ # up the call stack don't try to convert them.
 
         # In this particular case, X_1 instance in 'consumed' and X_1 instance
         # in 'bypassed' will be the same: because they have the same source and
@@ -555,7 +552,6 @@
 
         _bypassed = [ set.difference $(_bypassed) : $(_consumed) ] ;
 
-
         $(consumed-var) += $(_consumed) ;
         $(bypassed-var) += $(_bypassed) ;
     }
@@ -565,8 +561,8 @@
     rule convert-multiple-sources-to-consumable-types
       ( project : property-set : sources * : consumed-var bypassed-var )
     {
- # We process each source one-by-one, trying to convert it to
- # a usable type.
+ # We process each source one-by-one, trying to convert it to a usable
+ # type.
         for local source in $(sources)
         {
             local _c ;
@@ -587,7 +583,7 @@
     {
         local real-source-type = [ $(source).type ] ;
 
- # If there are no source types, we can consume anything
+ # If there are no source types, we can consume anything.
         local source-types = $(self.source-types) ;
         source-types ?= $(real-source-type) ;
 
@@ -606,8 +602,8 @@
         }
     }
 
- # Returns the class to be used to actions. Default implementation
- # returns "action".
+ # Returns the class to be used to actions. Default implementation returns
+ # "action".
     #
     rule action-class ( )
     {
@@ -625,10 +621,9 @@
 {
     .generators += $(g) ;
 
- # A generator can produce several targets of the
- # same type. We want unique occurence of that generator
- # in .generators.$(t) in that case, otherwise, it will
- # be tried twice and we'll get false ambiguity.
+ # A generator can produce several targets of the same type. We want unique
+ # occurence of that generator in .generators.$(t) in that case, otherwise,
+ # it will be tried twice and we'll get false ambiguity.
     for local t in [ sequence.unique [ $(g).target-types ] ]
     {
         .generators.$(t) += $(g) ;
@@ -636,20 +631,17 @@
 
     # Update the set of generators for toolset
 
- # TODO: should we check that generator with this id
- # is not already registered. For example, the fop.jam
- # module intentionally declared two generators with the
- # same id, so such check will break it.
+ # TODO: should we check that generator with this id is not already
+ # registered. For example, the fop.jam module intentionally declared two
+ # generators with the same id, so such check will break it.
     local id = [ $(g).id ] ;
 
- # Some generators have multiple periods in their name, so the
- # normal $(id:S=) won't generate the right toolset name.
- # e.g. if id = gcc.compile.c++, then
- # .generators-for-toolset.$(id:S=) will append to
- # .generators-for-toolset.gcc.compile, which is a separate
- # value from .generators-for-toolset.gcc. Correcting this
- # makes generator inheritance work properly.
- # See also inherit-generators in module toolset
+ # Some generators have multiple periods in their name, so the normal
+ # $(id:S=) won't generate the right toolset name. E.g. if id =
+ # = gcc.compile.c++, then .generators-for-toolset.$(id:S=) will append to
+ # .generators-for-toolset.gcc.compile, which is a separate value from
+ # .generators-for-toolset.gcc. Correcting this makes generator inheritance
+ # work properly. See also inherit-generators in the toolset module.
     local base = $(id) ;
     while $(base:S)
     {
@@ -729,8 +721,8 @@
     # 't' is the list of types which have not yet been processed.
     while $(t)
     {
- # Find all generators for current type.
- # Unlike 'find-viable-generators' we don't care about property-set.
+ # Find all generators for current type. Unlike 'find-viable-generators'
+ # we don't care about property-set.
         local generators = $(.generators.$(t[1])) ;
         t = $(t[2-]) ;
 

Modified: branches/proto/v4/tools/build/v2/build/modifiers.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/build/modifiers.jam (original)
+++ branches/proto/v4/tools/build/v2/build/modifiers.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -30,7 +30,7 @@
         id
         composing ?
         : source-types *
- : target-types-and-names +
+ : target-types-and-names +
         : requirements *
         )
     {
@@ -38,10 +38,10 @@
             : $(source-types)
             : $(target-types-and-names)
             : $(requirements) ;
-
+
         self.targets-in-progress = ;
     }
-
+
     # Wraps the generation of the target to call before and after rules to
     # affect the real target.
     #
@@ -72,7 +72,7 @@
             property-set = $(property-set_) ;
             sources = $(sources_) ;
             multiple = $(multiple_) ;
-
+
             # Generate the real target...
             local target-type-p =
                 [ property.select <main-target-type> : [ $(property-set).raw ] ] ;
@@ -83,7 +83,7 @@
                     : $(property-set)
                     : $(sources) ] ;
             self.targets-in-progress = $(self.targets-in-progress[1--2]) ;
-
+
             # After modifications...
             result =
                 [ modify-target-after $(result)
@@ -94,37 +94,37 @@
         }
         return $(result) ;
     }
-
+
     rule modify-project-before ( project name ? : property-set : sources + : multiple ? )
     {
         return $(project) ;
     }
-
+
     rule modify-name-before ( project name ? : property-set : sources + : multiple ? )
     {
         return $(name) ;
     }
-
+
     rule modify-properties-before ( project name ? : property-set : sources + : multiple ? )
     {
         return $(property-set) ;
     }
-
+
     rule modify-sources-before ( project name ? : property-set : sources + : multiple ? )
     {
         return $(sources) ;
     }
-
+
     rule modify-multiple-before ( project name ? : property-set : sources + : multiple ? )
     {
         return $(multiple) ;
     }
-
+
     rule modify-target-after ( target : project name ? : property-set : sources + : multiple ? )
     {
         return $(target) ;
     }
-
+
     # Utility, clones a file-target with optional changes to the name, type and
     # project of the target.
     # NOTE: This functionality should be moved, and generalized, to
@@ -137,19 +137,19 @@
         new-type ?= [ $(target).type ] ;
         new-project ?= [ $(target).project ] ;
         local result = [ new file-target $(new-name) : $(new-type) : $(new-project) ] ;
-
+
         if [ $(target).dependencies ] { $(result).depends [ $(target).dependencies ] ; }
         $(result).root [ $(target).root ] ;
         $(result).set-usage-requirements [ $(target).usage-requirements ] ;
-
+
         local action = [ $(target).action ] ;
         local action-class = [ modules.peek $(action) : __class__ ] ;
-
+
         local ps = [ $(action).properties ] ;
- local cloned-action = [ new $(action-class) $(result) :
+ local cloned-action = [ new $(action-class) $(result) :
           [ $(action).sources ] : [ $(action).action-name ] : $(ps) ] ;
         $(result).action $(cloned-action) ;
-
+
         return $(result) ;
     }
 }
@@ -167,13 +167,13 @@
         # Apply ourselves to EXE targets, for now.
         modifier.__init__ name.modifier : : EXE LIB : <name-modify>yes ;
     }
-
+
     # Modifies the name, by cloning the target with the new name.
     #
     rule modify-target-after ( target : project name ? : property-set : sources + : multiple ? )
     {
         local result = $(target) ;
-
+
         local name-mod-p = [ property.select <name-modifier> : [ $(property-set).raw ] ] ;
         if $(name-mod-p)
         {
@@ -190,10 +190,10 @@
                     : [ property-set.create [ $(property-set).raw ] <symlink-location>build-relative ] ] ;
             }
         }
-
+
         return $(result) ;
     }
-
+
     # Do the transformation of the name.
     #
     rule modify-name ( name : modifier-spec + )
@@ -218,7 +218,7 @@
         new-name-parts += $(name-parts) ;
         return [ sequence.join $(new-name-parts) ] ;
     }
-
+
     rule optional-properties ( )
     {
         return <name-modify>yes ;

Modified: branches/proto/v4/tools/build/v2/build/property.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/build/property.jam (original)
+++ branches/proto/v4/tools/build/v2/build/property.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -346,7 +346,7 @@
 }
 
 
-# Returns a property set containig all the elements in 'properties' that have
+# Returns a property set containing all the elements in 'properties' that have
 # their attributes listed in 'attributes'.
 rule take ( attributes + : properties * )
 {

Modified: branches/proto/v4/tools/build/v2/build/targets.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/build/targets.jam (original)
+++ branches/proto/v4/tools/build/v2/build/targets.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -5,29 +5,28 @@
 # (See accompanying file LICENSE_1_0.txt or copy at
 # http://www.boost.org/LICENSE_1_0.txt)
 
-# Supports 'abstract' targets, which are targets explicitly defined in a
-# Jamfile.
+# Supports 'abstract' targets, which are targets explicitly defined in a
+# Jamfile.
 #
-# Abstract targets are represented by classes derived from 'abstract-target'
-# class. The first abstract target is 'project-target', which is created for
-# each Jamfile, and can be obtained by the 'target' rule in the Jamfile's
-# module (see project.jam).
-#
-# Project targets keep a list of 'main-target' instances. A main target is
-# what the user explicitly defines in a Jamfile. It is possible to have
-# several definitions for a main target, for example to have different lists
-# of sources for different platforms. So, main targets keep a list of
-# alternatives.
-#
-# Each alternative is an instance of 'abstract-target'. When a main target
-# subvariant is defined by some rule, that rule will decide what class to use,
-# create an instance of that class and add it to the list of alternatives for
-# the main target.
-#
-# Rules supplied by the build system will use only targets derived from
-# 'basic-target' class, which will provide some default behaviour. There will
-# be different classes derived from it such as 'make-target', created by the
-# 'make' rule, and 'typed-target', created by rules such as 'exe' and 'lib'.
+# Abstract targets are represented by classes derived from 'abstract-target'
+# class. The first abstract target is 'project-target', which is created for
+# each Jamfile, and can be obtained by the 'target' rule in the Jamfile's module
+# (see project.jam).
+#
+# Project targets keep a list of 'main-target' instances. A main target is
+# what the user explicitly defines in a Jamfile. It is possible to have several
+# definitions for a main target, for example to have different lists of sources
+# for different platforms. So, main targets keep a list of alternatives.
+#
+# Each alternative is an instance of 'abstract-target'. When a main target
+# subvariant is defined by some rule, that rule will decide what class to use,
+# create an instance of that class and add it to the list of alternatives for
+# the main target.
+#
+# Rules supplied by the build system will use only targets derived from
+# 'basic-target' class, which will provide some default behaviour. There will be
+# different classes derived from it such as 'make-target', created by the 'make'
+# rule, and 'typed-target', created by rules such as 'exe' and 'lib'.
 
 #
 # +------------------------+
@@ -80,7 +79,9 @@
 import set ;
 import toolset ;
 
+
 # Base class for all abstract targets.
+#
 class abstract-target
 {
     import project ;
@@ -135,6 +136,7 @@
     # - a list of produced virtual targets, which may be empty.
     # If 'property-set' is empty, performs the default build of this target, in
     # a way specific to the derived class.
+ #
     rule generate ( property-set )
     {
         errors.error "method should be defined in derived classes" ;
@@ -181,6 +183,7 @@
 # that time, alternatives can also be renamed to account for inline targets.
 # - The first time 'main-target' or 'has-main-target' rule is called, all
 # alternatives are enumerated and main targets are created.
+#
 class project-target : abstract-target
 {
     import project ;
@@ -211,6 +214,7 @@
 
     # This is needed only by the 'make' rule. Need to find the way to make
     # 'make' work without this method.
+ #
     rule project-module ( )
     {
         return $(self.project-module) ;
@@ -238,6 +242,7 @@
     }
 
     # Generates all possible targets contained in this project.
+ #
     rule generate ( property-set * )
     {
         if [ modules.peek : .debug-building ]
@@ -261,6 +266,7 @@
 
     # Computes and returns a list of abstract-target instances which must be
     # built when this project is built.
+ #
     rule targets-to-build ( )
     {
         local result ;
@@ -291,6 +297,7 @@
 
     # Add 'target' to the list of targets in this project that should be build
     # only by explicit request
+ #
     rule mark-target-as-explicit ( target-name )
     {
         # Record the name of the target, not instance, since this
@@ -299,6 +306,7 @@
     }
 
     # Add new target alternative
+ #
     rule add-alternative ( target-instance )
     {
         if $(self.built-main-targets)
@@ -310,6 +318,7 @@
     }
 
     # Returns a 'main-target' class instance corresponding to the 'name'.
+ #
     rule main-target ( name )
     {
         if ! $(self.built-main-targets)
@@ -321,6 +330,7 @@
     }
 
     # Tells if a main target with the specified name exists.
+ #
     rule has-main-target ( name )
     {
         if ! $(self.built-main-targets)
@@ -334,8 +344,9 @@
         }
     }
 
- # Find and return the target with the specified id, treated
- # relative to self.
+ # Find and return the target with the specified id, treated relative to
+ # self.
+ #
     rule find-really ( id )
     {
         local result ;
@@ -452,6 +463,7 @@
     }
 
     # Accessor, add a constant.
+ #
     rule add-constant (
         name # Variable name of the constant.
         : value + # Value of the constant.
@@ -506,7 +518,8 @@
 }
 
 
-# Helper rules to detect cycles in main target references
+# Helper rules to detect cycles in main target references.
+#
 local rule start-building ( main-target-instance )
 {
     if $(main-target-instance) in $(.targets-being-built)
@@ -532,6 +545,7 @@
 
 
 # A named top-level target in Jamfile.
+#
 class main-target : abstract-target
 {
     import assert ;
@@ -568,6 +582,7 @@
 
     # Returns the best viable alternative for this property-set. See the
     # documentation for selection rules.
+ #
     local rule select-alternatives ( property-set debug ? )
     {
         # When selecting alternatives we have to consider defaults, for example:
@@ -697,8 +712,9 @@
 
     # Select an alternative for this main target, by finding all alternatives
     # which requirements are satisfied by 'properties' and picking the one with
- # longest requirements set. Returns the result of calling 'generate' on that
- # alternative.
+ # the longest requirements set. Returns the result of calling 'generate' on
+ # that alternative.
+ #
     rule generate ( property-set )
     {
         start-building $(__name__) ;
@@ -726,7 +742,8 @@
     # Generates the main target with the given property set and returns a list
     # which first element is property-set object containing usage-requirements
     # of generated target and with generated virtual target in other elements.
- # It's possible that no targets are generated.
+ # It is possible that no targets are generated.
+ #
     local rule generate-really ( property-set )
     {
         local best-alternatives = [ select-alternatives $(property-set) ] ;
@@ -757,6 +774,7 @@
 # Abstract target which refers to a source file. This is an artificial entity
 # allowing sources to a target to be represented using a list of abstract target
 # instances.
+#
 class file-reference : abstract-target
 {
     import virtual-target ;
@@ -811,6 +829,7 @@
 # Given a target-reference, made in context of 'project', returns the
 # abstract-target instance that is referred to, as well as properties explicitly
 # specified for this reference.
+#
 rule resolve-reference ( target-reference : project )
 {
     # Separate target name from properties override
@@ -834,6 +853,7 @@
 # both to a main target or to a file. Returns a list consisting of
 # - usage requirements
 # - generated virtual targets, if any
+#
 rule generate-from-reference (
     target-reference # Target reference.
     : project # Project where the reference is made.
@@ -861,6 +881,7 @@
 
 # Given a build request and requirements, return properties common to dependency
 # build request and target build properties.
+#
 rule common-properties ( build-request requirements )
 {
     # For optimization, we add free requirements directly, without using a
@@ -891,6 +912,7 @@
 #
 # If 'what' is 'refined' returns context refined with new requirements. If
 # 'what' is 'added' returns just the requirements to be applied.
+#
 rule evaluate-requirements ( requirements : context : what )
 {
     # Apply non-conditional requirements. It's possible that further conditional
@@ -1007,6 +1029,7 @@
 # Implements the most standard way of constructing main target alternative from
 # sources. Allows sources to be either file or other main target and handles
 # generation of those dependency targets.
+#
 class basic-target : abstract-target
 {
     import build-request ;
@@ -1051,9 +1074,11 @@
     # Returns the list of abstract-targets which are used as sources. The extra
     # properties specified for sources are not represented. The only user for
     # this rule at the moment is the "--dump-tests" feature of the test system.
+ #
     rule sources ( )
     {
- if ! $(self.source-targets) {
+ if ! $(self.source-targets)
+ {
             for local s in $(self.sources)
             {
                 self.source-targets +=
@@ -1075,16 +1100,16 @@
 
     # Returns the alternative condition for this alternative, if the condition
     # is satisfied by 'property-set'.
+ #
     rule match ( property-set debug ? )
     {
- # The condition is composed of all base non-conditional properties. It's
- # not clear if we should expand 'self.requirements' or not. For one
+ # The condition is composed of all base non-conditional properties. It
+ # is not clear if we should expand 'self.requirements' or not. For one
         # thing, it would be nice to be able to put
         # <toolset>msvc-6.0
- # in requirements.
- # On the other hand, if we have <variant>release in condition it does
- # not make sense to require <optimization>full to be in build request
- # just to select this variant.
+ # in requirements. On the other hand, if we have <variant>release as a
+ # condition it does not make sense to require <optimization>full to be
+ # in the build request just to select this variant.
         local bcondition = [ $(self.requirements).base ] ;
         local ccondition = [ $(self.requirements).conditional ] ;
         local condition = [ set.difference $(bcondition) : $(ccondition) ] ;
@@ -1116,6 +1141,7 @@
     #
     # The results are added to the variable called 'result-var'. Usage
     # requirements are added to the variable called 'usage-requirements-var'.
+ #
     rule generate-dependencies ( dependencies * : property-set
         : result-var usage-requirements-var )
     {
@@ -1124,9 +1150,8 @@
             local grist = $(dependency:G) ;
             local id = $(dependency:G=) ;
 
- local result =
- [ targets.generate-from-reference $(id) : $(self.project)
- : $(property-set) ] ;
+ local result = [ targets.generate-from-reference $(id) :
+ $(self.project) : $(property-set) ] ;
 
             $(result-var) += $(result[2-]:G=$(grist)) ;
             $(usage-requirements-var) += [ $(result[1]).raw ] ;
@@ -1135,6 +1160,7 @@
 
     # Determines final build properties, generates sources, and calls
     # 'construct'. This method should not be overridden.
+ #
     rule generate ( property-set )
     {
         if [ modules.peek : .debug-building ]
@@ -1171,12 +1197,11 @@
                 local properties = [ $(rproperties).non-dependency ] ;
                 local usage-requirements ;
 
- generate-dependencies [ $(rproperties).dependency ]
- : $(rproperties)
- : properties usage-requirements ;
+ generate-dependencies [ $(rproperties).dependency ] :
+ $(rproperties) : properties usage-requirements ;
 
- generate-dependencies $(self.sources) : $(rproperties)
- : source-targets usage-requirements ;
+ generate-dependencies $(self.sources) : $(rproperties) :
+ source-targets usage-requirements ;
 
                 if [ modules.peek : .debug-building ]
                 {
@@ -1201,9 +1226,8 @@
                 # libraries having the same <library> usage requirement.
                 source-targets = [ sequence.unique $(source-targets) ] ;
 
- local result =
- [ construct $(self.name) :
- $(source-targets) : $(rproperties) ] ;
+ local result = [ construct $(self.name) : $(source-targets) :
+ $(rproperties) ] ;
 
                 if $(result)
                 {
@@ -1222,7 +1246,7 @@
                     if [ modules.peek : .debug-building ]
                     {
                         ECHO [ targets.indent ]
- "Usage requirements from $(self.name) are "
+ "Usage requirements from $(self.name) are"
                             [ $(ur).raw ] ;
                     }
 
@@ -1233,8 +1257,9 @@
             {
                 if $(rproperties[1]) = "@error"
                 {
- ECHO [ targets.indent ]
- "Skipping build of: " [ full-name ] " cannot compute common properties" ;
+ ECHO [ targets.indent ] "Skipping build of:" [ full-name ]
+
+ "cannot compute common properties" ;
                 }
                 else if [ $(rproperties).get <build> ] = no
                 {
@@ -1246,7 +1271,7 @@
                     ECHO [ targets.indent ] "Skipping build of: " [ full-name ] " unknown reason" ;
                 }
 
- # We're here either because there's been an error computing
+ # We are here either because there's been an error computing
                 # properties, or there's <build>no in properties. In the latter
                 # case we don't want any diagnostic. In the former case, we need
                 # diagnostics. FIXME
@@ -1267,6 +1292,7 @@
 
     # Given the set of generated targets, and refined build properties,
     # determines and sets appripriate usage requirements on those targets.
+ #
     rule compute-usage-requirements ( subvariant )
     {
         local rproperties = [ $(subvariant).build-properties ] ;
@@ -1309,6 +1335,7 @@
     # 'root-targets' - virtual targets to be returned to dependants
     # 'all-targets' - virtual targets created while building this main target
     # 'build-request' - property-set instance with requested build properties
+ #
     local rule create-subvariant ( root-targets *
         : all-targets * : build-request : sources * : rproperties
         : usage-requirements )
@@ -1333,8 +1360,9 @@
     }
 
     # Constructs virtual targets for this abstract target and the dependency
- # graph. Returns the list of virtual targets. Should be overriden in derived
- # classes.
+ # graph. Returns a usage-requirements property-set and a list of virtual
+ # targets. Should be overriden in derived classes.
+ #
     rule construct ( name : source-targets * : properties * )
     {
         errors.error "method should be defined in derived classes" ;
@@ -1423,6 +1451,7 @@
 # Returns the requirements to use when declaring a main target, obtained by
 # translating all specified property paths and refining project requirements
 # with the ones specified for the target.
+#
 rule main-target-requirements (
     specification * # Properties explicitly specified for the main target.
     : project # Project where the main target is to be declared.
@@ -1444,6 +1473,7 @@
 # Returns the usage requirements to use when declaring a main target, which are
 # obtained by translating all specified property paths and adding project's
 # usage requirements.
+#
 rule main-target-usage-requirements (
     specification * # Use-properties explicitly specified for a main target.
     : project # Project where the main target is to be declared.
@@ -1466,6 +1496,7 @@
 # Return the default build value to use when declaring a main target, which is
 # obtained by using the specified value if not empty and parent's default build
 # attribute otherwise.
+#
 rule main-target-default-build (
     specification * # Default build explicitly specified for a main target.
     : project # Project where the main target is to be declared.
@@ -1485,6 +1516,7 @@
 
 
 # Registers the specified target as a main target alternative and returns it.
+#
 rule main-target-alternative ( target )
 {
     local ptarget = [ $(target).project ] ;
@@ -1496,6 +1528,7 @@
 # Creates a typed-target with the specified properties. The 'name', 'sources',
 # 'requirements', 'default-build' and 'usage-requirements' are assumed to be in
 # the form specified by the user in Jamfile corresponding to 'project'.
+#
 rule create-typed-target ( type : project : name : sources * : requirements *
     : default-build * : usage-requirements * )
 {

Modified: branches/proto/v4/tools/build/v2/build/virtual-target.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/build/virtual-target.jam (original)
+++ branches/proto/v4/tools/build/v2/build/virtual-target.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -4,10 +4,10 @@
 # Distributed under the Boost Software License, Version 1.0.
 # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 
-# Implements virtual targets, which correspond to actual files created during
-# a build, but are not yet targets in Jam sense. They are needed, for example,
-# when searching for possible transormation sequences, when it's not yet known
-# whether a particular target should be created at all.
+# Implements virtual targets, which correspond to actual files created during a
+# build, but are not yet targets in Jam sense. They are needed, for example,
+# when searching for possible transformation sequences, when it's not yet known
+# whether a particular target should be created at all.
 
 import "class" : new ;
 import errors ;
@@ -64,6 +64,7 @@
 # The 'compile-action' and 'link-action' classes are not defined here but in
 # builtin.jam modules. They are shown in the diagram to give the big picture.
 
+
 # Models a potential target. It can be converted into a Jam target and used in
 # building, if needed. However, it can be also dropped, which allows us to
 # search for different transformations and select only one.
@@ -86,12 +87,15 @@
     }
 
     # Name of this target.
+ #
     rule name ( ) { return $(self.name) ; }
 
     # Project of this target.
+ #
     rule project ( ) { return $(self.project) ; }
 
     # Adds additional 'virtual-target' instances this one depends on.
+ #
     rule depends ( d + )
     {
         self.dependencies = [ sequence.merge $(self.dependencies)
@@ -113,6 +117,7 @@
     # file if 'scanner' is specified.
     #
     # If scanner is not specified then the actual target is returned.
+ #
     rule actualize ( scanner ? )
     {
         local actual-name = [ actualize-no-scanner ] ;
@@ -146,12 +151,14 @@
 
     # Sets up build actions for 'target'. Should call appropriate rules and set
     # target variables.
+ #
     rule actualize-action ( target )
     {
         errors.error "method should be defined in derived classes" ;
     }
 
     # Sets up variables on 'target' which specify its location.
+ #
     rule actualize-location ( target )
     {
         errors.error "method should be defined in derived classes" ;
@@ -159,6 +166,7 @@
 
     # If the target is a generated one, returns the path where it will be
     # generated. Otherwise, returns an empty list.
+ #
     rule path ( )
     {
         errors.error "method should be defined in derived classes" ;
@@ -166,6 +174,7 @@
 
     # Returns the actual target name to be used in case when no scanner is
     # involved.
+ #
     rule actual-name ( )
     {
         errors.error "method should be defined in derived classes" ;
@@ -175,8 +184,8 @@
     rule actualize-no-scanner ( )
     {
         # In fact, we just need to merge virtual-target with
- # abstract-virtual-target as the latter is the only class derived from
- # the former. But that's for later.
+ # abstract-file-target as the latter is the only class derived from the
+ # former. But that's for later.
         errors.error "method should be defined in derived classes" ;
     }
 }
@@ -190,6 +199,7 @@
 #
 # The target's grist is concatenation of its project's location, properties of
 # action (for derived files) and, optionally, value identifying the main target.
+#
 class abstract-file-target : virtual-target
 {
     import project ;
@@ -230,12 +240,14 @@
 
     # Sets the path. When generating target name, it will override any path
     # computation from properties.
+ #
     rule set-path ( path )
     {
         self.path = [ path.native $(path) ] ;
     }
 
     # Returns the currently set action.
+ #
     rule action ( )
     {
         return $(self.action) ;
@@ -243,6 +255,7 @@
 
     # Sets/gets the 'root' flag. Target is root if it directly corresponds to
     # some variant of a main target.
+ #
     rule root ( set ? )
     {
         if $(set)
@@ -256,9 +269,10 @@
     # when target is brought into existance and is never changed after that. In
     # particular, if a target is shared by a subvariant, only the first is
     # stored.
- rule creating-subvariant ( s ? # If specified, specifies the value to set,
- # which should be a 'subvariant' class
- # instance.
+ #
+ rule creating-subvariant ( s ? # If specified, specifies the value to set,
+ # which should be a 'subvariant' class
+ # instance.
                              )
     {
         if $(s) && ! $(self.creating-subvariant) && ! $(overwrite)
@@ -333,7 +347,6 @@
             local grist = [ grist ] ;
             local basename = [ path.native $(self.name) ] ;
             self.actual-name = <$(grist)>$(basename) ;
-
         }
         return $(self.actual-name) ;
     }
@@ -341,6 +354,7 @@
     # Helper to 'actual-name', above. Computes a unique prefix used to
     # distinguish this target from other targets with the same name creating
     # different files.
+ #
     rule grist ( )
     {
         # Depending on target, there may be different approaches to generating
@@ -379,11 +393,12 @@
 
     # Given the target name specified in constructor, returns the name which
     # should be really used, by looking at the <tag> properties. Tag properties
- # need to be specified as <tag>@rule-name. This makes Boost.Build call the
+ # need to be specified as <tag>@rule-name. This makes Boost Build call the
     # specified rule with the target name, type and properties to get the new
     # name. If no <tag> property is specified or the rule specified by <tag>
     # returns nothing, returns the result of calling
     # virtual-target.add-prefix-and-suffix.
+ #
     rule _adjust-name ( specified-name )
     {
         local ps ;
@@ -468,6 +483,7 @@
 
 # Appends the suffix appropriate to 'type/property-set' combination to the
 # specified name and returns the result.
+#
 rule add-prefix-and-suffix ( specified-name : type ? : property-set )
 {
     local suffix = [ type.generated-target-suffix $(type) : $(property-set) ] ;
@@ -546,7 +562,7 @@
             DEPENDS $(target) : $(path) ;
             common.MkDir $(path) ;
 
- # It's possible that the target name includes a directory too, for
+ # It is possible that the target name includes a directory too, for
             # example when installing headers. Create that directory.
             if $(target:D)
             {
@@ -584,6 +600,7 @@
     }
 
     # Returns the directory for this target.
+ #
     rule path ( )
     {
         if ! $(self.path)
@@ -616,6 +633,7 @@
     }
 
     # Returns nothing to indicate that the target's path is not known.
+ #
     rule path ( )
     {
         return ;
@@ -635,7 +653,7 @@
 # rule action-name ( targets + : sources * : properties * )
 # Targets and sources are passed as actual Jam targets. The rule may not
 # establish additional dependency relationships.
-
+#
 class action
 {
     import "class" ;
@@ -691,6 +709,7 @@
     }
 
     # Generates actual build instructions.
+ #
     rule actualize ( )
     {
         if ! $(self.actualized)
@@ -733,6 +752,7 @@
 
     # Helper for 'actualize-sources'. For each passed source, actualizes it with
     # the appropriate scanner. Returns the actualized virtual targets.
+ #
     rule actualize-source-type ( sources * : property-set )
     {
         local result = ;
@@ -756,6 +776,7 @@
     #
     # New values will be *appended* to the variables. They may be non-empty if
     # caller wants it.
+ #
     rule actualize-sources ( sources * : property-set )
     {
         local dependencies = [ $(self.properties).get <dependency> ] ;
@@ -786,6 +807,7 @@
     # the last chance to fix properties, for example to adjust includes to get
     # generated headers correctly. Default implementation simply returns its
     # argument.
+ #
     rule adjust-properties ( property-set )
     {
         return $(property-set) ;
@@ -797,6 +819,7 @@
 # properties out of nowhere. It's needed to distinguish virtual targets with
 # different properties that are known to exist and have no actions which create
 # them.
+#
 class null-action : action
 {
     rule __init__ ( property-set ? )
@@ -820,6 +843,7 @@
 
 # Class which acts exactly like 'action', except that its sources are not
 # scanned for dependencies.
+#
 class non-scanning-action : action
 {
     rule __init__ ( sources * : action-name + : property-set ? )
@@ -846,6 +870,7 @@
 # name and source location for the project, and use that path to determine if
 # the target was already created.
 # TODO: passing a project with all virtual targets is starting to be annoying.
+#
 rule from-file ( file : file-loc : project )
 {
     import type ; # Had to do this here to break a circular dependency.
@@ -880,6 +905,7 @@
 # same sources and equal action. If such target is found it is returned and a
 # new 'target' is not registered. Otherwise, 'target' is registered and
 # returned.
+#
 rule register ( target )
 {
     local signature = [ sequence.join
@@ -905,9 +931,9 @@
                 {
                     local ps1 = [ $(a1).properties ] ;
                     local ps2 = [ $(a2).properties ] ;
- local p1 = [ $(ps1).base ] [ $(ps1).free ]
+ local p1 = [ $(ps1).base ] [ $(ps1).free ]
                       [ set.difference [ $(ps1).dependency ] : [ $(ps1).incidental ] ] ;
- local p2 = [ $(ps2).base ] [ $(ps2).free ]
+ local p2 = [ $(ps2).base ] [ $(ps2).free ]
                       [ set.difference [ $(ps2).dependency ] : [ $(ps2).incidental ] ] ;
                     if $(p1) = $(p2)
                     {
@@ -934,6 +960,7 @@
 # Each target returned by 'register' is added to a recent-targets list, returned
 # by this function. This allows us to find all targets created when building a
 # given main target, even if the target... !!!MISSING TEXT HERE!!!
+#
 rule recent-targets ( )
 {
     return $(.recent-targets) ;
@@ -947,6 +974,7 @@
 
 
 # Returns all virtual targets ever created.
+#
 rule all-targets ( )
 {
     return $(.all-targets) ;
@@ -955,6 +983,7 @@
 
 # Returns all targets from 'targets' with types equal to 'type' or derived from
 # it.
+#
 rule select-by-type ( type : targets * )
 {
     local result ;
@@ -1013,6 +1042,7 @@
 # found during traversal, it's either included or not, depending on the value of
 # 'include-roots'. In either case traversal stops at root targets, i.e. sources
 # of root targets are not traversed.
+#
 rule traverse ( target : include-roots ? : include-sources ? )
 {
     local result ;
@@ -1046,6 +1076,7 @@
 # produced by the action. The rule-name and properties are set to
 # 'new-rule-name' and 'new-properties', if those are specified. Returns the
 # cloned action.
+#
 rule clone-action ( action : new-project : new-action-name ? : new-properties ? )
 {
     if ! $(new-action-name)
@@ -1059,7 +1090,7 @@
 
     local action-class = [ modules.peek $(action) : __class__ ] ;
     local cloned-action = [ class.new $(action-class)
- [ $(action).sources ] : $(new-action-name) : $(new-properties) ] ;
+ [ $(action).sources ] : $(new-action-name) : $(new-properties) ] ;
 
     local cloned-targets ;
     for local target in [ $(action).targets ]
@@ -1151,6 +1182,7 @@
     # indirectly, and either as sources, or as dependency properties. Targets
     # referred to using the dependency property are returned as properties, not
     # targets.
+ #
     rule all-referenced-targets ( )
     {
         # Find directly referenced targets.
@@ -1179,6 +1211,7 @@
     # referred by <implcit-dependecy> properties. For all targets of type
     # 'target-type' (or for all targets, if 'target-type' is not specified), the
     # result will contain <$(feature)>path-to-that-target.
+ #
     rule implicit-includes ( feature : target-type ? )
     {
         local key = ii$(feature)-$(target-type:E="") ;

Modified: branches/proto/v4/tools/build/v2/doc/src/extending.xml
==============================================================================
--- branches/proto/v4/tools/build/v2/doc/src/extending.xml (original)
+++ branches/proto/v4/tools/build/v2/doc/src/extending.xml 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -335,15 +335,13 @@
         converted to the right types to actually create the result.
       </para>
 
- <para>The <code>generated-target</code> <!-- Is it generated-target or generated-targets? -->
- method can be overridden
- when you want to add additional properties to the generated
- targets or use additional sources. For a real-life example,
- suppose you have a program analysis tool that should be given a
- name of executable and the list of all sources. Naturally, you
- don't want to list all source files manually. Here's how the
- <code>generated-targets</code> method can find the list of
- sources automatically:
+ <para>The <code>generated-targets</code> method can be overridden when you
+ want to add additional properties to the generated targets or use
+ additional sources. For a real-life example, suppose you have a program
+ analysis tool that should be given a name of executable and the list of
+ all sources. Naturally, you don't want to list all source files
+ manually. Here's how the <code>generated-targets</code> method can find
+ the list of sources automatically:
 <programlisting>
 class itrace-generator : generator {
 ....

Modified: branches/proto/v4/tools/build/v2/doc/src/tutorial.xml
==============================================================================
--- branches/proto/v4/tools/build/v2/doc/src/tutorial.xml (original)
+++ branches/proto/v4/tools/build/v2/doc/src/tutorial.xml 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -18,7 +18,7 @@
 
   <para>This section will guide you though the most basic features of
   Boost.Build V2. We will start with the &#x201C;Hello, world&#x201D; example,
- learn how to use libraries, and finish with testing and installing features.
+ learn how to use libraries, and finish with testing and installing features.
   </para>
 
   <section id="bbv2.tutorial.hello">
@@ -37,9 +37,9 @@
       things. First of all, just invoking <command>bjam</command> will
       build the <filename>hello</filename>
       executable by compiling and
- linking <filename>hello.cpp</filename>. By default, debug variant
+ linking <filename>hello.cpp</filename>. By default, debug variant
       is built. Now, to build the
- release variant of <filename>hello</filename>, invoke
+ release variant of <filename>hello</filename>, invoke
 
 <screen>
 bjam release
@@ -66,7 +66,7 @@
       Since we have already built both variants
       of <filename>hello</filename>, hello.cpp won't be recompiled;
       instead the existing object files will just be linked into the
- corresponding variants of <filename>hello2</filename>. Now
+ corresponding variants of <filename>hello2</filename>. Now
       let's remove all the built products:
 
 <screen>
@@ -140,7 +140,7 @@
     <section id="bbv2.tutorial.properties.requirements">
       <title>Build Requests and Target Requirements</title>
 
- <para>
+ <para>
         The set of properties specified on the command line constitute
         a <firstterm>build request</firstterm>&#x2014;a description of
         the desired properties for building the requested targets (or,
@@ -162,15 +162,15 @@
       </para>
 
 <programlisting>
-exe hello
+exe hello
     : hello.cpp
     : &lt;include&gt;boost &lt;threading&gt;multi
     ;
 </programlisting>
 
- <para>
+ <para>
         When <filename>hello</filename> is built, the two
- requirements specified above will always be present.
+ requirements specified above will always be present.
         If the build request given on the <command>bjam</command>
         command-line explictly contradicts a target's requirements,
         the target requirements usually override (or, in the case of
@@ -187,7 +187,7 @@
       <tip>
         <para>The value of the <varname>&lt;include&gt;</varname> feature is
           relative to the location of <filename>Jamroot</filename> where it's
- used.
+ used.
         </para>
       </tip>
 
@@ -200,14 +200,14 @@
         target, <filename>hello2</filename>, we could simply duplicate
         them. However, as projects grow, that approach leads to a great
         deal of repeated boilerplate in Jamfiles.
-
+
         Fortunately, there's a better way. Each project can specify a
         set of <firstterm>attributes</firstterm>, including
         requirements:
 
 <programlisting>
-project
- : requirements &lt;include&gt;/home/ghost/Work/boost &lt;threading&gt;multi
+project
+ : requirements &lt;include&gt;/home/ghost/Work/boost &lt;threading&gt;multi
     ;
 
 exe hello : hello.cpp ;
@@ -236,7 +236,7 @@
     example, in the following directory layout:
 
 <screen>
-top/
+top/
   |
   +-- Jamroot
   |
@@ -244,7 +244,7 @@
   | |
   | +-- Jamfile
   | `-- app.cpp
- |
+ |
   `-- util/
        |
        +-- foo/
@@ -274,7 +274,7 @@
     <para>
       Projects inherit all attributes (such as requirements)
       from their parents. Inherited requirements are combined with
- any requirements specified by the subproject.
+ any requirements specified by the subproject.
       For example, if <filename>top/Jamroot</filename> has
 
 <programlisting>
@@ -289,8 +289,8 @@
       rather than added-to, in subprojects. See <xref
       linkend="bbv2.reference.features.attributes"/> for more
       information</para>
- </footnote>
- More details can be found in
+ </footnote>
+ More details can be found in
       <xref linkend= "bbv2.advanced.projects"/>.
     </para>
 
@@ -346,7 +346,7 @@
       While <code>app.cpp</code> refers to a regular source file,
       <code>../util/foo//bar</code> is a reference to another target:
       a library <filename>bar</filename> declared in the Jamfile at
- <filename>../util/foo</filename>.
+ <filename>../util/foo</filename>.
     </para>
 
     <tip>
@@ -378,13 +378,13 @@
       <filename>app.cpp</filename>. We could manually add the necessary
       <code>#include</code> paths to <filename>app</filename>'s
       requirements as values of the
- <varname>&lt;include&gt;</varname> feature, but then this work will
+ <varname>&lt;include&gt;</varname> feature, but then this work will
       be repeated for all programs
       that use <filename>foo</filename>. A better solution is to modify
       <filename>util/foo/Jamfile</filename> in this way:
 
 <programlisting>
-project
+project
     : usage-requirements &lt;include&gt;.
     ;
 
@@ -399,7 +399,7 @@
 
     <para>Another improvement is using symbolic identifiers to refer to
       the library, as opposed to <filename>Jamfile</filename> location.
- In a large project, a library can be used by many targets, and if
+ In a large project, a library can be used by many targets, and if
       they all use <filename>Jamfile</filename> location,
       a change in directory organization entails much work.
       The solution is to use project ids&#x2014;symbolic names
@@ -415,14 +415,14 @@
 <programlisting>
 exe app : app.cpp /library-example/foo//bar ;
 </programlisting>
-The <filename>/library-example/foo//bar</filename> syntax is used
+The <filename>/library-example/foo//bar</filename> syntax is used
       to refer to the target <filename>bar</filename> in
       the project with id <filename>/library-example/foo</filename>.
       We've achieved our goal&#x2014;if the library is moved to a different
       directory, only <filename>Jamroot</filename> must be modified.
       Note that project ids are global&#x2014;two Jamfiles are not
       allowed to assign the same project id to different directories.
-
+
     </para>
 
     <tip>
@@ -434,12 +434,12 @@
       <code>&lt;library&gt;/boost/filesystem//fs</code> to the project's requirements, like this:</para>
 
       <programlisting>
-project
+project
    : requirements &lt;source&gt;/boost/filesystem//fs
- ;
+ ;
       </programlisting>
     </tip>
-
+
   </section>
 
   <section id="bbv2.tutorial.testing">
@@ -457,38 +457,35 @@
     <emphasis>dynamic</emphasis>), which are only referred to from executables,
     and must be available at run time. Boost.Build can create and use both kinds.
     </para>
-
+
     <para>The kind of library produced from a <code>lib</code> target is
     determined by the value of the <varname>link</varname> feature. Default
- value is <literal>shared</literal>, and to build static library, the value
- should be <literal>static</literal>. You can either requiest static build
+ value is <literal>shared</literal>, and to build a static library, the value
+ should be <literal>static</literal>. You can request a static build either
     on the command line:
     <screen>
 bjam link=static
     </screen>
- or in the library's requirements:
+ or in the library's requirements:
     <programlisting>
 lib l : l.cpp : &lt;link&gt;static ;
     </programlisting>
     </para>
 
     <para>
- We can also use the <varname>&lt;link&gt;</varname> property
- to express linking requirements on a per-target basis.
- For example, if a particular executable can be correctly built
- only with the static version of a library, we can qualify the
- executable's <link
- linkend="bbv2.reference.targets.references">target
- reference</link> to the library as follows:
-
-<!-- There has been no earlier indication that target references can
- contain properties. You can't assume that the reader will
- recognize that strange incantation as a target reference, or that
- she'll know what it means. You also can't assume that hyperlinks
- will help the reader, because she may be working from a printout,
- as I was.
- VP: to be addressed when this section is moved. See comment
- below.
+ We can also use the <varname>&lt;link&gt;</varname> property to express
+ linking requirements on a per-target basis. For example, if a particular
+ executable can be correctly built only with the static version of a
+ library, we can qualify the executable's <link
+ linkend="bbv2.reference.targets.references">target reference</link> to the
+ library as follows:
+
+<!-- There has been no earlier indication that target references can contain
+ properties. You can't assume that the reader will recognize that strange
+ incantation as a target reference, or that she'll know what it means. You
+ also can't assume that hyperlinks will help the reader, because she may be
+ working from a printout, as I was.
+ VP: to be addressed when this section is moved. See comment below.
 -->
 
     <programlisting>
@@ -521,14 +518,14 @@
 exe e1 : e1.cpp foo ;
 exe e10 : e10.cpp foo ;</programlisting>
 
- The <link linkend="bbv2.tasks.alias"><functionname>alias</functionname></link>
+ The <link linkend="bbv2.tasks.alias"><functionname>alias</functionname></link>
         rule is specifically used to rename a reference to a target and possibly
         change the properties.
-
+
         <!-- You should introduce the alias rule in an earlier
              section, before describing how it applies to this
              specific use-case, and the foregoing sentence should
- go there.
+ go there.
              VP: we've agreed that this section should be moved further
              in the docs, since it's more like advanced reading. When
              I'll move it, I'll make sure 'alias' is already mentioned.
@@ -540,10 +537,10 @@
           When one library uses another, you put the second library in
           the source list of the first. For example:
           <programlisting>
-lib utils : utils.cpp /boost/filesystem//fs ;
+lib utils : utils.cpp /boost/filesystem//fs ;
 lib core : core.cpp utils ;
 exe app : app.cpp core ;</programlisting>
- This works no matter what kind of linking is used. When
+ This works no matter what kind of linking is used. When
           <filename>core</filename> is built as a shared library, it is linked
           directly into <filename>utils</filename>. Static libraries can't
           link to other libraries, so when <filename>core</filename> is built
@@ -575,11 +572,11 @@
     <para>Sometimes, particular relationships need to be maintained
     among a target's build properties. For example, you might want to set
     specific <code>#define</code> when a library is built as shared,
- or when a target's <code>release</code> variant is built.
- This can be achieved with <firstterm>conditional requirements</firstterm>.
+ or when a target's <code>release</code> variant is built.
+ This can be achieved with <firstterm>conditional requirements</firstterm>.
 
     <programlisting>
-lib network : network.cpp
+lib network : network.cpp
     : <emphasis role="bold">&lt;link&gt;shared:&lt;define&gt;NEWORK_LIB_SHARED</emphasis>
      &lt;variant&gt;release:&lt;define&gt;EXTRA_FAST
     ;
@@ -588,7 +585,7 @@
       In the example above, whenever <filename>network</filename> is
       built with <code>&lt;link&gt;shared</code>,
       <code>&lt;define&gt;NEWORK_LIB_SHARED</code> will be in its
- properties, too. Also, whenever its release variant is built,
+ properties, too. Also, whenever its release variant is built,
       <code>&lt;define&gt;EXTRA_FAST</code> will appear in its properties.
     </para>
 
@@ -606,7 +603,7 @@
 </programlisting>
       When building <filename>demangler</filename>, Boost.Build will compare
       requirements for each alternative with build properties to find the best
- match. For example, when building with <code>&lt;toolset&gt;gcc</code>
+ match. For example, when building with <code>&lt;toolset&gt;gcc</code>
       alternative 2, will be selected, and when building with
       <code>&lt;toolset&gt;msvc</code> alternative 3 will be selected. In all
       other cases, the most generic alternative 1 will be built.
@@ -625,12 +622,12 @@
 <programlisting>
 # util/lib2/Jamfile
 lib lib2
- :
+ :
     : &lt;file&gt;lib2_release.a &lt;variant&gt;release
     ;
 
 lib lib2
- :
+ :
     : &lt;file&gt;lib2_debug.a &lt;variant&gt;debug
     ;
 </programlisting>
@@ -650,7 +647,7 @@
       As with any target, the alternative selected depends on the
       properties propagated from <filename>lib2</filename>'s dependents.
       If we build the the release and debug versions of <filename>app</filename> will be linked
- with <filename>lib2_release.a</filename> and <filename>lib2_debug.a</filename>, respectively.
+ with <filename>lib2_release.a</filename> and <filename>lib2_debug.a</filename>, respectively.
 
     </para>
 
@@ -668,7 +665,7 @@
       compiler. If the gcc toolset were used to link an executable
       target to <filename>pythonlib</filename>, <option>-lpython22</option>
       would appear in the command line (other compilers may use
- different options).
+ different options).
     </para>
 
     <para>
@@ -688,7 +685,7 @@
     </para>
 
     <para>A more advanced use of prebuilt targets is described in <xref
- linkend="bbv2.recipies.site-config"/>.
+ linkend="bbv2.recipies.site-config"/>.
     </para>
 
   </section>

Modified: branches/proto/v4/tools/build/v2/kernel/class.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/kernel/class.jam (original)
+++ branches/proto/v4/tools/build/v2/kernel/class.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -28,7 +28,7 @@
 #
 # The __init__ rule is the constructor, and sets member variables.
 #
-# New instances are created by invoking [ new <class> <args...> ]::
+# New instances are created by invoking [ new <class> <args...> ]:
 #
 # local x = [ new myclass foo ] ; # x is a new myclass object
 # assert.result foo : [ $(x).method1 ] ; # $(x).method1 returns "foo"
@@ -49,18 +49,18 @@
 # }
 # }
 #
-# All methods operate virtually, replacing behavior in the base
-# classes. For example::
+# All methods operate virtually, replacing behavior in the base classes. For
+# example::
 #
-# local y = [ new derived foo ] ; # y is a new derived object
-# assert.result fooXXX : [ $(y).method1 ] ; # $(y).method1 returns "foo"
+# local y = [ new derived foo ] ; # y is a new derived object
+# assert.result fooXXX : [ $(y).method1 ] ; # $(y).method1 returns "foo"
 #
-# Each class instance is its own core Jam module. All instance
-# attributes and methods are accessible without additional
-# qualification from within the class instance. All rules imported in
-# class declaration, or visible in base classses are also visible.
-# Base methods are available in qualified form: base-name.method-name.
-# By convention, attribute names are prefixed with "self.".
+# Each class instance is its own core Jam module. All instance attributes and
+# methods are accessible without additional qualification from within the class
+# instance. All rules imported in class declaration, or visible in base classses
+# are also visible. Base methods are available in qualified form:
+# base-name.method-name. By convention, attribute names are prefixed with
+# "self.".
 
 import numbers ;
 import errors : * ;
@@ -113,6 +113,7 @@
     }
 }
 
+
 rule is-derived ( class : bases + )
 {
     #local all = $(class) $(bases) ;
@@ -141,13 +142,15 @@
     return $(found) ;
 }
 
+
 # Returns true if the 'value' is a class instance.
-rule is-instance ( value # The value to check
- )
+#
+rule is-instance ( value )
 {
     return [ MATCH "^(object\\()[^@]+\\)@.*" : $(value) ] ;
 }
 
+
 # Check if the given value is of the given type.
 #
 rule is-a (
@@ -161,6 +164,7 @@
     }
 }
 
+
 local rule typecheck ( x )
 {
     local class-name = [ MATCH "^\\[(.*)\\]$" : [ BACKTRACE 1 ] ] ;
@@ -170,14 +174,14 @@
     }
 }
 
+
 local rule __test__ ( )
 {
     import "class" : * ;
     import assert ;
     import errors : * ;
 
- # This will be the construction function for a class called
- # 'myclass'
+ # This will be the construction function for a class called 'myclass'.
     class myclass
     {
         import assert : nonempty-variable ;
@@ -277,15 +281,13 @@
             return $(z) ;
         }
 
- # Check that 'assert.equal' visible in base class is visible
- # here.
+ # Check that 'assert.equal' visible in base class is visible here.
         rule invariant2 ( )
         {
             assert.equal 2 : 2 ;
         }
         
- # Check that 'nonempty-variable' visible in base class is
- # visible here.
+ # Check that 'nonempty-variable' visible in base class is visible here.
         rule invariant3 ( )
         {
             local v = 10 ;
@@ -336,11 +338,10 @@
     expect_derived2 $(d) ;
     expect_derived2 $(e) ;
 
- # argument checking is set up to call exit(1) directly on
- # failure, and we can't hijack that with try, so we'd better
- # not do this test by default. We could fix this by having
- # errors look up and invoke the EXIT rule instead; EXIT can be
- # hijacked (;-)
+ # Argument checking is set up to call exit(1) directly on failure, and we
+ # can't hijack that with try, so we'd better not do this test by default.
+ # We could fix this by having errors look up and invoke the EXIT rule
+ # instead; EXIT can be hijacked (;-)
     if --fail-typecheck in [ modules.peek : ARGV ]
     {
         try ;
@@ -385,7 +386,7 @@
     $(b).invariant2 ;
     $(b).invariant3 ;
     
- # Check that the __class__ attribute is getting properly set.
+ # Check that the __class__ attribute is getting properly set.
     assert.result myclass : $(a).get-class ;
     assert.result derived1 : $(b).get-class ;
     assert.result $(a) : $(a).get-instance ;

Modified: branches/proto/v4/tools/build/v2/test/BoostBuild.py
==============================================================================
--- branches/proto/v4/tools/build/v2/test/BoostBuild.py (original)
+++ branches/proto/v4/tools/build/v2/test/BoostBuild.py 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -139,14 +139,48 @@
     def _status(self):
         return self.status
 
+
 class Tester(TestCmd.TestCmd):
- """Class for testing Boost.Build.
+ """Main tester class for Boost Build.
 
- Optional argument `executable` indicates the name of the executable to
- invoke. Set this to "jam" to test Boost.Build v1 behavior.
+ Optional arguments:
 
- Optional argument `work_dir` indicates an absolute directory, where the test
- will run be run.
+ `arguments` - Arguments passed to the run executable.
+ `executable` - Name of the executable to invoke.
+ `match` - Function to use for compating actual and
+ expected file contents.
+ `boost_build_path` - Boost build path to be passed to the run
+ executable.
+ `translate_suffixes` - Whether to update suffixes on the the file
+ names passed from the test script so they
+ match those actually created by the current
+ toolset. For example, static library files
+ are specified by using the .lib suffix but
+ when the 'gcc' toolset is used it actually
+ creates them using the .a suffix.
+ `pass_toolset` - Whether the test system should pass the
+ specified toolset to the run executable.
+ `use_test_config` - Whether the test system should tell the run
+ executable to read in the test_config.jam
+ configuration file.
+ `ignore_toolset_requirements` - Whether the test system should tell the run
+ executable to ignore toolset requirements.
+ `workdir` - indicates an absolute directory where the
+ test will be run from.
+
+ Optional arguments inherited from the base class:
+
+ `description` - Test description string displayed in case of
+ a failed test.
+ `subdir' - List of subdirectories to automatically
+ create under the working directory. Each
+ subdirectory needs to be specified
+ separately parent coming before its child.
+ `verbose` - Flag that may be used to enable more verbose
+ test system output. Note that it does not
+ also enable more verbose build system
+ output like the --verbose command line
+ option does.
     """
     def __init__(self, arguments="", executable="bjam",
         match=TestCmd.match_exact, boost_build_path=None,
@@ -157,7 +191,8 @@
         if workdir != '' and not os.path.isabs(workdir):
             raise "Parameter workdir <"+workdir+"> must point to an absolute directory: "
 
- self.last_build_time = 0
+ self.last_build_time_start = 0
+ self.last_build_time_finish = 0
         self.translate_suffixes = translate_suffixes
         self.use_test_config = use_test_config
 
@@ -186,9 +221,9 @@
                 elif os.uname()[0] == 'SunOS':
                     jam_build_dir = "bin.solaris"
                 elif os.uname()[0] == 'Darwin':
- if os.uname()[4] == 'i386':
+ if os.uname()[4] == 'i386':
                         jam_build_dir = "bin.macosxx86"
- else:
+ else:
                         jam_build_dir = "bin.macosxppc"
                 elif os.uname()[0] == "AIX":
                     jam_build_dir = "bin.aix"
@@ -221,7 +256,7 @@
 
         verbosity = ['-d0', '--quiet']
         if '--verbose' in sys.argv:
- keywords['verbose'] = 1
+ keywords['verbose'] = True
             verbosity = ['-d+2']
 
         if boost_build_path is None:
@@ -235,7 +270,7 @@
         else:
             program_list.append(os.path.join(jam_build_dir, executable))
             inpath_bjam = None
- program_list.append('-sBOOST_BUILD_PATH=' + boost_build_path)
+ program_list.append('-sBOOST_BUILD_PATH="' + boost_build_path + '"')
         if verbosity:
             program_list += verbosity
         if arguments:
@@ -256,7 +291,7 @@
             TestCmd.TestCmd.cleanup(self)
             os.chdir(self.original_workdir)
         except AttributeError:
- # When this is called during by TestCmd.TestCmd.__del__ we can have
+ # When this is called during TestCmd.TestCmd.__del__ we can have
             # both 'TestCmd' and 'os' unavailable in our scope. Do nothing in
             # this case.
             pass
@@ -265,7 +300,7 @@
     # Methods that change the working directory's content.
     #
     def set_tree(self, tree_location):
- # Seems like it's not possible to remove the current a directory.
+ # It is not possible to remove the current directory.
         d = os.getcwd()
         os.chdir(os.path.dirname(self.workdir))
         shutil.rmtree(self.workdir, ignore_errors=False)
@@ -284,7 +319,7 @@
         os.path.walk(".", make_writable, None)
 
     def write(self, file, content):
- self.wait_for_time_change()
+ self.wait_for_time_change_since_last_build()
         nfile = self.native_file_name(file)
         try:
             os.makedirs(os.path.dirname(nfile))
@@ -307,7 +342,7 @@
         self.touch(new);
 
     def copy(self, src, dst):
- self.wait_for_time_change()
+ self.wait_for_time_change_since_last_build()
         try:
             self.write(dst, self.read(src, 1))
         except:
@@ -321,12 +356,12 @@
         os.utime(dst_name, (stats.st_atime, stats.st_mtime))
 
     def touch(self, names):
- self.wait_for_time_change()
+ self.wait_for_time_change_since_last_build()
         for name in self.adjust_names(names):
             os.utime(self.native_file_name(name), None)
 
     def rm(self, names):
- self.wait_for_time_change()
+ self.wait_for_time_change_since_last_build()
         if not type(names) == types.ListType:
             names = [names]
 
@@ -344,7 +379,7 @@
                 else:
                     os.unlink(n)
 
- # Create working dir root again, in case we've removed it.
+ # Create working dir root again in case we removed it.
         if not os.path.exists(self.workdir):
             os.mkdir(self.workdir)
         os.chdir(self.workdir)
@@ -365,45 +400,50 @@
     #
     def run_build_system(self, extra_args="", subdir="", stdout=None, stderr="",
         status=0, match=None, pass_toolset=None, use_test_config=None,
- ignore_toolset_requirements=None, **kw):
+ ignore_toolset_requirements=None, expected_duration=None, **kw):
 
- if os.path.isabs(subdir):
- if stderr:
- print "You must pass a relative directory to subdir <"+subdir+">."
- status = 1
- return
+ self.last_build_time_start = time.time()
 
- self.previous_tree = tree.build_tree(self.workdir)
+ try:
+ if os.path.isabs(subdir):
+ if stderr:
+ print "You must pass a relative directory to subdir <"+subdir+">."
+ status = 1
+ return
 
- if match is None:
- match = self.match
+ self.previous_tree = tree.build_tree(self.workdir)
 
- if pass_toolset is None:
- pass_toolset = self.pass_toolset
+ if match is None:
+ match = self.match
 
- if use_test_config is None:
- use_test_config = self.use_test_config
+ if pass_toolset is None:
+ pass_toolset = self.pass_toolset
 
- if ignore_toolset_requirements is None:
- ignore_toolset_requirements = self.ignore_toolset_requirements
+ if use_test_config is None:
+ use_test_config = self.use_test_config
 
- try:
- kw['program'] = []
- kw['program'] += self.program
- if extra_args:
- kw['program'] += extra_args.split(" ")
- if pass_toolset:
- kw['program'].append("toolset=" + self.toolset)
- if use_test_config:
- kw['program'].append('--test-config="%s"'
- % os.path.join(self.original_workdir, "test-config.jam"))
- if ignore_toolset_requirements:
- kw['program'].append("--ignore-toolset-requirements")
- kw['chdir'] = subdir
- apply(TestCmd.TestCmd.run, [self], kw)
- except:
- self.dump_stdio()
- raise
+ if ignore_toolset_requirements is None:
+ ignore_toolset_requirements = self.ignore_toolset_requirements
+
+ try:
+ kw['program'] = []
+ kw['program'] += self.program
+ if extra_args:
+ kw['program'] += extra_args.split(" ")
+ if pass_toolset:
+ kw['program'].append("toolset=" + self.toolset)
+ if use_test_config:
+ kw['program'].append('--test-config="%s"'
+ % os.path.join(self.original_workdir, "test-config.jam"))
+ if ignore_toolset_requirements:
+ kw['program'].append("--ignore-toolset-requirements")
+ kw['chdir'] = subdir
+ apply(TestCmd.TestCmd.run, [self], kw)
+ except:
+ self.dump_stdio()
+ raise
+ finally:
+ self.last_build_time_finish = time.time()
 
         if status != None and _failed(self, status):
             expect = ''
@@ -426,7 +466,7 @@
             self.maybe_do_diff(self.stdout(), stdout)
             self.fail_test(1, dump_stdio=False)
 
- # Intel tends to produce some message to stderr which makes tests fail.
+ # Intel tends to produce some messages to stderr which make tests fail.
         intel_workaround = re.compile("^xi(link|lib): executing.*\n", re.M)
         actual_stderr = re.sub(intel_workaround, "", self.stderr())
 
@@ -438,13 +478,19 @@
             self.maybe_do_diff(actual_stderr, stderr)
             self.fail_test(1, dump_stdio=False)
 
+ if not expected_duration is None:
+ actual_duration = self.last_build_time_finish - self.last_build_time_start
+ if ( actual_duration > expected_duration ):
+ print "Test run lasted %f seconds while it was expected to " \
+ "finish in under %f seconds." % (actual_duration,
+ expected_duration)
+ self.fail_test(1, dump_stdio=False)
+
         self.tree = tree.build_tree(self.workdir)
         self.difference = tree.trees_difference(self.previous_tree, self.tree)
         self.difference.ignore_directories()
         self.unexpected_difference = copy.deepcopy(self.difference)
 
- self.last_build_time = time.time()
-
     def glob_file(self, name):
         result = None
         if hasattr(self,'difference'):
@@ -783,14 +829,14 @@
         return os.path.normpath(apply(os.path.join, [self.workdir]+elements))
 
     # Wait while time is no longer equal to the time last "run_build_system"
- # call finished.
- def wait_for_time_change(self):
+ # call finished. Used to avoid subsequent builds treating existing files as
+ # 'current'.
+ def wait_for_time_change_since_last_build(self):
         while 1:
- f = time.time();
             # In fact, I'm not sure why "+ 2" as opposed to "+ 1" is needed but
             # empirically, "+ 1" sometimes causes 'touch' and other functions
             # not to bump the file time enough for a rebuild to happen.
- if math.floor(f) < math.floor(self.last_build_time) + 2:
+ if math.floor(time.time()) < math.floor(self.last_build_time_finish) + 2:
                 time.sleep(0.1)
             else:
                 break

Modified: branches/proto/v4/tools/build/v2/test/TestCmd.py
==============================================================================
--- branches/proto/v4/tools/build/v2/test/TestCmd.py (original)
+++ branches/proto/v4/tools/build/v2/test/TestCmd.py 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1,28 +1,26 @@
 """
 TestCmd.py: a testing framework for commands and scripts.
 
-The TestCmd module provides a framework for portable automated testing
-of executable commands and scripts (in any language, not just Python),
-especially commands and scripts that require file system interaction.
+The TestCmd module provides a framework for portable automated testing of
+executable commands and scripts (in any language, not just Python), especially
+commands and scripts that require file system interaction.
 
 In addition to running tests and evaluating conditions, the TestCmd module
-manages and cleans up one or more temporary workspace directories, and
-provides methods for creating files and directories in those workspace
-directories from in-line data, here-documents), allowing tests to be
-completely self-contained.
+manages and cleans up one or more temporary workspace directories, and provides
+methods for creating files and directories in those workspace directories from
+in-line data, here-documents), allowing tests to be completely self-contained.
 
 A TestCmd environment object is created via the usual invocation:
 
     test = TestCmd()
 
-The TestCmd module provides pass_test(), fail_test(), and no_result()
-unbound methods that report test results for use with the Aegis change
-management system. These methods terminate the test immediately,
-reporting PASSED, FAILED, or NO RESULT respectively, and exiting with
-status 0 (success), 1 or 2 respectively. This allows for a distinction
-between an actual failed test and a test that could not be properly
-evaluated because of an external condition (such as a full file system
-or incorrect permissions).
+The TestCmd module provides pass_test(), fail_test(), and no_result() unbound
+methods that report test results for use with the Aegis change management
+system. These methods terminate the test immediately, reporting PASSED, FAILED
+or NO RESULT respectively and exiting with status 0 (success), 1 or 2
+respectively. This allows for a distinction between an actual failed test and a
+test that could not be properly evaluated because of an external condition (such
+as a full file system or incorrect permissions).
 """
 
 # Copyright 2000 Steven Knight
@@ -67,6 +65,7 @@
 import tempfile
 import traceback
 
+
 tempfile.template = 'testcmd.'
 
 _Cleanup = []
@@ -81,6 +80,7 @@
 
 sys.exitfunc = _clean
 
+
 def caller(tblist, skip):
     string = ""
     arr = []
@@ -98,12 +98,13 @@
         atfrom = "\tfrom"
     return string
 
-def fail_test(self = None, condition = 1, function = None, skip = 0):
+
+def fail_test(self=None, condition=True, function=None, skip=0):
     """Cause the test to fail.
 
- By default, the fail_test() method reports that the test FAILED
- and exits with a status of 1. If a condition argument is supplied,
- the test fails only if the condition is true.
+ By default, the fail_test() method reports that the test FAILED and exits
+ with a status of 1. If a condition argument is supplied, the test fails only
+ if the condition is true.
     """
     if not condition:
         return
@@ -124,15 +125,15 @@
 
     sys.stderr.write("FAILED test" + of + desc + sep + at + """
 in directory: """ + os.getcwd() )
-
     sys.exit(1)
 
-def no_result(self = None, condition = 1, function = None, skip = 0):
+
+def no_result(self=None, condition=True, function=None, skip=0):
     """Causes a test to exit with no valid result.
 
- By default, the no_result() method reports NO RESULT for the test
- and exits with a status of 2. If a condition argument is supplied,
- the test fails only if the condition is true.
+ By default, the no_result() method reports NO RESULT for the test and exits
+ with a status of 2. If a condition argument is supplied, the test fails only
+ if the condition is true.
     """
     if not condition:
         return
@@ -151,15 +152,15 @@
 
     at = caller(traceback.extract_stack(), skip)
     sys.stderr.write("NO RESULT for test" + of + desc + sep + at)
-
     sys.exit(2)
 
-def pass_test(self = None, condition = 1, function = None):
+
+def pass_test(self=None, condition=True, function=None):
     """Causes a test to pass.
 
- By default, the pass_test() method reports PASSED for the test
- and exits with a status of 0. If a condition argument is supplied,
- the test passes only if the condition is true.
+ By default, the pass_test() method reports PASSED for the test and exits
+ with a status of 0. If a condition argument is supplied, the test passes
+ only if the condition is true.
     """
     if not condition:
         return
@@ -168,8 +169,10 @@
     sys.stderr.write("PASSED\n")
     sys.exit(0)
 
-def match_exact(lines = None, matches = None):
- """
+
+def match_exact(lines=None, matches=None):
+ """Returns whether the given lists or strings containing lines separated
+ using newline characters contain exactly the same data.
     """
     if not type(lines) is ListType:
         lines = split(lines, "\n")
@@ -182,8 +185,11 @@
             return
     return 1
 
-def match_re(lines = None, res = None):
- """
+
+def match_re(lines=None, res=None):
+ """Given lists or strings contain lines separated using newline characters.
+ This function matches those lines one by one, interpreting the lines in the
+ res parameter as regular expressions.
     """
     if not type(lines) is ListType:
         lines = split(lines, "\n")
@@ -196,25 +202,20 @@
             return
     return 1
 
+
 class TestCmd:
- """Class TestCmd
+ """Class TestCmd.
     """
 
- def __init__(self, description = None,
- program = None,
- interpreter = None,
- workdir = None,
- subdir = None,
- verbose = 0,
- match = None,
- inpath = None):
+ def __init__(self, description=None, program=None, workdir=None,
+ subdir=None, verbose=False, match=None, inpath=None):
+
         self._cwd = os.getcwd()
         self.description_set(description)
         if inpath:
             self.program = program
         else:
             self.program_set(program)
- self.interpreter_set(interpreter)
         self.verbose_set(verbose)
         if not match is None:
             self.match_func = match
@@ -252,20 +253,20 @@
     def __repr__(self):
         return "%x" % id(self)
 
- def cleanup(self, condition = None):
- """Removes any temporary working directories for the specified
- TestCmd environment. If the environment variable PRESERVE was
- set when the TestCmd environment was created, temporary working
- directories are not removed. If any of the environment variables
- PRESERVE_PASS, PRESERVE_FAIL, or PRESERVE_NO_RESULT were set
- when the TestCmd environment was created, then temporary working
- directories are not removed if the test passed, failed, or had
- no result, respectively. Temporary working directories are also
- preserved for conditions specified via the preserve method.
-
- Typically, this method is not called directly, but is used when
- the script exits to clean up temporary working directories as
- appropriate for the exit status.
+ def cleanup(self, condition=None):
+ """Removes any temporary working directories for the specified TestCmd
+ environment. If the environment variable PRESERVE was set when the
+ TestCmd environment was created, temporary working directories are not
+ removed. If any of the environment variables PRESERVE_PASS,
+ PRESERVE_FAIL or PRESERVE_NO_RESULT were set when the TestCmd
+ environment was created, then temporary working directories are not
+ removed if the test passed, failed or had no result, respectively.
+ Temporary working directories are also preserved for conditions
+ specified via the preserve method.
+
+ Typically, this method is not called directly, but is used when the
+ script exits to clean up temporary working directories as appropriate
+ for the exit status.
         """
         if not self._dirlist:
             return
@@ -280,10 +281,10 @@
             for dir in list:
                 self.writable(dir, 1)
                 shutil.rmtree(dir, ignore_errors = 1)
-
+
         self._dirlist = []
         self.workdir = None
- os.chdir(self._cwd)
+ os.chdir(self._cwd)
         try:
             global _Cleanup
             _Cleanup.remove(self)
@@ -295,11 +296,7 @@
         """
         self.description = description
 
-# def diff(self):
-# """Diff two arrays.
-# """
-
- def fail_test(self, condition = 1, function = None, skip = 0):
+ def fail_test(self, condition=True, function=None, skip=0):
         """Cause the test to fail.
         """
         if not condition:
@@ -310,12 +307,6 @@
                   function = function,
                   skip = skip)
 
- def interpreter_set(self, interpreter):
- """Set the program to be used to interpret the program
- under test as a script.
- """
- self.interpreter = interpreter
-
     def match(self, lines, matches):
         """Compare actual and expected file contents.
         """
@@ -331,7 +322,7 @@
         """
         return match_re(lines, res)
 
- def no_result(self, condition = 1, function = None, skip = 0):
+ def no_result(self, condition=True, function=None, skip=0):
         """Report that the test could not be run.
         """
         if not condition:
@@ -342,7 +333,7 @@
                   function = function,
                   skip = skip)
 
- def pass_test(self, condition = 1, function = None):
+ def pass_test(self, condition=True, function=None):
         """Cause the test to pass.
         """
         if not condition:
@@ -351,11 +342,10 @@
         pass_test(self = self, condition = condition, function = function)
 
     def preserve(self, *conditions):
- """Arrange for the temporary working directories for the
- specified TestCmd environment to be preserved for one or more
- conditions. If no conditions are specified, arranges for
- the temporary working directories to be preserved for all
- conditions.
+ """Arrange for the temporary working directories for the specified
+ TestCmd environment to be preserved for one or more conditions. If no
+ conditions are specified, arranges for the temporary working directories
+ to be preserved for all conditions.
         """
         if conditions is ():
             conditions = ('pass_test', 'fail_test', 'no_result')
@@ -369,13 +359,12 @@
             program[0] = os.path.join(self._cwd, program[0])
         self.program = program
 
- def read(self, file, mode = 'rb'):
- """Reads and returns the contents of the specified file name.
- The file name may be a list, in which case the elements are
- concatenated with the os.path.join() method. The file is
- assumed to be under the temporary working directory unless it
- is an absolute path name. The I/O mode for the file may
- be specified; it must begin with an 'r'. The default is
+ def read(self, file, mode='rb'):
+ """Reads and returns the contents of the specified file name. The file
+ name may be a list, in which case the elements are concatenated with the
+ os.path.join() method. The file is assumed to be under the temporary
+ working directory unless it is an absolute path name. The I/O mode for
+ the file may be specified; it must begin with an 'r'. The default is
         'rb' (binary read).
         """
         if type(file) is ListType:
@@ -386,14 +375,10 @@
             raise ValueError, "mode must begin with 'r'"
         return open(file, mode).read()
 
- def run(self, program = None,
- interpreter = None,
- arguments = None,
- chdir = None,
- stdin = None):
- """Runs a test of the program or script for the test
- environment. Standard output and error output are saved for
- future retrieval via the stdout() and stderr() methods.
+ def run(self, program=None, arguments=None, chdir=None, stdin=None):
+ """Runs a test of the program or script for the test environment.
+ Standard output and error output are saved for future retrieval via the
+ stdout() and stderr() methods.
         """
         if chdir:
             oldcwd = os.getcwd()
@@ -407,12 +392,8 @@
             if program[0] != self.program[0] and not os.path.isabs(program[0]):
                 program[0] = os.path.join(self._cwd, program[0])
             cmd += program
- # if interpreter:
- # cmd = interpreter + " " + cmd
         else:
             cmd += self.program
- # if self.interpreter:
- # cmd = self.interpreter + " " + cmd
         if arguments:
             cmd += arguments.split(" ")
         if self.verbose:
@@ -420,7 +401,65 @@
         try:
             p = popen2.Popen3(cmd, 1)
         except AttributeError:
- (tochild, fromchild, childerr) = os.popen3(join(cmd, " "))
+ # We end up here in case the popen2.Popen3 class is not available
+ # (e.g. on Windows). We will be using the os.popen3() Python API
+ # which takes a string parameter and so needs its executable quoted
+ # in case its name contains spaces.
+ cmd[0] = '"' + cmd[0] + '"'
+ command_string = join(cmd, " ")
+ if ( os.name == 'nt' ):
+ # This is a workaround for a longstanding Python bug on Windows
+ # when using os.popen(), os.system() and similar functions to
+ # execute a command containing quote characters. The bug seems
+ # to be related to the quote stripping functionality used by the
+ # Windows cmd.exe interpreter when its /S is not specified.
+ #
+ # Cleaned up quote from the cmd.exe help screen as displayed on
+ # Windows XP SP2:
+ #
+ # 1. If all of the following conditions are met, then quote
+ # characters on the command line are preserved:
+ #
+ # - no /S switch
+ # - exactly two quote characters
+ # - no special characters between the two quote
+ # characters, where special is one of: &<>()@^|
+ # - there are one or more whitespace characters between
+ # the two quote characters
+ # - the string between the two quote characters is the
+ # name of an executable file.
+ #
+ # 2. Otherwise, old behavior is to see if the first character
+ # is a quote character and if so, strip the leading
+ # character and remove the last quote character on the
+ # command line, preserving any text after the last quote
+ # character.
+ #
+ # This causes some commands containing quotes not to be executed
+ # correctly. For example:
+ #
+ # "\Long folder name\aaa.exe" --name="Jurko" --no-surname
+ #
+ # would get its outermost quotes stripped and would be executed
+ # as:
+ #
+ # \Long folder name\aaa.exe" --name="Jurko --no-surname
+ #
+ # which would report an error about '\Long' not being a valid
+ # command.
+ #
+ # cmd.exe help seems to indicate it would be enough to add an
+ # extra space character in front of the command to avoid this
+ # but this does not work, most likely due to the shell first
+ # stripping all leading whitespace characters from the command.
+ #
+ # Solution implemented here is to quote the whole command in
+ # case it contains any quote characters. Note thought this will
+ # not work correctly should Python ever fix this bug.
+ # (01.05.2008.) (Jurko)
+ if command_string.find('"') != -1:
+ command_string = '"' + command_string + '"'
+ (tochild, fromchild, childerr) = os.popen3(command_string)
             if stdin:
                 if type(stdin) is ListType:
                     for line in stdin:
@@ -429,7 +468,7 @@
                     tochild.write(stdin)
             tochild.close()
             self._stdout.append(fromchild.read())
- self._stderr.append(childerr.read())
+ self._stderr.append(childerr.read())
             fromchild.close()
             self.status = childerr.close()
             if not self.status:
@@ -447,20 +486,19 @@
             self._stdout.append(p.fromchild.read())
             self._stderr.append(p.childerr.read())
             self.status = p.wait()
-
+
         if self.verbose:
             sys.stdout.write(self._stdout[-1])
             sys.stderr.write(self._stderr[-1])
-
+
         if chdir:
             os.chdir(oldcwd)
 
- def stderr(self, run = None):
- """Returns the error output from the specified run number.
- If there is no specified run number, then returns the error
- output of the last run. If the run number is less than zero,
- then returns the error output from that many runs back from the
- current run.
+ def stderr(self, run=None):
+ """Returns the error output from the specified run number. If there is
+ no specified run number, then returns the error output of the last run.
+ If the run number is less than zero, then returns the error output from
+ that many runs back from the current run.
         """
         if not run:
             run = len(self._stderr)
@@ -471,12 +509,11 @@
             return ''
         return self._stderr[run]
 
- def stdout(self, run = None):
- """Returns the standard output from the specified run number.
- If there is no specified run number, then returns the standard
- output of the last run. If the run number is less than zero,
- then returns the standard output from that many runs back from
- the current run.
+ def stdout(self, run=None):
+ """Returns the standard output from the specified run number. If there
+ is no specified run number, then returns the standard output of the last
+ run. If the run number is less than zero, then returns the standard
+ output from that many runs back from the current run.
         """
         if not run:
             run = len(self._stdout)
@@ -488,11 +525,11 @@
         return self._stdout[run]
 
     def subdir(self, *subdirs):
- """Create new subdirectories under the temporary working
- directory, one for each argument. An argument may be a list,
- in which case the list elements are concatenated using the
- os.path.join() method. Subdirectories multiple levels deep
- must be created using a separate argument for each level:
+ """Create new subdirectories under the temporary working directory, one
+ for each argument. An argument may be a list, in which case the list
+ elements are concatenated using the os.path.join() method.
+ Subdirectories multiple levels deep must be created using a separate
+ argument for each level:
 
                 test.subdir('sub', ['sub', 'dir'], ['sub', 'dir', 'ectory'])
 
@@ -514,11 +551,10 @@
         return count
 
     def unlink (self, file):
- """Unlinks the specified file name.
- The file name may be a list, in which case the elements are
- concatenated with the os.path.join() method. The file is
- assumed to be under the temporary working directory unless it
- is an absolute path name.
+ """Unlinks the specified file name. The file name may be a list, in
+ which case the elements are concatenated using the os.path.join()
+ method. The file is assumed to be under the temporary working directory
+ unless it is an absolute path name.
         """
         if type(file) is ListType:
             file = apply(os.path.join, tuple(file))
@@ -526,16 +562,14 @@
             file = os.path.join(self.workdir, file)
         os.unlink(file)
 
-
     def verbose_set(self, verbose):
         """Set the verbose level.
         """
         self.verbose = verbose
 
     def workdir_set(self, path):
- """Creates a temporary working directory with the specified
- path name. If the path is a null string (''), a unique
- directory name is created.
+ """Creates a temporary working directory with the specified path name.
+ If the path is a null string (''), a unique directory name is created.
         """
 
         if os.path.isabs(path):
@@ -554,9 +588,9 @@
                     _Cleanup.append(self)
                 # We'd like to set self.workdir like this:
                 # self.workdir = path
- # But symlinks in the path will report things
- # differently from os.getcwd(), so chdir there
- # and back to fetch the canonical path.
+ # But symlinks in the path will report things differently from
+ # os.getcwd(), so chdir there and back to fetch the canonical
+ # path.
                 cwd = os.getcwd()
                 os.chdir(path)
                 self.workdir = os.getcwd()
@@ -565,16 +599,16 @@
                 self.workdir = None
 
     def workpath(self, *args):
- """Returns the absolute path name to a subdirectory or file
- within the current temporary working directory. Concatenates
- the temporary working directory name with the specified
- arguments using the os.path.join() method.
+ """Returns the absolute path name to a subdirectory or file within the
+ current temporary working directory. Concatenates the temporary working
+ directory name with the specified arguments using the os.path.join()
+ method.
         """
         return apply(os.path.join, (self.workdir,) + tuple(args))
 
     def writable(self, top, write):
- """Make the specified directory tree writable (write == 1)
- or not (write == None).
+ """Make the specified directory tree writable (write == 1) or not
+ (write == None).
         """
 
         def _walk_chmod(arg, dirname, names):
@@ -598,16 +632,15 @@
         try:
             os.path.walk(top, _walk_chmod, f)
         except:
- pass # ignore any problems changing modes
+ pass # Ignore any problems changing modes.
 
- def write(self, file, content, mode = 'wb'):
- """Writes the specified content text (second argument) to the
- specified file name (first argument). The file name may be
- a list, in which case the elements are concatenated with the
- os.path.join() method. The file is created under the temporary
- working directory. Any subdirectories in the path must already
- exist. The I/O mode for the file may be specified; it must
- begin with a 'w'. The default is 'wb' (binary write).
+ def write(self, file, content, mode='wb'):
+ """Writes the specified content text (second argument) to the specified
+ file name (first argument). The file name may be a list, in which case
+ the elements are concatenated using the os.path.join() method. The file
+ is created under the temporary working directory. Any subdirectories in
+ the path must already exist. The I/O mode for the file may be specified;
+ it must begin with a 'w'. The default is 'wb' (binary write).
         """
         if type(file) is ListType:
             file = apply(os.path.join, tuple(file))

Modified: branches/proto/v4/tools/build/v2/test/rebuilds.py
==============================================================================
--- branches/proto/v4/tools/build/v2/test/rebuilds.py (original)
+++ branches/proto/v4/tools/build/v2/test/rebuilds.py 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -35,7 +35,7 @@
 t.expect_addition('bar')
 t.expect_nothing_more()
 
-t.wait_for_time_change()
+t.wait_for_time_change_since_last_build()
 t.run_build_system('-ffile.jam foo')
 t.expect_touch('bar')
 t.expect_addition('foo')

Modified: branches/proto/v4/tools/build/v2/test/test_all.py
==============================================================================
--- branches/proto/v4/tools/build/v2/test/test_all.py (original)
+++ branches/proto/v4/tools/build/v2/test/test_all.py 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -16,13 +16,13 @@
     'BOOST_ROOT','BOOST_BUILD_PATH','JAM_TOOLSET','BCCROOT',
     'MSVCDir','MSVC','MSVCNT','MINGW','watcom'
     ):
-
+
     try:
         del os.environ[s]
     except:
         pass
 
-BoostBuild.set_defer_annotations(1)
+BoostBuild.set_defer_annotations(1)
 
 def run_tests(critical_tests, other_tests):
     """Runs first critical tests and then other_tests.
@@ -59,7 +59,7 @@
         BoostBuild.flush_annotations();
         pass_count = pass_count + 1
         sys.stdout.flush() # makes testing under emacs more entertaining.
-
+
     # Erase the file on success
     if failures_count == 0:
         open('test_results.txt', 'w')
@@ -69,7 +69,7 @@
     PASS: %d
     FAIL: %d
     """ % (pass_count, failures_count)
-
+
 
 def last_failed_test():
     "Returns the name of last failed test or None"
@@ -87,7 +87,7 @@
     except ValueError:
         return tests
 
-
+
 critical_tests = ["unit_tests", "module_actions", "startup_v1", "startup_v2"]
 
 critical_tests += ["core_d12", "core_typecheck", "core_delete_module",
@@ -167,6 +167,7 @@
           "example_make",
           "remove_requirement",
           "free_features_request",
+ "sort_rule"
           ]
 
 if os.name == 'posix':
@@ -193,7 +194,7 @@
     tests.append("example_customization")
     # Requires gettext tools.
     tests.append("example_gettext")
-
+
 else:
     print 'Note: skipping extra tests'
 

Modified: branches/proto/v4/tools/build/v2/test/test_system.html
==============================================================================
--- branches/proto/v4/tools/build/v2/test/test_system.html (original)
+++ branches/proto/v4/tools/build/v2/test/test_system.html 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -12,14 +12,14 @@
 <style type="text/css">
         hr { color: black }
         p.revision { text-align: right; font-style: italic }
- pre.code { margin-left: 2em }
- pre.example { margin-left: 2em; border: solid black thin }
+ pre.code { margin-left: 2em }
+ pre.example { margin-left: 2em; border: solid black thin }
         pre.output { margin-left: 2em }
         img.banner { border: 0; float: left }
         h1 { text-align: right }
         br.clear { clear: left }
         div.attention { color: red }
-
+
 </style>
   </head>
 
@@ -34,6 +34,12 @@
     <dl class="page-index">
       <dt>Introduction for users</dt>
 
+ <dd>
+ <dl class="page-index">
+ <dt>Command line options</dt>
+ </dl>
+ </dd>
+
       <dt>Introduction for developers</dt>
 
       <dd>
@@ -41,8 +47,8 @@
           <dt><a href="#sec-intro-changing">Changing the working
           directory</a></dt>
 
- <dt><a href="#sec-intro-examining">Examining the working directory
- and changing it</a></dt>
+ <dt><a href="#sec-intro-examining">Examining the working directory and
+ changing it</a></dt>
 
           <dt>Test result</dt>
         </dl>
@@ -87,14 +93,13 @@
 
     <h2><a name="sec-intro">Introduction for users</a></h2>
 
- <p>The testing system for Boost.Build is a small set of Python modules
- and scripts for automatically testing user-obversable behaviour. It uses
- components from testing systems of <a href=
- "http://www.scons.org">Scons</a> and <a href=
- "http://subversion.tigris.org">Subversion</a>, together with some
- additional functionality.</p>
+ <p>The testing system for Boost.Build is a small set of Python modules and
+ scripts for automatically testing user-obversable behaviour. It uses
+ components from testing systems of Scons
+ and Subversion, together with
+ some additional functionality.</p>
 
- <p>To run the tests you'd need:</p>
+ <p>To run the tests you need to:</p>
 
     <ol>
       <li>Get the source tree of Boost.Build (located at <tt>tools/build</tt>
@@ -115,24 +120,46 @@
       for testing.</li>
     </ol>
 
- <p>When all is done, you can run the tests with</p>
+ <p>When all is set, you can run all the tests using the <tt>test_all.py</tt>
+ script or you can run a specific test by starting its Python script
+ directly.</p>
+
+ <p>Examples:</p>
+
 <pre class="code">
 python test_all.py
+python generators_test.py
 </pre>
 
- <p>which will use the default toolset, or you can specify toolset on the
- command line, for example:</p>
+ <p>If everything is OK, you will see a list of passed tests. Otherwise, a
+ failure will be reported.</p>
+
+ <h3><a name="sec-command-line-options">Command line options</a></h3>
+
+ <p>Test scripts will use the toolset you configured to be the default or
+ you can specify a specific one on the command line:</p>
+
 <pre class="code">
 python test_all.py borland
+python generators_test.py msvc-7.1
 </pre>
 
- <p>If everything's OK, you'll see a list of passed tests. Otherwise, a
- failure will be reported.</p>
+ <p>Other test script flags you can specify on the command line are:</p>
 
- <p>It is possible to run a specific test, for example:</p>
-<pre class="code">
-python generators_test.py
-</pre>
+ <ul>
+ <li><tt>--default-bjam</tt> -- By default the test system will use the
+ Boost Jam executable found built in its default development build
+ location. This option makes it use the default one available on your
+ system, i.e. the one found in the system path.</li>
+
+ <li><tt>--preserve</tt> -- In case of a failed test its working
+ directory will be copied to the "failed_test" directory under the
+ current directory.</li>
+
+ <li><tt>--verbose</tt> -- Makes the test system and the run build system
+ display additional output. Note though that this may cause tests that
+ check the build system output to fail.</li>
+ </ul>
 
     <h2><a name="sec-developers">Introduction for developers</a></h2>
 
@@ -144,28 +171,28 @@
       <li>For an interpreted language like Jam, without any static checks,
       testing is simply the only sefeguard we can have.</li>
 
- <li>Good tests allow to change internal design much more safely, and we
- didn't nailed everything down yet.</li>
+ <li>Good tests allow us to change internal design much more safely, and we
+ have not gotten everything nailed down yet.</li>
     </ul>
 
     <p>Adding a new test is simple:</p>
 
     <ol>
       <li>Go to <tt>$boost_build_root/test/test_all.py</tt> and add new test
- name to the list at the end of file. Suppose the test name is
- "hello".</li>
+ name to the list at the end of the file. Suppose the test name is "hello".
+ </li>
 
- <li>Add a new python module, in this example "hello.py", to do actual
+ <li>Add a new python module, in this example "hello.py", to do the actual
       testing.</li>
     </ol>
 
     <p>The module, in general will perform these basic actions:</p>
 
     <ol>
- <li>Setting the initial working directory state</li>
+ <li>Set up the initial working directory state</li>
 
       <li>
- Running the build system and checking:
+ Run the build system and check the results:
 
         <ol>
           <li>generated output,</li>
@@ -176,10 +203,10 @@
         </ol>
       </li>
 
- <li>Adding, removing or touching files, or changing their content and
- then repeating the previous step, until satisfied.</li>
+ <li>Add, remove or touch files or change their content and then repeat
+ the previous step until satisfied.</li>
 
- <li>Cleaning up</li>
+ <li>Clean up</li>
     </ol>
 
     <p>The "hello.py" module might contain:</p>
@@ -204,12 +231,12 @@
 
 t.run_build_system()
 
-# First, create a list of three pathnames
+# First, create a list of three pathnames.
 file_list = List("bin/$toolset/debug/") * List("hello.exe hello.obj")
 # Second, assert that those files were added as result of the last build system invocation.
 t.expect_addition(file_list)
 
-# Invoke the build system once again
+# Invoke the build system once again.
 t.run_build_system("clean")
 # Check if the files added previously were removed.
 t.expect_removal(file_list)
@@ -221,18 +248,18 @@
     <p>The <tt>test</tt> directory contains a file "template.py" which can be
     used as a start for your own tests.</p>
 
- <p>Overview of the most important methods of class
- <tt>TestBoostBuild</tt> follows.</p>
+ <p>Overview of the most important methods of class <tt>Tester</tt> follows.
+ </p>
 
     <h3><a name="sec-intro-changing">Changing the working directory</a></h3>
 
- <p>The class <tt>TestBoostBuild</tt> creates a temporary directory in its
+ <p>The class <tt>Tester</tt> creates a temporary directory in its
     constructor and changes to that directory. It can be modified by calling
     these methods:</p>
 
     <ul>
- <li><tt>set_tree</tt> -- sets the content of the working directory to
- be equal to the content of the specified directory. This method is
+ <li><tt>set_tree</tt> -- sets the content of the working directory to be
+ equal to the content of the specified directory. This method is
       preferrable when directory tree for testing is large.</li>
 
       <li><tt>write</tt> -- sets the content of file in a working directory.
@@ -245,28 +272,27 @@
     <h3><a name="sec-intro-examining">Examining the working directory and
     changing it</a></h3>
 
- <p>The method <tt>read</tt>, inherited from the <tt>TestCmd</tt> class,
- can be used to read any file in the working directory and check its
- content. <tt>TestBoostBuild</tt> adds another method for tracking
- changes. Whenever build system is run (via <tt>run_build_system</tt>),
- the state of working dir before and after running is recorded. In
- addition, difference between the two states -- i.e. lists of files that
- were added, removed, modified or touched -- is stored in two member
- variables, <tt>tree_difference</tt> and
- <tt>unexpected_difference</tt>.</p>
-
- <p>After than, the test author may specify that some change is expected,
- for example, by calling <tt>expect_addition("foo")</tt>. This call will
- check if the file was indeed added, and if so, will remove its name from
- the list of added files in <tt>unexpected_difference</tt>. Likewise, it's
- possible to specify that some changes are not interesting, for example a
- call <tt>ignore("*.obj")</tt> will just remove every files with ".obj"
+ <p>The method <tt>read</tt>, inherited from the <tt>TestCmd</tt> class, can
+ be used to read any file in the working directory and check its content.
+ <tt>Tester</tt> adds another method for tracking changes. Whenever the build
+ system is run (using <a href="#method-run_build_system"><tt>run_build_system
+ </tt></a>), the working dir state before and after running is recorded. In
+ addition, difference between the two states -- i.e. lists of files that were
+ added, removed, modified or touched -- are stored in two member variables -
+ <tt>tree_difference</tt> and <tt>unexpected_difference</tt>.</p>
+
+ <p>After than, the test author may specify that some change is expected, for
+ example, by calling <tt>expect_addition("foo")</tt>. This call will check if
+ the file was indeed added, and if so, will remove its name from the list of
+ added files in <tt>unexpected_difference</tt>. Likewise, it is possible to
+ specify that some changes are not interesting, for example a call to
+ <tt>ignore("*.obj")</tt> will just remove every file with the ".obj"
     extension from <tt>unexpected_difference</tt>.</p>
 
     <p>When test has finished with expectations and ignoring, the member
- <tt>unexpected_difference</tt> will contain the list of all changes not
- yet accounted for. It is possible to assure that this list is empty by
- calling <tt>expect_nothing_more</tt> member function.</p>
+ <tt>unexpected_difference</tt> will contain the list of all changes not yet
+ accounted for. It is possible to assure that this list is empty by calling
+ the <tt>expect_nothing_more</tt> member function.</p>
 
     <h3><a name="sec-intro-results">Test result</a></h3>
 
@@ -277,24 +303,74 @@
     <tt>pass_test</tt> and <tt>fail_test</tt> are used to explicitly give the
     test outcome.</p>
 
- <p>Typically, after test termination, the working directory is erased. To
- debug a failed test, you should add "--preserve" option when invoking
- test. On failure, the working directory will be copied to "failed_test"
- directory in the current dir.</p>
+ <p>Typically, after test termination, the working directory is erased. See
+ the "--preserve" command line option
+ for information on how to preserve the working directory content for failed
+ tests for debugging purposes.</p>
 
     <h2 id="sec-reference">Reference documentation</h2>
 
     <p>The test system is composed of class <tt>Tester</tt>, derived form
- <tt>TestCmd.TestCmd</tt>, and helper class <tt>List</tt>. The methods of
- <tt>Tester</tt>, and the class <tt>List</tt> are described below.</p>
+ <tt>TestCmd.TestCmd</tt>, and helper class <tt>List</tt>. <tt>Tester</tt>
+ and <tt>List</tt> methods are described below.</p>
 
- <p>The documentation frequently refer to filename. In all cases, files
- are specified in unix style: a sequence of components, separated by "/".
- This is true on all platforms. In some contexts, a list of files is
- allowed. In that case any object with sequence interface is allowed.</p>
+ <p>The documentation frequently refers to <tt>filename</tt>. In all cases,
+ files are specified in unix style: a sequence of components, separated by
+ "/". This is true on all platforms. In some contexts a list of files is
+ allowed. In those cases any object with a sequence interface is allowed.</p>
+
+ <h3><a name="method-__init__">Method <tt>__init__(self, arguments="",
+ executable="bjam", match=TestCmd.match_exact, boost_build_path=None,
+ translate_suffixes=True, pass_toolset=True, use_test_config=True,
+ ignore_toolset_requirements=True, workdir="", **keywords)</tt></a></h3>
 
- <h3><a name="method-__init__">Method <tt>__init__(self, workdir='',
- arguments='', executable='bjam')</tt></a></h3>
+ <p><b>Optional arguments:</b></p>
+
+ <ul>
+ <li><tt>arguments</tt>
+ -- Arguments passed to the run executable.</li>
+ <li><tt>executable</tt>
+ -- Name of the executable to invoke.</li>
+ <li><tt>match</tt>
+ -- Function to use for compating actual and expected file contents.
+ </li>
+ <li><tt>boost_build_path</tt>
+ -- Boost build path to be passed to the run executable.</li>
+ <li><tt>translate_suffixes</tt>
+ -- Whether to update suffixes on the the file names passed from the
+ test script so they match those actually created by the current
+ toolset. For example, static library files are specified by using
+ the .lib suffix but when the 'gcc' toolset is used it actually
+ creates them using the .a suffix.</li>
+ <li><tt>pass_toolset</tt>
+ -- Whether the test system should pass the specified toolset to the
+ run executable.</li>
+ <li><tt>use_test_config</tt>
+ -- Whether the test system should tell the run executable to read in
+ the test_config.jam configuration file.</li>
+ <li><tt>ignore_toolset_requirements</tt>
+ -- Whether the test system should tell the run executable to ignore
+ toolset requirements.</li>
+ <li><tt>workdir</tt>
+ -- Indicates an absolute directory where the test will be run from.
+ </li>
+ </ul>
+
+ <p><b>Optional arguments inherited from the base class:</b></p>
+
+ <ul>
+ <li><tt>description</tt>
+ -- Test description string displayed in case of a failed test.</li>
+ <li><tt>subdir</tt>
+ -- List of subdirectories to automatically create under the working
+ directory. Each subdirectory needs to be specified separately
+ parent coming before its child.</li>
+ <li><tt>verbose</tt>
+ -- Flag that may be used to enable more verbose test system output.
+ Note that it does not also enable more verbose build system output
+ like the <a href="#sec-command-line-options">"--verbose" command
+ line option</a> does.</li>
+ </ul>
 
     <p><b>Effects:</b></p>
 
@@ -302,20 +378,23 @@
       <li>Remembers the current working directory in member
       <tt>original_workdir</tt>.</li>
 
- <li>Determines the location of executable (<code>bjam</code> by
+ <li>Determines the location of the executable (<code>bjam</code> by
       default) and build system files, assuming that the current directory is
       <tt>tools/build/test</tt>. Formulates jam invocation command, which
- will include explicit setting for <tt>BOOST_BUILD_PATH</tt> variable
+ will include explicit setting for the <tt>BOOST_BUILD_PATH</tt> variable
       and arguments passed to this methods, if any. This command will be used
- by subsequent invocation of <a href=
- "#method-run_build_system"><tt>run_build_system</tt></a>. Finally,
- initializes the base class.</li>
+ by subsequent invocation of <a href="#method-run_build_system"><tt>
+ run_build_system</tt></a>. Finally, initializes the base class.</li>
 
- <li>Changes current working dir to the temporary working directory
- created by the base constructor.</li>
+ <li>Changes the current working directory to the temporary working
+ directory created by the base constructor.</li>
 
- <li>If you want to run a test in a existing directory, pass it to
+ <li>If you want to run a test in an existing directory, pass it as
       <tt>workdir</tt>.</li>
+
+ <li> Most parameters passed to this constructor function may be overruled
+ for each specific test system run using <a href=
+ "#method-run_build_system"><tt>run_build_system</tt></a> parameters.
     </ol>
 
     <h3><a name="method-set_tree">Method <tt>set_tree(self,
@@ -348,13 +427,14 @@
 
     <p><b>Effects:</b></p>
 
- <p>Sets the access and modification times for all files in <tt>names</tt>
- to the current time. All the elements in <tt>names</tt> should be
- relative paths.</p>
+ <p>Sets the access and modification times for all files in <tt>names</tt> to
+ the current time. All the elements in <tt>names</tt> should be relative
+ paths.</p>
 
     <h3><a name="method-run_build_system">Method <tt>run_build_system(self,
- subdir='', extra_args='', stdout=None, stderr='', status=0,
- **kw)</tt></a></h3>
+ extra_args="", subdir="", stdout=None, stderr="", status=0, match=None,
+ pass_toolset=None, use_test_config=None, ignore_toolset_requirements=None,
+ expected_duration=None, **kw)</tt></a></h3>
 
     <p><b>Effects:</b></p>
 
@@ -375,18 +455,18 @@
       invocation with values to appropriate parameters, if they are not
       <tt>None</tt>. If any difference is found, the test fails.</li>
 
- <li>
- <p>Stores the new state of the working directory in
- <tt>self.tree</tt>. Computes the difference between previous and
- current trees and store them in variables
- <tt>self.tree_difference</tt> and
- <tt>self.unexpected_difference</tt>.</p>
-
- <p>Both variables are instances of class
- <tt>tree.Trees_different</tt>, which have four attributes:
- <tt>added_files</tt>, <tt>removed_files</tt>, <tt>modified_files</tt>
- and <tt>touched_files</tt>. Each is a list of strings.</p>
- </li>
+ <li>If the <tt>expected_duration</tt> parameter is specified then it
+ represents the maximal allowed time in seconds for the test to run. The
+ test will be marked as failed if its duration is greater than the given
+ <tt>expected_duration</tt> parameter value.</li>
+
+ <li>Stores the new state of the working directory in <tt>self.tree</tt>.
+ Computes the difference between previous and current trees and stores them
+ in variables <tt>self.tree_difference</tt> and
+ <tt>self.unexpected_difference</tt>. Both variables are instances of class
+ <tt>tree.Trees_different</tt>, which have four attributes:
+ <tt>added_files</tt>, <tt>removed_files</tt>, <tt>modified_files</tt> and
+ <tt>touched_files</tt>. Each is a list of strings.</p></li>
     </ol>
 
     <h3><a name="method-read">Method <tt>read(self, name)</tt></a></h3>
@@ -396,104 +476,95 @@
     <p>Read the specified file and returns it content. Raises an exception is
     the file is absent.</p>
 
- <h3><a name="method-read_and_strip">Method <tt>read_and_strip(self,
- name)</tt></a></h3>
+ <h3><a name="method-read_and_strip">Method <tt>read_and_strip(self, name)
+ </tt></a></h3>
 
     <p><b>Effects:</b></p>
 
- <p>Read the specified file and returns it content, after removing
- trailing whitespace from every line. Raises an exception is the file is
- absent.</p>
+ <p>Read the specified file and returns it content, after removing trailing
+ whitespace from every line. Raises an exception is the file is absent.</p>
 
     <p><b>Rationale:</b></p>
 
- <p>Althought this method is questionable, there are a lot of cases when
- jam or shells it uses insert spaces. It seems that introducing this
- method is much simpler than dealing with all those cases.</p>
-
- <h3><a name="methods-expectations">Methods for declaring
- expectations</a></h3>
-
- <p>Accordingly to the number of changes kinds that are detected, there
- are four methods that specify that test author expects a specific change
- to occur. They check <tt>self.unexpected_difference</tt>, and if the
- change is present there, it is removed. Otherwise, test fails.</p>
+ <p>Althought this method is questionable, there are a lot of cases when jam
+ or shells it uses insert spaces. It seems that introducing this method is
+ much simpler than dealing with all those cases.</p>
+
+ <h3><a name="methods-expectations">Methods for declaring expectations</a>
+ </h3>
+
+ <p>Accordingly to the number of changes kinds that are detected, there are
+ four methods that specify that test author expects a specific change to
+ occur. They check <tt>self.unexpected_difference</tt>, and if the change is
+ present there, it is removed. Otherwise, test fails.</p>
 
     <p>Each method accepts a list of names. Those names use <tt>/</tt> path
- separator on all systems. Additionaly, the test system translates
- suffixes appropriately. For the test to be portable, suffixes should use
- Windows convention: <tt>exe</tt> for executables, <tt>dll</tt> for
- dynamic libraries and <tt>lib</tt> for static libraries. Lastly, the
- string "$toolset" in file names is replaced by the name of tested
- toolset.</p>
+ separator on all systems. Additionaly, the test system translates suffixes
+ appropriately. For the test to be portable, suffixes should use Windows
+ convention: <tt>exe</tt> for executables, <tt>dll</tt> for dynamic libraries
+ and <tt>lib</tt> for static libraries. Lastly, the string "$toolset" in file
+ names is replaced by the name of tested toolset.</p>
 
     <p><b>Note:</b> The <tt>List</tt> helper class might be useful to create
     lists of names.</p>
 
- <p><b>Note:</b> The file content can be examined using
+ <p><b>Note:</b> The file content can be examined using the
     <tt>TestCmd.read</tt> function.</p>
 
     <p>The members are:</p>
 
     <ul>
       <li>expect_addition</li>
-
       <li>expect_removal</li>
-
       <li>expect_modification</li>
-
       <li>expect_nothing</li>
     </ul>
 
     <p>Note that <tt>expect_modification</tt> is used to check that a either
- file content or timestamp has changed. The rationale is that some
- compilers change content even if sources does not change, and it's easier
- to have a method which checks for both content and time changes.</p>
+ file content or timestamp has changed. The rationale is that some compilers
+ change content even if sources does not change, and it's easier to have a
+ method which checks for both content and time changes.</p>
 
- <p>There's also a member <tt>expect_nothing_more</tt>, which checks that
- all the changes are either expected or ignored, in other words that
+ <p>There's also a member <tt>expect_nothing_more</tt>, which checks that all
+ the changes are either expected or ignored, in other words that
     <tt>unexpected_difference</tt> is empty by now.</p>
 
- <p>Lastly, there's a method to compare file content with expected
- content:</p>
- <tt>expect_content(self, name, content, exact=0)</tt>
+ <p>Lastly, there's a method to compare file content with expected content:
+ </p>
+ <tt>expect_content(self, name, content, exact=0)</tt>
 
- <p>The method fails the test if the content of file identified by 'name'
- is different from 'content'. If 'exact' is true, the file content is used
+ <p>The method fails the test if the content of file identified by 'name' is
+ different from 'content'. If 'exact' is true, the file content is used
     as-is, otherwise, two transformations are applied:</p>
 
     <ul>
       <li>The <tt>read_and_strip</tt> method is used to read the file, which
       removes trailing whitespace</li>
 
- <li>Each backslash in the file content is converted to forward
- slash.</li>
+ <li>Each backslash in the file content is converted to forward slash.</li>
     </ul>
 
     <h3><a name="methods-ignoring">Methods for ignoring changes</a></h3>
 
     <p>There are five methods which ignore changes made to the working tree.
- They silently remove elements from <tt>self.unexpected_difference</tt>,
- and don't generate error if element is not found. They accept shell style
+ They silently remove elements from <tt>self.unexpected_difference</tt>, and
+ don't generate error if element is not found. They accept shell style
     wildcard.</p>
 
     <p>The following methods correspond to four kinds of changes:</p>
 
     <ul>
       <li>ignore_addition(self, wildcard)</li>
-
       <li>ignore_removal(self, wildcard)</li>
-
       <li>ignore_modification(self, wildcard)</li>
-
       <li>ignore_touch(self, wilcard)</li>
     </ul>
 
- <p>The method <tt>ignore(self, wildcard)</tt> ignores all the changes
- made to files that match a wildcard.</p>
+ <p>The method <tt>ignore(self, wildcard)</tt> ignores all the changes made
+ to files that match a wildcard.</p>
 
- <h3><a name="methods-result">Methods for explicitly specifying
- results</a></h3>
+ <h3><a name="methods-result">Methods for explicitly specifying results</a>
+ </h3>
 
     <h4>Method <tt>pass_test(self, condition=1)</tt></h4>
 
@@ -503,51 +574,46 @@
 
     <h4>Method <tt>fail_test(self, condition=1)</tt></h4>
 
- <p><b>Effects:</b> Cause the test to fail if <tt>condition</tt> is
- true.</p>
+ <p><b>Effects:</b> Cause the test to fail if <tt>condition</tt> is true.</p>
 
     <h3><a name="class-list">Helper class <tt>List</tt></a></h3>
- The class has sequence interface and two additional methods.
+ The class has sequence interface and two additional methods.
 
     <h4>Method <tt>__init__(self, string)</tt></h4>
 
- <p><b>Effects:</b> Splits the string on unescaped spaces and tabs. The
- split components can further be retrieved using standard sequence
- access.</p>
+ <p><b>Effects:</b> Splits the string on unescaped spaces and tabs. The split
+ components can further be retrieved using standard sequence access.</p>
 
     <h4>Method <tt>__mul__(self, other)</tt></h4>
 
- <p><b>Effects:</b> Returns an <tt>List</tt> instance, which elements are
- all possible concatenations of two string, first of which is from
- <tt>self</tt>, and second of which is from <tt>other</tt>.</p>
+ <p><b>Effects:</b> Returns an <tt>List</tt> instance, which elements are all
+ possible concatenations of two string, first of which is from <tt>self</tt>,
+ and second of which is from <tt>other</tt>.</p>
 
     <p>The class also defines <tt>__str__</tt> and <tt>__repr__</tt> methods.
- Finally, there's <tt>__coerce__</tt> method which allows to convert
- strings to instances of <tt>List</tt>.</p>
+ Finally, there's <tt>__coerce__</tt> method which allows to convert strings
+ to instances of <tt>List</tt>.</p>
 
     <p><b>Example:</b></p>
 <pre>
     l = "a b" * List("c d")
     for e in l:
- print e
-
+ print e
 </pre>
 
- <p>will output</p>
+ <p>will output:</p>
 <pre>
     ac
     ad
     bc
     bd
-
+
 </pre>
     <hr>
-
- <p class="revision">Last modified: Mar 11, 2005</p>
-
- <p>&copy; Copyright Vladimir Prus 2002, 2003, 2004, 2005.
+ <p class="revision">Last modified: May 02, 2008</p>
+ <p>&copy; Copyright Vladimir Prus 2002, 2003, 2004, 2005.<br>
+ &copy; Copyright Jurko Gospodnetic 2008.<br>
     Distributed under the Boost Software License, Version 1.0.
     (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)</p>
   </body>
 </html>
-

Modified: branches/proto/v4/tools/build/v2/test/unit_test.py
==============================================================================
--- branches/proto/v4/tools/build/v2/test/unit_test.py (original)
+++ branches/proto/v4/tools/build/v2/test/unit_test.py 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -5,18 +5,17 @@
 # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 
 # Test the unit_test rule
-from BoostBuild import Tester, List
+import BoostBuild
 
-t = Tester()
+t = BoostBuild.Tester()
 
-# Create the needed files
-t.write("project-root.jam", """
+# Create the needed files.
+t.write("Jamroot.jam", """
 using testing ;
-""")
-t.write("Jamfile", """
 lib helper : helper.cpp ;
 unit-test test : test.cpp : <library>helper ;
 """)
+
 t.write("test.cpp", """
 void helper();
 int main()
@@ -37,7 +36,4 @@
 t.run_build_system("link=static")
 t.expect_addition("bin/$toolset/debug/link-static/test.passed")
 
-
-
-
 t.cleanup()

Modified: branches/proto/v4/tools/build/v2/tools/builtin.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/tools/builtin.jam (original)
+++ branches/proto/v4/tools/build/v2/tools/builtin.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -42,6 +42,7 @@
 
 # Translates from bjam current OS to the os tags used in host-os and target-os,
 # i.e. returns the running host-os.
+#
 local rule default-host-os ( )
 {
     local host-os ;
@@ -278,6 +279,7 @@
 #
 # Lastly, makes appropriate value of 'variant' property expand to the full
 # property set.
+#
 rule variant ( name # Name of the variant
     : parents-or-properties * # Specifies parent variants, if
                                # 'explicit-properties' are given, and
@@ -443,15 +445,14 @@
 
 scanner.register c-scanner : include ;
 
-# It most cases where a CPP file or a H file is a source of some action,
-# we should rebuild the result if any of files included by CPP/H
-# are changed. One case when this is not needed is installation,
-# which is handled specifically.
+# It most cases where a CPP file or a H file is a source of some action, we
+# should rebuild the result if any of files included by CPP/H are changed. One
+# case when this is not needed is installation, which is handled specifically.
 type.set-scanner CPP : c-scanner ;
 type.set-scanner C : c-scanner ;
-# One case where scanning of H/HPP files is necessary is PCH generation --
-# if any header included by HPP being precompiled changes, we need to
-# recompile the header.
+# One case where scanning of H/HPP files is necessary is PCH generation -- if
+# any header included by HPP being precompiled changes, we need to recompile the
+# header.
 type.set-scanner H : c-scanner ;
 type.set-scanner HPP : c-scanner ;
 
@@ -459,6 +460,7 @@
 # The generator class for libraries (target type LIB). Depending on properties
 # it will request building of the appropriate specific library type --
 # -- SHARED_LIB, STATIC_LIB or SHARED_LIB.
+#
 class lib-generator : generator
 {
     rule __init__ ( * : * )
@@ -515,6 +517,7 @@
 
 # The implementation of the 'lib' rule. Beyond standard syntax that rule allows
 # simplified: "lib a b c ;".
+#
 rule lib ( names + : sources * : requirements * : default-build *
     : usage-requirements * )
 {
@@ -640,6 +643,7 @@
 
     # For all virtual targets for the same dependency graph as self, i.e. which
     # belong to the same main target, add their directories to the include path.
+ #
     rule adjust-properties ( property-set )
     {
         local s = [ $(self.targets[1]).creating-subvariant ] ;
@@ -653,6 +657,7 @@
 # type used to represent 'action' in the constructed dependency graph to
 # 'compile-action'. That class in turn adds additional include paths to handle
 # cases when a source file includes headers which are generated themselves.
+#
 class C-compiling-generator : generator
 {
     rule __init__ ( id : source-types + : target-types + : requirements *
@@ -679,10 +684,12 @@
 # FIXME: this is ugly, should find a better way (we'd like client code to
 # register all generators as "generators.some-rule" instead of
 # "some-module.some-rule".)
+#
 IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ;
 
 
 # The generator class for handling EXE and SHARED_LIB creation.
+#
 class linking-generator : generator
 {
     import path ;
@@ -854,6 +861,7 @@
 
 
 # The generator class for handling STATIC_LIB creation.
+#
 class archive-generator : generator
 {
     import property-set ;
@@ -918,6 +926,7 @@
 
 # Generator that accepts everything and produces nothing. Useful as a general
 # fallback for toolset-specific actions like PCH generation.
+#
 class dummy-generator : generator
 {
     import property-set ;

Modified: branches/proto/v4/tools/build/v2/tools/common.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/tools/common.jam (original)
+++ branches/proto/v4/tools/build/v2/tools/common.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -63,6 +63,7 @@
     #
     # Returns 'true' if the configuration has been added and an empty value if
     # it already exists. Reports an error if the configuration is 'used'.
+ #
     rule register ( id )
     {
         if $(id) in $(self.used)
@@ -88,6 +89,7 @@
     # Returns 'true' if the state of the configuration has been changed to
     # 'used' and an empty value if it the state wasn't changed. Reports an error
     # if the configuration isn't known.
+ #
     rule use ( id )
     {
         if ! $(id) in $(self.all)
@@ -109,24 +111,28 @@
     }
 
     # Return all registered configurations.
+ #
     rule all ( )
     {
         return $(self.all) ;
     }
 
     # Return all used configurations.
+ #
     rule used ( )
     {
         return $(self.used) ;
     }
 
     # Returns the value of a configuration parameter.
+ #
     rule get ( id : param )
     {
         return $(self.$(param).$(id)) ;
     }
 
     # Sets the value of a configuration parameter.
+ #
     rule set ( id : param : value * )
     {
         self.$(param).$(id) = $(value) ;
@@ -140,11 +146,12 @@
 # will check that the combination of all parameter values is unique in all
 # invocations.
 #
-# Each parameter name corresponds to a subfeature. This rule will declare
-# a subfeature the first time a non-empty parameter value is passed and will
+# Each parameter name corresponds to a subfeature. This rule will declare a
+# subfeature the first time a non-empty parameter value is passed and will
 # extend it with all the values.
 #
 # The return value from this rule is a condition to be used for flags settings.
+#
 rule check-init-parameters ( toolset requirement * : * )
 {
     local sig = $(toolset) ;
@@ -251,6 +258,7 @@
 # This rule returns the command to be used when invoking the tool. If we can't
 # find the tool, a warning is issued. If 'path-last' is specified, PATH is
 # checked after 'additional-paths' when searching for 'tool'.
+#
 rule get-invocation-command-nodefault (
     toolset : tool : user-provided-command * : additional-paths * : path-last ? )
 {
@@ -281,6 +289,7 @@
 
 # Same as get-invocation-command-nodefault, except that if no tool is found,
 # returns either the user-provided-command, if present, or the 'tool' parameter.
+#
 rule get-invocation-command (
     toolset : tool : user-provided-command * : additional-paths * : path-last ? )
 {
@@ -304,6 +313,7 @@
 
 # Given an invocation command return the absolute path to the command. This
 # works even if command has no path element and was found on the PATH.
+#
 rule get-absolute-tool-path ( command )
 {
     if $(command:D)
@@ -323,6 +333,7 @@
 # absolute name. If the tool is found in several directories, returns all paths.
 # Otherwise, returns an empty string. If 'path-last' is specified, PATH is
 # searched after 'additional-paths'.
+#
 rule find-tool ( name : additional-paths * : path-last ? )
 {
     local path = [ path.programs-path ] ;
@@ -358,6 +369,7 @@
 
 # Checks if 'command' can be found either in path or is a full name to an
 # existing file.
+#
 rule check-tool-aux ( command )
 {
     if $(command:D)
@@ -384,6 +396,7 @@
 # Checks that a tool can be invoked by 'command'. If command is not an absolute
 # path, checks if it can be found in 'path'. If comand is an absolute path,
 # check that it exists. Returns 'command' if ok or empty string otherwise.
+#
 rule check-tool ( xcommand + )
 {
     if [ check-tool-aux $(xcommand[1]) ] ||
@@ -399,8 +412,9 @@
 # - CONFIG_COMMAND to 'command'
 # - OPTIONS for compile.c to the value of <cflags> in options
 # - OPTIONS for compile.c++ to the value of <cxxflags> in options
-# - OPTIOns for compile to the value of <compileflags> in options
-# - OPTIONs for link to the value of <linkflags> in options
+# - OPTIONS for compile to the value of <compileflags> in options
+# - OPTIONS for link to the value of <linkflags> in options
+#
 rule handle-options ( toolset : condition * : command * : options * )
 {
     if $(.debug-configuration)
@@ -411,19 +425,20 @@
     # The last parameter ('true') says it's OK to set flags for another module.
     toolset.flags $(toolset) CONFIG_COMMAND $(condition) : $(command) : unchecked ;
     toolset.flags $(toolset).compile OPTIONS $(condition) :
- [ feature.get-values <compileflags> : $(options) ] : unchecked ;
+ [ feature.get-values <compileflags> : $(options) ] : unchecked ;
     toolset.flags $(toolset).compile.c OPTIONS $(condition) :
- [ feature.get-values <cflags> : $(options) ] : unchecked ;
+ [ feature.get-values <cflags> : $(options) ] : unchecked ;
     toolset.flags $(toolset).compile.c++ OPTIONS $(condition) :
- [ feature.get-values <cxxflags> : $(options) ] : unchecked ;
+ [ feature.get-values <cxxflags> : $(options) ] : unchecked ;
     toolset.flags $(toolset).compile.fortran OPTIONS $(condition) :
- [ feature.get-values <fflags> : $(options) ] : unchecked ;
+ [ feature.get-values <fflags> : $(options) ] : unchecked ;
     toolset.flags $(toolset).link OPTIONS $(condition) :
- [ feature.get-values <linkflags> : $(options) ] : unchecked ;
+ [ feature.get-values <linkflags> : $(options) ] : unchecked ;
 }
 
 
-# Returns the location of the "program files" directory on a windows platform.
+# Returns the location of the "program files" directory on a Windows platform.
+#
 rule get-program-files-dir ( )
 {
     local ProgramFiles = [ modules.peek : ProgramFiles ] ;
@@ -471,6 +486,7 @@
 # visible in the environment seen by subsequently executed commands. In other
 # words, on Unix systems, the variable is exported, which is consistent with the
 # only possible behavior on Windows systems.
+#
 rule variable-setting-command ( variable : value )
 {
     local nl = "
@@ -489,6 +505,7 @@
 
 # Returns a command to sets a named shell path variable to the given NATIVE
 # paths on the current platform.
+#
 rule path-variable-setting-command ( variable : paths * )
 {
     local sep = [ os.path-separator ] ;
@@ -498,6 +515,7 @@
 
 # Returns a command that prepends the given paths to the named path variable on
 # the current platform.
+#
 rule prepend-path-variable-command ( variable : paths * )
 {
     return [ path-variable-setting-command $(variable)
@@ -508,6 +526,7 @@
 # Return a command which can create a file. If 'r' is result of invocation, then
 # 'r foobar' will create foobar with unspecified content. What happens if file
 # already exists is unspecified.
+#
 rule file-creation-command ( )
 {
     if [ modules.peek : NT ]
@@ -524,6 +543,7 @@
 # Returns a command that may be used for 'touching' files. It is not a real
 # 'touch' command on NT because it adds an empty line at the end of file but it
 # works with source files.
+#
 rule file-touch-command ( )
 {
     if [ os.name ] in NT
@@ -545,15 +565,15 @@
     if $(<) != $(DOT) && ! $($(<)-mkdir)
     {
         # Cheesy gate to prevent multiple invocations on same dir.
- # MkDir1 has the actions.
- # Arrange for jam dirs.
-
         $(<)-mkdir = true ;
         MkDir1 $(<) ;
- Depends dirs : $(<) ;
 
- # Recursively make parent directories.
- # $(<:P) = $(<)'s parent, & we recurse until root
+ # Prepare a Jam 'dirs' target that can be used to make the build only
+ # construct all the target directories.
+ DEPENDS dirs : $(<) ;
+
+ # Recursively create parent directories. $(<:P) = $(<)'s parent & we
+ # recurse until root.
 
         local s = $(<:P) ;
 
@@ -568,7 +588,7 @@
 
         if $(s) && $(s) != $(<)
         {
- Depends $(<) : $(s) ;
+ DEPENDS $(<) : $(s) ;
             MkDir $(s) ;
         }
         else if $(s)
@@ -703,7 +723,7 @@
                         result += [ join-tag $(f:G=) : $(p) ] ;
                     }
                 }
-
+
                 case * :
                 result += $(f:G=) ;
             }

Modified: branches/proto/v4/tools/build/v2/tools/intel-darwin.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/tools/intel-darwin.jam (original)
+++ branches/proto/v4/tools/build/v2/tools/intel-darwin.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -105,6 +105,13 @@
       flags intel-darwin.link OPTIONS $(condition)/<runtime-link>static : -static -static-intel -lstdc++ -lpthread ;
       flags intel-darwin.link OPTIONS $(condition)/<runtime-link>shared : -shared-intel -lstdc++ -lpthread ;
     }
+
+ local minor = [ MATCH ".*\\.(.).*" : $(version) ] ;
+
+ # wchar_t char_traits workaround for compilers older than 10.2
+ if $(major) = "9" || ( $(major) = "10" && ( $(minor) = "0" || $(minor) = "1" ) ) {
+ flags intel-darwin.compile DEFINES $(condition) : __WINT_TYPE__=int : unchecked ;
+ }
 }
 
 SPACE = " " ;

Modified: branches/proto/v4/tools/build/v2/tools/make.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/tools/make.jam (original)
+++ branches/proto/v4/tools/build/v2/tools/make.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1,9 +1,9 @@
-# Copyright 2003 Dave Abrahams
-# Copyright 2003 Douglas Gregor
-# Copyright 2006 Rene Rivera
-# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
-# Distributed under the Boost Software License, Version 1.0.
-# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+# Copyright 2003 Dave Abrahams
+# Copyright 2003 Douglas Gregor
+# Copyright 2006 Rene Rivera
+# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 
 # This module defines the 'make' main target rule.
 
@@ -16,58 +16,56 @@
 import property-set ;
 import project ;
 
+
 class make-target-class : basic-target
 {
- import type regex virtual-target ;
+ import type regex virtual-target ;
     import "class" : new ;
-
+
     rule __init__ ( name : project : sources * : requirements *
         : default-build * : usage-requirements * )
- {
- basic-target.__init__ $(name) : $(project) : $(sources)
+ {
+ basic-target.__init__ $(name) : $(project) : $(sources)
           : $(requirements) : $(default-build) : $(usage-requirements) ;
     }
-
+
     rule construct ( name : source-targets * : property-set )
     {
- local action-name = [ $(property-set).get <action> ] ;
- # 'm' will always be set -- we add '@' outselfs in 'make'
- # rule below.
+ local action-name = [ $(property-set).get <action> ] ;
+ # 'm' will always be set -- we add '@' ourselves in 'make' rule below.
         local m = [ MATCH ^@(.*) : $(action-name) ] ;
-
+
         local a = [ new action $(source-targets) : $(m[1])
- : $(property-set) ] ;
- local t = [ new file-target $(self.name) exact
- : [ type.type $(self.name) ] : $(self.project) : $(a) ] ;
+ : $(property-set) ] ;
+ local t = [ new file-target $(self.name) exact
+ : [ type.type $(self.name) ] : $(self.project) : $(a) ] ;
         return [ property-set.empty ] [ virtual-target.register $(t) ] ;
- }
+ }
 }
 
 # Declares the 'make' main target.
+#
 rule make ( target-name : sources * : generating-rule + : requirements *
     : usage-requirements * )
 {
     local project = [ project.current ] ;
-
- # The '@' sign causes the feature.jam module to qualify rule name
- # with the module name of current project, if needed.
+
+ # The '@' sign causes the feature.jam module to qualify rule name with the
+ # module name of current project, if needed.
     local m = [ MATCH ^(@).* : $(generating-rule) ] ;
     if ! $(m)
     {
         generating-rule = @$(generating-rule) ;
- }
+ }
     requirements += <action>$(generating-rule) ;
-
+
     targets.main-target-alternative
      [ new make-target-class $(target-name) : $(project)
- : [ targets.main-target-sources $(sources) : $(target-name) ]
- : [ targets.main-target-requirements $(requirements) : $(project) ]
- : [ targets.main-target-default-build : $(project) ]
+ : [ targets.main-target-sources $(sources) : $(target-name) ]
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
+ : [ targets.main-target-default-build : $(project) ]
        : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
      ] ;
-
 }
 
 IMPORT $(__name__) : make : : make ;
-
-

Modified: branches/proto/v4/tools/build/v2/tools/pathscale.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/tools/pathscale.jam (original)
+++ branches/proto/v4/tools/build/v2/tools/pathscale.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -41,6 +41,9 @@
 
   toolset.flags pathscale CONFIG_F_COMMAND $(condition) : $(command_f) ;
   toolset.flags pathscale CONFIG_F90_COMMAND $(condition) : $(command_f90) ;
+
+ # always link lib rt to resolve clock_gettime()
+ flags pathscale.link FINDLIBS-SA : rt : unchecked ;
 }
 
 # Declare generators
@@ -112,7 +115,6 @@
 flags pathscale.link FINDLIBS-ST <find-static-library> ;
 flags pathscale.link FINDLIBS-SA <find-shared-library> ;
 flags pathscale.link FINDLIBS-SA <threading>multi : pthread ;
-flags pathscale.link FINDLIBS-SA <threading>multi : rt ;
 flags pathscale.link LIBRARIES <library-file> ;
 flags pathscale.link LINK-RUNTIME <runtime-link>static : static ;
 flags pathscale.link LINK-RUNTIME <runtime-link>shared : dynamic ;

Modified: branches/proto/v4/tools/build/v2/tools/pgi.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/tools/pgi.jam (original)
+++ branches/proto/v4/tools/build/v2/tools/pgi.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -36,11 +36,15 @@
   flags pgi.compile DEFINES $(condition) :
     [ feature.get-values <define> : $(options) ] : unchecked ;
 
+ # IOV_MAX support
+ flags pgi.compile DEFINES $(condition) : __need_IOV_MAX : unchecked ;
+
   # set link flags
   flags pgi.link FINDLIBS-ST : [
     feature.get-values <find-static-library> : $(options) ] : unchecked ;
 
- flags pgi.link FINDLIBS-SA : [
+ # always link lib rt to resolve clock_gettime()
+ flags pgi.link FINDLIBS-SA : rt [
     feature.get-values <find-shared-library> : $(options) ] : unchecked ;
 
   gcc.init-link-flags pgi gnu $(condition) ;

Modified: branches/proto/v4/tools/build/v2/tools/stage.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/tools/stage.jam (original)
+++ branches/proto/v4/tools/build/v2/tools/stage.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -4,8 +4,8 @@
 # Distributed under the Boost Software License, Version 1.0.
 # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 
-# This module defines the 'install' rule, used to copy a set of targets to a
-# single location
+# This module defines the 'install' rule, used to copy a set of targets to a
+# single location.
 
 import targets ;
 import "class" : new ;
@@ -49,6 +49,7 @@
     }
 
     # If <location> is not set, sets it based on the project data.
+ #
     rule update-location ( property-set )
     {
         local loc = [ $(property-set).get <location> ] ;
@@ -62,8 +63,9 @@
         return $(property-set) ;
     }
 
- # Takes a target that is installed and property set which is
- # used when installing.
+ # Takes a target that is installed and a property set which is used when
+ # installing.
+ #
     rule adjust-properties ( target : build-property-set )
     {
         local ps-raw ;
@@ -73,33 +75,31 @@
             local ps = [ $(a).properties ] ;
             ps-raw = [ $(ps).raw ] ;
 
- # Unless <hardcode-dll-paths>true is in properties, which can
- # happen only if the user has explicitly requested it, nuke all
+ # Unless <hardcode-dll-paths>true is in properties, which can happen
+ # only if the user has explicitly requested it, nuke all.
             # <dll-path> properties
             if [ $(property-set).get <hardcode-dll-paths> ] != true
             {
                 ps-raw = [ property.change $(ps-raw) : <dll-path> ] ;
             }
 
- # If any <dll-path> properties were specified for installing,
- # add them.
+ # If any <dll-path> properties were specified for installing, add
+ # them.
             local l = [ $(build-property-set).get <dll-path> ] ;
             ps-raw += $(l:G=<dll-path>) ;
 
- # Also copy <linkflags> feature from current build
- # set, to be used for relinking.
+ # Also copy <linkflags> feature from current build set, to be used
+ # for relinking.
             local l = [ $(build-property-set).get <linkflags> ] ;
             ps-raw += $(l:G=<linkflags>) ;
         }
 
         # Remove the <tag> feature on original targets.
         ps-raw = [ property.change $(ps-raw) : <tag> ] ;
- # And <location>. If stage target has another stage target
- # in sources, then we'll get virtual targets with <location>
- # property set.
+ # And <location>. If stage target has another stage target in sources,
+ # then we'll get virtual targets with <location> property set.
         ps-raw = [ property.change $(ps-raw) : <location> ] ;
 
-
         local d = [ $(build-property-set).get <dependency> ] ;
         ps-raw += $(d:G=<dependency>) ;
 
@@ -110,8 +110,8 @@
         ps-raw += $(ns:G=<install-no-version-symlinks>) ;
 
         local d = [ $(build-property-set).get <install-source-root> ] ;
- # Make the path absolute: we'll use it to compute relative
- # paths and making the path absolute will help.
+ # Make the path absolute: we'll use it to compute relative paths and
+ # making the path absolute will help.
         if $(d)
         {
             d = [ path.root $(d) [ path.pwd ] ] ;
@@ -130,8 +130,8 @@
 
     rule construct ( name : source-targets * : property-set )
     {
- source-targets = [
- targets-to-stage $(source-targets) : $(property-set) ] ;
+ source-targets = [ targets-to-stage $(source-targets) :
+ $(property-set) ] ;
 
         property-set = [ update-location $(property-set) ] ;
 
@@ -139,8 +139,8 @@
 
         if $(ename) && $(source-targets[2])
         {
- errors.error
- "When <name> property is used in 'install', only one source is allowed" ;
+ errors.error "When <name> property is used in 'install', only one"
+ "source is allowed" ;
         }
 
         local result ;
@@ -148,11 +148,11 @@
         {
             local staged-targets ;
 
- local new-properties =
- [ adjust-properties $(i) : $(property-set) ] ;
+ local new-properties = [ adjust-properties $(i) :
+ $(property-set) ] ;
 
- # See if something special should be done when staging this
- # type. It is indicated by presense of special "staged" type
+ # See if something special should be done when staging this type. It
+ # is indicated by the presense of special "INSTALLED_" type.
             local t = [ $(i).type ] ;
             if $(t) && [ type.registered INSTALLED_$(t) ]
             {
@@ -162,8 +162,8 @@
                 }
                 else
                 {
- local targets = [ generators.construct $(self.project) $(name) :
- INSTALLED_$(t) : $(new-properties) : $(i) ] ;
+ local targets = [ generators.construct $(self.project)
+ $(name) : INSTALLED_$(t) : $(new-properties) : $(i) ] ;
                     staged-targets += $(targets[2-]) ;
                 }
             }
@@ -187,8 +187,9 @@
         return [ property-set.empty ] $(result) ;
     }
 
- # Given the list of source targets explicitly passed to 'stage',
- # returns the list of targets which must be staged.
+ # Given the list of source targets explicitly passed to 'stage', returns the
+ # list of targets which must be staged.
+ #
     rule targets-to-stage ( source-targets * : property-set )
     {
         local result ;
@@ -206,7 +207,7 @@
             local ty = [ $(r).type ] ;
             if $(ty)
             {
- # Don't stage searched libs.
+ # Do not stage searched libs.
                 if $(ty) != SEARCHED_LIB
                 {
                     if $(included-types)
@@ -224,8 +225,8 @@
             }
             else if ! $(included-types)
             {
- # Don't install typeless target if there's
- # explicit list of allowed types.
+ # Don't install typeless target if there is an explicit list of
+ # allowed types.
                 result += $(r) ;
             }
         }
@@ -234,6 +235,7 @@
     }
 
     # CONSIDER: figure out why we can't use virtual-target.traverse here.
+ #
     rule collect-targets ( targets * )
     {
         # Find subvariants
@@ -261,6 +263,7 @@
     }
 
     # Returns true iff 'type' is subtype of some element of 'types-to-include'.
+ #
     local rule include-type ( type : types-to-include * )
     {
         local found ;
@@ -280,41 +283,42 @@
 
 # Creates a copy of target 'source'. The 'properties' object should have a
 # <location> property which specifies where the target must be placed.
+#
 rule copy-file ( project name ? : source : properties )
 {
     local targets ;
     name ?= [ $(source).name ] ;
 
- new-a = [
- new non-scanning-action $(source) : common.copy : $(properties) ] ;
+ local new-a = [ new non-scanning-action $(source) : common.copy :
+ $(properties) ] ;
     local source-root = [ $(properties).get <install-source-root> ] ;
     if $(source-root)
     {
- # Get the real path of the target. We probably need to strip
- # relative path from the target name at construction...
+ # Get the real path of the target. We probably need to strip relative
+ # path from the target name at construction.
         local path = [ $(source).path ] ;
         path = [ path.root $(name:D) $(path) ] ;
- # Make the path absolute. Otherwise, it's hard to compute relative
- # path. The 'source-root' is already absolute, see the
+ # Make the path absolute. Otherwise, it would be hard to compute the
+ # relative path. The 'source-root' is already absolute, see the
         # 'adjust-properties' method above.
         path = [ path.root $(path) [ path.pwd ] ] ;
 
         relative = [ path.relative-to $(source-root) $(path) ] ;
- # Note: using $(name:D=$(relative)) might be faster
- # here, but then we need to explicitly check that
- # relative is not ".", otherwise we might get paths like
+ # Note: using $(name:D=$(relative)) might be faster here, but then we
+ # need to explicitly check that relative is not ".", otherwise we might
+ # get paths like
         #
         # <prefix>/boost/.
         #
         # try to create it, and mkdir will obviously fail.
         name = [ path.root $(name:D=) $(relative) ] ;
- targets = [ new file-target $(name) exact : [ $(source).type ]
- : $(project) : $(new-a) ] ;
+ targets = [ new file-target $(name) exact : [ $(source).type ] :
+ $(project) : $(new-a) ] ;
     }
     else
     {
- targets = [ new file-target $(name:D=) exact : [ $(source).type ]
- : $(project) : $(new-a) ] ;
+ targets = [ new file-target $(name:D=) exact : [ $(source).type ] :
+ $(project) : $(new-a) ] ;
     }
 
     return $(targets) ;
@@ -323,12 +327,9 @@
 
 rule symlink ( name : project : source : properties )
 {
- local a = [ new action $(source) : symlink.ln :
- $(properties) ] ;
- local targets = [
- new file-target $(name) exact : [ $(source).type ] : $(project) : $(a) ] ;
-
- return $(targets) ;
+ local a = [ new action $(source) : symlink.ln : $(properties) ] ;
+ return [ new file-target $(name) exact : [ $(source).type ] : $(project) :
+ $(a) ] ;
 }
 
 
@@ -336,10 +337,8 @@
 {
     local action = [ $(source).action ] ;
     local cloned-action = [ virtual-target.clone-action $(action) : $(project) :
- "" : $(property-set) ] ;
- local result = [ $(cloned-action).targets ] ;
-
- return $(result) ;
+ "" : $(property-set) ] ;
+ return [ $(cloned-action).targets ] ;
 }
 
 
@@ -347,6 +346,7 @@
 # relinking to the new location.
 type.register INSTALLED_EXE : : EXE ;
 
+
 class installed-exe-generator : generator
 {
     import type ;
@@ -376,6 +376,7 @@
     }
 }
 
+
 generators.register [ new installed-exe-generator ] ;
 
 
@@ -383,6 +384,7 @@
 # links.
 type.register INSTALLED_SHARED_LIB : : SHARED_LIB ;
 
+
 class installed-shared-lib-generator : generator
 {
     import type ;
@@ -401,12 +403,9 @@
         if [ $(property-set).get <os> ] in NT CYGWIN ||
             [ $(property-set).get <target-os> ] in windows cygwin
         {
- local copied = [ stage.copy-file $(project)
- : $(source) : $(property-set) ] ;
-
- copied = [ virtual-target.register $(copied) ] ;
-
- return $(copied) ;
+ local copied = [ stage.copy-file $(project) : $(source) :
+ $(property-set) ] ;
+ return [ virtual-target.register $(copied) ] ;
         }
         else
         {
@@ -415,8 +414,8 @@
             if ! $(a)
             {
                 # Non-derived file, just copy.
- copied = [ stage.copy-file $(project)
- : $(source) : $(property-set) ] ;
+ copied = [ stage.copy-file $(project) : $(source) :
+ $(property-set) ] ;
             }
             else
             {
@@ -427,38 +426,38 @@
                 if $(current-dll-path) != $(new-dll-path)
                 {
                     # Rpath changed, need to relink.
- copied = [ stage.relink-file
- $(project) : $(source) : $(property-set) ] ;
+ copied = [ stage.relink-file $(project) : $(source) :
+ $(property-set) ] ;
                 }
                 else
                 {
- copied = [ stage.copy-file $(project)
- : $(source) : $(property-set) ] ;
+ copied = [ stage.copy-file $(project) : $(source) :
+ $(property-set) ] ;
                 }
             }
 
             copied = [ virtual-target.register $(copied) ] ;
 
             local result = $(copied) ;
- # If the name is in the form NNN.XXX.YYY.ZZZ, where all
- # 'X', 'Y' and 'Z' are numbers, we need to create
- # NNN.XXX and NNN.XXX.YYY symbolic links.
+ # If the name is in the form NNN.XXX.YYY.ZZZ, where all 'X', 'Y' and
+ # 'Z' are numbers, we need to create NNN.XXX and NNN.XXX.YYY
+ # symbolic links.
             local m = [ MATCH (.*)\\.([0123456789]+)\\.([0123456789]+)\\.([0123456789]+)$
               : [ $(copied).name ] ] ;
             if $(m)
             {
                 # Symlink without version at all is used to make
                 # -lsome_library work.
- result += [ stage.symlink $(m[1]) : $(project)
- : $(copied) : $(property-set) ] ;
+ result += [ stage.symlink $(m[1]) : $(project) : $(copied) :
+ $(property-set) ] ;
 
- # Symlinks of some libfoo.N and libfoo.N.M are used
- # so that library can found at runtime, if libfoo.N.M.X
- # has soname of libfoo.N. That happens when the library
- # makes some binary compatibility guarantees. If not,
- # it's possible to skip those symlinks.
+ # Symlinks of some libfoo.N and libfoo.N.M are used so that
+ # library can found at runtime, if libfoo.N.M.X has soname of
+ # libfoo.N. That happens when the library makes some binary
+ # compatibility guarantees. If not, it is possible to skip those
+ # symlinks.
                 local suppress =
- [ $(property-set).get <install-no-version-symlinks> ] ;
+ [ $(property-set).get <install-no-version-symlinks> ] ;
 
                 if $(suppress) != "on"
                 {
@@ -478,13 +477,13 @@
 
 
 # Main target rule for 'install'.
+#
 rule install ( name : sources * : requirements * : default-build * )
 {
     local project = [ project.current ] ;
 
     # Unless the user has explicitly asked us to hardcode dll paths, add
- # <hardcode-dll-paths>false in requirements, to override default
- # value.
+ # <hardcode-dll-paths>false in requirements, to override default value.
     if ! <hardcode-dll-paths>true in $(requirements)
     {
         requirements += <hardcode-dll-paths>false ;
@@ -504,5 +503,6 @@
       ] ;
 }
 
+
 IMPORT $(__name__) : install : : install ;
 IMPORT $(__name__) : install : : stage ;

Modified: branches/proto/v4/tools/build/v2/tools/testing.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/tools/testing.jam (original)
+++ branches/proto/v4/tools/build/v2/tools/testing.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -239,6 +239,9 @@
         }
     }
 
+ local target-name = [ $(project).get location ] // [ $(target).name ] .test ;
+ target-name = $(target-name:J=) ;
+
     local r = [ $(target).requirements ] ;
     # Extract values of the <test-info> feature.
     local test-info = [ $(r).get <test-info> ] ;
@@ -251,6 +254,7 @@
 " ;
         .contents on $(.out-xml) +=
             "$(nl) <test type=\"$(type)\" name=\"$(name)\">"
+ "$(nl) <target><![CDATA[$(target-name)]]></target>"
             "$(nl) <info><![CDATA[$(test-info)]]></info>"
             "$(nl) <source><![CDATA[$(source-files)]]></source>"
             "$(nl) </test>"

Modified: branches/proto/v4/tools/build/v2/util/path.jam
==============================================================================
--- branches/proto/v4/tools/build/v2/util/path.jam (original)
+++ branches/proto/v4/tools/build/v2/util/path.jam 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -6,16 +6,16 @@
 # (See accompanying file LICENSE_1_0.txt or copy at
 # http://www.boost.org/LICENSE_1_0.txt)
 
-# Performs various path manipulations. Paths are always in a 'normalized'
-# representation. In it, a path may be either:
+# Performs various path manipulations. Paths are always in a 'normalized'
+# representation. In it, a path may be either:
 #
 # - '.', or
 #
-# - ['/'] [ ( '..' '/' )* (token '/')* token ]
+# - ['/'] [ ( '..' '/' )* (token '/')* token ]
 #
-# In plain english, path can be rooted, '..' elements are allowed only
-# at the beginning, and it never ends in slash, except for path consisting
-# of slash only.
+# In plain english, path can be rooted, '..' elements are allowed only at the
+# beginning, and it never ends in slash, except for path consisting of slash
+# only.
 
 import errors ;
 import modules ;
@@ -35,7 +35,7 @@
     }
 }
 
-# Converts the native path into normalized form.
+# Converts the native path into normalized form.
 #
 rule make ( native )
 {
@@ -43,7 +43,7 @@
 }
 
 
-# Builds native representation of the path.
+# Builds native representation of the path.
 #
 rule native ( path )
 {
@@ -51,7 +51,7 @@
 }
 
 
-# Tests if a path is rooted.
+# Tests if a path is rooted.
 #
 rule is-rooted ( path )
 {
@@ -59,7 +59,7 @@
 }
 
 
-# Tests if a path has a parent.
+# Tests if a path has a parent.
 #
 rule has-parent ( path )
 {
@@ -74,7 +74,7 @@
 }
 
 
-# Returns the path without any directory components.
+# Returns the path without any directory components.
 #
 rule basename ( path )
 {
@@ -82,7 +82,7 @@
 }
 
 
-# Returns parent directory of the path. If no parent exists, error is issued.
+# Returns parent directory of the path. If no parent exists, error is issued.
 #
 rule parent ( path )
 {
@@ -94,8 +94,8 @@
         }
         else
         {
- # Strip everything at the end of path up to and including
- # the last slash
+ # Strip everything at the end of path up to and including the last
+ # slash.
             local result = [ regex.match "((.*)/)?([^/]+)" : $(path) : 2 3 ] ;
 
             # Did we strip what we shouldn't?
@@ -127,8 +127,8 @@
 }
 
 
-# Returns path2 such that "[ join path path2 ] = .".
-# The path may not contain ".." element or be rooted.
+# Returns path2 such that "[ join path path2 ] = .". The path may not contain
+# ".." element or be rooted.
 #
 rule reverse ( path )
 {
@@ -150,8 +150,8 @@
 
 
 # Auxillary rule: does all the semantic of 'join', except for error cheching.
-# The error checking is separated because this rule is recursive, and I don't
-# like the idea of checking the same input over and over.
+# The error checking has been separated because this rule is recursive, and I
+# do not like the idea of checking the same input over and over.
 #
 local rule join-imp ( elements + )
 {
@@ -168,8 +168,8 @@
 }
 
 
-# Contanenates the passed path elements. Generates an error if
-# any element other than the first one is rooted.
+# Concatenates the passed path elements. Generates an error if any element other
+# than the first one is rooted.
 #
 rule join ( elements + )
 {
@@ -191,7 +191,7 @@
 }
 
 
-# If 'path' is relative, it is rooted at 'root'. Otherwise, it's unchanged.
+# If 'path' is relative, it is rooted at 'root'. Otherwise, it's unchanged.
 #
 rule root ( path root )
 {
@@ -203,7 +203,7 @@
 }
 
 
-# Returns the current working directory.
+# Returns the current working directory.
 #
 rule pwd ( )
 {
@@ -219,19 +219,20 @@
 }
 
 
-# Returns the list of files matching the given pattern in the
-# specified directory. Both directories and patterns are
-# supplied as portable paths. Each pattern should be non-absolute
-# path, and can't contain "." or ".." elements. Each slash separated
-# element of pattern can contain the following special characters:
-# - '?', which match any character
-# - '*', which matches arbitrary number of characters.
-# A file $(d)/e1/e2/e3 (where 'd' is in $(dirs)) matches pattern p1/p2/p3
-# if and only if e1 matches p1, e2 matches p2 and so on.
-#
-# For example:
-# [ glob . : *.cpp ]
-# [ glob . : */build/Jamfile ]
+# Returns the list of files matching the given pattern in the specified
+# directory. Both directories and patterns are supplied as portable paths. Each
+# pattern should be non-absolute path, and can't contain "." or ".." elements.
+# Each slash separated element of pattern can contain the following special
+# characters:
+# - '?', which match any character
+# - '*', which matches arbitrary number of characters.
+# A file $(d)/e1/e2/e3 (where 'd' is in $(dirs)) matches pattern p1/p2/p3 if and
+# only if e1 matches p1, e2 matches p2 and so on.
+#
+# For example:
+# [ glob . : *.cpp ]
+# [ glob . : */build/Jamfile ]
+#
 rule glob ( dirs * : patterns + : exclude-patterns * )
 {
     local result ;
@@ -262,12 +263,11 @@
 }
 
 
-# Recursive version of GLOB. Builds the glob of files while
-# also searching in the subdirectories of the given roots. An
-# optional set of exclusion patterns will filter out the
-# matching entries from the result. The exclusions also apply
-# to the subdirectory scanning, such that directories that
-# match the exclusion patterns will not be searched.
+# Recursive version of GLOB. Builds the glob of files while also searching in
+# the subdirectories of the given roots. An optional set of exclusion patterns
+# will filter out the matching entries from the result. The exclusions also
+# apply to the subdirectory scanning, such that directories that match the
+# exclusion patterns will not be searched.
 #
 rule glob-tree ( roots * : patterns + : exclude-patterns * )
 {
@@ -311,9 +311,9 @@
 NATIVE_RULE path : exists ;
 
 
-# Find out the absolute name of path and returns the list of all the parents,
-# starting with the immediate one. Parents are returned as relative names.
-# If 'upper_limit' is specified, directories above it will be pruned.
+# Find out the absolute name of path and returns the list of all the parents,
+# starting with the immediate one. Parents are returned as relative names. If
+# 'upper_limit' is specified, directories above it will be pruned.
 #
 rule all-parents ( path : upper_limit ? : cwd ? )
 {
@@ -349,8 +349,8 @@
 }
 
 
-# Search for 'pattern' in parent directories of 'dir', up till and including
-# 'upper_limit', if it is specified, or till the filesystem root otherwise.
+# Search for 'pattern' in parent directories of 'dir', up till and including
+# 'upper_limit', if it is specified, or till the filesystem root otherwise.
 #
 rule glob-in-parents ( dir : patterns + : upper-limit ? )
 {
@@ -366,8 +366,8 @@
 }
 
 
-# Assuming 'child' is a subdirectory of 'parent', return the relative
-# path from 'parent' to 'child'
+# Assuming 'child' is a subdirectory of 'parent', return the relative path from
+# 'parent' to 'child'.
 #
 rule relative ( child parent )
 {
@@ -429,8 +429,9 @@
 }
 
 
-# Returns the list of paths which are used by the operating system
-# for looking up programs
+# Returns the list of paths which are used by the operating system for looking
+# up programs.
+#
 rule programs-path ( )
 {
     local result ;
@@ -451,10 +452,10 @@
     local tokens = [ regex.split $(native) "[/\\]" ] ;
     local result ;
 
- # Handle paths ending with slashes
+ # Handle paths ending with slashes.
     if $(tokens[-1]) = ""
     {
- tokens = $(tokens[1--2]) ; # discard the empty element
+ tokens = $(tokens[1--2]) ; # Discard the empty element.
     }
 
     result = [ path.join $(tokens) ] ;
@@ -518,16 +519,17 @@
 rule native-CYGWIN ( path )
 {
     local result = $(path) ;
- if [ regex.match "(^/.:)" : $(path) ] # win absolute
+ if [ regex.match "(^/.:)" : $(path) ] # Windows absolute path.
     {
- result = [ MATCH "^/?(.*)" : $(path) ] ; # remove leading '/'
+ result = [ MATCH "^/?(.*)" : $(path) ] ; # Remove leading '/'.
     }
     return [ native-UNIX $(result) ] ;
 }
 
 
-# split-VMS: splits input native path into
-# device dir file (each part is optional),
+# split-path-VMS: splits input native path into device dir file (each part is
+# optional).
+#
 # example:
 #
 # dev:[dir]file.c => dev: [dir] file.c
@@ -545,12 +547,11 @@
 
 # Converts a native VMS path into a portable path spec.
 #
-# Does not handle current-device absolute paths such
-# as "[dir]File.c" as it is not clear how to represent
-# them in the portable path notation.
+# Does not handle current-device absolute paths such as "[dir]File.c" as it is
+# not clear how to represent them in the portable path notation.
 #
-# Adds a trailing dot (".") to the file part if no extension
-# is present (helps when converting it back into native path).
+# Adds a trailing dot (".") to the file part if no extension is present (helps
+# when converting it back into native path).
 #
 rule make-VMS ( native )
 {
@@ -621,8 +622,8 @@
 
 # Converts a portable path spec into a native VMS path.
 #
-# Relies on having at least one dot (".") included in the file
-# name to be able to differentiate it ftom the directory part.
+# Relies on having at least one dot (".") included in the file name to be able
+# to differentiate it from the directory part.
 #
 rule native-VMS ( path )
 {

Modified: branches/proto/v4/tools/jam/doc/bjam.qbk
==============================================================================
--- branches/proto/v4/tools/jam/doc/bjam.qbk (original)
+++ branches/proto/v4/tools/jam/doc/bjam.qbk 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -124,7 +124,7 @@
 
 [ [=build.bat=] [Windows NT, 2000, and XP]
     [[lines
- [line [@http://www.borland.com/bcppbuilder/freecompiler =borland=]]
+ [line [@http://www.codegear.com/downloads/free/cppbuilder =borland=]]
         [line [@http://www.borland.com/ Borland] C++Builder (BCC 5.5)]
         ]]
     [[list
@@ -291,7 +291,7 @@
 
 [ [] []
     [[lines
- [line [@http://www.borland.com/bcppbuilder/freecompiler =kylix=]]
+ [line [@http://www.codegear.com/downloads/free/cppbuilder =kylix=]]
         [line [@http://www.borland.com/ Borland] C++Builder]
         ]]
     [[list
@@ -341,7 +341,7 @@
 
 [ [] []
     [[lines
- [line [@http://www-3.ibm.com/software/ad/vacpp/ =vacpp=]]
+ [line [@http://www-306.ibm.com/software/awdtools/vacpp/ =vacpp=]]
         [line IBM VisualAge C++]
         ]]
     [[list
@@ -758,7 +758,7 @@
 rule DEPENDS ( /targets1/ * : /targets2/ * )
 ]
 
-Builds a direct dependency: makes each of /targets1/ depend on each of /targets2/. Generally, /targets1/ will be rebuilt if /targets2/ are themselves rebuilt are or are newer than /targets1/.
+Builds a direct dependency: makes each of /targets1/ depend on each of /targets2/. Generally, /targets1/ will be rebuilt if /targets2/ are themselves rebuilt or are newer than /targets1/.
 
 [endsect]
 
@@ -954,7 +954,7 @@
 # It clears the list of targets to update, and
 # Causes the specified targets to be updated.
 
-If no target was specified with the =UPDATE= rule, no targets will be updated. To support changing of the update list in more usefull ways, the rule also returns the targets previously in the update list. This makes it possible to add targets as such:
+If no target was specified with the =UPDATE= rule, no targets will be updated. To support changing of the update list in more useful ways, the rule also returns the targets previously in the update list. This makes it possible to add targets as such:
 
 [pre
 local previous-updates = \[ UPDATE \] ;
@@ -1801,4 +1801,4 @@
 
 [section History]
 [include history.qbk]
-[endsect]
\ No newline at end of file
+[endsect]

Modified: branches/proto/v4/tools/jam/src/compile.c
==============================================================================
--- branches/proto/v4/tools/jam/src/compile.c (original)
+++ branches/proto/v4/tools/jam/src/compile.c 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -1118,13 +1118,12 @@
 }
 
 /*
- * Call the given rule with the specified parameters.
- * The parameters should be of LIST* and end with NULL pointer.
- * This differs from the 'evaluate_rule' in that frame
- * for called rule is prepared in 'call_rule'.
+ * Call the given rule with the specified parameters. The parameters should be
+ * of type LIST* and end with a NULL pointer. This differs from 'evaluate_rule'
+ * in that frame for the called rule is prepared inside 'call_rule'.
  *
- * This function is usefull when builtin rule (in C) wants to
- * call another rule, which might be implemented in Jam.
+ * This function is useful when a builtin rule (in C) wants to call another
+ * rule which might be implemented in Jam.
  */
 LIST *call_rule( char *rulename, FRAME* caller_frame, ...)
 {

Modified: branches/proto/v4/tools/regression/src/regression.py
==============================================================================
--- branches/proto/v4/tools/regression/src/regression.py (original)
+++ branches/proto/v4/tools/regression/src/regression.py 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -140,7 +140,10 @@
         self.regression_root = root
         self.boost_root = os.path.join( self.regression_root, 'boost' )
         self.regression_results = os.path.join( self.regression_root, 'results' )
- self.regression_log = os.path.join( self.regression_results, 'bjam.log' )
+ if self.pjl_toolset != 'python':
+ self.regression_log = os.path.join( self.regression_results, 'bjam.log' )
+ else:
+ self.regression_log = os.path.join( self.regression_results, 'bjam.xml' )
         self.tools_bb_root = os.path.join( self.regression_root,'tools_bb' )
         self.tools_bjam_root = os.path.join( self.regression_root,'tools_bjam' )
         self.tools_regression_root = os.path.join( self.regression_root,'tools_regression' )
@@ -289,7 +292,8 @@
     def command_setup(self):
         self.command_patch()
         self.build_if_needed(self.bjam,self.bjam_toolset)
- self.build_if_needed(self.process_jam_log,self.pjl_toolset)
+ if self.pjl_toolset != 'python':
+ self.build_if_needed(self.process_jam_log,self.pjl_toolset)
     
     def command_test(self, *args):
         if not args or args == None or args == []: args = [ "test", "process" ]
@@ -308,7 +312,8 @@
             self.command_test_run()
 
         if "process" in args:
- self.command_test_process()
+ if self.pjl_toolset != 'python':
+ self.command_test_process()
     
     def command_test_clean(self):
         results_libs = os.path.join( self.regression_results, 'libs' )
@@ -318,11 +323,18 @@
     
     def command_test_run(self):
         self.import_utils()
- test_cmd = '%s -d2 --dump-tests %s "--build-dir=%s" >>"%s" 2>&1' % (
- self.bjam_cmd( self.toolsets ),
- self.bjam_options,
- self.regression_results,
- self.regression_log )
+ if self.pjl_toolset != 'python':
+ test_cmd = '%s -d2 --dump-tests %s "--build-dir=%s" >>"%s" 2>&1' % (
+ self.bjam_cmd( self.toolsets ),
+ self.bjam_options,
+ self.regression_results,
+ self.regression_log )
+ else:
+ test_cmd = '%s -d1 --dump-tests --verbose-test %s "--build-dir=%s" "--out-xml=%s"' % (
+ self.bjam_cmd( self.toolsets ),
+ self.bjam_options,
+ self.regression_results,
+ self.regression_log )
         self.log( 'Starting tests (%s)...' % test_cmd )
         cd = os.getcwd()
         os.chdir( os.path.join( self.boost_root, 'status' ) )
@@ -362,7 +374,7 @@
         svn_info_file = os.path.join( self.boost_root, 'svn_info.txt' )
         if os.path.exists( svn_root_file ):
             source = 'SVN'
- self.svn_command( 'info --xml "%s" >%s' % (self.boost_root,svn_info_file) )
+ self.svn_command( 'info --xml "%s" >"%s"' % (self.boost_root,svn_info_file) )
 
         if os.path.exists( svn_info_file ):
             f = open( svn_info_file, 'r' )
@@ -376,15 +388,33 @@
                   revision += svn_info[i]
                   i += 1
 
- from collect_and_upload_logs import collect_logs
- collect_logs(
- self.regression_results,
- self.runner, self.tag, self.platform, comment_path,
- self.timestamp_path,
- self.user,
- source, run_type,
- self.dart_server, self.proxy,
- revision )
+ if self.pjl_toolset != 'python':
+ from collect_and_upload_logs import collect_logs
+ collect_logs(
+ self.regression_results,
+ self.runner, self.tag, self.platform, comment_path,
+ self.timestamp_path,
+ self.user,
+ source, run_type,
+ self.dart_server, self.proxy,
+ revision )
+ else:
+ from process_jam_log import BJamLog2Results
+ BJamLog2Results([
+ '--output='+os.path.join(self.regression_results,self.runner+'.xml'),
+ '--runner='+self.runner,
+ '--comment='+comment_path,
+ '--tag='+self.tag,
+ '--platform='+self.platform,
+ '--source='+source,
+ '--revision='+revision,
+ '--incremental' if run_type == 'incremental' else '',
+ self.regression_log
+ ])
+ self.compress_file(
+ os.path.join(self.regression_results,self.runner+'.xml'),
+ os.path.join(self.regression_results,self.runner+'.zip')
+ )
         
     def command_upload_logs(self):
         self.import_utils()
@@ -673,6 +703,33 @@
         smtp_server.sendmail( self.mail, [ self.mail ],
             'Subject: %s\nTo: %s\n\n%s' % ( subject, self.mail, msg ) )
 
+ def compress_file( self, file_path, archive_path ):
+ self.import_utils()
+ utils.log( 'Compressing "%s"...' % file_path )
+
+ try:
+ import zipfile
+ z = zipfile.ZipFile( archive_path, 'w', zipfile.ZIP_DEFLATED )
+ z.write( file_path, os.path.basename( file_path ) )
+ z.close()
+ utils.log( 'Done writing "%s".'% archive_path )
+ except Exception, msg:
+ utils.log( 'Warning: Compressing falied (%s)' % msg )
+ utils.log( ' Trying to compress using a platform-specific tool...' )
+ try:
+ import zip_cmd
+ except ImportError:
+ script_dir = os.path.dirname( os.path.abspath( sys.argv[0] ) )
+ utils.log( 'Could not find \'zip_cmd\' module in the script directory (%s).' % script_dir )
+ raise Exception( 'Compressing failed!' )
+ else:
+ if os.path.exists( archive_path ):
+ os.unlink( archive_path )
+ utils.log( 'Removing stale "%s".' % archive_path )
+
+ zip_cmd.main( file_path, archive_path )
+ utils.log( 'Done compressing "%s".' % archive_path )
+
     #~ Dowloading source, from SVN...
 
     def svn_checkout( self ):

Modified: branches/proto/v4/tools/regression/src/run.py
==============================================================================
--- branches/proto/v4/tools/regression/src/run.py (original)
+++ branches/proto/v4/tools/regression/src/run.py 2008-05-02 13:44:19 EDT (Fri, 02 May 2008)
@@ -23,7 +23,7 @@
 root = os.path.abspath(os.path.dirname(os.path.realpath(__file__)))
 print '# Running regressions in %s...' % root
 
-script_sources = [ 'collect_and_upload_logs.py', 'regression.py' ]
+script_sources = [ 'collect_and_upload_logs.py', 'process_jam_log.py', 'regression.py' ]
 script_local = os.path.join(root,'tools','regression','src')
 script_remote = 'http://svn.boost.org/svn/boost/trunk/tools/regression/src'
 script_dir = os.path.join(root,'tools_regression_src')


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk