find_backward.qbk 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. [/ File find_backward.qbk]
  2. [section:find_backward find_backward ]
  3. [/license
  4. Copyright (c) 2018 T. Zachary Laine
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  7. ]
  8. The header file 'find_backward.hpp' contains variants of the stl algorithm
  9. `find`. These variants are like `find`, except that the evaluate the elements
  10. of the given sequence in reverse order.
  11. Consider how finding the last element that is equal to `x` in a range is
  12. typically done:
  13. // Assume a valid range if elements delimited by [first, last).
  14. while (last-- != first) {
  15. if (*last == x) {
  16. // Use last here...
  17. }
  18. }
  19. Raw loops are icky though. Perhaps we should do a bit of extra work to allow
  20. the use of `std::find()`:
  21. auto rfirst = std::make_reverse_iterator(last);
  22. auto rlast = std::make_reverse_iterator(first);
  23. auto it = std::find(rfirst, rlast, x);
  24. // Use it here...
  25. That seems nicer in that there is no raw loop, but it has two major drawbacks.
  26. First, it requires an unpleasant amount of typing. Second, it is less
  27. efficient than forward-iterator `find` , since `std::reverse_iterator` calls
  28. its base-iterator's `operator--()` in most of its member functions before
  29. doing the work that the member function requires.
  30. [heading interface]
  31. template<typename BidiIter, typename T>
  32. BidiIter find_backward(BidiIter first, BidiIter last, const T & x);
  33. template<typename Range, typename T>
  34. boost::range_iterator<Range> find_backward(Range & range, const T & x);
  35. These overloads of `find_backward` return an iterator to the last element that
  36. is equal to `x` in `[first, last)` or `r`, respectively.
  37. template<typename BidiIter, typename T>
  38. BidiIter find_not_backward(BidiIter first, BidiIter last, const T & x);
  39. template<typename Range, typename T>
  40. boost::range_iterator<Range> find_not_backward(Range & range, const T & x);
  41. These overloads of `find_not_backward` return an iterator to the last element
  42. that is not equal to `x` in `[first, last)` or `r`, respectively.
  43. template<typename BidiIter, typename Pred>
  44. BidiIter find_if_backward(BidiIter first, BidiIter last, Pred p);
  45. template<typename Range, typename Pred>
  46. boost::range_iterator<Range> find_if_backward(Range & range, Pred p);
  47. These overloads of `find_if_backward` return an iterator to the last element
  48. for which `pred` returns `true` in `[first, last)` or `r`, respectively.
  49. template<typename BidiIter, typename Pred>
  50. BidiIter find_if_not_backward(BidiIter first, BidiIter last, Pred p);
  51. template<typename Range, typename Pred>
  52. boost::range_iterator<Range> find_if_not_backward(Range & range, Pred p);
  53. These overloads of `find_if_not_backward` return an iterator to the last
  54. element for which `pred` returns `false` in `[first, last)` or `r`,
  55. respectively.
  56. [heading Examples]
  57. Given the container `c1` containing `{ 2, 1, 2 }`, then
  58. find_backward ( c1.begin(), c1.end(), 2 ) --> --c1.end()
  59. find_backward ( c1.begin(), c1.end(), 3 ) --> c1.end()
  60. find_if_backward ( c1.begin(), c1.end(), [](int i) {return i == 2;} ) --> --c1.end()
  61. find_if_backward ( c1.begin(), c1.end(), [](int i) {return i == 3;} ) --> c1.end()
  62. find_not_backward ( c1.begin(), c1.end(), 2 ) --> std::prev(c1.end(), 2)
  63. find_not_backward ( c1.begin(), c1.end(), 1 ) --> c1.end()
  64. find_if_not_backward ( c1.begin(), c1.end(), [](int i) {return i == 2;} ) --> std::prev(c1.end(), 2)
  65. find_if_not_backward ( c1.begin(), c1.end(), [](int i) {return i == 1;} ) --> c1.end()
  66. [heading Iterator Requirements]
  67. All variants work on bidirectional iterators.
  68. [heading Complexity]
  69. Linear.
  70. [heading Exception Safety]
  71. All of the variants take their parameters by value and do not depend upon any
  72. global state. Therefore, all the routines in this file provide the strong
  73. exception guarantee.
  74. [heading Notes]
  75. All variants are `constexpr` in C++14 or later.
  76. [endsect]
  77. [/ File equal.qbk
  78. Copyright 2018 T. Zachary Laine
  79. Distributed under the Boost Software License, Version 1.0.
  80. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
  81. ]