Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
set.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///
6/// @file set.hpp
7/// @brief Provides the implementation of @c arene::base::inline_set .
8///
9#ifndef INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_SET_HPP_
10#define INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_SET_HPP_
11
12// parasoft-begin-suppress AUTOSAR-A16_2_2-a-2 "Arene Base aggregate headers permitted by A16-2-2 Permit #1"
13#include "arene/base/algorithm/lexicographical_compare.hpp"
14#include "arene/base/algorithm/rotate.hpp"
15#include "arene/base/array/array.hpp"
16#include "arene/base/compare/compare_three_way.hpp"
17#include "arene/base/compare/operators.hpp"
18#include "arene/base/compare/strong_ordering.hpp"
19#include "arene/base/compiler_support/attributes.hpp"
20#include "arene/base/constraints/constraints.hpp"
21#include "arene/base/contracts/contract.hpp"
22#include "arene/base/inline_container/detail/compare.hpp"
23#include "arene/base/inline_container/detail/lower_bound_index.hpp"
24#include "arene/base/integer_sequences/sequential_values.hpp"
25#include "arene/base/iterator/advance.hpp"
26#include "arene/base/iterator/next.hpp"
27#include "arene/base/iterator/reverse_iterator.hpp"
28#include "arene/base/optional/optional.hpp"
29#include "arene/base/optional/optional_resetter.hpp"
30#include "arene/base/stdlib_choice/cstddef.hpp"
31#include "arene/base/stdlib_choice/enable_if.hpp"
32#include "arene/base/stdlib_choice/forward.hpp"
33#include "arene/base/stdlib_choice/ignore.hpp"
34#include "arene/base/stdlib_choice/initializer_list.hpp"
35#include "arene/base/stdlib_choice/integer_sequence.hpp"
36#include "arene/base/stdlib_choice/integral_constant.hpp"
37#include "arene/base/stdlib_choice/is_assignable.hpp"
38#include "arene/base/stdlib_choice/is_constructible.hpp"
39#include "arene/base/stdlib_choice/is_copy_assignable.hpp"
40#include "arene/base/stdlib_choice/is_copy_constructible.hpp"
41#include "arene/base/stdlib_choice/is_destructible.hpp"
42#include "arene/base/stdlib_choice/is_integral.hpp"
43#include "arene/base/stdlib_choice/is_move_assignable.hpp"
44#include "arene/base/stdlib_choice/is_move_constructible.hpp"
45#include "arene/base/stdlib_choice/iterator_tags.hpp"
46#include "arene/base/stdlib_choice/iterator_traits.hpp"
47#include "arene/base/stdlib_choice/move.hpp"
48#include "arene/base/stdlib_choice/pair.hpp"
49#include "arene/base/type_manipulation/non_constructible_dummy.hpp"
50#include "arene/base/type_manipulation/smallest_integer_for.hpp"
51#include "arene/base/type_traits/conditional.hpp"
52#include "arene/base/type_traits/decays_to.hpp"
53#include "arene/base/type_traits/is_invocable.hpp"
54#include "arene/base/type_traits/is_transparent_comparator_for.hpp"
55#include "arene/base/type_traits/iterator_category_traits.hpp"
56#include "arene/base/utility/forward_like.hpp"
57#include "arene/base/utility/in_place.hpp"
58#include "arene/base/utility/make_subrange.hpp"
59// parasoft-end-suppress AUTOSAR-A16_2_2-a-2
60
61namespace arene {
62namespace base {
63
64// forward declaration
65// IWYU pragma: begin_keep
66template <typename Value, std::size_t Capacity, typename Compare>
67class inline_set;
68// IWYU pragma: end_keep
69
70namespace inline_set_detail {
71/// @brief Tag type to indicate the comparator for an inline_set
72struct inline_set_comparator_tag {};
73
74/// @brief Passkey type for iterator access.
75class set_passkey {
76 private:
77 /// @brief Prevent construction from @c {}
78 explicit set_passkey() = default;
79
80 // parasoft-begin-suppress AUTOSAR-A11_3_1-a-2 "Passkey idiom permitted by A11-3-1 Permit #1"
81 /// @brief friend declaration to allow inline_set to construct the passkey.
82 template <typename Value, std::size_t Capacity, typename Compare>
83 friend class ::arene::base::inline_set;
84 // parasoft-end-suppress AUTOSAR-A11_3_1-a-2
85};
86} // namespace inline_set_detail
87
88// parasoft-begin-suppress AUTOSAR-A12_1_5-a-2 "False positive: delegating constructors are used"
89// parasoft-begin-suppress AUTOSAR-A10_1_1-a-2 "False positive: 'generic_ordering_from_three_way_compare' is an
90// interface"
91// parasoft-begin-suppress AUTOSAR-A12_0_1-a-2 "False Positive: Copy operations are defined or deleted as appropriate"
92// parasoft-begin-suppress AUTOSAR-A1_1_1-b-2 "False Positive: Copy operations are defined or deleted as appropriate"
93/// @brief A non-allocating fixed-capacity associative container storing elements of type @c Value .
94///
95/// Any attempt to store more than @c Capacity elements will result in an @c ARENE_PRECONDITION violation. The
96/// comparison function specified with the @c Compare template parameter can either return @c bool, in which case it is
97/// assumed to be a simple ordering comparison like @c std::less, or it can return @c strong_ordering, in which case it
98/// is assumed to be a three-way comparison operator. The default comparison is @c three_way_compare.
99/// @tparam Value The type of values stored in the set. Must satisfy @c std::is_nothrow_destructible .
100/// @tparam Capacity The maximum number of elements that can be stored in the set .
101/// @tparam Compare The comparison function used to impose a sort order on the elements. Must satisfy
102/// @c std::is_nothrow_destructible as well as either
103/// <c>is_invocable_r_v<bool, const Compare&, const Value&, const Value&></c> or
104/// <c>is_invocable_r_v<strong_ordering, const Compare&, const Value&, const Value&></c>. The comparison must
105/// provide a strict ordering over the values of @c Value , and copies or moves of the comparator must yield the
106/// same ordering. Defaults to @c compare_three_way .
107template <typename Value, std::size_t Capacity, typename Compare = compare_three_way>
108// NOLINTNEXTLINE(hicpp-special-member-functions)
109class inline_set
110 : inline_container::detail::compare_wrapper<Compare, Value>
111 , generic_ordering_from_three_way_compare<inline_set<Value, Capacity, Compare>> {
112 static_assert(std::is_nothrow_destructible<Value>::value, "Destructors must not throw");
113 static_assert(std::is_nothrow_destructible<Compare>::value, "Destructors must not throw");
114 static_assert(
115 is_invocable_r_v<bool, Compare const&, Value const&, Value const&> ||
116 is_invocable_r_v<strong_ordering, Compare const&, Value const&, Value const&>,
117 "Compare must be invocable with two Values, and yield either a bool or a strong_ordering"
118 );
119
120 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
121 /// @brief helper trait for determining if the comparator supports transparent comparisons.
122 /// @tparam OtherKey the type of the other operand to test for validity against.
123 /// @return bool @c true If @c Compare satisfies either @c is_transparent_comparator_for_v or
124 /// @c is_transparent_three_way_comparator_for_v with @c Value and @c OtherKey , else @c false .
125 template <typename OtherKey>
126 static constexpr bool
127 transparent_comparison_supported_for{::arene::base::is_transparent_comparator_for_v<Compare, Value const&, OtherKey const&> || ::arene::base::is_transparent_three_way_comparator_for_v<Compare, Value const&, OtherKey const&>};
128 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
129
130 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
131 /// @brief The base class that holds the comparator
132 using comparator_base = inline_container::detail::compare_wrapper<Compare, Value>;
133 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
134 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
135 /// @brief The base class that injects operator overloads.
136 using operator_base = generic_ordering_from_three_way_compare<inline_set<Value, Capacity, Compare>>;
137 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
138
139 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
140 /// @brief Can comparisons throw?
141 /// @tparam OtherKey The type of the rhs operand to a comparison.
142 /// @return bool alias for @c comparator_base::template comparison_is_noexcept<OtherKey>
143 template <typename OtherKey = Value>
144 static constexpr bool comparison_is_noexcept{comparator_base::template comparison_is_noexcept<OtherKey>};
145 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
146
147 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
148 /// @brief The type of each element in the index
149 using index_type = smallest_unsigned_integer_for<Capacity>;
150 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
151
152 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
153 /// @brief The type of the storage for an individual element
154 using entry_type = optional<Value>;
155 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
156
157 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
158 /// @brief The argument to the "move constructor": @c inline_set if the move constructor is supported, @c
159 /// non_constructible_dummy otherwise
160 using move_construct_source = conditional_t<
161 std::is_move_constructible<Compare>::value && std::is_move_constructible<Value>::value,
162 inline_set,
163 non_constructible_dummy>;
164 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
165 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
166 /// @brief The argument to the "move assignment operator": @c inline_set if the move assignment operator is supported,
167 /// @c non_constructible_dummy otherwise
168 using move_assign_source = conditional_t<
169 std::is_move_assignable<Compare>::value && std::is_move_constructible<Value>::value,
170 inline_set,
171 non_constructible_dummy>;
172 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
173 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
174 /// @brief The argument to the deleted "move assignment operator": @c inline_set if the move assignment operator is
175 /// NOT supported, @c non_constructible_dummy otherwise
176 using deleted_move_assign_source = conditional_t<
177 std::is_move_assignable<Compare>::value && std::is_move_constructible<Value>::value,
178 non_constructible_dummy,
179 inline_set>;
180 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
181 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
182 /// @brief The argument to the "copy assignment operator": @c inline_set if the copy assignment operator is supported,
183 /// @c non_constructible_dummy otherwise
184 using copy_assign_source = conditional_t<
185 std::is_copy_assignable<Compare>::value && std::is_copy_constructible<Value>::value,
186 inline_set,
187 non_constructible_dummy>;
188 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
189 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
190 /// @brief The argument to the deleted "copy assignment operator": @c inline_set if the copy assignment operator is
191 /// NOT supported, @c non_constructible_dummy otherwise
192 using deleted_copy_assign_source = conditional_t<
193 std::is_copy_assignable<Compare>::value && std::is_copy_constructible<Value>::value,
194 non_constructible_dummy,
195 inline_set>;
196 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
197
198 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
199 /// @brief An iterator into an @c inline_set
200 class iterator_impl : generic_ordering_from_three_way_compare<iterator_impl> {
201 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
202 /// @brief The set
203 inline_set const* set_{nullptr};
204 /// @brief The index to the target element
205 index_type element_index_{0};
206
207 public:
208 /// @brief The category of this iterator
209 using iterator_category = std::bidirectional_iterator_tag;
210
211 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "Required type alias to meet iterator requirements"
212 /// @brief The value type
213 using value_type = Value;
214 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
215
216 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "Required type alias to meet iterator requirements"
217 /// @brief The return type of @c operator->
218 using pointer = Value const*;
219 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
220
221 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "Required type alias to meet iterator requirements"
222 /// @brief The return type of @c operator*
223 using reference = Value const&;
224 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
225
226 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "Required type alias to meet iterator requirements"
227 /// @brief The type of the difference between two iterators
228 using difference_type = std::ptrdiff_t;
229 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
230
231 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
232 // initialize the base class"
233 /// @brief A default constructed iterator has no associated set
234 /// @post @c is_for(/*non-null*/) will return @c false .
235 /// @post @c index() will return @c 0 .
236 iterator_impl() noexcept
237 : iterator_impl(inline_set_detail::set_passkey{}, nullptr, 0U) {}
238 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
239
240 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
241 /// @brief Construct an iterator for the specified set and element index
242 ///
243 /// @param set_to_iterate The set to refer to
244 /// @param element The index into @c inline_set::indices_ of the element the iterator currently points to.
245 /// @post @c is_for(set_to_iterate) will return @c true .
246 /// @post @c index() will return @c element .
247 iterator_impl(inline_set_detail::set_passkey, inline_set const* set_to_iterate, index_type element) noexcept
248 : generic_ordering_from_three_way_compare<iterator>(),
249 set_(set_to_iterate),
250 element_index_(element) {}
251 // parasoft-end-suppress CERT_C-EXP37-a-3
252
253 /// @brief Get a reference to the target element
254 ///
255 /// @return reference A reference to the element at the current position.
256 /// @pre @c *this!=iterator{} , else @c ARENE_PRECONDITION violation.
257 /// @pre The iterator is in the valid range of the set, else @c ARENE_PRECONDITION violation.
258 auto operator*() const noexcept -> reference {
259 ARENE_PRECONDITION(set_ != nullptr);
260 return *(set_->values_[set_->indices_[element_index_]]);
261 }
262 /// @brief Get a pointer to the target element
263 ///
264 /// @return pointer A pointer to the element at the current position.
265 /// @pre @c *this!=iterator{} , else @c ARENE_PRECONDITION violation.
266 /// @pre The iterator is in the valid range of the set, else @c ARENE_PRECONDITION violation.
267 auto operator->() const noexcept -> pointer { return &**this; }
268
269 /// @brief Pre-increment the iterator
270 ///
271 /// @return iterator& The iterator post-modification
272 /// @post The iterator points to the next position in the set.
273 auto operator++() noexcept -> iterator_impl& {
274 ++element_index_;
275 return *this;
276 }
277
278 // parasoft-begin-suppress AUTOSAR-A3_9_1-b-2 "False positive: postincrement requires an int parameter"
279 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
280 /// @brief Post-increment the iterator
281 ///
282 /// @return iterator A copy of the iterator pre-modification
283 /// @post The iterator points to the next position in the set.
284 auto operator++(int) noexcept -> iterator_impl {
285 iterator temp{*this};
286 ++(*this);
287 return temp;
288 }
289 // parasoft-end-suppress CERT_C-EXP37-a-3
290 // parasoft-end-suppress AUTOSAR-A3_9_1-b-2
291
292 /// @brief Pre-decrement the iterator
293 ///
294 /// @return iterator& The iterator post-modification
295 /// @post The iterator points to the previous position in the set.
296 auto operator--() noexcept -> iterator_impl& {
297 ARENE_PRECONDITION(element_index_ > 0U);
298 --element_index_;
299 return *this;
300 }
301
302 // parasoft-begin-suppress AUTOSAR-A3_9_1-b-2 "False positive: postdecrement requires an int parameter"
303 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
304 /// @brief Post-increment the iterator
305 ///
306 /// @return iterator A copy of the iterator pre-modification
307 /// @post The iterator points to the previous position in the set.
308 auto operator--(int) noexcept -> iterator_impl {
309 iterator temp{*this};
310 --(*this);
311 return temp;
312 }
313 // parasoft-end-suppress CERT_C-EXP37-a-3
314 // parasoft-end-suppress AUTOSAR-A3_9_1-b-2
315
316 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
317 /// @brief Do three-way comparison on the provided iterators.
318 ///
319 /// @param lhs The first iterator to compare
320 /// @param rhs The second iterator to compare
321 /// @return @c strong_ordering::less if @c lhs comes before @c rhs in iteration order.
322 /// @return @c strong_ordering::equal if @c lhs is the same as @c rhs in iteration order.
323 /// @return @c strong_ordering::greater if @c lhs comes after @c rhs in iteration order.
324 /// @pre The iterators must be constructed from the same @c inline_set instance, else @c ARENE_PRECONDITION
325 /// violation.
326 static auto three_way_compare(iterator_impl const lhs, iterator_impl const rhs) noexcept -> strong_ordering {
327 ARENE_PRECONDITION(lhs.is_for(rhs.set_));
328 return compare_three_way{}(lhs.element_index_, rhs.element_index_);
329 }
330 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
331
332 /// @brief check if iterators are from the same set.
333 ///
334 /// @param set_to_check The set to check for
335 /// @return true if @c this->set_==set_to_check
336 /// @return false otherwise
337 auto is_for(inline_set const* set_to_check) const noexcept -> bool { return set_ == set_to_check; }
338
339 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
340 /// @brief Get the position this iterator references within a set.
341 /// Can only be called by members of @c inline_set
342 /// @return index_type The index position of this iterator.
343 auto index(inline_set_detail::set_passkey) const noexcept -> index_type { return element_index_; }
344 // parasoft-end-suppress CERT_C-EXP37-a-3
345 };
346
347 public:
348 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
349 /// @brief The type of the value in the set
350 using value_type = Value;
351 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
352
353 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
354 /// @brief The type of the comparator for the value
355 using value_compare = Compare;
356 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
357
358 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
359 /// @brief The type of the key in the set, which is the same as the value
360 using key_type = Value;
361 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
362
363 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
364 /// @brief The type of the comparator for the key
365 using key_compare = Compare;
366 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
367
368 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
369 /// @brief A pointer to the value
370 using pointer = value_type*;
371 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
372
373 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
374 /// @brief A pointer to a const value
375 using const_pointer = value_type const*;
376 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
377
378 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
379 /// @brief A reference to a value
380 using reference = value_type&;
381 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
382
383 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
384 /// @brief A reference to a const value
385 using const_reference = value_type const&;
386 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
387
388 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
389 /// @brief The type of the size of the container
390 using size_type = std::size_t;
391 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
392
393 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
394 /// @brief The type of the difference between two iterators
395 using difference_type = std::ptrdiff_t;
396 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
397
398 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
399 /// @brief The iterator type for the set.
400 using iterator = iterator_impl;
401 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
402
403 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
404 /// @brief A const iterator for the set: the same as @c iterator, since elements are @c const
405 using const_iterator = iterator;
406 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
407
408 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
409 /// @brief A reverse iterator for the set
410 using reverse_iterator = ::arene::base::reverse_iterator<iterator>;
411 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
412
413 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
414 /// @brief A const reverse iterator for the set.
415 using const_reverse_iterator = ::arene::base::reverse_iterator<const_iterator>;
416 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
417
418 /// @brief Construct a set with no elements and a default-constructed comparator
419 inline_set() = default;
420
421 /// @brief Default destructor; destroys all stored elements
422 ~inline_set() = default;
423
424 /// @brief Construct a set with no elements, using the specified comparator
425 ///
426 /// @param comp The comparator to use
427 /// @post @c size()==0
428 explicit inline_set(Compare const& comp) noexcept(std::is_nothrow_copy_constructible<Compare>::value)
430 operator_base() {}
431
432 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
433 /// @brief Construct a set from the specified list of values.
434 ///
435 /// @param init The list of elements to store in the set
436 /// @post @c size()==init.size()
437 /// @post The elements in the set will be the unique elements of @c init , sorted via a default-constructed instance
438 /// of @c Compare .
439 /// @pre @c init.size()<=max_size() else @c ARENE_PRECONDITION violation .
440 inline_set(std::initializer_list<Value> init
442 : inline_set() {
443 insert(init);
444 }
445 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
446
447 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
448 /// @brief Construct a set from the specified list of values and a specified comparator instance .
449 ///
450 /// @param init The list of elements to store in the set .
451 /// @param comp The comparator to use.
452 /// @post @c size()==init.size()
453 /// @post The elements in the set will be the unique elements of @c init , sorted via @c comp .
454 /// @pre @c init.size()<=max_size() else @c ARENE_PRECONDITION violation .
455 inline_set(std::initializer_list<Value> init, Compare const& comp) noexcept(
457 )
458 : inline_set(comp) {
459 insert(init);
460 }
461 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
462
463 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
464 /// @brief Attempt to construct a set from the specified list of values.
465 ///
466 /// @param init The list of elements to store in the set
467 /// @return optional<inline_set> If the number of unique elements in @c init is less than or equal to @c Capacity ,
468 /// then will return a populated optional equivalent to @c inline_set{init} . Otherwise returns a null optional.
469 ARENE_NODISCARD static auto try_construct(std::initializer_list<Value> init
471 -> optional<inline_set> {
472 optional<inline_set> res{in_place};
473 if (!res->insert_elements_if_they_fit(init.begin(), init.end())) {
474 res.reset();
475 }
476 return res;
477 }
478 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
479
480 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
481 /// @brief Attempt to construct a set from the specified list of values and a comparator.
482 ///
483 /// @param init The list of elements to store in the set
484 /// @param comp The comparator to use.
485 /// @return optional<inline_set> If the number of unique elements in @c init is less than or equal to @c Capacity ,
486 /// then will return a populated optional equivalent to @c inline_set{init,comp} . Otherwise returns a null optional.
487 ARENE_NODISCARD static auto try_construct(std::initializer_list<Value> init, Compare const& comp) noexcept(
489 ) -> optional<inline_set> {
490 optional<inline_set> res{in_place, comp};
491 if (!res->insert_elements_if_they_fit(init.begin(), init.end())) {
492 res.reset();
493 }
494 return res;
495 }
496 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
497
498 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
499 /// @brief Construct a set from the elements in the provided iterator range.
500 ///
501 /// @tparam Iterator The type of the iterators. Must satisfy
502 /// @c std::is_constructible<Value,std::iterator_traits<Iterator>::reference> .
503 /// @param first The iterator to the first element in the range
504 /// @param last The iterator to the one-past-the-end element in the range
505 /// @post @c size() will be equal to the number of unique elements in the range @c [first,last)
506 /// @post The elements in the set will be the unique elements in the range @c [first,last) , sorted via a
507 /// default-constructed instance of @c Compare .
508 /// @pre The number of unique elements in the range @c [first,last) is less than or equal to @c max_size() , else @c
509 /// ARENE_PRECONDITION violation.
510 template <
511 typename Iterator,
512 constraints<
513 std::enable_if_t<base::is_input_iterator_v<Iterator>>,
514 std::enable_if_t<std::is_constructible<Value, typename std::iterator_traits<Iterator>::reference>::value>> =
515 nullptr>
516 inline_set(Iterator first, Iterator last) noexcept(
517 std::is_nothrow_constructible<Value, typename std::iterator_traits<Iterator>::reference>::value &&
518 std::is_nothrow_constructible<Compare>::value
519 )
520 : inline_set() {
521 insert(first, last);
522 }
523 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
524
525 // parasoft-begin-suppress AUTOSAR-A12_1_1-a-2 "False positive: This constructor delegates to another, which does
526 /// @brief Construct a set from the elements in the provided iterator range and comparator.
527 ///
528 /// @tparam Iterator The type of the iterators. Must satisfy
529 /// @c std::is_constructible<Value,std::iterator_traits<Iterator>::reference> .
530 /// @param first The iterator to the first element in the range
531 /// @param last The iterator to the one-past-the-end element in the range
532 /// @param comp The comparator to use .
533 /// @post @c size() will be equal to the number of unique elements in the range @c [first,last)
534 /// @post The elements in the set will be the unique elements in the range @c [first,last) , sorted via @c comp .
535 /// @pre The number of unique elements in the range @c [first,last) is less than or equal to @c max_size() , else @c
536 /// ARENE_PRECONDITION violation.
537 template <
538 typename Iterator,
539 constraints<
540 std::enable_if_t<base::is_input_iterator_v<Iterator>>,
541 std::enable_if_t<std::is_constructible<Value, typename std::iterator_traits<Iterator>::reference>::value>> =
542 nullptr>
543 inline_set(Iterator first, Iterator last, Compare const& comp) noexcept(
544 std::is_nothrow_constructible<Value, typename std::iterator_traits<Iterator>::reference>::value &&
545 std::is_nothrow_copy_constructible<Compare>::value
546 )
547 : inline_set(comp) {
548 insert(first, last);
549 }
550 // parasoft-end-suppress AUTOSAR-A12_1_1-a-2
551
552 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
553 /// @brief Attempt to construct a set from the specified sequence of values.
554 ///
555 /// @tparam Iterator The type of the iterators. Must satisfy
556 /// @c std::is_constructible<Value,std::iterator_traits<Iterator>::reference> .
557 /// @param first The iterator to the first element in the range
558 /// @param last The iterator to the one-past-the-end element in the range
559 /// @return optional<inline_set> If the number of unique elements in the range @c [first,last) is less than or equal
560 /// to @c Capacity , then will return a populated optional equivalent to @c inline_set{first,last} . Otherwise returns
561 /// a null optional.
562 template <
563 typename Iterator,
564 constraints<
565 std::enable_if_t<base::is_input_iterator_v<Iterator>>,
566 std::enable_if_t<std::is_constructible<Value, typename std::iterator_traits<Iterator>::reference>::value>> =
567 nullptr>
568 ARENE_NODISCARD static auto try_construct(Iterator first, Iterator last) noexcept(
569 noexcept(inline_set{first, last}) && std::is_nothrow_move_constructible<inline_set>::value
570 ) -> optional<inline_set> {
571 optional<inline_set> res{in_place};
572 if (!res->insert_elements_if_they_fit(first, last)) {
573 res.reset();
574 }
575 return res;
576 }
577 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
578
579 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
580 /// @brief Attempt to construct a set from the specified sequence of values and a comparator.
581 ///
582 /// @tparam Iterator The type of the iterators. Must satisfy
583 /// @c std::is_constructible<Value,std::iterator_traits<Iterator>::reference> .
584 /// @param first The iterator to the first element in the range
585 /// @param last The iterator to the one-past-the-end element in the range
586 /// @param comp The comparator to use .
587 /// @return optional<inline_set> If the number of unique elements in the range @c [first,last) is less than or equal
588 /// to @c Capacity , then will return a populated optional equivalent to @c inline_set{first,last} . Otherwise returns
589 /// a null optional.
590 template <
591 typename Iterator,
592 constraints<
593 std::enable_if_t<base::is_input_iterator_v<Iterator>>,
594 std::enable_if_t<std::is_constructible<Value, typename std::iterator_traits<Iterator>::reference>::value>> =
595 nullptr>
596 ARENE_NODISCARD static auto try_construct(Iterator first, Iterator last, Compare const& comp) noexcept(
597 noexcept(inline_set{first, last, comp}) && std::is_nothrow_move_constructible<inline_set>::value
598 ) -> optional<inline_set> {
599 optional<inline_set> res{in_place, comp};
600 if (!res->insert_elements_if_they_fit(first, last)) {
601 res.reset();
602 }
603 return res;
604 }
605 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
606
607 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
608 /// @brief copy ctor.
609 // NOLINTBEGIN(google-explicit-constructor,hicpp-explicit-conversions) These are copy ctors.
610 inline_set(inline_set const&) = default;
611 // parasoft-end-suppress CERT_C-EXP37-a-3
612
613 /// @brief copy construct from a set with a smaller capacity
614 ///
615 /// Participates in overload resolution if @c Value and @c Compare satisfy @c is_copy_constructible
616 ///
617 /// @tparam OtherCapacity The capacity of the other set
618 /// @param other The set to copy from.
619 /// @post @c size()==other.size()
620 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
621 /// copy-construction.
622 template <
623 std::size_t OtherCapacity,
624 constraints<
625 std::enable_if_t<(OtherCapacity < Capacity)>,
626 std::enable_if_t<std::is_copy_constructible<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
627 inline_set(inline_set<Value, OtherCapacity, Compare> const& other
628 ) noexcept(std::is_nothrow_copy_constructible<Value>::value && std::is_nothrow_copy_constructible<Compare>::value)
629 : comparator_base(other.get_comparator_base(inline_set_detail::set_passkey{})),
630 operator_base() {
631 do_copy(other);
632 }
633
634 /// @brief copy construct from a set with a larger capacity
635 ///
636 /// Participates in overload resolution if @c Value and @c Compare satisfy @c is_copy_constructible
637 ///
638 /// @tparam OtherCapacity The capacity of the other set
639 /// @param other The set to copy from.
640 /// @post @c size()==other.size()
641 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
642 /// copy-construction.
643 /// @pre @c other.size()<=maximum_size() else @c ARENE_PRECONDITION violation.
644 template <
645 std::size_t OtherCapacity,
646 constraints<
647 std::enable_if_t<(OtherCapacity > Capacity)>,
648 std::enable_if_t<std::is_copy_constructible<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
649 inline_set(inline_set<Value, OtherCapacity, Compare> const& other
650 ) noexcept(std::is_nothrow_copy_constructible<Value>::value && std::is_nothrow_copy_constructible<Compare>::value)
651 : comparator_base(other.get_comparator_base(inline_set_detail::set_passkey{})),
652 operator_base() {
653 ARENE_PRECONDITION(other.size() <= max_size());
654 do_copy(other);
655 }
656 // NOLINTEND(google-explicit-constructor,hicpp-explicit-conversions)
657
658 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
659 /// @brief Attempts to construct a set via copy-construction from a set with the same or smaller capacity.
660 ///
661 /// @tparam OtherCapacity The capacity of the other set
662 /// @param other The set to copy from.
663 /// @return A populated optional equivalent to @c inline_set{other}
664 template <
665 std::size_t OtherCapacity,
666 constraints<
667 std::enable_if_t<(OtherCapacity <= Capacity)>,
668 std::enable_if_t<std::is_copy_constructible<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
669 ARENE_NODISCARD static auto try_construct(inline_set<Value, OtherCapacity, Compare> const& other
670 ) noexcept(noexcept(inline_set{other})) -> optional<inline_set> {
671 return optional<inline_set>{in_place, other};
672 }
673 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
674
675 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
676 /// @brief Attempts to construct a set from a set with a larger capacity.
677 ///
678 /// @tparam OtherCapacity The capacity of the other set
679 /// @param other The set to copy from.
680 /// @return optional<inline_set> If @c other.size()<=Capacity , then will return a populated optional equivalent to
681 /// @c inline_set{other} . Otherwise returns a null optional.
682 template <
683 std::size_t OtherCapacity,
684 constraints<
685 std::enable_if_t<(OtherCapacity > Capacity)>,
686 std::enable_if_t<std::is_copy_constructible<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
687 ARENE_NODISCARD static auto try_construct(inline_set<Value, OtherCapacity, Compare> const& other
688 ) noexcept(noexcept(inline_set{other})) -> optional<inline_set> {
689 if (other.size() <= Capacity) {
690 return optional<inline_set>{in_place, other};
691 }
692 return nullopt;
693 }
694 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
695
696 // parasoft-begin-suppress AUTOSAR-A15_5_1-b-2 "False positive: Conditionally noxecept"
697 // NOLINTBEGIN(google-explicit-constructor,hicpp-explicit-conversions) clang-tidy doesn't see these as move ctors.
698 /// @brief move ctor
699 ///
700 /// Participates in overload resolution if @c Value satisfies @c is_move_constructible
701 ///
702 /// @tparam OtherCapacity The maximum capacity of the other set to move from.
703 /// @param other The set to move from
704 /// @post @c size()==other.size()
705 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
706 /// move-construction.
707 inline_set(move_construct_source&& other
708 ) noexcept(std::is_nothrow_move_constructible<Value>::value && std::is_nothrow_constructible<Compare>::value)
709 : comparator_base(std::move(static_cast<comparator_base&>(other))),
710 operator_base(),
711 number_of_active_elements_(other.number_of_active_elements_),
712 values_(move_values(other, std::make_index_sequence<Capacity>())),
713 indices_(std::move(other.indices_)) {}
714 // parasoft-end-suppress AUTOSAR-A15_5_1-b-2
715
716 /// @brief move construct from a set with a larger capacity
717 ///
718 /// Participates in overload resolution if @c Value satisfies @c is_move_constructible
719 ///
720 /// @tparam OtherCapacity The maximum capacity of the other set to move from.
721 /// @param other The set to move from
722 /// @post @c size()==other.size()
723 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
724 /// move-construction.
725 /// @pre @c other.size()<=maximum_size() else @c ARENE_PRECONDITION violation.
726 template <
727 std::size_t OtherCapacity,
728 constraints<
729 std::enable_if_t<(OtherCapacity > Capacity)>,
730 std::enable_if_t<std::is_move_constructible<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
731 inline_set(inline_set<Value, OtherCapacity, Compare>&& other)
732 : comparator_base(std::move(other.get_comparator_base(inline_set_detail::set_passkey{}))),
733 operator_base() {
734 ARENE_PRECONDITION(other.size() <= max_size());
735 do_move(std::move(other));
736 }
737 /// @brief move construct from a set with a smaller capacity
738 ///
739 /// Participates in overload resolution if @c Value satisfies @c is_move_constructible
740 ///
741 /// @tparam OtherCapacity The maximum capacity of the other set to move from.
742 /// @param other The set to move from
743 /// @post @c size()==other.size()
744 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
745 /// move-construction.
746 template <
747 std::size_t OtherCapacity,
748 constraints<
749 std::enable_if_t<(OtherCapacity < Capacity)>,
750 std::enable_if_t<std::is_move_constructible<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
751 inline_set(inline_set<Value, OtherCapacity, Compare>&& other
752 ) noexcept(std::is_nothrow_move_constructible<Value>::value && std::is_nothrow_move_constructible<Compare>::value)
753 : comparator_base(std::move(other.get_comparator_base(inline_set_detail::set_passkey{}))),
754 operator_base() {
755 do_move(std::move(other));
756 }
757 /// @}
758 // NOLINTEND(google-explicit-constructor,hicpp-explicit-conversions) clang-tidy doesn't see these as move ctors.
759
760 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
761 /// @brief Attempts to construct a set via move-construction from a set with a capacity that is less than or equal to
762 /// the target capacity.
763 ///
764 /// @tparam OtherCapacity The capacity of the other set
765 /// @param other The set to move from.
766 /// @return A populated optional equivalent to @c inline_set{other} .
767 template <
768 std::size_t OtherCapacity,
769 constraints<
770 std::enable_if_t<(OtherCapacity <= Capacity)>,
771 std::enable_if_t<std::is_copy_constructible<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
772 ARENE_NODISCARD static auto try_construct(inline_set<Value, OtherCapacity, Compare>&& other
773 ) noexcept(noexcept(inline_set{std::move(other)})) -> optional<inline_set> {
774 return optional<inline_set>{in_place, std::move(other)};
775 }
776 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
777
778 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
779 /// @brief Attempts to construct a set via move-construction from a set with a larger capacity.
780 ///
781 /// @tparam OtherCapacity The capacity of the other set
782 /// @param other The set to move from.
783 /// @return If @c other.size()<=Capacity , then will return a populated optional equivalent to @c inline_set{other} .
784 /// Otherwise returns a null optional.
785 template <
786 std::size_t OtherCapacity,
787 constraints<
788 std::enable_if_t<(OtherCapacity > Capacity)>,
789 std::enable_if_t<std::is_copy_constructible<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
790 ARENE_NODISCARD static auto try_construct(inline_set<Value, OtherCapacity, Compare>&& other
791 ) noexcept(noexcept(inline_set{other})) -> optional<inline_set> {
792 if (other.size() <= Capacity) {
793 return optional<inline_set>{in_place, std::move(other)};
794 }
795 return nullopt;
796 }
797 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
798
799 /// @brief Deleted copy-assignment operator where the set is not copy-assignable
800 auto operator=(deleted_copy_assign_source const& other) -> inline_set& = delete;
801 /// @brief copy-assignment operator.
802 ///
803 /// Participates in overload resolution if @c Value satisfies @c std::is_copy_constructible and @c Compare satisfies
804 /// @c is_copy_assignable
805 ///
806 /// @tparam OtherCapacity the capacity of the other set.
807 /// @param other The set to copy-assign from.
808 /// @return inline_set& The set post-assignment.
809 /// @post @c size()==other.size()
810 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
811 /// copy-assignment/construction.
812 /// @pre @c other.size()<=maximum_size() else @c ARENE_PRECONDITION violation.
813 auto operator=(copy_assign_source const& other
815 -> inline_set& {
816 if (this != &other) {
817 static_cast<comparator_base&>(*this) = other;
818 do_copy(other);
819 }
820 return *this;
821 }
822 /// @brief copy-assignment operator for copying from a set with a larger capacity
823 ///
824 /// Participates in overload resolution if @c Value satisfies @c std::is_copy_constructible and @c Compare satisfies
825 /// @c is_copy_assignable
826 ///
827 /// @tparam OtherCapacity the capacity of the other set.
828 /// @param other The set to copy-assign from.
829 /// @return inline_set& The set post-assignment.
830 /// @post @c size()==other.size()
831 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
832 /// copy-assignment/construction.
833 /// @pre @c other.size()<=maximum_size() else @c ARENE_PRECONDITION violation.
834 template <
835 std::size_t OtherCapacity,
836 constraints<
837 std::enable_if_t<(OtherCapacity > Capacity)>,
838 std::enable_if_t<std::is_copy_assignable<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
839 auto operator=(inline_set<Value, OtherCapacity, Compare> const& other
840 ) noexcept(std::is_nothrow_copy_constructible<Value>::value && std::is_nothrow_copy_assignable<Compare>::value)
841 -> inline_set& {
842 ARENE_PRECONDITION(other.size() <= max_size());
843 static_cast<comparator_base&>(*this) = other.get_comparator_base(inline_set_detail::set_passkey{});
844 do_copy(other);
845 return *this;
846 }
847 /// @brief copy-assignment operator for copying from a set with a smaller capacity
848 ///
849 /// Participates in overload resolution if @c Value satisfies @c std::is_copy_constructible and @c Compare satisfies
850 /// @c is_copy_assignable
851 ///
852 /// @tparam OtherCapacity the capacity of the other set.
853 /// @param other The set to copy-assign from.
854 /// @return inline_set& The set post-assignment.
855 /// @post @c size()==other.size()
856 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
857 /// copy-assignment/construction.
858 template <
859 std::size_t OtherCapacity,
860 constraints<
861 std::enable_if_t<(OtherCapacity < Capacity)>,
862 std::enable_if_t<std::is_copy_assignable<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
863 auto operator=(inline_set<Value, OtherCapacity, Compare> const& other
864 ) noexcept(std::is_nothrow_copy_assignable<inline_set<Value, OtherCapacity, Compare>>::value) -> inline_set& {
865 static_cast<comparator_base&>(*this) = other.get_comparator_base(inline_set_detail::set_passkey{});
866 do_copy(other);
867 return *this;
868 }
869 /// @}
870
871 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
872 /// @brief The move assignment operator is deleted if move assignment is not supported
873 auto operator=(deleted_move_assign_source&&) -> inline_set& = delete;
874 // parasoft-end-suppress CERT_C-EXP37-a-3
875
876 // parasoft-begin-suppress AUTOSAR-A15_5_1-b-2 "False positive: Conditionally noxecept"
877 /// @brief move-assignment operator
878 ///
879 /// Participates in overload resolution if @c Value satisfies @c is_move_constructible, and @c Compare satisfies @c
880 /// std::is_move_assignable
881 ///
882 /// @param other The set to move-assign from.
883 /// @return inline_set& The set post-assignment.
884 /// @post @c size()==other.size()
885 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
886 /// move-assignment/construction.
887 /// @pre @c other.size()<=maximum_size() else @c ARENE_PRECONDITION violation.
888 auto operator=(move_assign_source&& other
890 -> inline_set& {
891 if (this != &other) {
892 static_cast<comparator_base&>(*this) = std::move(other);
893 do_move(std::move(other));
894 }
895 return *this;
896 }
897 // parasoft-end-suppress AUTOSAR-A15_5_1-b-2
898
899 /// @brief move-assignment operator from an @c inline_set with a larger capacity
900 ///
901 /// Participates in overload resolution if @c Value satisfies @c is_move_constructible, and @c Compare satisfies @c
902 /// std::is_move_assignable
903 ///
904 /// @tparam OtherCapacity The capacity of the source set
905 /// @param other The set to move-assign from.
906 /// @return inline_set& The set post-assignment.
907 /// @post @c size()==other.size()
908 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
909 /// move-assignment/construction.
910 /// @pre @c other.size()<=maximum_size() else @c ARENE_PRECONDITION violation.
911 template <
912 std::size_t OtherCapacity,
913 constraints<
914 std::enable_if_t<(OtherCapacity > Capacity)>,
915 std::enable_if_t<std::is_move_assignable<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
916 auto operator=(inline_set<Value, OtherCapacity, Compare>&& other) -> inline_set& {
917 ARENE_PRECONDITION(other.size() <= max_size());
918 static_cast<comparator_base&>(*this) = std::move(other.get_comparator_base(inline_set_detail::set_passkey{}));
919 do_move(std::move(other));
920 return *this;
921 }
922
923 /// @brief move-assignment operator from an @c inline_set with a smaller capacity
924 ///
925 /// Participates in overload resolution if @c Value satisfies @c is_move_constructible, and @c Compare satisfies @c
926 /// std::is_move_assignable
927 ///
928 /// @tparam OtherCapacity The capacity of the source set
929 /// @param other The set to move-assign from.
930 /// @return inline_set& The set post-assignment.
931 /// @post @c size()==other.size()
932 /// @post The elements in the set will be equivalent to the elements that were in @c other , produced as if via
933 /// move-assignment/construction.
934 template <
935 std::size_t OtherCapacity,
936 constraints<
937 std::enable_if_t<(OtherCapacity < Capacity)>,
938 std::enable_if_t<std::is_move_assignable<inline_set<Value, OtherCapacity, Compare>>::value>> = nullptr>
939 auto operator=(inline_set<Value, OtherCapacity, Compare>&& other
940 ) noexcept(std::is_nothrow_move_assignable<inline_set<Value, OtherCapacity, Compare>>::value) -> inline_set& {
941 static_cast<comparator_base&>(*this) = std::move(other.get_comparator_base(inline_set_detail::set_passkey{}));
942 do_move(std::move(other));
943 return *this;
944 }
945 /// @}
946
947 /// @brief Check if the set is empty
948 /// @return @c true if the set does not hold any elements, @c false otherwise
949 ARENE_NODISCARD auto empty() const noexcept -> bool { return number_of_active_elements_ == 0U; }
950
951 /// @brief Get the number of elements in the set
952 /// @return The number of elements in the set
953 auto size() const noexcept -> std::size_t { return number_of_active_elements_; }
954
955 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property,
956 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
957 /// @brief The maximum number of elements that can be held in the set.
958 ///
959 /// @return size_t Equivalent to @c Capacity .
960 static constexpr std::integral_constant<size_type, Capacity> capacity{};
961 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
962 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
963
964 // parasoft-begin-suppress AUTOSAR-M11_0_1-a-2 "False positive: this is not 'member data', it is a public property,
965 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
966 /// @brief Get the maximum number of elements in the set
967 ///
968 /// @return size_t Equivalent to @c Capacity .
970 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
971 // parasoft-end-suppress AUTOSAR-M11_0_1-a-2
972
973 /// @brief Get the comparator
974 /// @return A copy of the comparator
975 auto key_comp() const noexcept(std::is_nothrow_copy_constructible<Compare>::value) -> key_compare {
976 return comparator_base::get_comparator();
977 }
978
979 /// @brief Get the comparator
980 /// @return A copy of the comparator
981 auto value_comp() const noexcept(std::is_nothrow_copy_constructible<Compare>::value) -> value_compare {
982 return comparator_base::get_comparator();
983 }
984
985 /// @brief Obtain an iterator referring to the element equivalent to the supplied value, if there is one.
986 ///
987 /// @param value_to_find The value to find
988 /// @return iterator to the equivalent element, or @c end() if the element is not found
989 auto find(Value const& value_to_find) noexcept(comparison_is_noexcept<>) -> iterator {
990 return do_find(value_to_find);
991 }
992 /// @brief Obtain an iterator referring to the element equivalent to the supplied value, if there is one.
993 ///
994 /// @param value_to_find The value to find
995 /// @return const_iterator to the equivalent element, or @c end() if the element is not found
996 auto find(Value const& value_to_find) const noexcept(comparison_is_noexcept<>) -> const_iterator {
997 return do_find(value_to_find);
998 }
999 /// @brief Obtain an iterator referring to the element equivalent to the supplied value, if there is one.
1000 ///
1001 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1002 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1003 /// @param value The value to find
1004 /// @return iterator to the equivalent element, or @c end() if the element is not found
1005 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1006 auto find(OtherKey const& value) noexcept(comparison_is_noexcept<OtherKey>) -> iterator {
1007 return do_find(value);
1008 }
1009 /// @brief Obtain an iterator referring to the element equivalent to the supplied value, if there is one.
1010 ///
1011 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1012 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1013 /// @param value The value to find
1014 /// @return const_iterator to the equivalent element, or @c end() if the element is not found
1015 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1016 auto find(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> const_iterator {
1017 return do_find(value);
1018 }
1019
1020 /// @brief Check if the set contains a specific value
1021 ///
1022 /// @param value_to_check The value to search for
1023 /// @return true if @c find(value_to_check)!=end() .
1024 /// @return false if @c find(value_to_check)==end() .
1025 auto contains(Value const& value_to_check) const noexcept(comparison_is_noexcept<>) -> bool {
1026 return do_contains(value_to_check);
1027 }
1028 /// @brief Check if the set contains a value equivalent to a specific value.
1029 ///
1030 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1031 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1032 /// @param value The value to search for
1033 /// @return true if @c find(value)!=end() .
1034 /// @return false if @c find(value)==end() .
1035 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1036 auto contains(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> bool {
1037 return do_contains(value);
1038 }
1039
1040 /// @brief Return the number of elements in the set equivalent to a specific value.
1041 ///
1042 /// @param value_to_count The value to search for.
1043 /// @return std::size_t @c 0 if the element was not in the set, else @c 1 .
1044 auto count(Value const& value_to_count) const noexcept(comparison_is_noexcept<>) -> std::size_t {
1045 return do_count(value_to_count);
1046 }
1047 /// @brief Return the number of elements in the set equivalent to a specific value.
1048 ///
1049 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1050 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1051 /// @param value The value to search for.
1052 /// @return std::size_t @c 0 if the element was not in the set, else @c 1 .
1053 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1054 auto count(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> std::size_t {
1055 return do_count(value);
1056 }
1057
1058 /// @brief Find the first element which is _not less than_ a given value.
1059 ///
1060 /// @param value_to_find The value to find the lower bound for.
1061 /// @return iterator to the first element which is _not less than_ @c value_to_find, or @c end() if there is no
1062 /// such element.
1063 auto lower_bound(Value const& value_to_find) noexcept(comparison_is_noexcept<>) -> iterator {
1064 return do_lower_bound(value_to_find);
1065 }
1066 /// @brief Find the first element which is _not less than_ a given value.
1067 ///
1068 /// @param value_to_find The value to find the lower bound for.
1069 /// @return const_iterator to the first element which is _not less than_ @c value_to_find, or @c end() if there is no
1070 /// such element.
1071 auto lower_bound(Value const& value_to_find) const noexcept(comparison_is_noexcept<>) -> const_iterator {
1072 return do_lower_bound(value_to_find);
1073 }
1074 /// @brief Find the first element which is _not less than_ a given value.
1075 ///
1076 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1077 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1078 /// @param value The value to find the lower bound for.
1079 /// @return iterator to the first element which is _not less than_ @c value , or @c end() if there is no
1080 /// such element.
1081 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1082 auto lower_bound(OtherKey const& value) noexcept(comparison_is_noexcept<OtherKey>) -> iterator {
1083 return do_lower_bound(value);
1084 }
1085 /// @brief Find the first element which is _not less than_ a given value.
1086 ///
1087 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1088 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1089 /// @param value The value to find the lower bound for.
1090 /// @return const_iterator to the first element which is _not less than_ @c value , or @c end() if there is no
1091 /// such element.
1092 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1093 auto lower_bound(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> const_iterator {
1094 return do_lower_bound(value);
1095 }
1096
1097 /// @brief Find the first element which is _greater than_ a given value.
1098 ///
1099 /// @param value_to_find The value to search for.
1100 /// @return iterator to the first element which is _greater than_ @c value_to_find , or @c end() if there is no such
1101 /// element.
1102 auto upper_bound(Value const& value_to_find) noexcept(comparison_is_noexcept<>) -> iterator {
1103 return do_upper_bound(value_to_find);
1104 }
1105 /// @brief Find the first element which is _greater than_ a given value.
1106 ///
1107 /// @param value_to_find The value to search for.
1108 /// @return const_iterator to the first element which is _greater than_ @c value_to_find , or @c end() if there is no
1109 /// such
1110 /// element.
1111 auto upper_bound(Value const& value_to_find) const noexcept(comparison_is_noexcept<>) -> const_iterator {
1112 return do_upper_bound(value_to_find);
1113 }
1114 /// @brief Find the first element which is _greater than_ a given value.
1115 ///
1116 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1117 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1118 /// @param value The value to search for.
1119 /// @return iterator to the first element which is _greater than_ @c value , or @c end() if there is no such
1120 /// element.
1121 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1122 auto upper_bound(OtherKey const& value) noexcept(comparison_is_noexcept<OtherKey>) -> iterator {
1123 return do_upper_bound(value);
1124 }
1125 /// @brief Find the first element which is _greater than_ a given value.
1126 ///
1127 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1128 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1129 /// @param value The value to search for.
1130 /// @return const_iterator to the first element which is _greater than_ @c value , or @c end() if there is no such
1131 /// element.
1132 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1133 auto upper_bound(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> const_iterator {
1134 return do_upper_bound(value);
1135 }
1136
1137 /// @brief Finds the sequence of values which compare equivalent to a given value.
1138 ///
1139 /// @param value_to_find The value to search for
1140 /// @return std::pair<iterator, iterator> A pair of iterators such that all values in the range @c [first,second)
1141 /// compare equal to @c value_to_find if there was an element equivalent to @c value_to_find in the set.
1142 /// Otherwise both iterators will be @c end() .
1143 auto equal_range(Value const& value_to_find) noexcept(comparison_is_noexcept<>) -> std::pair<iterator, iterator> {
1144 return do_equal_range(value_to_find);
1145 }
1146 /// @brief Finds the sequence of values which compare equivalent to a given value.
1147 ///
1148 /// @param value_to_find The value to search for
1149 /// @return std::pair<const_iterator, const_iterator> A pair of iterators such that all values in the range
1150 /// @c [first,second) compare equal to @c value_to_find if there was an element equivalent to @c value_to_find
1151 /// in the set. Otherwise both iterators will be @c end() .
1152 auto equal_range(Value const& value_to_find) const noexcept(comparison_is_noexcept<>)
1153 -> std::pair<const_iterator, const_iterator> {
1154 return do_equal_range(value_to_find);
1155 }
1156 /// @brief Finds the sequence of values which compare equivalent to a given value.
1157 ///
1158 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1159 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1160 /// @param value The value to search for
1161 /// @return std::pair<iterator, iterator> A pair of iterators such that all values in the range @c [first,second)
1162 /// compare equal to @c value if there was an element equivalent to @c value in the set. Otherwise both
1163 /// iterators will be @c end() .
1164 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1165 auto equal_range(OtherKey const& value) noexcept(comparison_is_noexcept<OtherKey>) -> std::pair<iterator, iterator> {
1166 return do_equal_range(value);
1167 }
1168 /// @brief Finds the sequence of values which compare equivalent to a given value.
1169 ///
1170 /// @tparam OtherKey the type of the value to find. Must satisfy @c is_transparent_comparator_for<Compare,Value,K> or
1171 /// @c is_transparent_three_way_comparator_for<Compare,Value,K> .
1172 /// @param value The value to search for
1173 /// @return std::pair<const_iterator, const_iterator> A pair of iterators such that all values in the range
1174 /// @c [first,second) compare equal to @c value if there was an element equivalent to @c value in the set.
1175 /// Otherwise both iterators will be @c end() .
1176 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1177 auto equal_range(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>)
1178 -> std::pair<const_iterator, const_iterator> {
1179 return do_equal_range(value);
1180 }
1181
1182 // parasoft-begin-suppress AUTOSAR-A13_3_1-a-2 "Constrained via SFINAE, permitted by A13-3-1 Permit #1"
1183 /// @brief Attempt to insert an element into the set.
1184 ///
1185 /// @param value_to_insert The element to insert via copy-construction
1186 /// @return std::pair<iterator,bool> A pair where the first element is an iterator pointing to either the newly
1187 /// inserted element at its sort-order position in the set, or the existing element in the set if the set
1188 /// already contained @c value_to_insert , and the second element is a boolean which is @c true if the
1189 /// insertion happened, or @c false otherwise.
1190 /// @post If the insertion happened, @c size() increases by 1.
1191 /// @post If the insertion happened, there is an element equivalent to @c value_to_insert in the set at the position
1192 /// referenced
1193 /// by the returned iterator.
1194 /// @pre @c size()+1<=max_size() , else @c ARENE_PRECONDITION violation .
1195 auto insert(Value const& value_to_insert
1196 ) noexcept(comparison_is_noexcept<> && std::is_nothrow_copy_constructible<Value>::value)
1197 -> std::pair<iterator, bool> {
1198 return internal_insert(value_to_insert);
1199 }
1200 // parasoft-end-suppress AUTOSAR-A13_3_1-a-2
1201
1202 /// @brief Attempt to insert an element into the set.
1203 ///
1204 /// @param value_to_insert The element to insert via move-construction
1205 /// @return std::pair<iterator,bool> A pair where the first element is an iterator pointing to either the newly
1206 /// inserted element at its sort-order position in the set, or the existing element in the set if the set
1207 /// already contained @c value_to_insert , and the second element is a boolean which is @c true if the
1208 /// insertion happened, or @c false otherwise.
1209 /// @post If the insertion happened, @c size() increases by 1.
1210 /// @post If the insertion happened, there is an element equivalent to @c value_to_insert in the set at the position
1211 /// referenced
1212 /// by the returned iterator.
1213 /// @pre @c size()+1<=max_size() , else @c ARENE_PRECONDITION violation .
1214 auto insert(Value&& value_to_insert
1215 ) noexcept(comparison_is_noexcept<> && std::is_nothrow_move_constructible<Value>::value)
1216 -> std::pair<iterator, bool> {
1217 return internal_insert(std::move(value_to_insert));
1218 }
1219
1220 /// @brief Attempt to insert an element into the set.
1221 ///
1222 /// @tparam OtherKey The type of the element to attempt to insert. Must satisfy
1223 /// @c std::is_constructible<Value,OtherKey&&>
1224 /// @param value The element to insert via perfect forwarding.
1225 /// @return std::pair<iterator,bool> A pair where the first element is an iterator pointing to either the newly
1226 /// inserted element at its sort-order position in the set, or the existing element in the set if the set
1227 /// already contained @c value , and the second element is a boolean which is @c true if the insertion
1228 /// happened, or @c false otherwise.
1229 /// @post If the insertion happened, @c size() increases by 1.
1230 /// @post If the insertion happened, there is an element equivalent to @c value in the set at the position referenced
1231 /// by the returned iterator.
1232 /// @pre @c size()+1<=max_size() , else @c ARENE_PRECONDITION violation .
1233 template <
1234 typename OtherKey,
1235 typename SfinaeKey = Value,
1236 constraints<
1237 std::enable_if_t<transparent_comparison_supported_for<OtherKey>>,
1238 std::enable_if_t<!std::is_integral<SfinaeKey>::value>,
1239 std::enable_if_t<std::is_constructible<Value, OtherKey&&>::value>> = nullptr>
1240 auto insert(OtherKey&& value
1241 ) noexcept(comparison_is_noexcept<OtherKey> && std::is_nothrow_constructible<Value, OtherKey&&>::value)
1242 -> std::pair<iterator, bool> {
1243 return internal_insert(std::forward<OtherKey>(value));
1244 }
1245
1246 /// @brief Insert all the elements in the provided iterator range into the set, if there are not already equivalent
1247 /// elements.
1248 /// @tparam Iterator The type of the iterators
1249 /// @param first The iterator to the first element in the range
1250 /// @param last The iterator to the one-past-the-end element in the range
1251 /// @post @c size() increases by the number of elements in @c [first,last) which did not already exist in the set.
1252 /// @post @c find(*itr) will return an iterator other than @c end() for all elements in the range @c [first,last)
1253 /// @pre Let @c unique_elements equal the number of elements in the range @c [first,last) for which @c contains(*itr)
1254 /// would return @c false ; @c size()+unique_elements<=max_size() , else @c ARENE_PRECONDITION violation .
1255 template <
1256 typename Iterator,
1257 constraints<
1258 std::enable_if_t<base::is_input_iterator_v<Iterator>>,
1259 std::enable_if_t<std::is_constructible<Value, typename std::iterator_traits<Iterator>::reference>::value>> =
1260 nullptr>
1261 void insert(Iterator first, Iterator last) noexcept(std::is_nothrow_constructible<Value, decltype(*first)>::value) {
1262 for (decltype(auto) element : arene::base::make_subrange(first, last)) {
1263 std::ignore = insert(std::forward<decltype(element)>(element));
1264 }
1265 }
1266
1267 // parasoft-begin-suppress AUTOSAR-A13_3_1-a-2 "Constrained via SFINAE, permitted by A13-3-1 Permit #1"
1268 /// @brief Attempt to insert the elements in the provided initializer list into the set.
1269 ///
1270 /// @param init The list of elements to insert
1271 /// @post @c size() increases by the number of elements in @c init which did not already exist in the set.
1272 /// @post @c find(*itr) wil return an iterator other than @c end() for all elements in @c init
1273 /// @pre Let @c unique_elements equal the number of elements in @c init for which @c contains()
1274 /// would return @c false ; @c size()+unique_elements<=max_size() , else @c ARENE_PRECONDITION violation .
1275 void insert(std::initializer_list<Value> init) { insert(init.begin(), init.end()); }
1276 // parasoft-end-suppress AUTOSAR-A13_3_1-a-2
1277
1278 /// @brief Obtain an iterator referring to the beginning of the sorted range of elements.
1279 /// @return const_iterator Points to the first element in the sequence, or @c end() if @c empty() .
1280 auto begin() const noexcept -> const_iterator { return make_iterator(*this, 0U); }
1281 /// @brief Obtain an iterator referring to the beginning of the sorted range of elements.
1282 /// @return const_iterator Points to the first element in the sequence, or @c end() if @c empty() .
1283 auto cbegin() const noexcept -> const_iterator { return make_iterator(*this, 0U); }
1284
1285 /// @brief Obtain an iterator referring to one past the last element in the sorted range of elements.
1286 /// @return const_iterator Points to one past the last element in the sequence.
1287 auto end() const noexcept -> const_iterator { return make_iterator(*this, number_of_active_elements_); }
1288 /// @brief Obtain an iterator referring to one past the last element in the sorted range of elements.
1289 /// @return const_iterator Points to one past the last element in the sequence.
1290 auto cend() const noexcept -> const_iterator { return make_iterator(*this, number_of_active_elements_); }
1291
1292 /// @brief Obtain an iterator referring to the beginning of a reversed traversal of the sorted range of elements.
1293 /// @return const_reverse_iterator Points to the last element in the sequence, or @c rend() if @c empty() .
1294 auto rbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(end()); }
1295 /// @brief Obtain an iterator referring to the beginning of a reversed traversal of the sorted range of elements.
1296 /// @return const_reverse_iterator Points to the last element in the sequence, or @c rend() if @c empty() .
1297 auto crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(end()); }
1298
1299 /// @brief Obtain an iterator referring to one past the last element in a reversed traversal of the sorted range of
1300 /// elements.
1301 /// @return const_reverse_iterator An iterator pointing to one before the first element in the sequence.
1302 auto rend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(begin()); }
1303 /// @brief Obtain an iterator referring to one past the last element in a reversed traversal of the sorted range of
1304 /// elements.
1305 /// @return const_reverse_iterator An iterator pointing to one before the first element in the sequence.
1306 auto crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(begin()); }
1307
1308 // parasoft-begin-suppress AUTOSAR-A8_4_2-a "False positive: function does have a return"
1309 // parasoft-begin-suppress CERT_C-MSC37-a "False positive: function does have a return"
1310 // parasoft-begin-suppress CERT_C-EXP37-a "False positive: function does have a return"
1311 // parasoft-begin-suppress CERT_CPP-MSC52-a "False positive: function does have a return"
1312 // parasoft-begin-suppress AUTOSAR-A0_1_4-a "False positive: Parameter is used"
1313 /// @brief Construct a new element from the specified initialization arguments, and then attempt to insert it.
1314 ///
1315 /// @tparam ArgTypes The types of the initialization arguments
1316 /// @param args The initialization arguments of the new element
1317 /// @return std::pair<iterator, bool> Equivalent to calling @c insert(Value{ArgTypes...}) .
1318 template <
1319 typename... ArgTypes,
1320 constraints<std::enable_if_t<std::is_constructible<Value, ArgTypes&&...>::value>> = nullptr>
1321 auto emplace(ArgTypes&&... args) -> std::pair<iterator, bool> {
1322 if (number_of_active_elements_ == Capacity) {
1323 Value const value{std::forward<ArgTypes>(args)...};
1324 auto const pos_info = lower_bound_index(value);
1325 ARENE_PRECONDITION(pos_info.order == strong_ordering::equal);
1326 return {make_iterator(*this, pos_info.index), false};
1327 }
1328 auto const new_index = indices_[number_of_active_elements_];
1329 auto& potentially_inserted_element = values_[new_index];
1330 potentially_inserted_element.emplace(std::forward<ArgTypes>(args)...);
1331 optional_resetter<Value> destroy_if_not_inserted{potentially_inserted_element};
1332 auto const pos_info = lower_bound_index(*potentially_inserted_element);
1333 bool const do_insert{pos_info.order != strong_ordering::equal};
1334 if (do_insert) {
1335 insert_index_at(pos_info.index, new_index);
1336 destroy_if_not_inserted.dismiss();
1337 }
1338 return {make_iterator(*this, pos_info.index), do_insert};
1339 }
1340 // parasoft-end-suppress AUTOSAR-A0_1_4-a
1341 // parasoft-end-suppress CERT_CPP-MSC52-a
1342 // parasoft-end-suppress AUTOSAR-A8_4_2-a
1343 // parasoft-end-suppress CERT_C-MSC37-a
1344 // parasoft-end-suppress CERT_C-EXP37-a
1345
1346 /// @brief Erase any elements with a value equivalent to the supplied element.
1347 ///
1348 /// @param value_to_erase The value of elements to erase
1349 /// @return The number of elements erased, which will be @c 1 if the element was in the set, else @c 0 .
1350 auto erase(Value const& value_to_erase) noexcept(comparison_is_noexcept<>) -> size_type {
1351 return do_erase(value_to_erase);
1352 }
1353 /// @brief Erase any elements with a value equivalent to the supplied element.
1354 ///
1355 /// @tparam OtherKey The type of the element to erase.
1356 /// @param value The value of elements to erase
1357 /// @return The number of elements erased, which will be @c 1 if the element was in the set, else @c 0 .
1358 template <typename OtherKey, constraints<std::enable_if_t<transparent_comparison_supported_for<OtherKey>>> = nullptr>
1359 auto erase(OtherKey const& value) noexcept(comparison_is_noexcept<OtherKey>) -> size_type {
1360 return do_erase(value);
1361 }
1362
1363 /// @brief Erase the element referred to be the specified iterator.
1364 /// @param pos The iterator referring to the element to erase
1365 /// @return An iterator referring to the element after the erased element if there is one, or @c end() otherwise.
1366 /// @pre @c pos Must be a deferencable iterator into @c *this
1367 auto erase(iterator pos) noexcept -> iterator {
1368 ARENE_PRECONDITION(pos.is_for(this));
1369 auto const index = pos.index(inline_set_detail::set_passkey{});
1370 ARENE_PRECONDITION(index <= number_of_active_elements_);
1371 std::ignore = erase_at_index(index);
1372 return pos;
1373 }
1374
1375 /// @brief Erase all the elements referred to be the specified iterator range.
1376 /// @param first The iterator for the start of the range
1377 /// @param last The iterator for one-past-the-end of the range
1378 /// @return An iterator referring to the element after the erased elements if there is one, or @c end() otherwise.
1379 /// @pre @c (first,last] Must be a valid iterator range into @c *this
1380 auto erase(iterator first, iterator last) noexcept -> iterator {
1381 ARENE_PRECONDITION(first.is_for(this) && last.is_for(this));
1382 index_type const first_index{first.index(inline_set_detail::set_passkey{})};
1383 index_type const last_index{last.index(inline_set_detail::set_passkey{})};
1384 ARENE_PRECONDITION((first_index <= last_index) && (last_index <= size()));
1385 std::ignore = erase_index_range(first_index, static_cast<index_type>(last_index - first_index));
1386 return first;
1387 }
1388
1389 /// @brief Erase all the elements in @c *this
1390 /// @post @c size()==0 .
1391 /// @post The destructors of all elements in the range @c [begin(),end()) will have been called once.
1392 void clear() noexcept { std::ignore = erase_index_range(0U, number_of_active_elements_); }
1393
1394 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1395 /// @brief Fast inequality heuristic to shortcut on different sized containers.
1396 ///
1397 /// @tparam OtherCapacity the capacity of @c rhs
1398 /// @param lhs The left-hand operand to the check
1399 /// @param rhs The right-hand operand to the check
1400 /// @return inequality_heuristic::may_be_equal_or_not_equal if @c lhs.size()==rhs.size()
1401 /// @return inequality_heuristic::definitely_not_equal if @c lhs.size()!=rhs.size()
1402 template <size_type OtherCapacity>
1403 ARENE_NODISCARD static auto
1404 fast_inequality_check(inline_set const& lhs, inline_set<Value, OtherCapacity, Compare> const& rhs) noexcept
1405 -> inequality_heuristic {
1406 return lhs.size() == rhs.size() ? inequality_heuristic::may_be_equal_or_not_equal
1407 : inequality_heuristic::definitely_not_equal;
1408 }
1409 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1410
1411 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1412 /// @brief Compares two sets lexicographically .
1413 ///
1414 /// @note Lexicographic comparison between sets ignores the order of keys as defined by @c Compare . That is, it is
1415 /// a lexicographic comparison between the @c value_type elements of each container, in iteration order, using the
1416 /// standard @c compare_three_way facility. This means that for all possible sets which result in element sequences
1417 /// <c>{1, 2, 3}</c> and <c>{1, 2, 5}</c>, when compared against each other
1418 /// the result of the comparison will always be the same, @c strong_ordering::less.
1419 ///
1420 /// @tparam OtherCapacity the capacity of @c rhs
1421 /// @tparam SfinaeKey dummy template parameter to disable the operator if @c key_Type is not three way comparable.
1422 /// @param lhs The left hand operand to the comparison.
1423 /// @param rhs The right hand operand to the comparison.
1424 /// @return strong_ordering Equivalent to
1425 /// @c arene::base::lexicographical_compare_three_way(lhs.begin(),lhs.end(),rhs.begin(),rhs.end())
1426 template <
1427 size_type OtherCapacity,
1428 typename SfinaeKey = key_type,
1429 constraints<std::enable_if_t<compare_three_way_supported_v<SfinaeKey>>> = nullptr>
1430 ARENE_NODISCARD static auto
1431 three_way_compare(inline_set const& lhs, inline_set<Value, OtherCapacity, Compare> const& rhs) noexcept
1432 -> strong_ordering {
1433 return ::arene::base::lexicographical_compare_three_way(lhs.begin(), lhs.end(), rhs.begin(), rhs.end());
1434 }
1435 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1436
1437 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
1438 /// @brief Get the comparator base.
1439 /// @note This can only be called from @c inline_set internals due to the passkey
1440 /// @return A reference to the base
1441 auto get_comparator_base(inline_set_detail::set_passkey) noexcept -> comparator_base& { return *this; }
1442 // parasoft-end-suppress CERT_C-EXP37-a-3
1443
1444 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
1445 /// @brief Get the comparator base.
1446 /// @note This can only be called from @c inline_set internals due to the passkey
1447 /// @return A reference to the base
1448 auto get_comparator_base(inline_set_detail::set_passkey) const noexcept -> comparator_base const& { return *this; }
1449 // parasoft-end-suppress CERT_C-EXP37-a-3
1450
1451 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
1452 /// @brief Gets a reference to the element corrsponding to a given index.
1453 /// @param index Index of the element in iteration order.
1454 /// @return A reference to the element for the given index.
1455 /// @note This can only be called from @c inline_set internals due to the passkey
1456 /// @pre @c index<indicies.size()
1457 auto entry_at_index(inline_set_detail::set_passkey, index_type index) noexcept -> entry_type& {
1458 return values_[indices_[index]];
1459 }
1460 // parasoft-end-suppress CERT_C-EXP37-a-3
1461
1462 // parasoft-begin-suppress CERT_C-EXP37-a-3 "False positive: The rule does not mention naming all parameters"
1463 /// @brief Gets a reference to the element corrsponding to a given index.
1464 /// @param index Index of the element in iteration order.
1465 /// @return A reference to the element for the given index.
1466 /// @note This can only be called from @c inline_set internals due to the passkey
1467 /// @pre @c index<indicies.size()
1468 auto entry_at_index(inline_set_detail::set_passkey, index_type index) const noexcept -> entry_type const& {
1469 return values_[indices_[index]];
1470 }
1471 // parasoft-end-suppress CERT_C-EXP37-a-3
1472
1473 private:
1474 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1475 /// @brief The type of the storage for the whole set of elements
1476 using storage_type = array<entry_type, Capacity>;
1477 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1478 /// @brief The current size of set
1479 index_type number_of_active_elements_{0};
1480 // parasoft-begin-suppress AUTOSAR-M8_5_2-b-2 "False Positive: all elements default-initialized"
1481 /// @brief The storage of the elements
1482 storage_type values_{};
1483 // parasoft-end-suppress AUTOSAR-M8_5_2-b-2
1484
1485 /// @brief The indices for the elements. Initially @c indices_[i] is @c i, so each element sets to the corresponding
1486 /// element in @c values_.
1487 array<index_type, Capacity> indices_{sequential_values<index_type, Capacity>};
1488
1489 /// @brief Implementation helper for @c try_construct
1490 ///
1491 /// @param first The first iterator in the sequence of elements to attempt to insert.
1492 /// @param last The last iterator in the sequence of elements to attempt to insert.
1493 /// @return true If all elements were successfully inserted without exceeding capacity.
1494 /// @return false If an element needed to be inserted, but there was not enough room.
1495 /// @post Equivalent to having called @c insert on each element in the range @c [first,last) until either all elements
1496 /// were successfully inserted or @c Capacity was reached an an element needed to be inserted still.
1497 template <
1498 typename Iterator,
1499 constraints<
1500 std::enable_if_t<base::is_input_iterator_v<Iterator>>,
1501 std::enable_if_t<std::is_constructible<Value, typename std::iterator_traits<Iterator>::reference>::value>> =
1502 nullptr>
1503 auto insert_elements_if_they_fit(Iterator first, Iterator last) noexcept(
1504 comparison_is_noexcept<> && std::is_nothrow_copy_constructible<Value>::value
1505 ) -> bool {
1506 while (first != last) {
1507 if (size() < Capacity) {
1508 std::ignore = insert(*first);
1509 } else if (!contains(*first)) {
1510 return false;
1511 } else {
1512 // do nothing, element already present
1513 }
1514 arene::base::advance(first, 1);
1515 }
1516 return true;
1517 }
1518
1519 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "False positive: this is not a move constructor"
1520 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "The universal reference is used to detect the value category"
1521 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "False positive: Self is a template parameter"
1522 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1523 /// @brief Deduced-this helper for universally constructing iterators.
1524 ///
1525 /// @tparam SelfType Deduced-this type of the set.
1526 /// @param self The instance of the set to operate on.
1527 /// @param index The index to create the iterator from
1528 /// @return auto An iterator constructed as if via @c self and @c index .
1529 template <typename SelfType, constraints<std::enable_if_t<decays_to_v<SelfType, inline_set>>> = nullptr>
1530 static auto make_iterator(SelfType&& self, index_type index) noexcept -> iterator {
1531 return iterator_impl{inline_set_detail::set_passkey{}, &self, index};
1532 }
1533 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1534 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
1535 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
1536 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
1537
1538 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1539 /// @brief Deduced-this helper that detemplitizes find iterator generation from key type.
1540 ///
1541 /// @tparam SelfType Deduced-this type of the set.
1542 /// @param self The instance of the set to operate on.
1543 /// @param lb_info An instance of the return from @c lower_bound_index()
1544 /// @return auto If @c lb_info.order==strong_ordering::equal , then an iterator constructed as if via @c
1545 /// make_iterator(self,lb_info.index) , otherwise @c self.end() .
1546 template <typename SelfType, constraints<std::enable_if_t<decays_to_v<SelfType, inline_set>>> = nullptr>
1547 static auto
1548 make_find_iterator(SelfType&& self, inline_container::detail::lower_bound_index_info<index_type> lb_info) noexcept
1549 -> iterator {
1550 if (lb_info.order == strong_ordering::equal) {
1551 return make_iterator(std::forward<SelfType>(self), lb_info.index);
1552 }
1553 return self.end();
1554 }
1555 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1556
1557 /// @brief Helper implementation for @c find() which works for all comparators and iterator types.
1558 ///
1559 /// @tparam OtherKey the type of the key to search for.
1560 /// @param value The key to search for.
1561 /// @return iterator The iterator at the position of @c value if it is found, else @c end() .
1562 template <typename OtherKey>
1563 auto do_find(OtherKey const& value) const -> iterator {
1564 return make_find_iterator(*this, lower_bound_index(value));
1565 }
1566
1567 /// @brief Helper implementation for @c contains which works for all comparators.
1568 ///
1569 /// @tparam OtherKey the type of the value to find
1570 /// @param value The value to search for
1571 /// @return true if @c find(value)!=end() .
1572 /// @return false if @c find(value)==end() .
1573 template <typename OtherKey>
1574 auto do_contains(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> bool {
1575 return do_find(value) != end();
1576 }
1577
1578 /// @brief Helper implementation for @c count which works for all comparators.
1579 ///
1580 /// @tparam OtherKey the type of the value to find.
1581 /// @param value The value to search for.
1582 /// @return std::size_t @c 0 if the element was not in the set, else @c 1 .
1583 template <typename OtherKey>
1584 auto do_count(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> std::size_t {
1585 return static_cast<std::size_t>(do_contains(value));
1586 }
1587
1588 /// @brief Helper implementation for @c lower_bound which works for all comparators and iterator types.
1589 ///
1590 /// @tparam OtherKey the type of the value to find.
1591 /// @param value The value to find the lower bound for.
1592 /// @return iterator An iterator to the first element which is _not less than_ @c value.
1593 template <typename OtherKey>
1594 auto do_lower_bound(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> iterator {
1595 return make_iterator(*this, lower_bound_index(value).index);
1596 }
1597
1598 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1599 /// @brief Deduced-this helper that detemplitizes upper_bound iterator generation from key type.
1600 ///
1601 /// @tparam SelfType Deduced-this type of the set.
1602 /// @param self The instance of the set to operate on.
1603 /// @param lb_info An instance of the return from @c lower_bound_index()
1604 /// @return auto If @c lb_info.order==strong_ordering::equal , then an iterator constructed as if via @c
1605 /// make_iterator(self,lb_info.index + 1) , otherwise @c make_iterator(self,lb_info.index) .
1606 template <typename SelfType, constraints<std::enable_if_t<decays_to_v<SelfType, inline_set>>> = nullptr>
1607 static auto make_upper_bound_iterator(
1608 SelfType&& self,
1609 inline_container::detail::lower_bound_index_info<index_type> lb_info
1610 ) noexcept -> iterator {
1611 if (lb_info.order == strong_ordering::equal) {
1612 ++lb_info.index;
1613 }
1614 return make_iterator(std::forward<SelfType>(self), lb_info.index);
1615 }
1616 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1617
1618 /// @brief Helper implementation for @c upper_bound which works for all comparators and iterator types.
1619 ///
1620 /// @tparam OtherKey the type of the value to find
1621 /// @param value The value to search for.
1622 /// @return An iterator to the first element which is _greater than_ @c value , or @c end() if there is no such
1623 /// element.
1624 template <typename OtherKey>
1625 auto do_upper_bound(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>) -> iterator {
1626 return make_upper_bound_iterator(*this, lower_bound_index(value));
1627 }
1628
1629 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1630 // parasoft-begin-suppress AUTOSAR-M0_1_3-a "False Positive: All local variables are used"
1631 // parasoft-begin-suppress AUTOSAR-A8_4_2-a "False positive: function does have a return"
1632 // parasoft-begin-suppress CERT_C-MSC37-a "False positive: function does have a return"
1633 // parasoft-begin-suppress CERT_C-EXP37-a "False positive: function does have a return"
1634 // parasoft-begin-suppress CERT_CPP-MSC52-a "False positive: function does have a return"
1635 /// @brief Deduced-this helper that detemplitizes equal_range iterator generation from key type.
1636 ///
1637 /// @tparam SelfType Deduced-this type of the set.
1638 /// @param self The instance of the set to operate on.
1639 /// @param lb_info An instance of the return from @c lower_bound_index()
1640 /// @return auto A pair of iterators where the first element is @c make_find_iterator(self,lb_info) , and the second
1641 /// element is either that iterator incremented by one if the iterator was not @c self.end() , otherwise @c self.end()
1642 template <typename SelfType, constraints<std::enable_if_t<decays_to_v<SelfType, inline_set>>> = nullptr>
1643 static auto
1644 make_equal_range_iterator(SelfType&& self, inline_container::detail::lower_bound_index_info<index_type> lb_info)
1645 -> std::pair<iterator, iterator> {
1646 auto first = make_find_iterator(std::forward<SelfType>(self), lb_info);
1647 auto last = first == self.end() ? first : ::arene::base::next(first);
1648 return std::make_pair(first, last);
1649 }
1650 // parasoft-end-suppress CERT_CPP-MSC52-a
1651 // parasoft-end-suppress AUTOSAR-A8_4_2-a
1652 // parasoft-end-suppress CERT_C-MSC37-a
1653 // parasoft-end-suppress CERT_C-EXP37-a
1654 // parasoft-end-suppress AUTOSAR-M0_1_3-a
1655 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1656
1657 /// @brief Helper implementation for @c equal_range which works for all comparators and iterator types.
1658 ///
1659 /// @tparam OtherKey the type of the value to find
1660 /// @param value The value to search for
1661 /// @return std::pair<iterator, iterator> A pair of iterators such that all values in the range @c [first,second)
1662 /// compare equal to @c value if there was an element equivalent to @c value in the set. Otherwise both
1663 /// iterators will be @c end() .
1664 template <typename OtherKey>
1665 auto do_equal_range(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>)
1666 -> std::pair<iterator, iterator> {
1667 return make_equal_range_iterator(*this, lower_bound_index(value));
1668 }
1669
1670 /// @brief Obtain the index of the first element such that @c element < @c value
1671 /// @param value The value to search for
1672 /// @return inline_container::detail::lower_bound_index_info<index_type> The index of the element, and the
1673 /// strong_ordering between that
1674 /// element and @c value . If @c value is greater than all elements, then the index is @c size() and the
1675 /// ordering is @c strong_ordering::greater .
1676 /// @throws Any exception thrown by the comparisons
1677 template <typename OtherKey>
1678 auto lower_bound_index(OtherKey const& value) const noexcept(comparison_is_noexcept<OtherKey>)
1679 -> inline_container::detail::lower_bound_index_info<index_type> {
1680 auto const compare = [this](key_type const& lhs, OtherKey const& rhs) noexcept(comparison_is_noexcept<OtherKey>) {
1681 return this->key_ordering(lhs, rhs);
1682 };
1683 auto const accessor = [this](index_type const index) noexcept -> key_type const& {
1684 return *(this->entry_at_index(inline_set_detail::set_passkey{}, index));
1685 };
1686 return inline_container::detail::lower_bound_index<key_type, OtherKey, index_type>(
1687 value,
1688 number_of_active_elements_,
1689 compare,
1690 accessor
1691 );
1692 }
1693
1694 /// @brief Helper implementation for @c erase which works for all comparators
1695 ///
1696 /// @tparam OtherKey The type of the element to erase.
1697 /// @param value The value of elements to erase
1698 /// @return The number of elements erased, which will be @c 1 if the element was in the set, else @c 0 .
1699 template <typename OtherKey>
1700 auto do_erase(OtherKey const& value) noexcept(comparison_is_noexcept<OtherKey>) -> size_type {
1701 return static_cast<size_type>(erase_at_index(do_find(value).index(inline_set_detail::set_passkey{})) != end());
1702 }
1703
1704 /// @brief Insert a new element at the specified index, constructed from the supplied value. This uses perfect
1705 /// forwarding so the same function handles copies and moves.
1706 /// @tparam V The type of the source value
1707 /// @param pos The position at which to insert the element
1708 /// @param value The new value
1709 /// @throws std::length_error if there is insufficient space to insert a new element
1710 template <typename V>
1711 void insert_at(index_type pos, V&& value) noexcept(std::is_nothrow_constructible<Value, V&&>::value) {
1712 auto const new_index = indices_[number_of_active_elements_];
1713 values_[new_index].emplace(std::forward<V>(value));
1714 insert_index_at(pos, new_index);
1715 }
1716
1717 // parasoft-begin-suppress AUTOSAR-A8_4_2-a "False positive: function does have a return"
1718 // parasoft-begin-suppress CERT_C-MSC37-a "False positive: function does have a return"
1719 // parasoft-begin-suppress CERT_C-EXP37-a "False positive: function does have a return"
1720 /// @brief Insert a new entry into the index at the specified position.
1721 /// @param pos The position at which to insert the new value
1722 /// @param new_index The index into the data array of the element being inserted
1723 void insert_index_at(index_type pos, index_type new_index) noexcept {
1724 for (index_type i{number_of_active_elements_}; i != pos; --i) {
1725 indices_[i] = indices_[static_cast<index_type>(i - 1U)];
1726 }
1727 indices_[pos] = new_index;
1728 ++number_of_active_elements_;
1729 }
1730 // parasoft-end-suppress AUTOSAR-A8_4_2-a
1731 // parasoft-end-suppress CERT_C-MSC37-a
1732 // parasoft-end-suppress CERT_C-EXP37-a
1733
1734 // parasoft-begin-suppress CERT_C-MSC37-a "False positive: function does have a return"
1735 // parasoft-begin-suppress CERT_CPP-MSC52-a "False positive: function does have a return"
1736 // parasoft-begin-suppress AUTOSAR-A8_4_2-a "False positive: function does have a return"
1737 /// @brief Insert a new element constructed from the specified value if there is not already an equivalent element in
1738 /// the map. Uses perfect forwarding to handle copying/moving as appropriate
1739 /// @tparam V The type of the source value
1740 /// @param value The new value
1741 /// @return A pair holding an iterator to the inserted element, or the existing element with equivalent value, and a
1742 /// boolean which is @c true if the value was inserted, and @c false otherwise.
1743 /// @pre If insertion is required, @c size<Capacity else @c ARENE_PRECONDITION violation.
1744 template <typename V>
1745 auto internal_insert(V&& value
1746 ) noexcept(comparison_is_noexcept<V> && std::is_nothrow_constructible<Value, V&&>::value)
1747 -> std::pair<iterator, bool> {
1748 auto const pos_info = lower_bound_index(value);
1749 auto const do_insert = pos_info.order != strong_ordering::equal;
1750 if (do_insert) {
1751 insert_at(pos_info.index, std::forward<V>(value));
1752 }
1753 return {make_iterator(*this, pos_info.index), do_insert};
1754 }
1755 // parasoft-end-suppress AUTOSAR-A8_4_2-a
1756 // parasoft-end-suppress CERT_CPP-MSC52-a
1757 // parasoft-end-suppress CERT_C-MSC37-a
1758
1759 /// @brief Erase the element at the specified index.
1760 /// @param index The index of the element to erase
1761 /// @return An iterator to the element after the erased element, or @c end() if @c index>=number_of_active_elements_.
1762 auto erase_at_index(index_type index) noexcept -> iterator {
1763 return index < number_of_active_elements_ ? erase_index_range(index, 1U) : end();
1764 }
1765
1766 /// @brief Erase the specified number of elements starting at the specified position.
1767 /// @param from The position in the index of the first element to erase
1768 /// @param count_to_erase The number of elements to erase
1769 /// @return An iterator to the element after the specified elements, or @c end() if there is no such element.
1770 // NOLINTNEXTLINE(bugprone-easily-swappable-parameters)
1771 auto erase_index_range(index_type from, index_type count_to_erase) noexcept -> iterator {
1772 index_type last_index{static_cast<index_type>(from + count_to_erase)};
1773 for (index_type index{from}; index < last_index; ++index) {
1774 entry_at_index(inline_set_detail::set_passkey{}, index).reset();
1775 }
1776 std::ignore = arene::base::rotate(
1777 indices_.begin() + from,
1778 indices_.begin() + last_index,
1779 indices_.begin() + number_of_active_elements_
1780 );
1781 number_of_active_elements_ = static_cast<index_type>(number_of_active_elements_ - (last_index - from));
1782
1783 return make_iterator(*this, from);
1784 }
1785
1786 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1787 /// @brief Move-construct a new element from the specified element, and clear the old element.
1788 /// @param other The element to move from
1789 /// @return The new element
1790 /// @throws Any exception thrown by the copy-constructor of @c Key or the
1791 /// move-constructor of @c Value
1792 static auto move_value(entry_type& other) noexcept(std::is_nothrow_move_constructible<value_type>::value)
1793 -> entry_type {
1794 entry_type res{std::move(other)};
1795 other.reset();
1796 return res;
1797 }
1798 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1799
1800 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1801 /// @brief Move the values from the source set into a new array. Clears the source set.
1802 /// @tparam Indices The indices into the source set
1803 /// @param source The source set
1804 /// @return The new data array
1805 template <std::size_t... Indices>
1806 static auto move_values(inline_set& source, std::index_sequence<Indices...>) -> storage_type {
1807 // parasoft-begin-suppress AUTOSAR-M0_1_3-a-2 "False positive: RAII class"
1808 auto const clear_on_exit = clear_on_scope_exit(source);
1809 // parasoft-end-suppress AUTOSAR-M0_1_3-a-2
1810 return {{move_value(source.values_[Indices])...}};
1811 }
1812 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1813
1814 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1815 /// @brief Move the values from a source set with a different capacity into a new array. Clears the source set.
1816 /// @tparam OtherCapacity The capacity of the other set
1817 /// @tparam Indices The indices into the source set
1818 /// @param source The source set
1819 /// @return The new data array
1820 /// @pre The size of the source set must be less than @c Capacity
1821 template <std::size_t OtherCapacity, std::size_t... Indices>
1822 static auto move_values(inline_set<Value, OtherCapacity, Compare>& source, std::index_sequence<Indices...>)
1823 -> storage_type {
1824 auto const clear_on_exit = clear_on_scope_exit(source);
1825 return {{move_value(source.entry_at_index(inline_set_detail::set_passkey{}, Indices))...}};
1826 }
1827 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1828
1829 // parasoft-begin-suppress AUTOSAR-A2_10_1-e-2 "False Positive: This identifier does not hide anything"
1830 /// @brief Helper to create a scope-guard which clears the input source on scope exit.
1831 ///
1832 /// @param source The container to clear on scope exit.
1833 /// @return A @c scope_guard which will call @c clear() on @c source .
1834 template <std::size_t OtherCapacity>
1835 static auto clear_on_scope_exit(inline_set<Value, OtherCapacity, Compare>& source) noexcept -> decltype(auto) {
1836 return on_scope_exit( //
1837 [&source]() noexcept { source.clear(); }
1838 );
1839 }
1840 // parasoft-end-suppress AUTOSAR-A2_10_1-e-2
1841
1842 // parasoft-begin-suppress AUTOSAR-M9_3_3-a-2 "False positive: Uses this"
1843 /// @brief Helper to create a scope-guard which resets all values between the current number_of_active_elements_ and
1844 /// an index.
1845 ///
1846 /// @param end_index One past the last index to reset to.
1847 /// @return A @c scope_guard which will call @c reset() on every element fetched via @c entry_at_index() in the range
1848 /// @c [number_of_active_elements_,end_index) .
1849 auto reset_trailing_values_on_scope_exit(index_type end_index) noexcept -> decltype(auto) {
1850 return on_scope_exit([this, end_index]() noexcept {
1851 for (index_type idx = this->number_of_active_elements_; idx < end_index; ++idx) {
1852 this->entry_at_index(inline_set_detail::set_passkey{}, idx).reset();
1853 }
1854 });
1855 }
1856 // parasoft-end-suppress AUTOSAR-M9_3_3-a-2
1857
1858 /// @brief Copy the elements from the other set over those in the current set.
1859 ///
1860 /// @tparam OtherSet The type of the set to copy from
1861 /// @param other The source set
1862 /// @throws Any exception thrown by the copy of the elements or comparator
1863 /// @post @c size()==other.size() , or the index of the first element which throws during copy construction if a throw
1864 /// occurs.
1865 /// @post @c The elements from @c other will have been copy-emplaced into @c this , up to the first element which
1866 /// threw during move-construction, if any.
1867 /// @post @c The elements in the range @c [size(),other.size()) will have been reset if @c other.size() was smaller
1868 /// than the original size of @c this .
1869 template <typename OtherSet>
1870 void do_copy(OtherSet const& other
1871 ) noexcept(std::is_nothrow_copy_constructible<OtherSet>::value && std::is_nothrow_copy_assignable<OtherSet>::value) {
1872 do_assignment(other);
1873 }
1874
1875 /// @brief Move the elements from the other set over those in the current set.
1876 ///
1877 /// @tparam OtherSet The type of the set to move from
1878 /// @param other The source set
1879 /// @throws Any exception thrown by the move of the elements or comparator
1880 /// @post @c size()==other.size() , or the index of the first element which throws during move construction if a throw
1881 /// occurs.
1882 /// @post @c other.clear() will have been executed
1883 /// @post @c The elements from @c other will have been move-emplaced into @c this , up to the first element which
1884 /// threw during move-construction, if any.
1885 /// @post @c The elements in the range @c [size(),other.size()) will have been reset if @c other.size() was smaller
1886 /// than the original size of @c this .
1887 template <typename OtherSet>
1888 void do_move(OtherSet&& other
1889 ) noexcept(std::is_nothrow_move_constructible<OtherSet>::value && std::is_nothrow_move_assignable<OtherSet>::value) {
1890 // parasoft-begin-suppress AUTOSAR-M0_1_3-a-2 "False positive: RAII class"
1891 auto const clear_on_exit = clear_on_scope_exit(other);
1892 // parasoft-end-suppress AUTOSAR-M0_1_3-a-2
1893 do_assignment(std::forward<OtherSet>(other));
1894 }
1895
1896 // parasoft-begin-suppress AUTOSAR-A8_4_6-a-2 "False positive: Elements are forwarded via 'forward_like'"
1897 // parasoft-begin-suppress AUTOSAR-A8_4_5-a-2 "False positive: Elements are forwarded via 'forward_like'"
1898 // parasoft-begin-suppress AUTOSAR-A12_8_4-a-2 "False positive: Elements are forwarded via 'forward_like'"
1899 /// @brief Helper for @c do_copy and @c do_move with non-copy/move dependent logic.
1900 ///
1901 /// @tparam OtherSet The type of the set to copy/move from
1902 /// @param other The source set top copy/move from.
1903 /// @throws Any exception thrown by the copy/move of the elements or comparator
1904 /// @post @c size()==other.size() , or the index of the first element which throws during move construction if a throw
1905 /// occurs.
1906 /// @post @c The elements from @c other will have been move-emplaced into @c this , up to the first element which
1907 /// threw during copy/move-construction, if any.
1908 /// @post @c The elements in the range @c [size(),other.size()) will have been reset if @c other.size() was smaller
1909 /// than the original size of @c this .
1910 template <typename OtherSet>
1911 void do_assignment(OtherSet&& other) noexcept(
1912 std::is_nothrow_constructible<OtherSet, OtherSet&&>::value &&
1913 std::is_nothrow_assignable<OtherSet&, OtherSet&&>::value
1914 ) {
1915 // parasoft-begin-suppress AUTOSAR-M0_1_3-a-2 "False positive: RAII class"
1916 auto const reset_trailing_values = reset_trailing_values_on_scope_exit(number_of_active_elements_);
1917 // parasoft-end-suppress AUTOSAR-M0_1_3-a-2
1918 number_of_active_elements_ = 0U;
1919 while (number_of_active_elements_ != other.size()) {
1920 this->entry_at_index(inline_set_detail::set_passkey{}, number_of_active_elements_)
1921 .emplace(forward_like<OtherSet>(
1922 *other.entry_at_index(inline_set_detail::set_passkey{}, number_of_active_elements_)
1923 ));
1924 ++number_of_active_elements_;
1925 }
1926 }
1927 // parasoft-end-suppress AUTOSAR-A8_4_6-a-2
1928 // parasoft-end-suppress AUTOSAR-A8_4_5-a-2
1929 // parasoft-end-suppress AUTOSAR-A12_8_4-a-2
1930}; // namespace base
1931// parasoft-end-suppress AUTOSAR-A1_1_1-c-2
1932// parasoft-end-suppress AUTOSAR-A12_0_1-a-2
1933// parasoft-end-suppress AUTOSAR-A10_1_1-a-2
1934// parasoft-end-suppress AUTOSAR-A12_1_5-a-2
1935
1936/// @brief Externalized initialization of max_size is needed pre C++17.
1937template <typename T, std::size_t Capacity, typename Compare>
1938constexpr std::integral_constant<std::size_t, Capacity> inline_set<T, Capacity, Compare>::max_size;
1939
1940/// @brief Externalized initialization of capacity is needed pre C++17.
1941template <typename T, std::size_t Capacity, typename Compare>
1942constexpr std::integral_constant<std::size_t, Capacity> inline_set<T, Capacity, Compare>::capacity;
1943
1944} // namespace base
1945} // namespace arene
1946
1947#endif // INCLUDE_GUARD_ARENE_BASE_ARENE_BASE_INLINE_CONTAINER_SET_HPP_
static ARENE_NODISCARD auto try_construct(std::initializer_list< Value > init) noexcept(noexcept(inline_set{init}) &&std::is_nothrow_move_constructible< inline_set >::value) -> optional< inline_set >
Attempt to construct a set from the specified list of values.
Definition set.hpp:469
inline_set()=default
Construct a set with no elements and a default-constructed comparator.
static constexpr std::integral_constant< size_type, Capacity > max_size
Get the maximum number of elements in the set.
Definition set.hpp:969
auto find(Value const &value_to_find) noexcept(comparison_is_noexcept<>) -> iterator
Obtain an iterator referring to the element equivalent to the supplied value, if there is one.
Definition set.hpp:989
auto key_comp() const noexcept(std::is_nothrow_copy_constructible< Compare >::value) -> key_compare
Get the comparator.
Definition set.hpp:975
static ARENE_NODISCARD auto try_construct(std::initializer_list< Value > init, Compare const &comp) noexcept(noexcept(inline_set{init, comp}) &&std::is_nothrow_move_constructible< inline_set >::value) -> optional< inline_set >
Attempt to construct a set from the specified list of values and a comparator.
Definition set.hpp:487
~inline_set()=default
Default destructor; destroys all stored elements.
auto find(Value const &value_to_find) const noexcept(comparison_is_noexcept<>) -> const_iterator
Obtain an iterator referring to the element equivalent to the supplied value, if there is one.
Definition set.hpp:996
auto value_comp() const noexcept(std::is_nothrow_copy_constructible< Compare >::value) -> value_compare
Get the comparator.
Definition set.hpp:981
inline_set(std::initializer_list< Value > init, Compare const &comp) noexcept(std::is_nothrow_copy_constructible< Value >::value &&std::is_nothrow_copy_constructible< Compare >::value)
Construct a set from the specified list of values and a specified comparator instance .
Definition set.hpp:455
inline_set(Compare const &comp) noexcept(std::is_nothrow_copy_constructible< Compare >::value)
Construct a set with no elements, using the specified comparator.
Definition set.hpp:428
auto operator=(copy_assign_source const &other) noexcept(std::is_nothrow_copy_constructible< Value >::value &&std::is_nothrow_copy_assignable< Compare >::value) -> inline_set &
copy-assignment operator.
Definition set.hpp:813
auto operator=(move_assign_source &&other) noexcept(std::is_nothrow_move_constructible< Value >::value &&std::is_nothrow_move_assignable< Compare >::value) -> inline_set &
move-assignment operator
Definition set.hpp:888
inline_set(std::initializer_list< Value > init) noexcept(std::is_nothrow_copy_constructible< Value >::value &&std::is_nothrow_constructible< Compare >::value)
Construct a set from the specified list of values.
Definition set.hpp:440
Definition array_exceptions_disabled.cpp:11
constexpr std::integral_constant< std::size_t, Capacity > inline_set< T, Capacity, Compare >::capacity
Externalized initialization of capacity is needed pre C++17.
Definition set.hpp:1942
Copyright 2026, Toyota Motor Corporation.
Definition array_exceptions_disabled.cpp:10