|  | Home | Libraries | People | FAQ | More | 
          none_of_equal
            Whether none of a range's elements matches a value
        
          one_of_equal
            Whether only one of a range's elements matches a
          value
        
          is_decreasing
            Whether an entire sequence is decreasing; i.e, each
          item is less than or equal to the previous one
        
          is_increasing
            Whether an entire sequence is increasing; i.e, each
          item is greater than or equal to the previous one
        
          is_strictly_decreasing
            Whether an entire sequence is strictly decreasing;
          i.e, each item is less than the previous one
        
          is_strictly_increasing
            Whether an entire sequence is strictly increasing;
          i.e, each item is greater than the previous one
        
The header file clamp.hpp contains two functions for "clamping" a value between a pair of boundary values.
          The function clamp (v, lo, hi) returns:
        
          Note: using clamp with
          floating point numbers may give unexpected results if one of the values
          is NaN.
        
          There is also a version that allows the caller to specify a comparison
          predicate to use instead of operator
          <.
        
template<typename T> const T& clamp ( const T& val, const T& lo, const T& hi ); template<typename T, typename Pred> const T& clamp ( const T& val, const T& lo, const T& hi, Pred p );
The following code:
int foo = 23; foo = clamp ( foo, 1, 10 );
          will leave foo with a value
          of 10
        
          Complexity: clamp will
          make either one or two calls to the comparison predicate before returning
          one of the three parameters.
        
          There are also four range-based versions of clamp, that apply clamping
          to a series of values. You could write them yourself with std::transform
          and bind, like this: std::transform
          ( first, last, out, bind ( clamp ( _1, lo, hi ))), but they are provided here for your
          convenience.
        
template<typename InputIterator, typename OutputIterator> OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, typename std::iterator_traits<InputIterator>::value_type lo, typename std::iterator_traits<InputIterator>::value_type hi ); template<typename Range, typename OutputIterator> OutputIterator clamp_range ( const Range &r, OutputIterator out, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi ); template<typename InputIterator, typename OutputIterator, typename Pred> OutputIterator clamp_range ( InputIterator first, InputIterator last, OutputIterator out, typename std::iterator_traits<InputIterator>::value_type lo, typename std::iterator_traits<InputIterator>::value_type hi, Pred p ); template<typename Range, typename OutputIterator, typename Pred> OutputIterator clamp_range ( const Range &r, OutputIterator out, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type lo, typename std::iterator_traits<typename boost::range_iterator<const Range>::type>::value_type hi, Pred p );
          clamp_range
            Perform clamp on the elements
          of a range and write the results into an output iterator
        
          The header file 'find_not.hpp' contains a variants of a the stl algorithm
          find. The algorithm finds
          the first value in the given sequence that is not equal to the given value.
        
          Consider this use of find():
        
std::vector<int> vec = { 1, 1, 2 }; auto it = std::find(vec.begin(), vec.end(), 1);
          This gives us the first occurance of 1
          in vec. What if we want
          to find the first occurrance of any number besides 1
          in vec? We have to write
          an unfortunate amount of code:
        
std::vector<int> vec = { 1, 1, 2 }; auto it = std::find_if(vec.begin(), vec.end(), [](int i) { return i != 1; });
          With find_not()
          the code gets much more terse:
        
std::vector<int> vec = { 1, 1, 2 }; auto it = find_not(vec.begin(), vec.end(), 1);
          The existing find variants
          are: find(),
          find_if(),
          and find_if_not().
          It seems natural to also have find_not(), for the very reason that we have find_if_not()
          -- to avoid having to write a lambda to wrap the negation of the find condition.
        
template<typename InputIter, typename Sentinel, typename T> InputIter find_not(InputIter first, Sentinel last, const T & x); template<typename Range, typename T> boost::range_iterator<Range> find_not(Range & r, const T & x);
          These overloads of find_not
          return the first value that is not equal to x
          in the sequence [first, last) or r,
          respectively.
        
          Given the container c1
          containing { 0, 1,
          2 },
          then
        
find_not ( c1.begin(), c1.end(), 1 ) --> c1.begin() find_not ( c1.begin(), c1.end(), 0 ) --> std::next(c1.begin())
          find_not works on all iterators
          except output iterators.
        
          The template parameter Sentinel
          is allowed to be different from InputIter,
          or they may be the same. For an InputIter
          it and a Sentinel end,
          it ==
          end and it
          != end
          must be well-formed expressions.
        
Linear.
          find_not takes its parameters
          by value and do not depend upon any global state. Therefore, it provides
          the strong exception guarantee.
        
          constexpr in C++14 or later.
        
          The header file 'find_backward.hpp' contains variants of the stl algorithm
          find. These variants are
          like find, except that
          the evaluate the elements of the given sequence in reverse order.
        
          Consider how finding the last element that is equal to x
          in a range is typically done:
        
// Assume a valid range if elements delimited by [first, last). while (last-- != first) { if (*last == x) { // Use last here... } }
          Raw loops are icky though. Perhaps we should do a bit of extra work to
          allow the use of std::find():
        
auto rfirst = std::make_reverse_iterator(last); auto rlast = std::make_reverse_iterator(first); auto it = std::find(rfirst, rlast, x); // Use it here...
          That seems nicer in that there is no raw loop, but it has two major drawbacks.
          First, it requires an unpleasant amount of typing. Second, it is less efficient
          than forward-iterator find
          , since std::reverse_iterator calls its base-iterator's
          operator--()
          in most of its member functions before doing the work that the member function
          requires.
        
template<typename BidiIter, typename T> BidiIter find_backward(BidiIter first, BidiIter last, const T & x); template<typename Range, typename T> boost::range_iterator<Range> find_backward(Range & range, const T & x);
          These overloads of find_backward
          return an iterator to the last element that is equal to x
          in [first, last) or r,
          respectively.
        
template<typename BidiIter, typename T> BidiIter find_not_backward(BidiIter first, BidiIter last, const T & x); template<typename Range, typename T> boost::range_iterator<Range> find_not_backward(Range & range, const T & x);
          These overloads of find_not_backward
          return an iterator to the last element that is not equal to x in [first, last)
          or r, respectively.
        
template<typename BidiIter, typename Pred> BidiIter find_if_backward(BidiIter first, BidiIter last, Pred p); template<typename Range, typename Pred> boost::range_iterator<Range> find_if_backward(Range & range, Pred p);
          These overloads of find_if_backward
          return an iterator to the last element for which pred
          returns true in [first, last) or r,
          respectively.
        
template<typename BidiIter, typename Pred> BidiIter find_if_not_backward(BidiIter first, BidiIter last, Pred p); template<typename Range, typename Pred> boost::range_iterator<Range> find_if_not_backward(Range & range, Pred p);
          These overloads of find_if_not_backward
          return an iterator to the last element for which pred
          returns false in [first, last) or r,
          respectively.
        
          Given the container c1
          containing { 2, 1,
          2 },
          then
        
find_backward ( c1.begin(), c1.end(), 2 ) --> --c1.end() find_backward ( c1.begin(), c1.end(), 3 ) --> c1.end() find_if_backward ( c1.begin(), c1.end(), [](int i) {return i == 2;} ) --> --c1.end() find_if_backward ( c1.begin(), c1.end(), [](int i) {return i == 3;} ) --> c1.end() find_not_backward ( c1.begin(), c1.end(), 2 ) --> std::prev(c1.end(), 2) find_not_backward ( c1.begin(), c1.end(), 1 ) --> c1.end() find_if_not_backward ( c1.begin(), c1.end(), [](int i) {return i == 2;} ) --> std::prev(c1.end(), 2) find_if_not_backward ( c1.begin(), c1.end(), [](int i) {return i == 1;} ) --> c1.end()
All variants work on bidirectional iterators.
Linear.
All of the variants take their parameters by value and do not depend upon any global state. Therefore, all the routines in this file provide the strong exception guarantee.
          All variants are constexpr
          in C++14 or later.
        
          find_not_backward
            Find the last element in a sequence that does not
          equal a value. See find_backward.
        
          find_if_backward
            Find the last element in a sequence that satisfies
          a predicate. See find_backward.
        
          find_if_not
            Find the first element in a sequence that does not
          satisfy a predicate. See find_not.
        
          find_if_not_backward
            Find the last element in a sequence that does not
          satisfy a predicate. See find_backward.
        
          The header file 'boost/algorithm/gather.hpp' contains two variants of a
          single algorithm, gather.
        
          gather()
          takes a collection of elements defined by a pair of iterators and moves
          the ones satisfying a predicate to them to a position (called the pivot)
          within the sequence. The algorithm is stable. The result is a pair of iterators
          that contains the items that satisfy the predicate.
        
          The function gather returns
          a std::pair of iterators that denote the elements
          that satisfy the predicate.
        
There are two versions; one takes two iterators, and the other takes a range.
namespace boost { namespace algorithm { template <typename BidirectionalIterator, typename Pred> std::pair<BidirectionalIterator,BidirectionalIterator> gather ( BidirectionalIterator first, BidirectionalIterator last, BidirectionalIterator pivot, Pred pred ); template <typename BidirectionalRange, typename Pred> std::pair<typename boost::range_iterator<const BidirectionalRange>::type, typename boost::range_iterator<const BidirectionalRange>::type> gather ( const BidirectionalRange &range, typename boost::range_iterator<const BidirectionalRange>::type pivot, Pred pred ); }}
Given an sequence containing:
0 1 2 3 4 5 6 7 8 9
a call to gather ( arr, arr + 10, arr + 4, IsEven ) will result in:
1 3 0 2 4 6 8 5 7 9 |---|-----| first | second pivot
          where first and second are the fields of the pair that
          is returned by the call.
        
          gather work on bidirectional
          iterators or better. This requirement comes from the usage of stable_partition, which requires bidirectional
          iterators. Some standard libraries (libstdc++ and libc++, for example)
          have implementations of stable_partition
          that work with forward iterators. If that is the case, then gather will work with forward iterators
          as well.
        
          gather uses stable_partition, which will attempt
          to allocate temporary memory, but will work in-situ if there is none available.
        
          If there is sufficient memory available, the run time is linear: O(N)
        
          If there is not any memory available, then the run time is O(N
          log N).
        
          The header file 'boost/algorithm/hex.hpp'
          contains three variants each of two algorithms, hex
          and unhex. They are inverse
          algorithms; that is, one undoes the effort of the other. hex takes a sequence of values, and turns
          them into hexadecimal characters. unhex
          takes a sequence of hexadecimal characters, and outputs a sequence of values.
        
          hex and unhex
          come from MySQL, where they are used in database queries and stored procedures.
        
          The function hex takes
          a sequence of values and writes hexadecimal characters. There are three
          different interfaces, differing only in how the input sequence is specified.
        
The first one takes an iterator pair. The second one takes a pointer to the start of a zero-terminated sequence, such as a c string, and the third takes a range as defined by the Boost.Range library.
template <typename InputIterator, typename OutputIterator> OutputIterator hex ( InputIterator first, InputIterator last, OutputIterator out ); template <typename T, typename OutputIterator> OutputIterator hex ( const T *ptr, OutputIterator out ); template <typename Range, typename OutputIterator> OutputIterator hex ( const Range &r, OutputIterator out );
          hex writes only values
          in the range '0'..'9' and 'A'..'F', but is not limited to character output.
          The output iterator could refer to a wstring, or a vector of integers,
          or any other integral type.
        
          The function unhex takes
          the output of hex and turns
          it back into a sequence of values.
        
          The input parameters for the different variations of unhex
          are the same as hex.
        
template <typename InputIterator, typename OutputIterator> OutputIterator unhex ( InputIterator first, InputIterator last, OutputIterator out ); template <typename T, typename OutputIterator> OutputIterator unhex ( const T *ptr, OutputIterator out ); template <typename Range, typename OutputIterator> OutputIterator unhex ( const Range &r, OutputIterator out );
The header 'hex.hpp' defines three exception classes:
struct hex_decode_error: virtual boost::exception, virtual std::exception {}; struct not_enough_input : public hex_decode_error; struct non_hex_input : public hex_decode_error;
          If the input to unhex does
          not contain an "even number" of hex digits, then an exception
          of type boost::algorithm::not_enough_input is thrown.
        
          If the input to unhex contains
          any non-hexadecimal characters, then an exception of type boost::algorithm::non_hex_input is thrown.
        
          If you want to catch all the decoding errors, you can catch exceptions
          of type boost::algorithm::hex_decode_error.
        
          Assuming that out is an
          iterator that accepts char
          values, and wout accepts
          wchar_t values (and that sizeof
          ( wchar_t ) == 2)
        
hex ( "abcdef", out ) --> "616263646566" hex ( "32", out ) --> "3332" hex ( "abcdef", wout ) --> "006100620063006400650066" hex ( "32", wout ) --> "00330032" unhex ( "616263646566", out ) --> "abcdef" unhex ( "3332", out ) --> "32" unhex ( "616263646566", wout ) --> "\6162\6364\6566" ( i.e, a 3 character string ) unhex ( "3332", wout ) --> "\3233" ( U+3332, SQUARE HUARADDO ) unhex ( "3", out ) --> Error - not enough input unhex ( "32", wout ) --> Error - not enough input unhex ( "ACEG", out ) --> Error - non-hex input
          hex and unhex
          work on all iterator types.
        
          All of the variants of hex
          and unhex run in O(N)
          (linear) time; that is, that is, they process each element in the input
          sequence once.
        
          All of the variants of hex
          and unhex take their parameters
          by value or const reference, and do not depend upon any global state. Therefore,
          all the routines in this file provide the strong exception guarantee. However,
          when working on input iterators, if an exception is thrown, the input iterators
          will not be reset to their original values (i.e, the characters read from
          the iterator cannot be un-read)
        
hex and unhex both do nothing when passed
              empty ranges.
            
          hex_lower
            Convert a sequence of integral types into a lower
          case hexadecimal sequence of characters
        
The header file 'is_palindrome.hpp' contains six variants of a single algorithm, is_palindrome. The algorithm tests the sequence and returns true if the sequence is a palindrome; i.e, it is identical when traversed either backwards or frontwards.
          The routine is_palindrome
          takes a sequence and, optionally, a predicate. It will return true if the
          predicate returns true for tested elements by algorithm in the sequence.
        
The routine come in 6 forms; the first one takes two iterators to define the range. The second form takes two iterators to define the range and a predicate. The third form takes a single range parameter, and uses Boost.Range to traverse it. The fourth form takes a single range parameter ( uses Boost.Range to traverse it) and a predicate. The fifth form takes a single C-string and a predicate. The sixth form takes a single C-string.
          The function is_palindrome
          returns true if the predicate returns true any tested by algorithm items
          in the sequence. There are six versions: 1) takes two iterators. 2) takes
          two iterators and a predicate. 3) takes a range. 4) takes a range and a
          predicate. 5) takes a C-string and a predicate. 6) takes a C-string.
        
template<typename BidirectionalIterator> bool is_palindrome ( BidirectionalIterator begin, BidirectionalIterator end ); template<typename BidirectionalIterator, typename Predicate> bool is_palindrome ( BidirectionalIterator begin, BidirectionalIterator end, Predicate p ); template<typename Range> bool is_palindrome ( const Range &r ); template<typename Range, typename Predicate> bool is_palindrome ( const Range &r, Predicate p ); template<typename Predicate> bool is_palindrome ( const char* str, Predicate p ); bool is_palindrome(const char* str);
Given the containers: const std::list<int> empty, const std::vector<char> singleElement{'z'}, int oddNonPalindrome[] = {3,2,2}, const int oddPalindrome[] = {1,2,3,2,1}, const int evenPalindrome[] = {1,2,2,1}, int evenNonPalindrome[] = {1,4,8,8}, then
is_palindrome(empty)) --> true //empty range is_palindrome(singleElement)) --> true is_palindrome(std::begin(oddNonPalindrome), std::end(oddNonPalindrome))) --> false is_palindrome(std::begin(evenPalindrome), std::end(evenPalindrome))) --> true is_palindrome(empty.begin(), empty.end(), functorComparator())) --> true //empty range is_palindrome(std::begin(oddNonPalindrome), std::end(oddNonPalindrome), funcComparator<int>)) --> false is_palindrome(std::begin(oddPalindrome), std::end(oddPalindrome)) --> true is_palindrome(evenPalindrome, std::equal_to<int>())) --> true is_palindrome(std::begin(evenNonPalindrome), std::end(evenNonPalindrome)) --> false is_palindrome("a") --> true is_palindrome("aba", std::equal_to<char>()) --> true
          is_palindrome work on Bidirectional
          and RandomAccess iterators.
        
          All of the variants of is_palindrome
          run in O(N) (linear) time; that is, they compare against
          each element in the list once. If any of the comparisons not succeed, the
          algorithm will terminate immediately, without examining the remaining members
          of the sequence.
        
          All of the variants of is_palindrome
          take their parameters by value, const pointer or const reference, and do
          not depend upon any global state. Therefore, all the routines in this file
          provide the strong exception guarantee.
        
is_palindrome returns
              true for empty ranges, const char* null pointers and for single element
              ranges.
            
          The header file 'is_partitioned_until.hpp' contains two variants of a single
          algorithm, is_partitioned_until.
          The algorithm tests to see if a sequence is partitioned according to a
          predicate; in other words, all the items in the sequence that satisfy the
          predicate are at the beginning of the sequence.
        
          The routine is_partitioned_until
          takes a sequence and a predicate. It returns the last iterator 'it' in
          the sequence [begin, end) for which the is_partitioned(begin, it) is true.
        
          is_partitioned_until come
          in two forms; the first one takes two iterators to define the range. The
          second form takes a single range parameter, and uses Boost.Range to traverse
          it.
        
          The function is_partitioned_until
          returns the last iterator 'it' in the sequence [begin, end) for which the
          is_partitioned(begin, it) is true. There are two versions; one takes two
          iterators, and the other takes a range.
        
template<typename InputIterator, typename Predicate> InputIterator is_partitioned_until ( InputIterator first, InputIterator last, Predicate p ); template<typename Range, typename Predicate> typename boost::range_iterator<const Range>::type is_partitioned_until ( const Range &r, Predicate p );
          Given the container c containing
          { 0, 1,
          2, 3, 14, 15 },
          then
bool isOdd ( int i ) { return i % 2 == 1; } bool lessThan10 ( int i ) { return i < 10; } is_partitioned_until ( c, isOdd ) --> iterator to '1' is_partitioned_until ( c, lessThan10 ) --> end is_partitioned_until ( c.begin (), c.end (), lessThan10 ) --> end is_partitioned_until ( c.begin (), c.begin () + 3, lessThan10 ) --> end is_partitioned_until ( c.end (), c.end (), isOdd ) --> end // empty range
          is_partitioned_until works
          on all iterators except output iterators.
        
          Both of the variants of is_partitioned_until
          run in O(N) (linear) time; that is, they compare against
          each element in the list once. If the sequence is found to be not partitioned
          at any point, the routine will terminate immediately, without examining
          the rest of the elements.
        
          Both of the variants of is_partitioned_until
          take their parameters by value or const reference, and do not depend upon
          any global state. Therefore, all the routines in this file provide the
          strong exception guarantee.
        
is_partitioned_until
              returns iterator to the end for empty and single-element ranges, no
              matter what predicate is passed to test against.
            See below
          The header file apply_permutation.hpp
          contains two algorithms, apply_permutation
          and apply_reverse_permutation.
          There are also range-based versions. The algorithms transform the item
          sequence according to index sequence order.
        
          The routine apply_permutation
          takes a item sequence and a order sequence. It reshuffles item sequence
          according to order sequence. Every value in order sequence means where
          the item comes from. Order sequence needs to be exactly a permutation of
          the sequence [0, 1, ... , N], where N is the biggest index in the item
          sequence (zero-indexed). The routine apply_reverse_permutation
          takes a item sequence and a order sequence. It will reshuffle item sequence
          according to order sequence. Every value in order sequence means where
          the item goes to. Order sequence needs to be exactly a permutation of the
          sequence [0, 1, ... , N], where N is the biggest index in the item sequence
          (zero-indexed).
        
Implementations are based on these articles: https://blogs.msdn.microsoft.com/oldnewthing/20170102-00/?p=95095 https://blogs.msdn.microsoft.com/oldnewthing/20170103-00/?p=95105 https://blogs.msdn.microsoft.com/oldnewthing/20170104-00/?p=95115 https://blogs.msdn.microsoft.com/oldnewthing/20170109-00/?p=95145 https://blogs.msdn.microsoft.com/oldnewthing/20170110-00/?p=95155 https://blogs.msdn.microsoft.com/oldnewthing/20170111-00/?p=95165
The routines come in 2 forms; the first one takes two iterators to define the item range and one iterator to define the beginning of index range. The second form takes range to define the item sequence and range to define index sequence.
There are two versions of algorithms: 1) takes four iterators. 2) takes two ranges.
template<typename RandomAccessIterator1, typename RandomAccessIterator2> void apply_permutation(RandomAccessIterator1 item_begin, RandomAccessIterator1 item_end, RandomAccessIterator2 ind_begin, RandomAccessIterator2 ind_end); template<typename Range1, typename Range2> void apply_permutation(Range1& item_range, Range2& ind_range); template<typename RandomAccessIterator1, typename RandomAccessIterator2> void apply_reverse_permutation(RandomAccessIterator1 item_begin, RandomAccessIterator1 item_end, RandomAccessIterator2 ind_begin, RandomAccessIterator2 ind_end); template<typename Range1, typename Range2> void apply_reverse_permutation(Range1& item_range, Range2& ind_range);
Given the containers: std::vector<int> emp_vec, emp_order, std::vector<int> one{1}, one_order{0}, std::vector<int> two{1,2}, two_order{1,0}, std::vector<int> vec{1, 2, 3, 4, 5}, std::vector<int> order{4, 2, 3, 1, 0}, then
apply_permutation(emp_vec, emp_order)) --> no changes apply_reverse_permutation(emp_vec, emp_order)) --> no changes apply_permutation(one, one_order) --> no changes apply_reverse_permutation(one, one_order) --> no changes apply_permutation(two, two_order) --> two:{2,1} apply_reverse_permutation(two, two_order) --> two:{2,1} apply_permutation(vec, order) --> vec:{5, 3, 4, 2, 1} apply_reverse_permutation(vec, order) --> vec:{5, 4, 2, 3, 1}
          apply_permutation and 'apply_reverse_permutation'
          work only on RandomAccess iterators. RandomAccess iterators required both
          for item and index sequences.
        
          All of the variants of apply_permutation
          and apply_reverse_permutation
          run in O(N) (linear) time. More
        
          All of the variants of apply_permutation
          and apply_reverse_permutation
          take their parameters by iterators or reference, and do not depend upon
          any global state. Therefore, all the routines in this file provide the
          strong exception guarantee.
        
apply_permutation and
              apply_reverse_permutation
              work also on empty sequences.
            
          copy_until
            Copy all the elements at the start of the input
          range that do not satisfy the predicate to the output range
        
          copy_while
            Copy all the elements at the start of the input
          range that satisfy the predicate to the output range