Skip to content

Add shift_left, shift_right, contains, contains_subrange and find_last #90

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions doc/algorithm.qbk
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ Apply a functor to the elements of a sequence

[endsect:CXX17]

[section:CXX23 C++23 Algorithms]

[section:CXX23_inner_algorithms]

[include contains.qbk]
[include find_last.qbk]

[endsect:CXX23_inner_algorithms]

[endsect:CXX23]

[section:Misc Other Algorithms]

Expand Down
68 changes: 68 additions & 0 deletions doc/contains.qbk
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
[/ File contains.qbk]

[section:contains contains ]

[/license
Copyright (c) 2022 T. Zachary Laine

Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

The header file 'contains.hpp' contains an implementation of the C++23 stl
algorithms `contains` and `contains_subrange`.

The functions in this header are as close to the ones in C++23's `std::ranges`
namespace as possible. In C++20 builds, they are constrained exactly as the
standard does it. They each return a `bool`.

[heading interface]

template<typename I, typename S, typename T, typename Proj = identity>
BOOST_CXX14_CONSTEXPR bool
contains(I first, S last, const T & value, Proj proj = {});

template<typename R, typename T, typename Proj = identity>
BOOST_CXX14_CONSTEXPR bool
contains(R && r, const T & value, Proj proj = {});

These overloads return `std::ranges::find(first, last, value, proj) != last`.

template<typename I1, typename S1, typename I2, typename S2,
typename Pred = std::equal_to<>, typename Proj1 = identity, typename Proj2 = identity>
BOOST_CXX14_CONSTEXPR bool contains_subrange(
I1 first1, S1 last1, I2 first2, S2 last2,
Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});

template<typename R1, typename R2, typename Pred = std::equal_to<>,
typename Proj1 = identity, typename Proj2 = identity>
BOOST_CXX14_CONSTEXPR bool contains_subrange(
R1 && r1, R2 && r2, Pred pred = {}, Proj1 proj1 = {}, Proj2 proj2 = {});

These overloads return `first2 == last2 || !std::ranges::search(first1, last1, first2, last2, pred, proj1, proj2).empty()`.

[heading Iterator Requirements]

All variants work on forward iterators.

[heading Complexity]

Linear.

[heading Exception Safety]

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.

[heading Notes]

All variants are `constexpr` in C++14 or later.

[endsect]

[/ File contains.qbk
Copyright 2022 T. Zachary Laine
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
]
96 changes: 96 additions & 0 deletions doc/find_last.qbk
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
[/ File find_last.qbk]

[section:find_last find_last ]

[/license
Copyright (c) 2022 T. Zachary Laine

Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
]

The header file 'find_last.hpp' contains variants of the stl algorithm
`find`. These variants are like `find`, except that they find the last
instance of an element instead of the first.

The functions in this header are as close to the ones in C++23's `std::ranges`
namespace as possible. In C++20 builds, they are constrained exactly as the
standard does it. They each return a `boost::algorithm::subrange`, which is a
mostly-API-compatible version of `std::ranges::subrange`. It's differences
from the C++20 `subrange` are that it does not support sized ranges, and that
it cannot be implicitly converted to a pair-like type.

[heading interface]

template<typename ForwardIterator, typename Sentinel, typename T, typename Proj = identity>
BOOST_CXX14_CONSTEXPR subrange<ForwardIterator>
find_last(ForwardIterator first, Sentinel last, const T & value, Proj proj = {})

template<typename R, typename T, typename Proj = identity>
BOOST_CXX14_CONSTEXPR subrange<iterator_t<R>>
find_last(R && r, const T & value, Proj proj = {})

These overloads of `find_last` return a subrange `[it, end)`, where `it` is
the position of the last element that is equal to `x` in the given range, and
`end` is the end of the given range.

template<typename ForwardIterator, typename Sentinel, typename Pred, typename Proj = identity>
BOOST_CXX14_CONSTEXPR subrange<ForwardIterator>
find_last_if(ForwardIterator first, Sentinel last, Pred pred, Proj proj = {})

template<typename R, typename Pred, typename Proj = identity>
BOOST_CXX14_CONSTEXPR subrange<iterator_t<R>>
find_last_if(R && r, Pred pred, Proj proj = {})

These overloads of `find_if_last` return a subrange `[it, end)`, where `it` is
the position of the last element for which `pred` returns `true` in the given
range, and `end` is the end of the given range.

template<typename ForwardIterator, typename Sentinel, typename Pred, typename Proj = identity>
BOOST_CXX14_CONSTEXPR subrange<ForwardIterator>
find_last_if_not(ForwardIterator first, Sentinel last, Pred pred, Proj proj = {})

template<typename R, typename Pred, typename Proj = identity>
BOOST_CXX14_CONSTEXPR subrange<iterator_t<R>>
find_last_if_not(R && r, Pred pred, Proj proj = {})

These overloads of `find_if_last` return a subrange `[it, end)`, where `it` is
the position of the last element for which `pred` returns `false` in the given
range, and `end` is the end of the given range.

[heading Examples]

Given the container `c1` containing `{ 2, 1, 2 }`, then

find_last ( c1.begin(), c1.end(), 2 ) --> --c1.end()
find_last ( c1.begin(), c1.end(), 3 ) --> c1.end()
find_last_if ( c1.begin(), c1.end(), [](int i) {return i == 2;} ) --> --c1.end()
find_last_if ( c1.begin(), c1.end(), [](int i) {return i == 3;} ) --> c1.end()
find_last_if_not ( c1.begin(), c1.end(), [](int i) {return i == 2;} ) --> std::prev(c1.end(), 2)
find_last_if_not ( c1.begin(), c1.end(), [](int i) {return i == 1;} ) --> c1.end()

[heading Iterator Requirements]

All variants work on forward iterators.

[heading Complexity]

Linear.

[heading Exception Safety]

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.

[heading Notes]

All variants are `constexpr` in C++14 or later.

[endsect]

[/ File find_last.qbk
Copyright 2022 T. Zachary Laine
Distributed under the Boost Software License, Version 1.0.
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).
]
Loading