mirror of
				https://github.com/saitohirga/WSJT-X.git
				synced 2025-10-30 20:40:28 -04:00 
			
		
		
		
	
		
			
	
	
		
			183 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
		
		
			
		
	
	
			183 lines
		
	
	
		
			6.5 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
|  | [/ | ||
|  |     Copyright 2010 Neil Groves | ||
|  |     Distributed under the Boost Software License, Version 1.0. | ||
|  |     (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
|  | /] | ||
|  | [section:algorithms Range Algorithms] | ||
|  | [section:introduction Introduction and motivation] | ||
|  | In its most simple form a [*Range Algorithm] (or range-based algorithm) is simply an iterator-based algorithm where the /two/ iterator arguments have been replaced by /one/ range argument. For example, we may write | ||
|  | 
 | ||
|  | `` | ||
|  | #include <boost/range/algorithm.hpp> | ||
|  | #include <vector> | ||
|  | 
 | ||
|  | std::vector<int> vec = ...; | ||
|  | boost::sort(vec); | ||
|  | `` | ||
|  | 
 | ||
|  | instead of | ||
|  | 
 | ||
|  | `` | ||
|  | std::sort(vec.begin(), vec.end()); | ||
|  | `` | ||
|  | 
 | ||
|  | However, the return type of range algorithms is almost always different from that of existing iterator-based algorithms. | ||
|  | 
 | ||
|  | One group of algorithms, like `boost::sort()`, will simply return the same range so that we can continue to pass the range around and/or further modify it. Because of this we may write | ||
|  | `` | ||
|  | boost:unique(boost::sort(vec)); | ||
|  | `` | ||
|  | to first sort the range and then run `unique()` on the sorted range. | ||
|  | 
 | ||
|  | Algorithms like `boost::unique()` fall into another group of algorithms that return (potentially) narrowed views of the original range. By default `boost::unique(rng)` returns the range `[boost::begin(rng), found)` where `found` denotes the iterator returned by `std::unique(boost::begin(rng), boost::end(rng))` | ||
|  | 
 | ||
|  | Therefore exactly the unique values can be copied by writing | ||
|  | `` | ||
|  | boost::copy(boost::unique(boost::sort(vec)), | ||
|  |             std::ostream_iterator<int>(std::cout)); | ||
|  | `` | ||
|  | 
 | ||
|  | Algorithms like `boost::unique` usually return the range: `[boost::begin(rng), found)`. | ||
|  | However, this behaviour may be changed by supplying a `range_return_value` | ||
|  | as a template parameter to the algorithm: | ||
|  | 
 | ||
|  | [table | ||
|  |     [[Expression] [Return]] | ||
|  |     [[`boost::unique<boost::return_found>(rng)`] [returns a single iterator like `std::unique`]] | ||
|  |     [[`boost::unique<boost::return_begin_found>(rng)`] [returns the range `[boost::begin(rng), found)` (this is the default)]] | ||
|  |     [[`boost::unique<boost::return_begin_next>(rng)`] [returns the range `[boost::begin(rng), boost::next(found))`]] | ||
|  |     [[`boost::unique<boost::return_found_end>(rng)`] [returns the range `[found, boost::end(rng))`]] | ||
|  |     [[`boost::unique<boost::return_next_end>(rng)`] [returns the range `[boost::next(found),boost::end(rng))`]] | ||
|  |     [[`boost::unique<boost::return_begin_end>(rng)`] [returns the entire original range.]] | ||
|  | ] | ||
|  | 
 | ||
|  | This functionality has the following advantages: | ||
|  | 
 | ||
|  | # it allows for ['*seamless functional-style programming*] where you do not need to use named local variables to store intermediate results | ||
|  | # it is very ['*safe*] because the algorithm can verify out-of-bounds conditions and handle tricky conditions that lead to empty ranges | ||
|  | 
 | ||
|  | For example, consider how easy we may erase the duplicates in a sorted container: | ||
|  | 
 | ||
|  | `` | ||
|  | std::vector<int> vec = ...; | ||
|  | boost::erase(vec, boost::unique<boost::return_found_end>(boost::sort(vec))); | ||
|  | `` | ||
|  | 
 | ||
|  | Notice the use of `boost::return_found_end`. What if we wanted to erase all the duplicates except one of them? In old-fashioned STL-programming we might write | ||
|  | 
 | ||
|  | `` | ||
|  | // assume 'vec' is already sorted | ||
|  | std::vector<int>::iterator i = std::unique(vec.begin(), vec.end()); | ||
|  | 
 | ||
|  | // remember this check or you get into problems | ||
|  | if (i != vec.end()) | ||
|  |     ++i; | ||
|  | 
 | ||
|  | vec.erase(i, vec.end()); | ||
|  | `` | ||
|  | 
 | ||
|  | The same task may be accomplished simply with | ||
|  | `` | ||
|  | boost::erase(vec, boost::unique<boost::return_next_end>(vec)); | ||
|  | `` | ||
|  | and there is no need to worry about generating an invalid range. Furthermore, if the container is complex, calling `vec.end()` several times will be more expensive than using a range algorithm. | ||
|  | 
 | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section:mutating Mutating algorithms] | ||
|  | [include algorithm/copy.qbk] | ||
|  | [include algorithm/copy_backward.qbk] | ||
|  | [include algorithm/fill.qbk] | ||
|  | [include algorithm/fill_n.qbk] | ||
|  | [include algorithm/generate.qbk] | ||
|  | [include algorithm/inplace_merge.qbk] | ||
|  | [include algorithm/merge.qbk] | ||
|  | [include algorithm/nth_element.qbk] | ||
|  | [include algorithm/partial_sort.qbk] | ||
|  | [include algorithm/partition.qbk] | ||
|  | [include algorithm/random_shuffle.qbk] | ||
|  | [include algorithm/remove.qbk] | ||
|  | [include algorithm/remove_copy.qbk] | ||
|  | [include algorithm/remove_copy_if.qbk] | ||
|  | [include algorithm/remove_if.qbk] | ||
|  | [include algorithm/replace.qbk] | ||
|  | [include algorithm/replace_copy.qbk] | ||
|  | [include algorithm/replace_copy_if.qbk] | ||
|  | [include algorithm/replace_if.qbk] | ||
|  | [include algorithm/reverse.qbk] | ||
|  | [include algorithm/reverse_copy.qbk] | ||
|  | [include algorithm/rotate.qbk] | ||
|  | [include algorithm/rotate_copy.qbk] | ||
|  | [include algorithm/sort.qbk] | ||
|  | [include algorithm/stable_partition.qbk] | ||
|  | [include algorithm/stable_sort.qbk] | ||
|  | [include algorithm/swap_ranges.qbk] | ||
|  | [include algorithm/transform.qbk] | ||
|  | [include algorithm/unique.qbk] | ||
|  | [include algorithm/unique_copy.qbk] | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section:non_mutating Non-mutating algorithms] | ||
|  | [include algorithm/adjacent_find.qbk] | ||
|  | [include algorithm/binary_search.qbk] | ||
|  | [include algorithm/count.qbk] | ||
|  | [include algorithm/count_if.qbk] | ||
|  | [include algorithm/equal.qbk] | ||
|  | [include algorithm/equal_range.qbk] | ||
|  | [include algorithm/for_each.qbk] | ||
|  | [include algorithm/find.qbk] | ||
|  | [include algorithm/find_end.qbk] | ||
|  | [include algorithm/find_first_of.qbk] | ||
|  | [include algorithm/find_if.qbk] | ||
|  | [include algorithm/lexicographical_compare.qbk] | ||
|  | [include algorithm/lower_bound.qbk] | ||
|  | [include algorithm/max_element.qbk] | ||
|  | [include algorithm/min_element.qbk] | ||
|  | [include algorithm/mismatch.qbk] | ||
|  | [include algorithm/search.qbk] | ||
|  | [include algorithm/search_n.qbk] | ||
|  | [include algorithm/upper_bound.qbk] | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section:set Set algorithms] | ||
|  | [include algorithm/includes.qbk] | ||
|  | [include algorithm/set_union.qbk] | ||
|  | [include algorithm/set_intersection.qbk] | ||
|  | [include algorithm/set_difference.qbk] | ||
|  | [include algorithm/set_symmetric_difference.qbk] | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section:heap Heap algorithms] | ||
|  | [include algorithm/push_heap.qbk] | ||
|  | [include algorithm/pop_heap.qbk] | ||
|  | [include algorithm/make_heap.qbk] | ||
|  | [include algorithm/sort_heap.qbk] | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section:permutation Permutation algorithms] | ||
|  | [include algorithm/next_permutation.qbk] | ||
|  | [include algorithm/prev_permutation.qbk] | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section:new New algorithms] | ||
|  | [include algorithm_ext/copy_n.qbk] | ||
|  | [include algorithm_ext/erase.qbk] | ||
|  | [include algorithm_ext/for_each.qbk] | ||
|  | [include algorithm_ext/insert.qbk] | ||
|  | [include algorithm_ext/iota.qbk] | ||
|  | [include algorithm_ext/is_sorted.qbk] | ||
|  | [include algorithm_ext/overwrite.qbk] | ||
|  | [include algorithm_ext/push_back.qbk] | ||
|  | [include algorithm_ext/push_front.qbk] | ||
|  | [include algorithm_ext/remove_erase.qbk] | ||
|  | [include algorithm_ext/remove_erase_if.qbk] | ||
|  | [endsect] | ||
|  | 
 | ||
|  | [section:numeric Numeric algorithms] | ||
|  | [include numeric/accumulate.qbk] | ||
|  | [include numeric/adjacent_difference.qbk] | ||
|  | [include numeric/inner_product.qbk] | ||
|  | [include numeric/partial_sum.qbk] | ||
|  | [endsect] | ||
|  | [endsect] |