Operators category (defined below), the<algorithm> headerfile must be included. Before using a generic algorithm in theOperators category the<numeric> header file must be included.In the previous chapter the Standard Template Library (STL) was introduced. Animportant element of the STL, thegeneric algorithms, was not covered inthat chapter as they form a fairly extensive part of the STL. Over time theSTL has grown considerably, mainly as a result of a growing importance andappreciation oftemplates. Covering generic algorithm in the STL chapteritself would turn that chapter into an unwieldy one and so the genericalgorithms were moved to a chapter of their own.
Generic algorithms perform an amazing task. Due to the strength of templates,algorithms could be developed that can be applied to a wide range of differentdata types while maintaining type safety. The prototypical example of this isthesort generic algorithm. To contrast: whileC requiresprogrammers to write callback functions in which type-unsafevoid const *parameters have to be used, internally forcing the programmer to resort tocasts, STL'ssort frequently allows the programmer merely to statesomething akin to
sort(first-element, last-element)
Generic algorithms should be used wherever possible. Avoid the urge to designyour own code for commonly encountered algorithms. Make it a habit tofirst thoroughly search the generic algorithms for an availablecandidate. The generic algorithms should become yourweapon of choice whenwriting code: acquire full familiarity with them and make their use your`second nature'.
On the other hand, without downgrading the importance of the genericalgorithms, it's clear that over the years the number of available genericalgorithms have seen an almost unlimited growth. Many new algorithms wereadded, even though for quite a few of them it's either very easy to providedirect implementations, or which may hardly ever be used. Anexample is theis_sorted generic algorithm, simply returningtrue if arange of elements is considered sorted andfalse if not. How hard is it todefine such a function in the occasional situation you might need it? Thisapplies to quite a few other generic algorithms. It's of course nice to havean extensive toolbox, but do you need, e.g., screwdrivers thatperfectly match the screws' heads? Most likely not.... To avoid an excessivegrowth of this chapter, some sections contain comparable algorithms, and insome sections links tocppreference areprovided when referring to comparable algorithms.
Nevertheless, this chapter's sections cover many of the STL'sgeneric algorithms (in alphabetical order). For each algorithm thefollowing information is provided:
Type is used to specify ageneric data type. Furthermore, the particular type of iterator (seesection18.2) that is required is mentioned as well as other generictypes that might be required (e.g., performingBinaryOperations, likeplus<Type>). Although iterators are commonly provided by abstractcontainers and comparable pre-defined data structures, at some point you maywant to design your own iterators. Section22.14 offers guidelinesfor constructing your own iterator classes and provides an overview of ofoperators that must be implemented for the various types of iterators.Almost every generic algorithm expects an iterator range[first, last),defining the series of elements on which the algorithm operates. The iteratorspoint to objects or values. When an iterator points to aType value orobject, function objects used by the algorithms usually receiveType const& objects or values. Usually function objects cannot modify the objects theyreceive as their arguments. This does not hold true formodifying genericalgorithms, whichare of course able to modify the objects they operateupon.
Generic algorithms may be categorized. TheC++ Annotations distinguishes the following categories of generic algorithms:
all_of; any_of;equal;includes;lexicographical_compare;mismatch;none_of;
copy;copy_backward;copy_if;move; move_backward;partition_copy;partial_sort_copy;remove_copy; remove_copy_if;replace_copy; replace_copy_if;reverse_copy;rotate_copy;sample;shift_left; shift_right;unique_copy;
count; count_if;
make_heap;pop_heap;push_heap;sort_heap;
fill; fill_n;generate; generate_n;iota;uninitialized (raw) memory;
begin; end;
accumulate;adjacent_difference;exclusive_scan; inclusive_scan;inner_product;partial_sum;reduce;transform_reduce;
adjacent_find;binary_search;equal_range;find;find_end;find_first_of;find_if; find_if_not;lower_bound;max;max_element; min_element;min;minmax;minmax_element;partition_point;search; search_n;set_difference;set_intersection;set_symmetric_difference;set_union;upper_bound;
inplace_merge;iter_swap;merge;next_permutation;nth_element;partial_sort;partition;prev_permutation;remove; remove_copy; remove_copy_if; remove_if;reverse; reverse_copy;rotate; rotate_copy;shuffle;sort;stable_partition;stable_sort;swap; swap_ranges;unique;
is_partitioned;is_permutation;is_sorted;is_sorted_until;
for_each;replace; replace_copy; replace_copy_if; replace_if;transform;unique_copy;
generate (section19.1.19), fillingthe elements with values produced by a generating function. If those valuesare randomly generated values thengenerated could very well beparallized, where each parallel thread handles a separate section of the rangeto be filled. Another example where parallel execution may be useful is whensorting series of values. For this the thesort generic algorithm can beused (section19.1.54, which also contains an example of parallelizedsorting).These (and many other) generic algorithms can be executed in parallel,depending on the specifiedexecution policy. When no execution policy isspecified then the algorithms operated in their standard, sequential, way. Thegeneric algorithms supporting execution policies have overloaded versionswhere the first parameter specifies the execution policy to use, followed bytheir remaining parameters. Function prototypes listed the following sectionsshowing a first parameter[ExecPol,] may specify one of the executionpolicies introduced in this section as their first arguments. E.g., one of thesort generic algorithm's prototypes is
void sort([ExecPol,] RandomAccessIterator first, RandomAccessIterator last);and to sort, e.g., a vector if strings (
vs), it can be called assort(vs.bgin(), vs.end());or as (see below)
sort(execution::par, vs.bgin(), vs.end());
In order to use execution policies the<execution> header file must beincluded, and the linking option-ltbb must be specified with linking thecompiled object files(s).
There are four types of execution policies (all defined in thestdnamespace):
<execution::sequenced_policy>, whose predefined objectexecution::seq is used to specify this execution policy when calling generic algorithms.When calling a generic algorithm specifying this policy it will not be using parallel execution.
<execution::parallel_policy>, whose predefined objectexecution::par is used to specify this execution policy when calling generic algorithms.When calling a generic algorithm specifying this policy it may be using parallel execution: the generic algorithm may decide not to use parallel execution when it decides that the overhead of parallel execution is in fact reducing the efficiency of non-parallel execution. E.g., when sorting 100 elements sequential execution is faster than parallel execution and an algorithm likesort won't use parallel execution.
<execution::parallel_unsequenced_policy>, whose predefined objectexecution::par_unseq is used to specify this execution policy when calling generic algorithms.When calling a generic algorithm specifying this policy it may be using parallel execution, execution may be migrated across threads (using a so-calledparent-stealing scheduler), or execution may bevectorized (i.e., a single thread is used accessing data items at completely different locations (like swapping the first and middle elements of vectors)). When using this policy the order in which processed elements are accessed and the threads from which these elements are accessed is undefined.
<execution::unsequenced_policy>, whose predefined objectexecution::unseq is used to specify this execution policy when calling generic algorithms.When calling a generic algorithm specifying this policy the algorithm uses vectorized execution.
Whenever algorithms are called using the above policy specifications andduring the execution of these algorithms functions are called generatinguncaught exceptionsstd::terminate is called.
When using parallel execution the objects or functions passed to the genericalgorithms might access data defined elsewhere. If those data are modifiedthen it is possible that modifications are requested from different executionthreads, which could result indata races ordeadlocks. The programmer should ensure that data races and/ordadlocks cannot occur when using parallel execution.
<numeric>Type accumulate(InputIterator first, InputIterator last, Type init);Type accumulate(InputIterator first, InputIterator last, Type init, BinaryOperation op);operator+ is applied to the initialvalueinit (lhs argument) and, in sequence, all elements reached fromthe iterator range (rhs argument). The resulting value is returned.op is applied tothe initial valueinit (lhs argument) and, in sequence, all elementsreached from the iterator range. The resulting value is returned.minus<int> is used with the intial value 1, and the iterators refer to 2 and 3, then at step 1: 1 - 2 = -1 is computed and at step 2: -1 - 3 = -4. Soaccumulate returns -4.(See also thereduce algorithm (section19.1.43)).
#include <numeric> #include <vector> #include <iostream> using namespace std; int main() { int ia[] = {1, 2, 3, 4}; vector<int> iv(ia, ia + 4); cout << "Sum: " << accumulate(iv.begin(), iv.end(), int()) << "\n" "Product: " << accumulate(iv.begin(), iv.end(), int(1), multiplies<int>{}) << '\n'; } // Displays: // Sum: 10 // Product: 24<numeric>OutputIterator adjacent_difference([ExecPol,] InputIterator first,InputIterator last, OutputIterator result);OutputIterator adjacent_difference([ExecPol,] InputIterator first,InputIterator last, OutputIterator result, BinaryOperation op);op applied to thecorresponding element in the input range (left operand) and its previouselement (right operand). #include <numeric> #include <vector> #include <iterator> #include <iostream> using namespace std; int main() { int ia[] = {1, 2, 5, 10}; vector<int> iv(ia, ia + 4); vector<int> ov(iv.size()); adjacent_difference(iv.begin(), iv.end(), ov.begin()); copy(ov.begin(), ov.end(), ostream_iterator<int>(cout, " ")); cout << '\n'; adjacent_difference(iv.begin(), iv.end(), ov.begin(), minus<int>()); copy(ov.begin(), ov.end(), ostream_iterator<int>(cout, " ")); cout << '\n'; } // Displays: // 1 1 3 5 // 1 1 3 5<algorithm>ForwardIterator adjacent_find([ExecPol,] ForwardIterator first, ForwardIterator last);OutputIterator adjacent_find([ExecPol,] ForwardIterator first,ForwardIterator last, Predicate pred);last is returned.pred returnstrue is returned. If no such element exists,last is returned. #include <algorithm> #include <string> #include <iostream> using namespace std; bool squaresDiff10(size_t first, size_t second) { return second * second - first * first >= 10; } int main() { string sarr[] = { "Alpha", "bravo", "charley", "delta", "echo", "echo", "foxtrot", "golf" }; auto last = end(sarr); // see the 'begin / end' section string *result = adjacent_find(sarr, last); cout << *result << '\n'; result = adjacent_find(++result, last); cout << "Second time, starting from the next position:\n" << ( result == last ? "** No more adjacent equal elements **" : "*result" ) << '\n'; size_t iv[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; size_t *ires = adjacent_find(iv, end(iv), squaresDiff10); cout << "The first numbers for which the squares differ at least 10: " << *ires << " and " << *(ires + 1) << '\n'; } // Displays: // // echo // Second time, starting from the next position: // ** No more adjacent equal elements ** // The first numbers for which the squares differ at least 10: 5 and 6<algorithm>bool all_of([ExecPol,] InputIterator first, InputIterator last, Predicate pred);bool any_of([ExecPol,] InputIterator first, InputIterator last, Predicate pred);bool none_of([ExecPol,] InputIterator first, InputIterator last, Predicate pred);true if the unary predicatepred returnstrue for all elements reached from the iterator range[first, last); otherwisefalse is returned.true if the unary predicatepred returnstrue for at least on of the elements reached from theiterator range[first, last); otherwisefalse is returned.true if the unary predicatepred returnstrue for none of the elements reached from the iteratorrange[first, last); otherwisefalse is returned. #include <algorithm> #include <string> #include <iostream> using namespace std; bool contains_a(string const &str) { return str.find('a') != string::npos; } int main() { string sarr[] = { "Alpha", "Bravo", "Charley", "Delta", "Echo" }; auto past = end(sarr); // see the next section cout << "All elements contain 'a': " << all_of(sarr, past, contains_a) << "\n" "At least one element contains 'a': " << any_of(sarr, past, contains_a) << "\n" "None of the elements contains 'a': " << none_of(sarr, past, contains_a) << '\n'; } // Displays: // All elements contain 'a': 0 // At least one element contains 'a': 1 // None of the elements contains 'a': 0<iterator> (also available when including<algorithm>)auto begin([const] &obj);auto end([const] &obj);Type [cons] *begin(Type [const] (&array)[N]);Type [cons] *end(Type [const] (&array)[N]);auto cbegin(const &obj);auto cend(const &obj);begin andend functions return, respectively, the begin-and end-iterators or pointers of objects offeringbegin() andend()members or of arrays of (compile-time) available sizes.obj.begin() andobj.end() of (possiblyconst) references toobjconst) pointers to, respectively, the first and beyond the last element of thearray argument, which must be an array of (compile-time) known size.obj.begin() andobj.end() ofconst references toobj #include <iterator> #include <iostream> #include <string> using namespace std; int main() { string sarr[] = { "Alpha", "Bravo", "Charley", "Delta", "Echo" }; // since sarr == begin(sarr), begin(...) is not used here auto next = end(sarr); cout << "sarr has " << size(sarr) << " (== " << (next - sarr) << ") elements\n" "the last char. of the first element is " << *(end(sarr[0]) - 1) << '\n'; } // Displays: // sarr has 5 (== 5) elements // the last char. of the first element is a<algorithm>bool binary_search(ForwardIterator first, ForwardIteratorlast, Type const &value);bool binary_search(ForwardIterator first, ForwardIteratorlast, Type const &value, Comparator comp);value is searched for using binarysearch in the elements reached from the iterator range[first,last). The elements must have been sorted by theType::operator<function.True is returned if the element was found,false otherwise.value is searched for using binarysearch in the elements reached from the iterator range[first,last). The elements in the range must have been sorted by theComparatorfunction object.True is returned if the element was found,falseotherwise. As illustrated by the following example, the function objectfunction's first parameter refers to an element in the iterator range, whilethe function object's second parameter refers tovalue. #include <algorithm> #include <string> #include <iostream> #include <functional> using namespace std; int main() { string sarr[] = { "alpha", "bravo", "charley", "delta", "echo", "foxtrot", "golf", "hotel" }; auto past = end(sarr); bool result = binary_search(sarr, past, "foxtrot"); cout << (result ? "found " : "didn't find ") << "foxtrot" << '\n'; reverse(sarr, past); // reverse the order of elements // binary search now fails: result = binary_search(sarr, past, "foxtrot"); cout << (result ? "found " : "didn't find ") << "foxtrot" << '\n'; // ok when using appropriate // comparator: result = binary_search(sarr, past, "foxtrot", greater<string>()); cout << (result ? "found " : "didn't find ") << "foxtrot" << '\n'; // alternatively, using a lambda expression showing the used 'sarr' // indices and the value of the second parameter: result = binary_search(sarr, past, "foxtrot", [&](string const &sarrEl, string const &value) { cout << "comparing element " << (&sarrEl - sarr) << " (" << sarrEl << ") to " << value << '\n'; return sarrEl > value; } ); cout << "found it: " << result << '\n'; } // Displays: // found foxtrot // didn't find foxtrot // found foxtrot // comparing element 4 (delta) to foxtrot // comparing element 2 (foxtrot) to foxtrot // comparing element 1 (golf) to foxtrot // comparing element -3 (foxtrot) to foxtrot // found it: 1Ifvalue is in fact present in the range of values, then this genericalgorithm doesn't answer the question wherevalue is located. If thatquestion must be answered the generic algorithmslower_boundandupper_bound can be used. Refer to sections19.1.30 and19.1.61 for examples illustrating the use of theselatter two algorithms.
<algorithm>OutputIterator copy([ExecPol,] InputIterator first,InputIterator last, OutputIterator destination);OutputIterator copy_if([ExecPol,] InputIterator first,InputIterator last, OutputIterator destination, Predicate pred);[first, last) are copied (assigned) to thedestination outputrange. The return value is the OutputIterator pointing just beyond the lastelement that was copied to the destination range (so, `last' in thedestination range is returned).n elements, returning an iterator pointingjust beyond the last element that was copied to the destination range.copy. It uses anostream_iterator forstring objects. This iterator writes thestring values to thespecifiedostream (i.e.,cout), separating the values by the specifiedseparation string (i.e.," "). #include <algorithm> #include <string> #include <iostream> #include <iterator> using namespace std; bool pred(std::string const &str) { return "aceg"s.find(str.front()) == string::npos; } int main() { string sarr[] = { "alpha", "bravo", "charley", "delta", "echo", "foxtrot", "golf", "hotel" }; auto last = end(sarr); copy(sarr + 2, last, sarr); // move all elements two positions left // copy to cout using an ostream_iterator for strings copy(sarr, last, ostream_iterator<string>(cout, " ")); cout << '\n'; // using copy_if: copy_if(sarr, sarr + size(sarr), sarr, pred); copy(sarr, sarr + size(sarr), ostream_iterator<string>(cout, " ")); cout << '\n'; } // Displays: // charley delta echo foxtrot golf hotel golf hotel // delta foxtrot hotel hotel golf hotel golf hotelunique_copy<algorithm>BidirectionalIterator copy_backward(InputIterator first,InputIterator last, BidirectionalIterator last2);[first, last) are copied from the element at positionlast - 1until (and including) the element at positionfirst to the element range,ending at positionlast2 - 1 using the assignment operator of theunderlying data type. The destination range is therefore[last2 - (last- first), last2).Note that this algorithm doesnot reverse the order of the elements whencopying them to the destination range.
The return value is the BidirectionalIterator pointing to the last elementthat was copied to the destination range (so, `first' in the destinationrange, pointed to bylast2 - (last - first), is returned).
#include <algorithm> #include <string> #include <iostream> #include <iterator> using namespace std; int main() { string sarr[] = { "alpha", "bravo", "charley", "delta", "echo", "foxtrot", "golf", "hotel" }; auto past = end(sarr); copy ( copy_backward(sarr + 3, past, past - 3), past, ostream_iterator<string>(cout, " ") ); cout << '\n'; } // Displays: golf hotel foxtrot golf hotel foxtrot golf hotel<algorithm>size_t count([ExecPol,] InputIterator first, InputIterator last, Type const &value);size_t count_if([ExecPol,] InputIterator first, InputIterator last, Predicate predicate);valueoccurs in the elements reached from the iterator range[first, last).UsesType::operator== to determine whethervalue is equal to anelement in the iterator range.predicate' returnstrue when applied to theelements reached from the iterator range[first, last). #include <algorithm> #include <iostream> using namespace std; bool pred(int value) { return value & 1; } int main() { int ia[] = {1, 2, 3, 4, 3, 4, 2, 1, 3}; cout << "Number of times the value 3 is available: " << count(ia, ia + size(ia), 3) << "\n" "Number of odd values in the array is: " << count_if(ia, ia + size(ia), pred) << '\n'; } // Displays: Number of times the value 3 is available: 3 // Number of odd values in the array is: 5<algorithm>bool equal([ExecPol,] InputIterator first, InputIterator last, InputIterator otherFirst);bool equal([ExecPol,] InputIterator first, InputIterator last, InputIterator otherFirst, BinaryPredicate pred);[first,last) are compared to a range of equal length starting atotherFirst. Thefunction returnstrue if the visited elements in both ranges are equalpairwise. The ranges need not be of equal length, only the elements in theindicated range are considered (and must be available).[first, last) are compared to a range of equal length starting atotherFirst. The function returnstrue if the binary predicate, appliedto all corresponding elements in both ranges returnstrue for every pairof corresponding elements. The ranges need not be of equal length, only theelements in the indicated range are considered (and must be available). #include <algorithm> #include <string> #include <cstring> #include <iostream> using namespace std; bool caseString(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) == 0; } int main() { string first[] = { "Alpha", "bravo", "Charley", "delta", "Echo", "foxtrot", "Golf", "hotel" }; string second[] = { "alpha", "bravo", "charley", "delta", "echo", "foxtrot", "golf", "hotel" }; auto past = end(first); cout << "The elements of `first' and `second' are pairwise " << (equal(first, past, second) ? "equal" : "not equal") << '\n' << "compared case-insensitively, they are " << ( equal(first, past, second, caseString) ? "equal" : "not equal" ) << '\n'; } // Displays: // The elements of `first' and `second' are pairwise not equal // compared case-insensitively, they are equal<algorithm>pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first, ForwardIterator last, Typeconst &value);pair<ForwardIterator, ForwardIterator> equal_range(ForwardIterator first, ForwardIterator last, Typeconst &value, Compare comp);map (section12.3.7) andmultimap (section12.3.8)):operator< of the data type to which the iterators point was used tosort the elements in the provided range), a pair of iterators is returnedrepresenting the return value of, respectively,lower_bound (returningthe first element that is not smaller than the provided reference value, seesection19.1.30) andupper_bound (returning the first elementbeyond the provided reference value, see section19.1.61).comp function object was used to sort the elements in the providedrange), a pair of iterators is returned representing the return values of,respectively, the functionslower_bound (section19.1.30) andupper_bound (section19.1.61). #include <algorithm> #include <functional> #include <iterator> #include <iostream> using namespace std; int main() { int range[] = {1, 3, 5, 7, 7, 9, 9, 9}; auto past = end(range); pair<int *, int *> pi; pi = equal_range(range, past, 6); cout << "Lower bound for 6: " << *pi.first << "\n" "Upper bound for 6: " << *pi.second << '\n'; pi = equal_range(range, past, 7); cout << "Lower bound for 7: "; copy(pi.first, past, ostream_iterator<int>(cout, " ")); cout << '\n'; cout << "Upper bound for 7: "; copy(pi.second, past, ostream_iterator<int>(cout, " ")); cout << '\n'; sort(range, past, greater<int>()); cout << "Sorted in descending order\n"; copy(range, past, ostream_iterator<int>(cout, " ")); cout << '\n'; pi = equal_range(range, past, 7, greater<int>()); cout << "Lower bound for 7: "; copy(pi.first, past, ostream_iterator<int>(cout, " ")); cout << '\n'; cout << "Upper bound for 7: "; copy(pi.second, past, ostream_iterator<int>(cout, " ")); cout << '\n'; } // Displays: // Lower bound for 6: 7 // Upper bound for 6: 7 // Lower bound for 7: 7 7 9 9 9 // Upper bound for 7: 9 9 9 // Sorted in descending order // 9 9 9 7 7 5 3 1 // Lower bound for 7: 7 7 5 3 1 // Upper bound for 7: 5 3 1<utility>Type exchange(Type &object1, ValueType &&newValue);newValue is assigned toobject1, andobject1's previous value is returned. #include <utility> #include <iostream> using namespace std; int main(int argc, char **argv) { bool more = argc > 5; cout << "more than 5: " << exchange(more, argc > 2) << ", more than 2: " << more << '\n'; } // With `a.out one two three' displays: // // more than 5: 0, more than 2: 1<algorithm>void fill([ExecPol,] ForwardIterator first,ForwardIterator last, Type const &value);void fill_n([ExecPol,] ForwardIterator first, Size n, Type const &value);[first, last) are initialized tovalue, overwritingpreviously stored values.n elements starting at the elementpointed to byfirst are initialized tovalue, overwriting previouslystored values. #include <algorithm> #include <vector> #include <iterator> #include <iostream> using namespace std; int main() { vector<int> iv(8); fill(iv.begin(), iv.end(), 8); copy(iv.begin(), iv.end(), ostream_iterator<int>(cout, " ")); cout << '\n'; fill_n(iv.begin() + 2, 4, 4); copy(iv.begin(), iv.end(), ostream_iterator<int>(cout, " ")); cout << '\n'; } // Displays: 8 8 8 8 8 8 8 8 // 8 8 4 4 4 4 8 8<algorithm>InputIterator find([ExecPol,] InputIterator first, InputIterator last, Type const &value);InputIterator find_if([ExecPol,] InputIterator first, InputIterator last, Predicate pred);InputIterator find_if_not([ExecPol,] InputIterator first, InputIterator last, Predicate pred);value is searched for in theelements reached from the iterator range[first, last). An iteratorpointing to the first element found is returned. If the element was not found,last is returned. Theoperator== of the underlying data type is usedto compare the elements.[first, last) for whichthe (unary) predicatepred returnstrue. If the element was not found,last is returned.[first, last) for which the(unary) predicatepred returnsfalse. If the element was not found,last is returned. Thus,pred defines what is considered acceptable, inwhich casefind_if_not returns an iterator to the first element thatisn't. #include <algorithm> #include <string> #include <cstring> #include <iterator> #include <iostream> using namespace std; class CaseName { std::string d_string; public: CaseName(char const *str): d_string(str) {} bool operator()(std::string const &element) const { return strcasecmp(element.c_str(), d_string.c_str()) == 0; } }; void show(string const *begin, string const *end) { if (begin == end) cout << "No elements were found"; else copy(begin, end, ostream_iterator<string>{ cout, " " }); cout << '\n'; } int main() { string sarr[] = { "Alpha", "Bravo", "Charley", "Delta", "Echo" }; auto past = end(sarr); show(find(sarr, past, "Delta"), past); show(find(sarr, past, "India"), past); show(find_if(sarr, sarr + size(sarr), CaseName{ "charley" }), past); if (find_if(sarr, sarr + size(sarr), CaseName{ "india" }) == past) cout << "`india' was not found in the range\n"; show(find_if_not(sarr, sarr + size(sarr), CaseName{ "alpha" }), past); } // Displays: // Delta Echo // No elements were found // Charley Delta Echo // `india' was not found in the range // Bravo Charley Delta Echo<algorithm>ForwardIterator1 find_end([ExecPol,] ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)ForwardIterator1 find_end([ExecPol,] ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2, BinaryPredicate pred)[first1, last1) is searched for the last occurrence of the sequence ofelements in the range[first2, last2). If the sequence[first2, last2) is not found,last1 is returned, otherwise aniterator pointing to the first element of the matching sequence isreturned. Theoperator== of the underlying data type is used to comparethe elements in the two sequences.[first1, last1) is searched for the last occurrence of the sequence ofelements in the range[first2, last2). If the sequence[first2,last2) is not found,last1 is returned, otherwise an iterator pointing tothe first element of the matching sequence is returned. The provided binarypredicate is used to compare the elements in the two sequences. #include <algorithm> #include <string> #include <iterator> #include <iostream> using namespace std; bool twice(size_t first, size_t second) { return first == (second << 1); } int main() { string sarr[] = { "alpha", "bravo", "charley", "delta", "echo", "foxtrot", "golf", "hotel", "foxtrot", "golf", "hotel", "india", "juliet", "kilo" }; string search[] = { "foxtrot", "golf", "hotel" }; auto past = end(sarr); copy ( find_end(sarr, past, search, search + 3), // sequence starting past, ostream_iterator<string>{ cout, " " } // at 2nd 'foxtrot' ); cout << '\n'; size_t range[] = { 2, 4, 6, 8, 10, 4, 6, 8, 10 }; size_t nrs[] = { 2, 3, 4 }; copy // sequence of values starting at last sequence ( // of range[] that are twice the values in nrs[] find_end(range, range + 9, nrs, nrs + 3, twice), range + 9, ostream_iterator<size_t>{ cout, " " } ); cout << '\n'; } // Displays: // foxtrot golf hotel india juliet kilo // 4 6 8 10<algorithm>ForwardIterator1 find_first_of([ExecPol,] ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2, ForwardIterator2 last2)ForwardIterator1 find_first_of([ExecPol,] ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2,ForwardIterator2 last2, BinaryPredicate pred)[first1, last1) is searched for the first occurrence of an element inthe sequence of elements in the range[first2, last2). If noelement in the sequence[first2, last2) is found,last1 isreturned, otherwise an iterator pointing to the first element in[first1, last1) that is equal to an element in[first2, last2)is returned. Theoperator== of the underlying data type is used to comparethe elements in the two sequences.[first1, last1) is searched for the first occurrence of an element inthe sequence of elements in the range[first2, last2). Each element inthe range[first1, last1) is compared to each element in the range[first2, last2), and an iterator to the first element in[first1, last1) for which the binary predicatepred (receiving anthe element out of the range[first1, last1) and an element from therange[first2, last2)) returnstrue is returned. Otherwise,last1 is returned. #include <algorithm> #include <string> #include <iterator> #include <iostream> using namespace std; bool twice(size_t first, size_t second) { return first == (second << 1); } int main() { string sarr[] = { "alpha", "bravo", "charley", "delta", "echo", "foxtrot", "golf", "hotel", "foxtrot", "golf", "hotel", "india", "juliet", "kilo" }; string search[] = { "foxtrot", "golf", "hotel" }; auto past = end(sarr); copy ( // sequence starting find_first_of(sarr, past, search, search + 3),// at 1st 'foxtrot' past, ostream_iterator<string>{ cout, " " } ); cout << '\n'; size_t range[] = {2, 4, 6, 8, 10, 4, 6, 8, 10}; size_t nrs[] = {2, 3, 4}; // copy the sequence of values in 'range', starting at the // first element in 'range' that is equal to twice one of the // values in 'nrs', and ending at the past element of 'range' copy ( find_first_of(range, range + 9, nrs, nrs + 3, twice), range + 9, ostream_iterator<size_t>{ cout, " " } ); cout << '\n'; } // Displays: // foxtrot golf hotel foxtrot golf hotel india juliet kilo // 4 6 8 10 4 6 8 10<algorithm>Function for_each([ExecPol,] ForwardIterator first, ForwardIterator last, Function func);[first, last) are passed in sequence as a reference to the function (orfunction object)func. The function may modify the elements it receives(as the used iterator is a forward iterator). Alternatively, if the elementsshould be transformed,transform (see section19.1.56) can beused. The function itself or a copy of the provided function object isreturned: see the example below, in which an extra argument list is added tothefor_each call, which argument is eventually also passed to thefunction given tofor_each. Withinfor_each the return value of thefunction that is passed to it is ignored. Thefor_each generic algorithmlooks a lot like the range-based for loop, but different from the range-basedfor-loop thefor_each algorithm can also be used with sub-ranges and withreverse-iterators. #include <algorithm> #include <string> #include <iostream> #include <cctype> using namespace std; void lowerCase(char &ch) // `ch' *is* modified { ch = tolower(static_cast<unsigned char>(ch)); } void capitalizedOutput(string const &str) // `str' is *not* modified { char *tmp = new char[str.size() + 1](); str.copy(tmp, str.size()); for_each(tmp + 1, tmp + str.size(), lowerCase); tmp[0] = toupper(*tmp); cout << tmp << ' '; delete[] tmp; } int main() { string sarr[] = { "alpha", "BRAVO", "charley", "DELTA", "echo", "FOXTROT", "golf", "HOTEL" }; for_each(sarr, end(sarr), capitalizedOutput)("that's all, folks"); cout << '\n'; } // Displays: // Alpha Bravo Charley Delta Echo Foxtrot Golf Hotel That's all, folks #include <algorithm> #include <string> #include <iostream> #include <cctype> using namespace std; void lowerCase(char &c) { c = tolower(static_cast<unsigned char>(c)); } class Show { int d_count; public: Show() : d_count(0) {} void operator()(std::string &str) { std::for_each(str.begin(), str.end(), lowerCase); str[0] = toupper(str[0]); // assuming str is not empty std::cout << ++d_count << " " << str << "; "; } int count() const { return d_count; } }; int main() { string sarr[] = { "alpha", "BRAVO", "charley", "DELTA", "echo", "FOXTROT", "golf", "HOTEL" }; string *last = sarr + sizeof(sarr) / sizeof(string); cout << for_each(sarr, last, Show{}).count() << '\n'; } /* Displays (all on one line): 1 Alpha; 2 Bravo; 3 Charley; 4 Delta; 5 Echo; 6 Foxtrot; 7 Golf; 8 Hotel; 8 */for_each algorithm may be used withfunctions definingconst and non-const parameters. Also, see section19.1.56 for differences between thefor_each andtransformgeneric algorithms.Thefor_each algorithm cannot directly be used (i.e., by passing*this as the function object argument) inside a member function to modifyits own object as thefor_each algorithm first creates its own copy of thepassed function object. Alambda function or awrapper class whoseconstructor accepts a pointer or reference to the current object and possiblyto one of its member functions solves this problem.
<algorithm>void generate([ExecPol,] ForwardIterator first, ForwardIterator last, Generator generator);void generate_n([ExecPol,] ForwardIterator first, Size n, Generator generator);[first, last) are initialized by the return value ofgenerator, which can be a function or functionobject.Generator::operator() does not receive any arguments. The exampleuses a well-known fact from algebra: in order to obtain the square ofn +1, add1 + 2 * n ton * n.n elements starting at the elementpointed to by iteratorfirst are initialized by the return value ofgenerator. #include <algorithm> #include <vector> #include <iterator> #include <iostream> using namespace std; class NaturalSquares { size_t d_newsqr; size_t d_last; public: NaturalSquares(): d_newsqr(0), d_last(0) {} size_t operator()() { // using: (a + 1)^2 == a^2 + 2*a + 1 return d_newsqr += (d_last++ << 1) + 1; } }; int main() { vector<size_t> uv(10); generate(uv.begin(), uv.end(), NaturalSquares{}); copy(uv.begin(), uv.end(), ostream_iterator<int>{ cout, " " }); cout << '\n'; uv = vector<size_t>(10); generate_n(uv.begin(), 5, NaturalSquares{}); copy(uv.begin(), uv.end(), ostream_iterator<int>{ cout, " " }); cout << '\n'; } // Displays: 1 4 9 16 25 36 49 64 81 100 // 1 4 9 16 25 0 0 0 0 0<algorithm>bool includes([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);bool includes([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,Compare comp);[first1, last1) and[first2, last2) should have beensorted using theoperator< of the data type to which the iteratorspoint. The function returnstrue if every element in the second sequence[first2, last2) is contained in the first sequence[first1,last1) (the second range is a subset of the first range).[first1, last1) and[first2, last2) should have beensorted using thecomp function object. The function returnstrue ifevery element in the second sequence[first2, last2) is contained inthe first sequence[first1, last1) (the second range is a subset ofthe first range). #include <algorithm> #include <string> #include <cstring> #include <iostream> using namespace std; bool caseString(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) == 0; } int main() { string first1[] = { "alpha", "bravo", "charley", "delta", "echo", "foxtrot", "golf", "hotel" }; auto past1 = end(first1); string first2[] = { "Alpha", "bravo", "Charley", "delta", "Echo", "foxtrot", "Golf", "hotel" }; auto past2 = end(first2); string second[] = { "charley", "foxtrot", "hotel" }; cout << "The elements of `second' are " << (includes(first1, past1, second, second + 3) ? "" : "not") << " contained in the first sequence:\n" "second is a subset of first1\n" "The elements of `first1' are " << (includes(second, second + 3, first1, past1) ? "" : "not") << " contained in the second sequence\n" "The elements of `second' are " << (includes(first2, past2, second, second + 3) ? "" : "not") << " contained in the first2 sequence\n" "Using case-insensitive comparison,\n" "the elements of `second' are " << (includes(first2, past2, second, second + 3, caseString) ? "" : "not") << " contained in the first2 sequence\n"; } // Displays: // The elements of `second' are contained in the first sequence: // second is a subset of first1 // The elements of `first1' are not contained in the second sequence // The elements of `second' are not contained in the first2 sequence // Using case-insensitive comparison, // the elements of `second' are contained in the first2 sequence<numeric>Type inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, Type init);Type inner_product(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, Type init, BinaryOperator1 op1, BinaryOperator2 op2);[first1, last1) and the same number ofelements starting at the element pointed to byfirst2 are added toinit, and this sum is returned. The function uses theoperator+ andoperator* of the data type to which the iterators point.op1 instead of thedefault addition operator, and binary operatorop2 instead of the defaultmultiplication operator are applied to all pairwise elements in therange[first1, last1) and the same number of elements starting at theelement pointed to byfirst2. The results of the binary operator calls areadded toinit andinit's final value is returned. #include <numeric> #include <algorithm> #include <iterator> #include <iostream> #include <string> using namespace std; class Cat { std::string d_sep; public: Cat(string const &sep) : d_sep(sep) {} string operator() (string const &s1, string const &s2) const { return s1 + d_sep + s2; } }; int main() { size_t ia1[] = { 1, 2, 3, 4, 5, 6, 7 }; cout << "The sum of all squares in "; copy(ia1, ia1 + 7, ostream_iterator<size_t>{ cout, " " }); cout << "is " << inner_product(ia1, ia1 + 7, ia1, 0) << '\n'; size_t ia2[] = { 7, 6, 5, 4, 3, 2, 1 }; cout << "The sum of all cross-products in "; copy(ia1, ia1 + 7, ostream_iterator<size_t>{ cout, " " }); cout << "and "; copy(ia2, ia2 + 7, ostream_iterator<size_t>{ cout, " " }); cout << "is " << inner_product(ia1, ia1 + 7, ia2, 0) << '\n'; string names1[] = { "Frank", "Karel", "Piet" }; string names2[] = { "Brokken", "Kubat", "Plomp"}; cout << "All combined names of "; copy(names1, names1 + 3, ostream_iterator<string>{ cout, " " }); cout << "and\n"; copy(names2, names2 + 3, ostream_iterator<string>{ cout, " " }); cout << "are:" << inner_product(names1, names1 + 3, names2, string{ "\t" }, Cat{ "\n\t"}, Cat{ " " }) << '\n'; } // Displays: // The sum of all squares in 1 2 3 4 5 6 7 is 140 // The sum of all cross-products in 1 2 3 4 5 6 7 and 7 6 5 4 3 2 1 is 84 // All combined names of Frank Karel Piet and Brokken Kubat Plomp are: // Frank Brokken // Karel Kubat // Piet Plomp<algorithm>void inplace_merge([ExecPol,] BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last);void inplace_merge([ExecPol,] BidirectionalIterator first, BidirectionalIterator middle, BidirectionalIterator last, Compare comp);[first,middle) and[middle, last) are merged, keeping a sorted list (using theoperator< of the data type to which the iterators point). The finalseries is stored in the range[first, last).[first,middle) and[middle, last) are merged, keeping a sorted list (using theboolean result of the binary comparison operatorcomp). The final seriesis stored in the range[first, last). #include <algorithm> #include <string> #include <cstring> #include <iterator> #include <iostream> using namespace std; bool caseString(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) == 0; } int main() { string range[] = { "alpha", "charley", "echo", "golf", "bravo", "delta", "foxtrot", }; inplace_merge(range, range + 4, range + 7); copy(range, range + 7, ostream_iterator<string>{ cout, " " }); cout << '\n'; string range2[] = { "ALPHA", "CHARLEY", "DELTA", "foxtrot", "hotel", "bravo", "ECHO", "GOLF" }; inplace_merge(range2, range2 + 5, range2 + 8, caseString); copy(range2, range2 + 8, ostream_iterator<string>{ cout, " " }); cout << '\n'; } // Displays: // alpha bravo charley delta echo foxtrot golf // ALPHA bravo CHARLEY DELTA ECHO foxtrot GOLF hotel<numeric>void iota(ForwardIterator first, ForwardIterator last, Type value);[first,last) are assigned the values of the incremented sequence of values starting atvalue.*first receivesvalue,*(first + 1) receives++value, etc. #include <numeric> #include <algorithm> #include <vector> #include <iostream> #include <iterator> using namespace std; int main() { vector<size_t> uv(10); iota(uv.begin(), uv.end(), 0); copy(uv.begin(), uv.end(), ostream_iterator<int>{ cout, " " }); cout << '\n'; } // Displays: 0 1 2 3 4 5 6 7 8 9<algorithm>bool is_partitioned([ExecPol,] InputIterator first, InputIterator last, UnaryPred pred);true ifpred, receiving all elements reachedfrom the iterator range[first, last), returnstrue until itreturnsfalse, and ifpred, receiving the remaining elements, returnsfalse. It also returnstrue if the range is empty. #include <algorithm> #include <iterator> #include <vector> #include <iostream> using namespace std; bool pCheck(int value) { return value < 3; } int main() { vector<int> uv = { 1, -2, 3, -4, 5, -6, 7, -8, 9}; cout << "partitioned before: " << is_partitioned(uv.begin(), uv.end(), pCheck) << "\n" "first value returning 'false' when partitioning: " << *partition(uv.begin(), uv.end(), pCheck) << '\n'; copy(uv.begin(), uv.end(), ostream_iterator<int>{ cout, " " }); cout << '\n'; cout << "partitioned after: " << is_partitioned(uv.begin(), uv.end(), pCheck) <<'\n'; } // Displays: 1 4 9 16 25 36 49 64 81 100 // 1 4 9 16 25 0 0 0 0 0<algorithm>bool is_permutation(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2);bool is_permutation(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2, ForwardIterator last2);bool is_permutation(ForwardIterator first1, ForwardIterator last1, ForwardIterator firs2, BinaryPred pred);bool is_permutation(ForwardIterator first1, ForwardIterator last1, ForwardIterator first2, ForwardIterator last2, BinaryPred pred);true if the elements in theiterator range[first1, last1), are a permutation of the elements inthe identically sized range starting atfirst2.pred to determine whether two elements are equal.pred to determine whether two elements are equal. #include <algorithm> #include <iostream> using namespace std; int main() { int one[] = { 1, -2, 3, -4, 5, -6, 7, -8, 9}; int two[] = { -8, -2, -4, -6, 3, 1, 5, 9, 7}; int three[] = { -8, -8, -4, -6, 3, 1, 5, 9, 7}; cout << "one is a permutation of two: " << is_permutation(one, end(one), two) << "\n" "one is a permutation of three: " << is_permutation(one, end(one), three, end(three)) << '\n'; } // Displays: one is a permutation of two: 1 // one is a permutation of three: 0<algorithm>bool is_sorted([ExecPol,] ForwardIterator first, ForwardIterator last);bool is_sorted([ExecPol,] ForwardIterator first, ForwardIterator last, BinaryPredicate pred);true if the elements in theiterator range[first, last), are sorted using the elements'operator< comparison operator.true if the elements in theiterator range[first, last), are sorted using the binary predicatepred. #include <algorithm> #include <vector> #include <iostream> using namespace std; int main() { vector<int> uv = { 1, -2, 3, -4, 5, -6, 7, -8, 9}; cout << "sorted before: " << is_sorted(uv.begin(), uv.end()) << '\n'; sort(uv.begin(), uv.end()); cout << "sorted after " << is_sorted(uv.begin(), uv.end()) << '\n'; } // Displays: // sorted before: 0 // sorted after 1<algorithm>ForwardIterator is_sorted_until([ExecPol,] ForwardIterator first, ForwardIterator last);ForwardIterator is_sorted_until([ExecPol,] ForwardIterator first, ForwardIterator last, BinaryPredicate pred);first whose elements are sorted using the elements'operator< comparison operator.first whose elements using the binary predicatepred.first + 1. #include <algorithm> #include <vector> #include <iostream> using namespace std; int main() { vector<int> uv = { 1, -2, 3, -4, 5, -6, 7, -8, 9}; cout << "sorted before: " << is_sorted(uv.begin(), uv.end()) << '\n'; sort(uv.begin(), uv.end()); cout << "sorted after " << is_sorted(uv.begin(), uv.end()) << '\n'; } // Displays: // sorted before: 0 // sorted after 1<algorithm>void iter_swap(ForwardIterator1 iter1, ForwardIterator2 iter2);iter1 anditer2 are swapped. #include <algorithm> #include <iterator> #include <iostream> #include <string> using namespace std; int main() { string first[] = { "alpha", "bravo", "charley" }; string second[] = { "echo", "foxtrot", "golf" }; cout << "Before:\n"; copy(first, first + 3, ostream_iterator<string>(cout, " ")); cout << '\n'; copy(second, second + 3, ostream_iterator<string>(cout, " ")); cout << '\n'; for (size_t idx = 0; idx != 3; ++idx) iter_swap(first + idx, second + idx); cout << "After:\n"; copy(first, first + 3, ostream_iterator<string>(cout, " ")); cout << '\n'; copy(second, second + 3, ostream_iterator<string>(cout, " ")); cout << '\n'; } // Displays: // Before: // alpha bravo charley // echo foxtrot golf // After: // echo foxtrot golf // alpha bravo charley<algorithm>bool lexicographical_compare([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, InputIterator2 last2);bool lexicographical_compare([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, Comparecomp);[first1, last1) and[first2,last2) are compared. The function returnstrueoperator<of the underlying data type),last1 is reached, butlast2 isn't reached yet.false isreturned:operator<of the data type to which the iterators point, reversing the operands),last2 is reached, butlast1 isn't reached yet,last1 andlast2 are reached.comp is used instead ofoperator< of the data type to which the iterators point. #include <algorithm> #include <iterator> #include <iostream> #include <string> #include <cstring> using namespace std; bool caseString(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) < 0; } void compare(string const &word1, string const &word2) { cout << '`' << word1 << "' is " << ( lexicographical_compare(word1.begin(), word1.end(), word2.begin(), word2.end()) ? "before `" : "beyond or at `" ) << word2 << "' in the alphabet\n"; } int main() { string word1 = "hello"; string word2 = "help"; compare(word1, word2); compare(word1, word1); compare(word2, word1); string one[] = {"alpha", "bravo", "charley"}; string two[] = {"ALPHA", "BRAVO", "DELTA"}; copy(one, one + 3, ostream_iterator<string>{ cout, " " }); cout << " is ordered " << ( lexicographical_compare(one, one + 3, two, two + 3, caseString) ? "before " : "beyond or at " ); copy(two, two + 3, ostream_iterator<string>{ cout, " " }); cout << "\n" "using case-insensitive comparisons.\n"; } // Displays: // `hello' is before `help' in the alphabet // `hello' is beyond or at `hello' in the alphabet // `help' is beyond or at `hello' in the alphabet // alpha bravo charley is ordered before ALPHA BRAVO DELTA // using case-insensitive comparisons.<algorithm>ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const Type &value);ForwardIterator lower_bound(ForwardIterator first, ForwardIterator last, const Type &value, BinaryPredicate pred);[first, last) are searched forthe first element that is not less than (i.e., greater than or equal to)value. The returned iterator marks the location in the sequence wherevalue can be inserted without breaking the sorted order of theelements. Theoperator< of the data type to which the iterators point isused. If no such element is found,last is returned.[first, last) must have been sorted using thecomp function(-object). Each element in the range is compared tovalue using thecomp function, receiving an element from the iterator range as its firstargument andtype as its second argument. An iterator to the first elementfor which the binary predicatecomp, applied to the elements of the rangeandvalue, returnsfalse is returned. If no such element is found,last is returned.As illustrated by the following example, the function objectfunction's first parameter refers to an element in the iterator range, whilethe function object's second parameter refers tovalue.
#include <algorithm> #include <iostream> #include <iterator> #include <vector> #include <functional> using namespace std; int main() { int ia[] = { 10, 20, 30 }; cout << "Sequence: "; copy(ia, ia + 3, ostream_iterator<int>(cout, " ")); cout << "\n" "15 can be inserted before " << *lower_bound(ia, ia + 3, 15) << "\n" "35 can be inserted after " << (lower_bound(ia, ia + 3, 35) == ia + 3 ? "the last element" : "???") << '\n'; cout << "Sequence: "; copy(ia, ia + 3, ostream_iterator<int>(cout, " ")); cout << "\n" "15 can be inserted before " << *lower_bound(ia, ia + 3, 15, less<int>()) << "\n" "35 can be inserted before " << (lower_bound(ia, ia + 3, 35, less<int>()) == ia ? "the first element " : "???") << '\n'; vector<int> array{ 5, 10, 20, 20, 20, 30 }; auto iter = lower_bound(array.begin(), array.end(), 20, [&](int &arrayEl, int value) { cout << "Comparing " << arrayEl << " (index: " << (&arrayEl - &array[0]) << ")" " to " << value << '\n'; return arrayEl < value; } ); cout << "New 20 to insert at idx " << (iter - array.begin()) << '\n'; } // Displays: // Sequence: 10 20 30 // 15 can be inserted before 20 // 35 can be inserted after the last element // Sequence: 10 20 30 // 15 can be inserted before 20 // 35 can be inserted before ??? // Comparing 20 (index: 3) to 20 // Comparing 10 (index: 1) to 20 // Comparing 20 (index: 2) to 20 // New 20 to insert at idx 2Thebinary_search generic algorithm (cf. section19.1.7)can be usedto determine whether or notvalue is present in the iterator range. Theupper_bound algorithm can be used to find the last element of a series ofvalues equal tovalue. Theupper_bound section (19.1.61) alsocontains an extensive example illustrating the use oflower_bound and asupper_bound.
<algorithm>Type const &max(Type const &one, Type const &two);Type const &max(Type const &one, Type const &two, Comparator comp);Type const &min(Type const &one, Type const &two);Type const &min(Type const &one, Type const &two, Comparator comp);oneandtwo is returned, using theoperator> of the data type to whichthe iterators point to determine which element is the larger one.one is returned if the binarypredicatecomp(one, two) returnstrue, otherwisetwo is returned.std::min instead ofstd::max,returning the smaller of the two arguments. #include <algorithm> #include <iostream> #include <string> #include <cstring> using namespace std; bool caseString(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) <= 0; } string const &call(bool first, string const &lhs, string const &rhs) { return first? max(lhs, rhs) : min(lhs, rhs); } string const &call(bool first, string const &lhs, string const &rhs, bool (*cmp)(string const &, string const &)) { return first? max(lhs, rhs, cmp) : min(lhs, rhs, cmp); } int main(int argc, char **argv) // no args: use max, else min { bool fun = argc == 1; char const *where = fun ? "last\n" : "first\n"; cout << "Word '" << call(fun, "first", "second") << "' is lexicographically " << where << "Word '" << call(fun, "first", "SECOND") << "' is lexicographically " << where << "Word '" << call(fun, "first", "SECOND", caseString) << "' is lexicographically " << where; } // Displays when calling without args: // Word 'second' is lexicographically last // Word 'first' is lexicographically last // Word 'SECOND' is lexicographically last // and with an argument: // Word 'first' is lexicographically first // Word 'SECOND' is lexicographically first // Word 'first' is lexicographically first<algorithm>ForwardIterator max_element([ExecPol,] ForwardIterator first, ForwardIterator last);ForwardIterator max_element([ExecPol,] ForwardIterator first, ForwardIterator last, BinaryPredicate pred);ForwardIterator min_element([ExecPol,] ForwardIterator first, ForwardIterator last);ForwardIterator min_element([ExecPol,] ForwardIterator first, ForwardIterator last, BinaryPredicate pred);pair<ForwardIterator, ForwardIterator> max_element([ExecPol,] ForwardIterator first,ForwardIterator last);pair<ForwardIterator, ForwardIterator> max_element([ExecPol,] ForwardIterator first,ForwardIterator last, BinaryPredicate pred);[first, last) is returned. Theoperator< of the data type to which the iterators point is used to decidewhich of the elements is the largest.operator<, thebinary predicatepred is used to make the comparisons between the elementsreached from the iterator range[first, last). The element for whichpred returns most oftentrue, compared with other elements, isreturned.std::min_element instead ofstd::max_element, returning iterators to the smallest elements in the iterator ranges[first, last).std::pair objects whosefirstmembers contain the iterators returned by themin generic algorithms andwhosesecond members contain the iterators returned by themax genericalgorithms. #include <algorithm> #include <iostream> using namespace std; bool absCompare(int first, int second) { return abs(first) < abs(second); }; int *maxMin(bool high, int *begin, int *end) { return high ? max_element(begin, end) : min_element(begin, end); } int *maxMin(bool high, int *begin, int *end, bool (*comp)(int, int)) { return high ? max_element(begin, end, comp) : min_element(begin, end, comp); } // no args: calls max_element, else min_element int main(int argc, char **argv) { bool max = argc == 1; char const *type = max? "max" : "min"; int ia[] = {-4, 7, -2, 10, -12}; cout << "The " << type << ". int value is " << *maxMin(max, ia, ia + 5) << "\n" "The max. absolute int value is " << *maxMin(max, ia, ia + 5, absCompare) << '\n'; } // Displays, when called without arguments: // The max. int value is 10 // The max. absolute int value is -12 // otherwise: // The minimum int value is -12 // The minimum absolute int value is -2<algorithm>OutputIterator merge([ExecPol,] InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result);OutputIterator merge([ExecPol,] InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, OutputIterator result, Compare comp);[first1,last1) and[first2, last2) are merged, keeping a sorted list (using theoperator< of the data type to which the iterators point). The finalseries is stored in the range starting atresult and ending just beforetheOutputIterator returned by the function.[first1,last1) and[first2, last2) are merged, keeping a sorted list (using theboolean result of the binary comparison operatorcomp). The final seriesis stored in the range starting atresult and ending just before theOutputIterator returned by the function. #include <algorithm> #include <string> #include <cstring> #include <iterator> #include <iostream> using namespace std; bool caseString(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) < 0; } int main() { string range1[] = // 5 elements { "alpha", "bravo", "foxtrot", "hotel", "zulu" }; string range2[] = // 4 elements { "delta", "echo", "golf", "romeo" }; string result[5 + 4]; copy(result, merge(range1, range1 + 5, range2, range2 + 4, result), ostream_iterator<string>{ cout, " " }); cout << '\n'; string range3[] = { "ALPHA", "bravo", "foxtrot", "HOTEL", "ZULU" }; string range4[] = { "delta", "ECHO", "GOLF", "romeo" }; copy(result, merge(range3, range3 + 5, range4, range4 + 4, result, caseString), ostream_iterator<string>{ cout, " " }); cout << '\n'; } // Displays: // alpha bravo delta echo foxtrot golf hotel romeo zulu // ALPHA bravo delta ECHO foxtrot GOLF HOTEL romeo ZULU<algorithm>pair<Type const &, Type const &> minmax( Type const &t1, Type const &t2);pair<Type const &, Type const &> minmax(Type const &t1, Type const &t2, BinaryPred pred);pair<Type const &, Type const &> minmax( std:initializer<list<Type> values);pair<Type const &, Type const &> minmax( std:initializer<list<Type> values, BinaryPred pred);std::pair whosefirstandsecond members contain, respectively, the smaller and the larger valueof the function's arguments, usingType's operator< to compare the twovalues.t1 is the smaller element ifpred(t1, t2) returnstrue.iterator_range objects. #include <algorithm> #include <iostream> #include <functional> using namespace std; int main() { vector<size_t> uv(10); auto values = minmax(5, 2, less<int>{}); cout << values.first << " is smaler than " << values.second << '\n'; } // Displays: 2 is smaler than 5<algorithm>pair<InputIterator1, InputIterator2> mismatch([ExecPol,] InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);pair<InputIterator1, InputIterator2> mismatch([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, Compare comp);first1 andfirst2 are compared using the equality operator of thedata type to which the iterators point. Comparison stops if the comparedelements differ (i.e.,operator== returns false) orlast1 isreached. Apair containing iterators pointing to the final positions isreturned. The second sequence may contain more elements than the firstsequence. The behavior of the algorithm is undefined if the second sequencecontains fewer elements than the first sequence.first1 andfirst2 are compared using the binary comparisonoperation as defined bycomp, instead ofoperator==. Comparison stops if thecomp function returnsfalseorlast1 is reached. Apair containing iterators pointing to the finalpositions is returned. The second sequence may contain more elements than thefirst sequence. The behavior of the algorithm is undefined if the secondsequence contains fewer elements than the first sequence. #include <algorithm> #include <string> #include <cstring> #include <iostream> #include <utility> using namespace std; bool caseString(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) == 0; } int main() { string range1[] = { "alpha", "bravo", "foxtrot", "hotel", "zulu" }; string range2[] = { "alpha", "bravo", "foxtrot", "Hotel", "zulu" }; pair<string *, string *> pss = mismatch(range1, range1 + 5, range2); cout << "The elements " << *pss.first << " and " << *pss.second << " differ at index " << (pss.first - range1) << '\n'; if ( mismatch(range1, range1 + 5, range2, caseString).first == range1 + 5 ) cout << "When compared case-insensitively they match\n"; } /* Displays: The elements hotel and Hotel at offset 3 differ When compared case-insensitively they match */<algorithm>OutputIter move([ExecPol,] InputIter first, InputIter last, OutputIter dest);BidirIter move_backward(BidirIter first, BidirIter last, BidirIter lastDest);[first, last) are moved to the range starting atdest,returning the iterator pointing just past the last element in the rangestarting atdest.[first, last) are moved in reverse order to the range starting,iterating backward, atlastDest, returning the iterator pointing to thebeginning of the rangeending atlastDest. The destination iteratorlastDest may not point to elements within the range[first, last).move(_backward) the elements in the iterator range[first, last) are still valid, but may have changed.See alsoshift_left andshift_right: (cppreference).
#include <algorithm> #include <string> #include <iostream> #include <iterator> using namespace std; void show(string const *begin, string const *end) { copy(begin, end, ostream_iterator<string>(cout, ", ")); cout << '\n'; } int main() { string sarr[] = { "alpha", "bravo", "charley", "delta" }; string dest[4] = { "", }; auto last = end(sarr); auto lastDest = move(sarr, last, dest); // move all elements to dest cout << "sarr after move:\n"; show(sarr, last); cout << "dest after move:\n"; show(dest, lastDest); move_backward(dest, lastDest, last); // move_backward to sarr cout << "sarr after move_backward:\n"; show(sarr, last); cout << "dest after move_backward:\n"; show(dest, lastDest); } // Displays: // sarr after move: // , , , , // dest after move: // alpha, bravo, charley, delta,<algorithm>bool next_permutation(BidirectionalIterator first, BidirectionalIterator last);bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, Comp comp);bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last);bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last, Comp comp);[first, last), is determined. For example, ifthe elements1, 2 and3 are the range for whichnext_permutationis called, then subsequent calls ofnext_permutation reorders thefollowing series:1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1
This example shows that the elements are reordered such that each newpermutation represents the next bigger value (132 is bigger than 123, 213 isbigger than 132, etc.) usingoperator< of the data type to which theiterators point. The valuetrue is returned if a reordering took place,the valuefalse is returned if no reordering took place, which is the caseif the sequence represents the last (biggest) value. In that case, thesequence is also sorted usingoperator<.
[first, last) is determined, using the binarypredicatecomp to compare elements. The elements in the range arereordered. The valuetrue is returned if a reordering took place, thevaluefalse is returned if no reordering took place, which is the case ifthe resulting sequence would haven been ordered using the binary predicatecomp to compare elements. #include <algorithm> #include <iterator> #include <iostream> #include <string> #include <cstring> using namespace std; bool caseString(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) < 0; } // to obtain previous permutations change 'next_' to 'prev_' int main() { string saints[] = {"Oh", "when", "the", "saints"}; cout << "All permutations of 'Oh when the saints':\n" "Sequences:\n"; do { copy(saints, saints + 4, ostream_iterator<string>{ cout, " " }); cout << '\n'; } while (next_permutation(saints, saints + 4, caseString)); cout << "After first sorting the sequence:\n"; sort(saints, saints + 4, caseString); cout << "Sequences:\n"; do { copy(saints, saints + 4, ostream_iterator<string>{ cout, " " }); cout << '\n'; } while (next_permutation(saints, saints + 4, caseString)); } // Displays (partially): // All permutations of 'Oh when the saints': // Sequences: // Oh when the saints // saints Oh the when // saints Oh when the // saints the Oh when // ... // After first sorting the sequence: // Sequences: // Oh saints the when // Oh saints when the // Oh the saints when // Oh the when saints // ...<algorithm>void nth_element([ExecPol,] RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last);void nth_element([ExecPol,] RandomAccessIterator first, RandomAccessIterator nth, RandomAccessIterator last, Compare comp);[first,last) are sorted relative to the element pointed to bynth: all elementsin the range[left, nth) are smaller than the element pointed to bynth, and alle elements in the range[nth + 1, last) are greaterthan the element pointed to bynth. The two subsets themselves are notsorted. Theoperator< of the data type to which the iterators point isused to compare the elements.[first,last) are sorted relative to the element pointed to bynth: all elementsin the range[left, nth) are smaller than the element pointed to bynth, and alle elements in the range[nth + 1, last) are greaterthan the element pointed to bynth. The two subsets themselves are notsorted. Thecomp function object is used to compare the elements. #include <algorithm> #include <iostream> #include <iterator> #include <functional> using namespace std; int main() { int ia[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 10}; nth_element(ia, ia + 3, ia + 10); cout << "sorting with respect to " << ia[3] << '\n'; copy(ia, ia + 10, ostream_iterator<int>(cout, " ")); cout << '\n'; nth_element(ia, ia + 5, ia + 10, greater<int>()); cout << "sorting with respect to " << ia[5] << '\n'; copy(ia, ia + 10, ostream_iterator<int>(cout, " ")); cout << '\n'; } // Displays: // sorting with respect to 4 // 1 2 3 4 9 7 5 6 8 10 // sorting with respect to 5 // 10 8 7 9 6 5 3 4 2 1<algorithm>void partial_sort([ExecPol,] RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end);void partial_sort([ExecPol,] RandomAccessIterator begin, RandomAccessIterator middle, RandomAccessIterator end, BinaryPredicate pred);void partial_sort_copy([ExecPol,] InputIterator begin, InputIterator end, RandomAccessIterator dest_begin, RandomAccessIterator dest_end);void partial_sort_copy([ExecPol,] InputIterator begin, InputIterator end, RandomAccessIterator dest_begin, RandomAccessIterator dest_end, BinaryPredicate pred);middle - begin) smallestelements are sorted and stored in the range[begin, middle) using theoperator< of the data type to which the iterators point to compareelements. The remaining elements of the series remain unsorted, and are storedin the range[middle, end).middle - begin) smallestelements (according to the provided binary predicatepred) are sorted andstored in the range[begin, middle). The remaining elements of theseries remain unsorted. #include <algorithm> #include <iostream> #include <functional> #include <iterator> using namespace std; int main() { int ia[] = { 1, 9, 5, 3, 7, 2, 4, 6, 8, 10 }; int ia2[6]; partial_sort_copy(ia, ia + 10, ia2, ia2 + 6); cout << "the 6 smallest elements: "; copy(ia2, ia2 + 6, ostream_iterator<int>(cout, " ")); cout << '\n'; partial_sort(ia, ia + 3, ia + 10); cout << "find the 3 smallest elements:\n"; copy(ia, ia + 3, ostream_iterator<int>(cout, " ")); cout << '\n'; cout << "find the 5 largest elements:\n"; partial_sort(ia, ia + 5, ia + 10, greater<int>()); copy(ia, ia + 5, ostream_iterator<int>(cout, " ")); cout << '\n'; } // Displays: // the 6 smallest elements: 1 2 3 4 5 6 // find the 3 smallest elements: // 1 2 3 // find the 5 biggest elements: // 10 9 8 7 6<numeric>OutputIterator partial_sum(InputIterator first,InputIterator last, OutputIterator result);OutputIterator partial_sum(InputIterator first, InputIteratorlast, OutputIterator result, BinaryOperation op);[result, <returned OutputIterator>) receives a value which is obtainedby adding the elements in the corresponding range of the range[first,last). The first element in the resulting range will be equal to the elementpointed to byfirst.[result, <returned OutputIterator>) is obtained by applying the binaryoperatorop to the previous element in the resulting range and thecorresponding element in the range[first, last). The firstelement in the resulting range will be equal to the element pointed to byfirst.inclusive_scan andexclusive_scan, supporting execution policies: (cppreference). #include <numeric> #include <algorithm> #include <iostream> #include <functional> #include <iterator> using namespace std; int main() { int ia[] = {1, 2, 3, 4, 5}; int ia2[5]; copy(ia2, partial_sum(ia, ia + 5, ia2), ostream_iterator<int>(cout, " ")); cout << '\n'; copy(ia2, partial_sum(ia, ia + 5, ia2, multiplies<int>()), ostream_iterator<int>(cout, " ")); cout << '\n'; } /* Displays: 1 3 6 10 15 1 2 6 24 120 */<algorithm>BidirectionalIterator partition([ExecPol,] BidirectionalIterator first, BidirectionalIterator last, UnaryPredicate pred);BidirectionalIterator stable_partition([ExecPol,]BidirectionalIterator first, BidirectionalIterator last, UnaryPredicatepred);ForwardIterator partition_point( ForwardIterator first, ForwardIterator last, UnaryPredicate pred );[first,last) for which the unary predicatepred evaluates astrue are placedbefore the elements which evaluate asfalse.false and the relative order of all elements for which the predicateevaluates totrue is kept.[first, last) range, but returns an iterator to the first element forwhichpred returnsfalse. Ifpred returnstrue for allelements thenlast is returned.pred evaluates astrue. #include <algorithm> #include <iostream> #include <string> #include <iterator> using namespace std; void show(int *begin, int *end) { copy(begin, end, ostream_iterator<int>{ cout, " " }); cout << '\n'; } int main() { int org[] = { 1, 3, 5, 7, 9, 10, 2, 8, 6, 4 }; int ia[10]; copy(org, org + 10, ia); auto lessThan4 = [=](int value) { return value <= 4; }; int *split = partition(ia, ia + 10, lessThan4); cout << "Last ia[]- element <= 4 is ia[" << split - ia - 1 << "]\n"; show(ia, end(ia)); copy(org, org + 10, ia); split = stable_partition(ia, ia + 10, lessThan4); cout << "Last org[]-element <= 4 is ia[" << split - ia - 1 << "]\n"; show(ia, end(ia)); cout << "org[]-elements up to the partition point 4 are:\n"; show(org, partition_point(org, org + 10, lessThan4)); } // Displays: // Last ia[]- element <= 4 is ia[3] // 1 3 4 2 9 10 7 8 6 5 // Last org[]-element <= 4 is ia[3] // 1 3 2 4 5 7 9 10 8 6 // org[]-elements up to the partition point 4 are: // 1 3<algorithm>std::pair<ForwardIter2, ForwardIter3> partition_copy([ExecPol,] ForwardIter1 first, ForwardIter1 last, ForwardIter2 trueDest, ForwardIter3 falseDest, UnaryPredicate pred );[first,last) for whichpred returnstrue are copied to the range starting attrueDest, while the remaining elements are copied to the range starting atfalseDest. the range[first, last) may not overlap with the rangesstarting attrueDest orfalseDest. #include <algorithm> #include <string> #include <iostream> #include <iterator> using namespace std; bool pred(std::string const &str) { return "aeiou"s.find(str.front()) != string::npos; } void show(string const *begin, string const *end) { copy(begin, end, ostream_iterator<string>(cout, ", ")); cout << '\n'; } int main() { string sarr[] = { "alpha", "bravo", "charley", "delta", "echo", "foxtrot", "golf", "hotel" }; string trueDest[size(sarr)]; string falseDest[size(sarr)]; pair<string *, string *> lastTF = // lastTrue, lastFalse partition_copy(sarr, end(sarr), trueDest, falseDest, pred); cout << "pred() == true elements:\n"; show(trueDest, lastTF.first); cout << "pred() == false elements:\n"; show(falseDest, lastTF.second); } // Displays: // pred() == true elements: // alpha, echo, // pred() == false elements: // bravo, charley, delta, foxtrot, golf, hotel,<numeric>Type reduce([ExecPol,] InputIterator first, InputIterator last);Type reduce([ExecPol,] InputIterator first, InputIterator last, Type init);Type reduce([ExecPol,] InputIterator first, InputIterator last, BinaryOperation op);Type reduce([ExecPol,] InputIterator first, InputIterator last, Type init, BinaryOperation op);accumulate(cf.accumulate), but the algorithm requires that the usedoperator is both associative and commutative: regrouping and rearranging theelements in any order may not affect the final outcome. E.g., the numericaddition operator satisfies both requirements.operator+ is applied to the elements inthe range[first, last), returning the resulting sum.op is applied tothe initial valueinit (lhs argument) and, respectively, the elements fromthe iterator range[first, last). The resulting sum value is returned.operator+ the binary operatorop isused, receiving the variable that's eventually returned from the function asits lhs argument and the elements in the iterator range as its rhs argument,assigning the operator's returned values to the variable that's eventuallyreturned. // compile as: g++ -O2 reduce.cc -ltbb #include <numeric> #include <vector> #include <execution> #include <iostream> using namespace std; int main() { int ia[] = {1, 2, 3, 4}; vector<int> iv(ia, ia + 4); // for demonstration purpose: it's unlikely that cout << // for 4 values parallel execution is used "Sum: " << reduce(execution::par, iv.begin(), iv.end(), int()) << "\n" "Product: " << reduce(iv.begin(), iv.end(), int(1), multiplies<int>{}) << '\n'; } // Displays: // Sum: 10 // Product: 24<algorithm>ForwardIterator remove([ExecPol,] ForwardIterator first, ForwardIterator last, Type const &value);OutputIterator remove_copy([ExecPol,] InputIterator first, InputIterator last, OutputIterator dest, Type const &value);OutputIterator remove_copy_if([ExecPol,] InputIterator first, InputIterator last, OutputIterator dest, UnaryPredicate pred);ForwardIterator remove_if([ExecPol,] ForwardIterator first, ForwardIterator last, UnaryPredicate pred);[first, last) are reordered such that all values unequal tovalueare placed at the beginning of the range. The returned forward iterator pointsto the first element that can be removed after reordering. The range[returnvalue, last) is called theleftover of the algorithm. Notethat the leftover may contain elements different fromvalue, but theseelements can be removed safely, as such elements are also present in the range[first, returnvalue). The function usesoperator== of the data typeto which the iterators point to determine which elements to remove.[first, last) not matchingvalue are copied to the range[dest, returnvalue), wherereturnvalue is the value returned bythe function. The range[first, last) is not modified. The functionusesoperator== of the data type to which the iterators point to determinewhich elements not to copy.[first, last) for which the unary predicatepred returnstrueare not inserted into theresult iterator. All other elements are copiedto the range[dest, returnvalue), wherereturnvalue is the valuereturned by the function. The range[first, last) is not modified.[first, last) are reordered such that all values for which the unarypredicatepred returnsfalse are placed at the beginning of therange, keeping their relative order. The returned forward iteratorpoints to the first element, after reordering, for whichpred returnedtrue. The range[returnvalue, last) is called theleftover ofthe algorithm. The leftovermay contain elements for which the predicatepred returnsfalse, but these can safely be removed, as such elementsare also present in the range[first, returnvalue). Such duplication isthe result of the fact that the algorithmcopies, rather thanmoveselements into new locations.copy-overloads expect output iterators. If thekept elements are to be stored in, e.g., a vectorkept thenkept.begin() could be passed as the function'sdest argument. However,that requires thatsize(kept) is large enough to contain all the keptelements, which must therefore be known before the function iscalled. Alternatively,back_insert_iterator could be used ensuring thatkept merely contains the kept elements once the function hasreturned. This approach is used in the example program. #include <algorithm> #include <iostream> #include <string> #include <iterator> #include <vector> using namespace std; using StrVect = vector<string>; bool judge(string const &word) { return count(word.begin(), word.end(), 'a') > 1; } void show(auto const &begin, auto const &end) { copy(begin, end, ostream_iterator<string>(cout, ", ")); cout << "\n"; } int main() { StrVect words = { "kilo", "alpha", "lima", "mike", "alpha", "november", "alpha", "alpha", "alpha", "papa", "quebec" }; auto src{ words }; cout << "Removing all \"alpha\"s:\n"; auto end = remove(src.begin(), src.end(), "alpha"); show(src.begin(), end); cout << "Leftover elements are:\n"; show(end, src.end()); src = words; cout << "Remove_copy_if removes words having > 1 'a' chars:\n"; StrVect kept; remove_copy_if(src.begin(), src.end(), back_inserter(kept), judge); show(kept.begin(), kept.end()); } // Displays: // Removing all "alpha"s: // kilo, lima, mike, november, papa, quebec, // Leftover elements are: // alpha, alpha, alpha, , , // Remove_copy_if removes words having > 1 'a' chars: // kilo, lima, mike, november, quebec,<algorithm>void replace([ExecPol,] ForwardIterator first, ForwardIterator last, Type const &oldvalue, Type const &newvalue);ForwardIterator replace_if([ExecPol,] ForwardIterator first, ForwardIterator last, UnaryPredicate pred, Type const &value);OutputIterator replace_copy([ExecPol,] InputIterator first, InputIterator last, OutputIterator result, Type const &oldvalue, Type const &newvalue);OutputIterator replace_copy_if([ExecPol,] ForwardIterator first, ForwardIterator last, OutputIterator result, UnaryPredicate pred, Type const &value);oldvalue inthe range pointed to by[first, last) are replaced by a copy ofnewvalue. The algorithm usesoperator== of the data type to which theiterators point.[first, last) for which the unary predicatepred evaluates astrue are replaced byvalue.oldvalue inthe range pointed to by[first, last) are sent to theresult outputiterator, replacing elements equal tooldValue bynewValue, usingoperator== of the data type to which the iterators point.[first, last) for which the unary predicatepred returnsfalseare sent to theresult output iterator, andvalue is sent toresult ifpred returnstrue. The range[first, last) is notmodified. #include <algorithm> #include <iostream> #include <string> #include <vector> #include <iterator> using namespace std; using StrVect = vector<string>; void show(StrVect const &vect) { copy(vect.begin(), vect.end(), ostream_iterator<string>(cout, " ")); cout.put('\n'); } bool isAlpha(string const &str) { return str == "alpha"; } int main() { StrVect words = { "kilo", "alpha", "lima", "mike", "alpha", "november", "alpha", "oscar", "alpha", "alpha", "papa" }; // replace(words.begin(), words.end(), "alpha"s, "ALPHA"s); // show(words); // or, using replace_if: // // replace_if(words.begin(), words.end(), isAlpha, "ALPHA"s); // show(words); // or, using replace_copy: // // StrVect result; // replace_copy(words.begin(), words.end(), result.begin(), // "alpha"s, "ALPHA"s); // show(result); // or, using replace_copy_if: // //StrVect result; replace_copy_if(words.begin(), words.end(), back_inserter(result), isAlpha, "ALPHA"s); show(result); } /* Displays kilo ALPHA lima mike ALPHA november ALPHA oscar ALPHA ALPHA papa */<algorithm>void reverse([ExecPol,] BidirectionalIterator first, BidirectionalIterator last);OutputIterator reverse_copy([ExecPol,] BidirectionalIterator first, BidirectionalIterator last, OutputIterator dest);[first, last) are reversed.[first, last) are inserted in reversed order intodest, returningthe output iterator following the last insertion. #include <algorithm> #include <iostream> #include <string> #include <vector> #include <iterator> using namespace std; using StrVect = vector<string>; void show(StrVect const &vect) { copy(vect.begin(), vect.end(), ostream_iterator<string>(cout, " ")); cout.put('\n'); } int main(int argc, char **argv) { StrVect words = { "alpha", "kilo", "lima", "mike", "november", "oscar", "papa" }; if (argc == 1) // no args: plain reverse { reverse(words.begin(), words.end()); show(words); return 0; } using StrVect = vector<string>; StrVect dest; reverse_copy(words.begin(), words.end(), back_inserter(dest)); show(dest); } // Displays: // papa oscar november mike lima kilo alpha<algorithm>void rotate([ExecPol,] ForwardIterator first, ForwardIterator middle, ForwardIterator last);OutputIterator rotate_copy([ExecPol,] ForwardIterator first,ForwardIterator middle, ForwardIterator last, OutputIterator result);[first,middle) are moved to the end of the container, the elements in the range[middle, last) are moved to the beginning of the container, keeping theorder of the elements in the two sub-ranges intact.[middle, last) andthen the elements in the range[first, middle) are inserted intoresult, returning the output iterator following the last insertion.The order of the elements in the source ranges is not altered. #include <algorithm> #include <iostream> #include <string> #include <iterator> #include <vector> using namespace std; using StrVect = vector<string>; void show(StrVect const &vect) { copy(vect.begin(), vect.end(), ostream_iterator<string>(cout, " ")); cout.put('\n'); } int main(int argc, char **argv) { StrVect words = { "kilo", "lima", "mike", "november", "oscar", "foxtrot", "golf", "hotel", "india", "juliet" }; if (argc == 1) // no args: plain rotate { rotate(words.begin(), words.begin() + words.size() / 2, words.end()); show(words); return 0; } using StrVect = vector<string>; StrVect dest; rotate_copy(words.begin(), words.begin() + words.size() / 2, words.end(), back_inserter(dest)); show(dest); } // Displays: // foxtrot golf hotel india juliet kilo lima mike november oscar<algorithm>OutputIterator sample(InputIterator first, InputIterator last, OutputIterator out, size_t sampleSize, Generator &&generator);sampleSize elements are randomly selected (withoutreplacement) from the input range[first, last), and copied to thedestination range starting atout and ending at the function's returnvalue. IfsampleSize >= (last - first) all elements are selected. Thegenerator is a (uniform) random number generator, like themt19937mercenne twister.shuffle: (cppreference). #include <algorithm> #include <iostream> #include <random> #include <string> using namespace std; int main() { string src{ "abcdefghijklmnopqrstuvwxyz" }; string dest; sample(src.begin(), src.end(), back_inserter(dest), 7, mt19937{}); std::cout << "Seven random letters out of " << src << " : " << dest << '\n'; } // Could display: // Seven random letters out of abcdefghijklmnopqrstuvwxyz : bciorux<algorithm>ForwardIterator search([ExecPol,] ForwardIterator first1,ForwardIterator last1, ForwardIterator first2, ForwardIterator last2);ForwardIterator1 search([ExecPol,] ForwardIterator first1,ForwardIterator last1, ForwardIterator first2, ForwardIterator last2,BinaryPredicate pred);constexpr ForwardIterator1 search([ExecPol,] ForwardIterator first, ForwardIterator last, Searcher const &searcher);ForwardIterator search_n([ExecPol,] ForwardIterator first,ForwardIterator last, Size count, Type const &value);ForwardIterator search_n([ExecPol,] ForwardIterator first1,ForwardIterator last1, Size count, Type const &value, BinaryPredicate pred);[first1, last1) is returned where the elements in the range[first2, last2) are found usingoperator== of the datatype to which the iterators point. If no such location exists,last1 isreturned.[first1, last1) is returned where the elements in the range[first2, last2) are found using the provided binary predicatepredto compare the elements in the two ranges. If no such location exists,last1 is returned.searcher(first, last).first:searcher receives the range of elements, and returns an iterator into thisrange (orlast ifsearcher found no match) assearcher(first,last).first.[first, last) for the first series ofcount elements equal tovalue, returning the first iterator to thosecount elements. If nosuch series exists thenlast is returned. The last protottype callspred to determine whether an element is equal tovalue. #include <algorithm> #include <iostream> #include <iterator> using namespace std; bool absEq(int i1, int i2) { return abs(i1) == abs(i2); } int main() { int range1[] = {-2, -4, -6, -8, 2, 4, 4, 6, 8}; int range2[] = {6, 8}; copy ( search(range1, end(range1), range2, range2 + 2), end(range1), ostream_iterator<int>(cout, " ") ); cout << '\n'; copy ( search(range1, end(range1), range2, range2 + 2, absEq), end(range1), ostream_iterator<int>(cout, " ") ); cout << '\n'; copy ( search_n(range1, end(range1), 2, 4, absEq), end(range1), ostream_iterator<int>(cout, " ") ); cout << '\n'; } // Displays: // 6 8 // -6 -8 2 4 4 6 8 // 4 4 6 8<algorithm>OutputIterator set_difference([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,OutputIterator result);OutputIterator set_difference([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,OutputIterator result, Compare comp);[first1, last1) that are not present in therange[first2, last2) is returned, starting atresult, and endingat theOutputIterator returned by the function. The elements in the tworanges must have been sorted usingoperator< of the data type to whichthe iterators point.[first1, last1) that are not present in therange[first2, last2) is returned, starting atresult, and endingat theOutputIterator returned by the function. The elements in the tworanges must have been sorted using thecomp function object. #include <algorithm> #include <iostream> #include <string> #include <cstring> #include <iterator> using namespace std; bool caseless(string const &left, string const &right) { return strcasecmp(left.c_str(), right.c_str()) < 0; } int main() { string set1[] = { "kilo", "lima", "mike", "november", "oscar", "papa", "quebec" }; string set2[] = { "papa", "quebec", "romeo"}; string result[7]; copy(result, set_difference(set1, set1 + 7, set2, set2 + 3, result), ostream_iterator<string>(cout, " ")); cout << '\n'; string set3[] = { "PAPA", "QUEBEC", "ROMEO"}; copy(result, set_difference(set1, set1 + 7, set3, set3 + 3, result, caseless), ostream_iterator<string>(cout, " ")); cout << '\n'; } // Displays: // kilo lima mike november oscar // kilo lima mike november oscar<algorithm>OutputIterator set_intersection([ExecPol,] InputIterator1 first1, InputIterator1) linebreak() tt(last1, InputIterator2first2, InputIterator2 last2, OutputIterator result);OutputIterator set_intersection([ExecPol,] InputIterator1first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,OutputIterator result, Compare comp);[first1, last1) that are also present in therange[first2, last2) is returned, starting atresult, and endingat theOutputIterator returned by the function. The elements in the tworanges must have been sorted usingoperator< of the data type to whichthe iterators point.[first1, last1) that are also present in therange[first2, last2) is returned, starting atresult, and endingat theOutputIterator returned by the function. The elements in the tworanges must have been sorted using thecomp function object. #include <algorithm> #include <iostream> #include <string> #include <cstring> #include <iterator> using namespace std; bool caseless(string const &left, string const &right) { return strcasecmp(left.c_str(), right.c_str()) < 0; } int main() { string set1[] = { "kilo", "lima", "mike", "november", "oscar", "papa", "quebec" }; string set2[] = { "papa", "quebec", "romeo"}; string result[7]; copy(result, set_intersection(set1, set1 + 7, set2, set2 + 3, result), ostream_iterator<string>(cout, " ")); cout << '\n'; string set3[] = { "PAPA", "QUEBEC", "ROMEO"}; copy(result, set_intersection(set1, set1 + 7, set3, set3 + 3, result, caseless), ostream_iterator<string>(cout, " ")); cout << '\n'; } // Displays: // papa quebec // papa quebec<algorithm>OutputIterator set_symmetric_difference([ExecPol,]InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,InputIterator2 last2, OutputIterator result);OutputIterator set_symmetric_difference([ExecPol,]InputIterator1 first1, InputIterator1 last1, InputIterator2 first2,InputIterator2 last2, OutputIterator result, Compare comp);[first1, last1) that are not present in therange[first2, last2) and those in the range[first2, last2)that are not present in the range[first1, last1) is returned, startingatresult, and ending at theOutputIterator returned by thefunction. The elements in the two ranges must have been sorted usingoperator< of the data type to which the iterators point.[first1, last1) that are not present in therange[first2, last2) and those in the range[first2, last2)that are not present in the range[first1, last1) is returned, startingatresult, and ending at theOutputIterator returned by thefunction. The elements in the two ranges must have been sorted using thecomp function object. #include <algorithm> #include <iostream> #include <string> #include <cstring> #include <iterator> using namespace std; bool caseless(string const &left, string const &right) { return strcasecmp(left.c_str(), right.c_str()) < 0; } int main() { string set1[] = { "kilo", "lima", "mike", "november", "oscar", "papa", "quebec" }; string set2[] = { "papa", "quebec", "romeo"}; string result[7]; copy(result, set_symmetric_difference(set1, set1 + 7, set2, set2 + 3, result), ostream_iterator<string>(cout, " ")); cout << '\n'; string set3[] = { "PAPA", "QUEBEC", "ROMEO"}; copy(result, set_symmetric_difference(set1, set1 + 7, set3, set3 + 3, result, caseless), ostream_iterator<string>(cout, " ")); cout << '\n'; } // Displays: // kilo lima mike november oscar romeo // kilo lima mike november oscar ROMEO<algorithm>OutputIterator set_union([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,OutputIterator result);OutputIterator set_union([ExecPol,] InputIterator1 first1,InputIterator1 last1, InputIterator2 first2, InputIterator2 last2,OutputIterator result, Compare comp);[first1, last1) or the range[first2, last2) or in both ranges is returned, starting atresult,and ending at theOutputIterator returned by the function. The elements inthe two ranges must have been sorted usingoperator< of the data type towhich the iterators point;[first1, last1) or the range[first2, last2) or in both ranges is returned, starting atresult,and ending at theOutputIterator returned by the function. The elements inthe two ranges must have been sorted usingcomp function object. #include <algorithm> #include <iostream> #include <string> #include <cstring> #include <iterator> #include <vector> using namespace std; bool caseless(string const &left, string const &right) { return strcasecmp(left.c_str(), right.c_str()) < 0; } int main() { string set1[] = { "kilo", "lima", "mike", "november", "oscar", "papa", "quebec" }; string set2[] = { "papa", "quebec", "romeo"}; string result[8]; copy(result, set_union(set1, set1 + 7, set2, set2 + 3, result), ostream_iterator<string>(cout, " ")); cout << '\n'; string set3[] = { "PAPA", "QUEBEC", "ROMEO"}; copy(result, set_union(set1, set1 + 7, set3, set3 + 3, result, caseless), ostream_iterator<string>(cout, " ")); cout << '\n'; std::vector<int> v1 = {1, 2, 3, 4, 5, 5, 5}; std::vector<int> v2 = { 3, 3, 3, 4, 5, 6, 7}; set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), ostream_iterator<int>(cout, " ")); cout << '\n'; } // Displays: // kilo lima mike november oscar papa quebec romeo // kilo lima mike november oscar papa quebec ROMEO // 1 2 3 3 3 4 5 5 5 6 7<algorithm>void sort([ExecPol,] RandomAccessIterator first, RandomAccessIterator last);void sort([ExecPol,] RandomAccessIterator first, RandomAccessIterator last, Compare comp);void stable_sort([ExecPol,] RandomAccessIterator first, RandomAccessIterator last);void stable_sort([ExecPol,] RandomAccessIterator first, RandomAccessIterator last, Compare comp);[first,last) are sorted in ascending order usingoperator< of the data type towhich the iterators point.[first, last) are sorted in ascending order using thecompfunction object to compare the elements. The binary predicatecompshould returntrue if its first argument should be placed earlier in thesorted sequence than its second argument. // compile as: g++ -O2 sort.cc -ltbb #include <algorithm> #include <cstdlib> #include <execution> #include <functional> #include <iostream> #include <iterator> #include <string> using namespace std; int main() { string words[] = { "november", "kilo", "mike", "lima", "oscar", "quebec", "papa" }; sort(words, words + 7); copy(words, words + 7, ostream_iterator<string>(cout, " ")); cout << '\n'; sort(words, words + 7, greater<string>()); copy(words, words + 7, ostream_iterator<string>(cout, " ")); cout << '\n'; int *vect = new int[10'000]; generate(execution::par, vect, vect + 10'000, random); cout << "sorted: " << is_sorted(vect, vect + 10'000) << '\n'; sort(execution::par, vect, vect + 10'000); cout << "sorted: " << is_sorted(vect, vect + 10'000) << '\n'; delete[] vect; // stable-sorting: using Pair = pair<size_t, string>; // days & nrs of the months vector<Pair> months = { { 31, "Jan." }, { 28, "Feb." }, { 31, "Mar." }, { 30, "Apr." }, { 31, "May." }, { 30, "Jun." }, { 31, "Jul." }, { 31, "Aug." }, { 30, "Sep." }, { 31, "Oct." }, { 30, "Nov." }, { 31, "Dec." }, }; stable_sort(months.begin(), months.end(), [&](Pair const &lhs, Pair const &rhs) { return lhs.first > rhs.first; } ); for (size_t idx = 0; auto const &month: months) cout << month.first << ": " << month.second << (++idx % 4 == 0 ? "\n" : " "); } // Displays: // kilo lima mike november oscar papa quebec // quebec papa oscar november mike lima kilo // unordered sequence // sorted sequence // 31: Jan. 31: Mar. 31: May. 31: Jul. // 31: Aug. 31: Oct. 31: Dec. 30: Apr. // 30: Jun. 30: Sep. 30: Nov. 28: Feb. The example also shows two generic algorithms using theexecution::par execution policy: firstgenerate is used to fill anarray with randomly determinedint-values, thensort is used to sortthose values.<algorithm>void swap(Type &object1, Type &object2) noexcept;void swap(Type (&object1)[N], Type (&object2))[N] noexcept;ForwardIterator2 swap_ranges([ExecPol,] ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 result);object1 andobject2exchange their values. They do so by either cyclic copy assignment or cyclicmove assignment (if available).object1 andobject2 arrays exchange their values.[first1, last1) are swapped with that number of elements in the range[result, returnvalue), wherereturnvalue is the value returned bythe function. The two ranges must be disjoint. #include <algorithm> #include <iostream> #include <string> #include <iterator> using namespace std; void show(string const *begin, string const *end) { copy(begin, end, ostream_iterator<string>(cout, " ")); cout << '\n'; } int main() { string first[] = { "alpha", "bravo", "charley" }; string second[] = { "echo", "foxtrot", "golf" }; cout << "Before:\n"; show(first, end(first)); show(second, end(second)); for (size_t idx = 0; idx < size(first); ++idx) swap(first[idx], second[idx]); cout << "After:\n"; show(first, end(first)); show(second, end(second)); swap_ranges(first, end(first), second); cout << "After swap_ranges:\n"; show(first, end(first)); show(second, end(second)); } // Displays: // Before: // alpha bravo charley // echo foxtrot golf // After: // echo foxtrot golf // alpha bravo charley // After swap_ranges: // alpha bravo charley // echo foxtrot golf<algorithm>OutputIterator transform([ExecPol,] InputIterator first, InputIterator last, OutputIterator result, UnaryOperator op);OutputIterator transform([ExecPol,] InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, OutputIterator result,BinaryOperator op);op is applied toeach of the elements in the range[first, last), and the resultingvalues are stored in the range starting atresult. The return value pointsjust beyond the last generated element.op is appliedto each of the elements in the range[first1, last1) and thecorresponding element in the second range starting atfirst2. Theresulting values are stored in the range starting atresult. The returnvalue points just beyond the last generated element. #include <functional> #include <vector> #include <algorithm> #include <iostream> #include <string> #include <cctype> #include <iterator> using namespace std; string caps(string const &src) { string tmp; tmp.resize(src.length()); transform(src.begin(), src.end(), tmp.begin(), ::toupper); return tmp; } int main() { string words[] = {"alpha", "bravo", "charley"}; copy(words, transform(words, words + 3, words, caps), ostream_iterator<string>(cout, " ")); cout << '\n'; int values[] = {1, 2, 3, 4, 5}; vector<int> squares; transform(values, values + 5, values, back_inserter(squares), multiplies<int>()); copy(squares.begin(), squares.end(), ostream_iterator<int>(cout, " ")); cout << '\n'; } /* Displays: ALPHA BRAVO CHARLEY 1 4 9 16 25 */for_each (section19.1.18) andtransform generic algorithms should be noted:transform thereturn value of the functionobject'soperator() member is used; the argument that is passed to theoperator() member itself is not changed.for_each the function object'soperator()receives a reference to an argument, which itself may be changed by thefunction object'soperator().transform generic algorithm. However, but different from therange-based for-loop thetransform algorithm can also be used widthsub-ranges and with reverse-iterators.<numeric>Type transform_reduce([ExecPol,] InputIterator first1, InputIterator last1, InputIterator first2, Type value);Type transform_reduce([ExecPol,] InputIterator first1, InputIterator last1, InputIterator first2, Type value, BinaryOperation reduce, BinaryOperation transform);Type transform_reduce([ExecPol,] InputIterator first1, InputIterator last1, Type value, BinaryOperation reduce, UnaryOperation transform);std::plus<> for thereduce binary operator andstd::mutiplies<>for thetransform binary operator. It's also equivalent to a parallelizedversion ofinner_product (cf. section19.1.21).transform binaryoperation to, as left-hand side operand, each element in the[first1,end1) range and as right-hand side operand the corresponding element of therange starting atfirst2. Each thus computed value is passed as right-handside operand, usingvalue as left-hand side operand to thereducebinary operation, returning the final value returned byreduce.transform to each element ofthe range[first1, end1), and then passesvalue and each of thevalues returned bytransform toreduce, returning the final valuereturned byreduce. #include <numeric> #include <algorithm> #include <iterator> #include <iostream> #include <string> using namespace std; class Cat { std::string d_sep; public: Cat(string const &sep) : d_sep(sep) {} string operator() (string const &s1, string const &s2) const { return s1 + d_sep + s2; } }; int main() { size_t ia1[] = { 1, 2, 3, 4, 5, 6, 7 }; // instead of inner_product: cout << "The sum of all squares in "; copy(ia1, ia1 + 7, ostream_iterator<size_t>{ cout, " " }); cout << "is " << transform_reduce(ia1, ia1 + 7, ia1, 0) << '\n'; size_t ia2[] = { 7, 6, 5, 4, 3, 2, 1 }; cout << "The sum of all cross-products in "; copy(ia1, ia1 + 7, ostream_iterator<size_t>{ cout, " " }); cout << "and "; copy(ia2, ia2 + 7, ostream_iterator<size_t>{ cout, " " }); cout << "is " << transform_reduce(ia1, ia1 + 7, ia2, 0) << '\n'; string names1[] = { "Frank", "Karel", "Piet" }; string names2[] = { "Brokken", "Kubat", "Plomp"}; cout << "All combined names of "; copy(names1, names1 + 3, ostream_iterator<string>{ cout, " " }); cout << "and "; copy(names2, names2 + 3, ostream_iterator<string>{ cout, " " }); cout << "are:" << transform_reduce(names1, names1 + 3, names2, "\t"s, Cat{ "\n\t"}, Cat{ " " }) << '\n'; } // Displays: // The sum of all squares in 1 2 3 4 5 6 7 is 140 // The sum of all cross-products in 1 2 3 4 5 6 7 and 7 6 5 4 3 2 1 is 84 // All combined names of Frank Karel Piet and Brokken Kubat Plomp are: // Frank Brokken // Karel Kubat // Piet PlompAs covered before, when calling something likeauto ptr = new string{"hello" } the string is constructed in memory specifically allocated tocontain the object, and the object type's constructor initializes the objectin that memory. Likewise, when callingdelete ptr the string's destructoris called, followed by returning the memory allocated bynew to the commonpool.
When using placement new the memory to contain the object is alreadyavailable, and the constructionauto ptr = new (storageAddress) string{"hello" } is used to merely construct the string at the location specified bystorageAddress. That string can then (as usual) be accessed viaptr,butdelete ptr cannot be used, since the memory atstorageAddress wasalready available before invoking the placement new operator. Therefore, inthese cases the remarkable situation is encountered where the object'sdestructor must explicitly be called (usingptr->~string()) and usingdelete ptr is completely wrong, causing a memory error which aborts theprogram.
Several generic algorithms, all supporting execution policies, are availablesimplifying the use ofplacement new. To use these algorithm the<memory> header file must be included.
Facilities are available to copy, fill, initialize, and move objects to/inuninitialized (raw) memory, as well as facilities to delete the objects storedin raw memory. Here is an overvieuw of the available facilities (cf.cppreference for more detailsabout the algorithms handling uninitialized memory):
uninitialized_copy([ExecPol,] ForwardIterator first, ForwardIterator last, ForwardIterator dest);[first, last) to the raw memory starting atdest, returning the location beyond the last copied element.uninitialized_copy_n([ExecPol,] ForwardIterator first, size_t nObjects, ForwardIterator dest);nObjects.uninitialized_default_construct([ExecPol,] ForwardIterator first, ForwardIterator last);[first, last). The algorithm requires that the types referred to by the iterators are either trivial types (like built-in types) or definevalue_type returning their type names. When using trivial types the installed do not assume that the installed values are 0-initialized.uninitialized_default_construct_n([ExecPol,] ForwardIterator first, size_t nObjects);nObjects in the uninitialized memory.uninitialized_fill([ExecPol,] ForwardIterator first, ForwardIterator last, Type const &value);value in the uninitialized memory.uninitialized_fill([ExecPol,] ForwardIterator first, size_t nObjects,Type const &value);value to thenObjects subsequent locations in the uninitialized memory. uninitialized_move([ExecPol,] ForwardIterator first, ForwardIterator last, ForwardIterator dest);[first, last) are moved to the raw memory.uninitialized_move_n([ExecPol,] ForwardIterator first, size_t nObjects, ForwardIterator dest);nObjects are moved.uninitialized_value_construct([ExecPol,] ForwardIterator first, ForwardIterator last);uninitialized_default_construct, but requires that the types referred to by the iterators definevalue_type returning their type names.uninitialized_value_construct_n([ExecPol,] ForwardIterator first, size_t nObjects);nObjects in the uninitialized memory.The algorithmType *construct_at(Type *raw, Args&&...args) constructs an object of typeType in the raw memory atraw, passingargs... toType's constructor.
To delete the objects installed in raw memory the following facilities areavailable:
void destroy([ExecPol,] ForwardIterator first, ForwardIterator last);first refers: it callsiterator->~Type() for all elements in the range[first, last).void destroy([ExecPol,] ForwardIterator first, size_t nObjects);nObjects objects.void destroy_at(Type *raw);raw using placement new. If theraw pointer points to an array of placement new allocated objects then the destructors of the elements of the array are called.Here is an example:
#include <memory> #include <vector> #include <iostream> #include <string> using namespace std; int main() { char raw[4 * sizeof(string)]; // raw memory to receive strings string *ptr = reinterpret_cast<string *>(raw); // pointer to strings // construct 4 strings in raw uninitialized_default_construct_n(ptr, 4); destroy(ptr, ptr + 4); // call the strings' destructors vector<string> vs(4, "string"); // move 4 strings to raw memory uninitialized_move(vs.begin(), vs.end(), ptr); cout << vs.front() << ", " << vs.back() << '\n' << ptr[0] << ", " << ptr[3] << '\n'; destroy(ptr, ptr + 4); // call the strings' destructors } // Displays: // , // string, string<algorithm>ForwardIterator unique([ExecPol,] ForwardIterator first,ForwardIterator last);ForwardIterator unique([ExecPol,] ForwardIterator first,ForwardIterator last, BinaryPredicate pred);OutputIterator unique_copy([ExecPol,] InputIterator first,InputIterator last, OutputIterator result);OutputIterator unique_copy([ExecPol,] InputIterator first,InputIterator last, OutputIterator result, BinaryPredicate pred);std::unique generic algorithm assumes that the elements in therange have previously been sorted (cf. section19.1.54).operator== of the data type towhich the iterators point, all but the first of consecutively equal elementsin the range pointed to by[first, last) are relocated to the end ofthe range. The returned forward iterator marks the beginning of theleftover. All elements in the range[first, return-value) areunique, all elements in the range[return-value, last) haveundetermined (but valid) values.[first, last) for which the binarypredicatepred returnstrue are relocated to the end of the range. Thepredicatepred expects two arguments of the data type to which theiterators point. The returned forward iterator marks the beginning of theleftover. For all pairs of elements in the range[first,return-value)pred returnsfalse (i.e., they areunique). Allelements in theleftover (i.e., the range[return-value, last))have undetermined (but valid) values. #include <algorithm> #include <iostream> #include <string> #include <cstring> #include <iterator> using namespace std; bool casestring(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) == 0; } int main() { string words[] = {"alpha", "alpha", "Alpha", "papa", "quebec" }; size_t const size = sizeof(words) / sizeof(string); string *removed = unique(words, words + size); copy(words, removed, ostream_iterator<string>(cout, " ")); cout << '\n' << "Trailing elements are:\n"; copy(removed, words + size, ostream_iterator<string>(cout, " ")); cout << '\n'; removed = unique(words, words + size, casestring); copy(words, removed, ostream_iterator<string>(cout, " ")); cout << '\n' << "Trailing elements are:\n"; copy(removed, words + size, ostream_iterator<string>(cout, " ")); cout << '\n'; } /* Displays: alpha Alpha papa quebec Trailing elements are: quebec alpha papa quebec Trailing elements are: quebec quebec */<algorithm>OutputIterator unique_copy([ExecPol,] InputIterator first,InputIterator last, OutputIterator result);OutputIterator unique_copy([ExecPol,] InputIterator first,InputIterator last, OutputIterator result, BinaryPredicate pred);[first,last) are copied to the resulting container, starting atresult.Consecutively equal elements (usingoperator== of the data type to whichthe iterators point) are copied only once (keeping the first of a series ofequal elements). The returned output iterator pointsjust beyond the last copied element.[first, last) are copied to the resulting container, starting atresult. Consecutive elements in the range pointed to by[first,last) for which the binary predicatepred returnstrue are copied onlyonce (keeping the first of a series of equal elements). The returned outputiterator points just beyond the last copied element. #include <algorithm> #include <iostream> #include <string> #include <vector> #include <iterator> #include <cstring> using namespace std; bool casestring(string const &first, string const &second) { return strcasecmp(first.c_str(), second.c_str()) == 0; } int main() { string words[] = {"oscar", "Alpha", "alpha", "alpha", "papa", "quebec" }; size_t const size = sizeof(words) / sizeof(string); vector<string> remaining; unique_copy(words, words + size, back_inserter(remaining)); copy(remaining.begin(), remaining.end(), ostream_iterator<string>(cout, " ")); cout << '\n'; vector<string> remaining2; unique_copy(words, words + size, back_inserter(remaining2), casestring); copy(remaining2.begin(), remaining2.end(), ostream_iterator<string>(cout, " ")); cout << '\n'; } /* Displays: oscar Alpha alpha papa quebec oscar Alpha papa quebec */<algorithm>ForwardIterator upper_bound(ForwardIterator first,ForwardIterator last, Type const &value);ForwardIterator upper_bound(ForwardIterator first,ForwardIterator last, Type const &value, Compare comp);[first, last) are searched for the firstelement that is greater thanvalue. The returned iterator marks the firstlocation in the sequence wherevalue can be inserted without breaking thesorted order of the elements usingoperator< of the data type to which theiterators point. If no such element is found,last is returned.[first, last) must have been sorted using thecomp functionor function object. Each element in the range is compared tovalue usingthecomp function. An iterator is returned pointing to the first elementfor which the binary predicatecomp, applied to the elements of the rangeandvalue, returnstrue. Thecomp function object function'sfirst parameter refers tovalue and the function object's second parameterrefers to an element in the iterator range.Caveat: note that thecomp object's parameters when usingupper_bound are swapped compared to the parameters expected bylower_bound.
operator<) thenupper_bound returns an iteratorpointing beyond the last of a series of values equal tovalue, whilelower_bound returns an iterator pointing to the first of such a series ofequal values.When the iterator range contains a series of values which are, according tocomp, equal tovalue thenupper_bound returns an iterator to thefirst element beyond that series, whilelower_bound returns an iterator tothe first element of that series.
The following program illustrates the various possibilities. Th programillustrates bothlower_bound andupper_bound and also illustrates thesituation wherevalue' Type is unequal to the types of the values in theiterator range. Specific comment is provided below the program's code.
1: #include <algorithm> 2: #include <iostream> 3: using namespace std; 4: 5: int main() 6: { 7: using pic = pair<int, char>; 8: 9: pic picArr[] =10: { {1, 'f'}, {5, 'r'}, {5, 'a'}, {7, 'n'}, {8, 'k'} };11: pic *picArrEnd = picArr + size(picArr);12: 13: cout << "Sequence: ";14: for (auto &pair: picArr)15: cout << '{' << pair.first << ',' << pair.second << "}, ";16: cout << '\n';17: 18: auto iter = lower_bound(picArr, picArrEnd, 5,19: [&](pic const &range, int value)20: {21: return range.first < value;22: }23: );24: cout << " lower bound, <, {5,?} can be inserted before {" <<25: iter->first << ',' << iter->second << "}\n";26: 27: iter = upper_bound(picArr, picArrEnd, 5,28: [&](int value, pic const &range)29: {30: return value < range.first;31: }32: );33: cout << " upper_bound, <, {5,?} can be inserted before {" <<34: iter->first << ',' << iter->second << "}\n";35: 36: iter = upper_bound(picArr, picArrEnd, 9,37: [&](int value, pic const &range)38: {39: return value < range.first;40: }41: );42: cout << " upper_bound, <, {9,?} can be inserted " <<43: ( &*iter == picArrEnd ? "at the end" : "???") << '\n';44: 45: sort(picArr, picArrEnd,46: [](pic const &lhs, pic const &rhs)47: {48: return lhs.first > rhs.first;49: }50: );51: 52: cout << "\nSequence: ";53: for (auto &pair: picArr)54: cout << '{' << pair.first << ',' << pair.second << "}, ";55: cout << '\n';56: 57: iter = lower_bound(picArr, picArrEnd, 5,58: [&](pic const &range, int value)59: {60: return range.first > value;61: }62: );63: cout << " lower_bound, >, {5,?} can be inserted before {" <<64: iter->first << ',' << iter->second << "}\n";65: 66: iter = upper_bound(picArr, picArrEnd, 5,67: [&](int value, pic const &range)68: {69: return value > range.first;70: }71: );72: cout << " upper_bound, >, {5,?} can be inserted before {" <<73: iter->first << ',' << iter->second << "}\n";74: 75: iter = upper_bound(picArr, picArrEnd, 0,76: [&](int value, pic const &range)77: {78: return value > range.first;79: }80: );81: cout << " upper_bound, >, {0,?} can be inserted " <<82: ( &*iter == picArrEnd ? "at the end" : "???") << '\n';83: }84: // Displays:85: // Sequence: {1,f}, {5,r}, {5,a}, {7,n}, {8,k},86: // lower bound, <, {5,?} can be inserted before {5,r}87: // upper_bound, <, {5,?} can be inserted before {7,n}88: // upper_bound, <, {9,?} can be inserted at the end89: //90: // Sequence: {8,k}, {7,n}, {5,r}, {5,a}, {1,f},91: // lower_bound, >, {5,?} can be inserted before {5,r}92: // upper_bound, >, {5,?} can be inserted before {1,f}93: // upper_bound, >, {0,?} can be inserted at the endpairs, sorted by theirfirst members.lower_bound is called using a lambda expression to define theCompare function object. Note (line 19) that a reference to a value in the iterator range is the lambda expression's first parameter, while the target value is its second parameter.upper_bound is called, also using a lambda expression. Withupper_bound the target value is the lambda expression's first parameter, while a reference to a value in the iterator range is its second parameter.picArr array in descending orderlower_bound andupper_bound are again used. This time instead of using the< operator the> operator should be used.Thebinary_search generic algorithm can be used to simplydetermine whether or nogvalue is present in the iterator range. Thelower_bound generic algorithm can be used to find the firstelement of a series of values equal tovalue.

12, 11, 10, 8, 9, 7, 6, 1, 2, 4, 3, 5
In the following description, keep two pointers into this array in mind:a pointernode indicates the location of the next node of the tree, apointerchild points to the next element which is a child of thenodepointer. Initially,node points to the first element, andchild pointsto the second element.
*node++ (== 12). 12 is the top node. its children are*child++(11) and*child++ (10), both less than 12.*node++ (== 11)), in turn, has*child++ (8)and*child++ (9) as its children.*node++ (== 10)) has*child++ (7)and*child++ (6) as its children.*node++ (== 8)) has*child++ (1)and*child++ (2) as its children.*node++ (== 9)) has children*child++ (4)and*child++ (3).*node++ (== 7)) hasone child*child++ (5)child now points beyond the array, the remaining nodes have nochildren. So, nodes 6, 1, 2, 4, 3 and 5 don't have children.Note that the left and right branches are not ordered: 8 is less than 9, but 7is larger than 6.
A heap is created by traversing a binary tree level-wise, starting from thetop node. The top node is 12, at the zeroth level. At the first level we find11 and 10. At the second level 8, 9, 7 and 6 are found, etc.
Heaps can be constructed in containers supporting random access. So, a list isnot an appropriate data structure for a heap. Heaps can be constructed from an(unsorted) array (usingmake_heap). The top-element canbe pruned from a heap, followed by reordering the heap (usingpop_heap), a new element can be added to the heap,followed by reordering the heap (usingpush_heap), andthe elements in a heap can be sorted (usingsort_heap,which, of course, invalidates the heap).
<algorithm>void make_heap(RandomAccessIterator first,RandomAccessIterator last);void make_heap(RandomAccessIterator first,RandomAccessIterator last, Compare comp);[first,last) are reordered to form amax-heap usingoperator< of the datatype to which the iterators point.[first,last) are reordered to form a max-heap using the binary comparison functionobjectcomp to compare elements.make_heap.<algorithm>void pop_heap(RandomAccessIterator first,RandomAccessIterator last);void pop_heap(RandomAccessIterator first,RandomAccessIterator last, Compare comp);[first, last) is moved tolast - 1. Then, the elements in the range[first, last - 1) are reordered to form a max-heap using theoperator< of the data type to which the iterators point.[first, last) is moved tolast - 1. Then, the elements in the range[first, last - 1) are reordered to form a max-heap using the binarycomparison function objectcomp to compare elements.pop_heap.<algorithm>void push_heap(RandomAccessIterator first,RandomAccessIterator last);void push_heap(RandomAccessIterator first,RandomAccessIterator last, Compare comp);[first,last - 1) contains a valid heap, and the element atlast - 1 contains anelement to be added to the heap, the elements in the range[first, last- 1) are reordered to form a max-heap using theoperator< of the datatype to which the iterators point.[first,last - 1) contains a valid heap, and the element atlast - 1 contains anelement to be added to the heap, the elements in the range[first, last- 1) are reordered to form a max-heap using the binary comparison functionobjectcomp to compare elements.push_heap.<algorithm>void sort_heap(RandomAccessIterator first,RandomAccessIterator last);void sort_heap(RandomAccessIterator first,RandomAccessIterator last, Compare comp);[first, last) form a valid max-heap, the elements in the range[first, last) are sorted usingoperator< of the data type towhich the iterators point.[first, last) form a valid heap, the elements in the range[first, last) are sorted using the binary comparison functionobjectcomp to compare elements.sort_heap. #include <algorithm> #include <iostream> #include <functional> #include <iterator> using namespace std; void show(int *ia, char const *header) { cout << header << ":\n"; copy(ia, ia + 20, ostream_iterator<int>(cout, " ")); cout << '\n'; } int main() { int ia[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; make_heap(ia, ia + 20); show(ia, "The values 1-20 in a max-heap"); pop_heap(ia, ia + 20); show(ia, "Removing the first element (now at the end)"); push_heap(ia, ia + 20); show(ia, "Adding 20 (at the end) to the heap again"); sort_heap(ia, ia + 20); show(ia, "Sorting the elements in the heap"); make_heap(ia, ia + 20, greater<int>()); show(ia, "The values 1-20 in a heap, using > (and beyond too)"); pop_heap(ia, ia + 20, greater<int>()); show(ia, "Removing the first element (now at the end)"); push_heap(ia, ia + 20, greater<int>()); show(ia, "Re-adding the removed element"); sort_heap(ia, ia + 20, greater<int>()); show(ia, "Sorting the elements in the heap"); } /* Displays: The values 1-20 in a max-heap: 20 19 15 18 11 13 14 17 9 10 2 12 6 3 7 16 8 4 1 5 Removing the first element (now at the end): 19 18 15 17 11 13 14 16 9 10 2 12 6 3 7 5 8 4 1 20 Adding 20 (at the end) to the heap again: 20 19 15 17 18 13 14 16 9 11 2 12 6 3 7 5 8 4 1 10 Sorting the elements in the heap: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 The values 1-20 in a heap, using > (and beyond too): 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Removing the first element (now at the end): 2 4 3 8 5 6 7 16 9 10 11 12 13 14 15 20 17 18 19 1 Re-adding the removed element: 1 2 3 8 4 6 7 16 9 5 11 12 13 14 15 20 17 18 19 10 Sorting the elements in the heap: 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 */