Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
unique.hpp
Go to the documentation of this file.
1// Copyright 2026, Toyota Motor Corporation
2//
3// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4
5#ifndef INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_UNIQUE_HPP_
6#define INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_UNIQUE_HPP_
7
8#include "arene/base/algorithm/detail/functional.hpp"
9#include "arene/base/algorithm/detail/traits.hpp"
10#include "arene/base/constraints.hpp"
11#include "arene/base/iterator/next.hpp"
12#include "arene/base/type_traits/is_binary_predicate.hpp"
13#include "arene/base/type_traits/iterator_category_traits.hpp"
14#include "stdlib/include/stdlib_detail/declval.hpp"
15#include "stdlib/include/stdlib_detail/enable_if.hpp"
16#include "stdlib/include/stdlib_detail/internal_named_requirements.hpp"
17#include "stdlib/include/stdlib_detail/is_assignable.hpp"
18#include "stdlib/include/stdlib_detail/is_copy_constructible.hpp"
19#include "stdlib/include/stdlib_detail/move.hpp"
20#include "stdlib/include/stdlib_detail/remove_reference.hpp"
21
22// parasoft-begin-suppress CERT_CPP-DCL58-a-2 "Part of a standard library implementation"
23// parasoft-begin-suppress AUTOSAR-A17_6_1-a-2 "Part of a standard library implementation"
24
25// IWYU pragma: private, include <algorithm>
26// IWYU pragma: friend "stdlib_detail/.*"
27
28namespace std {
29
30// parasoft-begin-suppress AUTOSAR-M3_3_2-a "False positive: inline function used in multiple translation units"
31
32/// @brief removes consecutive elements in a range
33/// @tparam I forward iterator type
34/// @tparam P binary predicate type
35/// @param first beginning of the range of elements
36/// @param last end of the range of elements
37/// @param pred binary predicate which returns @c true if the elements are
38/// equivalent
39///
40/// @pre @c ForwardIterator must satisfy the forward iterator requirements.
41/// @pre <tt>[begin, end)</tt> must be a valid range.
42/// @pre The expression <tt>pred(r1, r2)</tt> must be convertible to @c bool
43/// for every argument @c r1 and @c r2 of type @c RT, where @c RT is the
44/// reference type of @c I, regardless of value category, and must not modify
45/// @c r1 or @c r2.
46/// @pre pred must define an *equivalence relation*. For values
47/// @c a, @c b, and @c c, the following properties must be satisfied:
48/// * reflexivity: <tt> pred(a, a) </tt> is @c true
49/// * symmetry: <tt> pred(a, b) == pred(b, a) </tt> is @c true
50/// * transitivity: if @c pred(a, b) and @c pred(b, c) are both @c true, then
51/// @c pred(a, c) is @c true
52///
53/// Removes all except the first element from a consecutive group of equivalent
54/// elements in the range <tt> [first, last) </tt>, and and returns a
55/// past-the-end iterator for the new end of the range.
56///
57/// Removal is performed by shifting the elements in the range in such a way
58/// that the elements that are not to be removed appear in the beginning of the
59/// range. The relative ordering of non removed elements is maintained by
60/// @c std::unique, (i.e. relative ordering is stable).
61///
62/// @return past-the-end iterator for the new range of values. If this is not
63/// @c end(), then it points to an unspecified value, and so do iterators to
64/// any values between this iterator and @c end().
65///
66/// @note Complexity
67/// Given N as <tt> std::distance(first, last) </tt>, exactly
68/// <tt> max(0, N - 1) </tt> applications of the predicate @c pred.
69///
70template <
71 class I,
72 class P,
78 nullptr>
79auto unique(I first, I last, P pred) noexcept( //
81 noexcept(std::declval<I&>() == std::declval<I&>()) && //
82 noexcept(std::declval<I&>() != std::declval<I&>()) && //
83 noexcept(++std::declval<I&>()) && //
84 noexcept(!std::declval<P&>()(*std::declval<I&>(), *std::declval<I&>())) && //
88) -> I {
89 if (first == last) {
90 return last;
91 }
92
93 for (auto iter = arene::base::next(first); iter != last; ++iter) {
94 if (!pred(*first, *iter)) {
95 ++first;
96 if (first != iter) {
97 *first = std::move(*iter);
98 }
99 }
100 }
101
102 return ++first;
103}
104
105/// @brief removes consecutive elements in a range
106/// @tparam I forward iterator type
107/// @param first beginning of the range of elements
108/// @param last end of the range of elements
109///
110/// @pre @c ForwardIterator must satisfy the forward iterator requirements.
111/// @pre <tt>[begin, end)</tt> must be a valid range.
112/// @pre The expression <tt>pred(r1, r2)</tt> must be convertible to @c bool
113/// for every argument @c r1 and @c r2 of type @c RT, where @c RT is the
114/// reference type of @c I, regardless of value category, and must not modify
115/// @c r1 or @c r2.
116/// @pre @c operator== must define an *equivalence relation*. For values
117/// @c a, @c b, and @c c, the following properties must be satisfied:
118/// * reflexivity: <tt> pred(a, a) </tt> is @c true
119/// * symmetry: <tt> pred(a, b) == pred(b, a) </tt> is @c true
120/// * transitivity: if @c pred(a, b) and @c pred(b, c) are both @c true, then
121/// @c pred(a, c) is @c true
122///
123/// Removes all except the first element from a consecutive group of equal
124/// elements in the range <tt> [first, last) </tt>, and and returns a
125/// past-the-end iterator for the new end of the range.
126///
127/// Removal is performed by shifting the elements in the range in such a way
128/// that the elements that are not to be removed appear in the beginning of the
129/// range. The relative ordering of non removed elements is maintained by
130/// @c std::unique, (i.e. relative ordering is stable).
131///
132/// @return past-the-end iterator for the new range of values. If this is not
133/// @c end(), then it points to an unspecified value, and so do iterators to
134/// any values between this iterator and @c end().
135///
136/// @note Complexity
137/// Given N as <tt> std::distance(first, last) </tt>, exactly
138/// <tt> max(0, N - 1) </tt> applications of @c operator==.
139///
140template <
141 class I,
150auto unique(I first, I last) noexcept( //
152) -> I {
154}
155
156// parasoft-end-suppress AUTOSAR-M3_3_2-a
157
158} // namespace std
159
160#endif // INCLUDE_GUARD_ARENE_BASE_STDLIB_INCLUDE_STDLIB_DETAIL_UNIQUE_HPP_
constexpr auto operator()(::arene::base::result< void, E > const &value) const noexcept(noexcept(hash< E >{}(std::declval< E const & >()))) -> std::size_t
Calculate the hash of a result.
Definition result.hpp:1827