| 
									
										
										
										
											2013-01-22 00:44:53 +00:00
										 |  |  | /* 
 | 
					
						
							|  |  |  |     Copyright 2008 Adobe Systems Incorporated | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    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)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |  Revision history: | 
					
						
							|  |  |  |    January 2008 mtc Version for Adobe Source Library | 
					
						
							|  |  |  |    January 2013 mtc Version for Boost.Algorithm | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  | \author Marshall Clow | 
					
						
							|  |  |  | \date    January 2008 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #ifndef BOOST_ALGORITHM_GATHER_HPP
 | 
					
						
							| 
									
										
										
										
											2013-02-19 14:36:22 +00:00
										 |  |  | #define BOOST_ALGORITHM_GATHER_HPP
 | 
					
						
							| 
									
										
										
										
											2013-01-22 00:44:53 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <algorithm>                // for std::stable_partition
 | 
					
						
							|  |  |  | #include <functional>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <boost/bind.hpp>           // for boost::bind
 | 
					
						
							|  |  |  | #include <boost/range/begin.hpp>    // for boost::begin(range)
 | 
					
						
							|  |  |  | #include <boost/range/end.hpp>      // for boost::end(range)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************************************/ | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \defgroup gather gather | 
					
						
							|  |  |  |     \ingroup mutating_algorithm | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \c gather() takes a collection of elements defined by a pair of iterators and moves | 
					
						
							|  |  |  |     the ones satisfying a predicate to them to a position (called the pivot) within | 
					
						
							|  |  |  |     the sequence. The algorithm is stable. The result is a pair of iterators that | 
					
						
							|  |  |  |     contains the items that satisfy the predicate. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Given an sequence containing: | 
					
						
							|  |  |  |     <pre> | 
					
						
							|  |  |  |     0 1 2 3 4 5 6 7 8 9 | 
					
						
							|  |  |  |     </pre> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     a call to gather ( arr, arr + 10, arr + 4, IsEven ()) will result in: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     <pre> | 
					
						
							|  |  |  |     1 3 0 2 4 6 8 5 7 9 | 
					
						
							|  |  |  |         |---|-----| | 
					
						
							|  |  |  |       first |  second | 
					
						
							|  |  |  |           pivot | 
					
						
							|  |  |  |     </pre> | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The problem is broken down into two basic steps, namely, moving the items before the pivot | 
					
						
							|  |  |  |     and then moving the items from the pivot to the end. These "moves" are done with calls to | 
					
						
							|  |  |  |     stable_partition. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \par Storage Requirements: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     The algorithm uses stable_partition, which will attempt to allocate temporary memory, | 
					
						
							|  |  |  |     but will work in-situ if there is none available. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \par Time Complexity: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     If there is sufficient memory available, the run time is linear in <code>N</code>. | 
					
						
							|  |  |  |     If there is not any memory available, then the run time is <code>O(N log N)</code>. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace boost { namespace algorithm { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \ingroup gather | 
					
						
							|  |  |  |     \brief iterator-based gather implementation | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template < | 
					
						
							| 
									
										
										
										
											2013-02-25 22:31:52 +00:00
										 |  |  |     typename BidirectionalIterator,  // Iter models BidirectionalIterator
 | 
					
						
							|  |  |  |     typename Pred>                   // Pred models UnaryPredicate
 | 
					
						
							|  |  |  | std::pair<BidirectionalIterator, BidirectionalIterator> gather  | 
					
						
							|  |  |  |         ( BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator pivot, Pred pred ) | 
					
						
							| 
									
										
										
										
											2013-01-22 00:44:53 +00:00
										 |  |  | { | 
					
						
							|  |  |  | //  The first call partitions everything up to (but not including) the pivot element,
 | 
					
						
							|  |  |  | //  while the second call partitions the rest of the sequence.
 | 
					
						
							|  |  |  |     return std::make_pair ( | 
					
						
							|  |  |  |         std::stable_partition ( first, pivot, !boost::bind<bool> ( pred, _1 )), | 
					
						
							|  |  |  |         std::stable_partition ( pivot, last,   boost::bind<bool> ( pred, _1 ))); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*!
 | 
					
						
							|  |  |  |     \ingroup gather | 
					
						
							|  |  |  |     \brief range-based gather implementation | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template < | 
					
						
							| 
									
										
										
										
											2013-02-25 22:31:52 +00:00
										 |  |  |     typename BidirectionalRange,    //
 | 
					
						
							| 
									
										
										
										
											2013-01-22 00:44:53 +00:00
										 |  |  |     typename Pred>                  // Pred models UnaryPredicate
 | 
					
						
							|  |  |  | std::pair< | 
					
						
							| 
									
										
										
										
											2013-02-25 22:31:52 +00:00
										 |  |  |     typename boost::range_iterator<const BidirectionalRange>::type, | 
					
						
							|  |  |  |     typename boost::range_iterator<const BidirectionalRange>::type> | 
					
						
							| 
									
										
										
										
											2013-01-22 00:44:53 +00:00
										 |  |  | gather ( | 
					
						
							| 
									
										
										
										
											2013-02-25 22:31:52 +00:00
										 |  |  |     const BidirectionalRange &range, | 
					
						
							|  |  |  |     typename boost::range_iterator<const BidirectionalRange>::type pivot, | 
					
						
							| 
									
										
										
										
											2013-01-22 00:44:53 +00:00
										 |  |  |     Pred pred ) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return boost::algorithm::gather ( boost::begin ( range ), boost::end ( range ), pivot, pred ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }}  // namespace
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /**************************************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 |