libhatchet
Loading...
Searching...
No Matches
hxset_algorithms.hpp
Go to the documentation of this file.
1#pragma once
2// SPDX-FileCopyrightText: © 2017-2026 Adrian Johnston.
3// SPDX-License-Identifier: MIT
4// This file is licensed under the MIT license found in the LICENSE.md file.
5
14
15#include "hxrange.hpp"
16
17// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
18#if HX_USE_MACROS_WITH_MODULE
19#error Header does not provide macros alone.
20#endif
21
22HX_NS_BEGIN_
23
33template<hxrandom_range_concept_ range0_t_, hxrandom_range_concept_ range1_t_,
34 typename output_iterator_t_, typename less_t_>
36output_iterator_t_ hxmerge(range0_t_&& range0_, range1_t_&& range1_,
37 output_iterator_t_&& output_, const less_t_& less_) noexcept {
38 hxrestrict_t<decltype(range0_.begin())> src0_(range0_.begin());
39 const auto end0_ = range0_.end();
40 hxrestrict_t<decltype(range1_.begin())> src1_(range1_.begin());
41 const auto end1_ = range1_.end();
43 while(src0_ != end0_ && src1_ != end1_) {
44 const bool take1_ = less_(*src1_, *src0_);
45 if(take1_) { *output_r_ = hxforward_like<range1_t_>(*src1_); }
46 else { *output_r_ = hxforward_like<range0_t_>(*src0_); }
47 ++output_r_;
48 src1_ = src1_ + static_cast<ptrdiff_t>(take1_);
49 src0_ = src0_ + static_cast<ptrdiff_t>(!take1_);
50 }
51 while(src0_ != end0_) {
52 *output_r_ = hxforward_like<range0_t_>(*src0_);
53 ++output_r_; ++src0_;
54 }
55 while(src1_ != end1_) {
56 *output_r_ = hxforward_like<range1_t_>(*src1_);
57 ++output_r_; ++src1_;
58 }
59 return output_r_;
60}
61
65template<hxsorted_range_concept_ range0_t_, hxsorted_range_concept_ range1_t_,
66 typename output_iterator_t_>
68output_iterator_t_ hxmerge(range0_t_&& range0_, range1_t_&& range1_,
69 output_iterator_t_&& output_) noexcept {
70 const auto begin0_ = range0_.begin();
73 hxkey_less_t<decltype(*begin0_)>{});
74}
75
78template<typename iterator_t_>
80public:
81 iterator_t_ min;
82 iterator_t_ max;
83};
84
91template<hxrange_concept_ range_t_, typename less_t_>
93auto hxminmax(range_t_&& range_, const less_t_& less_) -> hxminmax_result<decltype(range_.begin())> {
94 hxrestrict_t<decltype(range_.begin())> it_(range_.begin());
95 const auto end_ = range_.end();
96 hxminmax_result<decltype(range_.begin())> result_{it_, it_};
97 if(it_ == end_) { return result_; }
98 for(++it_; it_ != end_; ++it_) {
99 if(less_(*it_, *result_.min)) {
100 result_.min = it_;
101 }
102 else if(less_(*result_.max, *it_)) {
103 result_.max = it_;
104 }
105 }
106 return result_;
107}
108
111template<hxrange_concept_ range_t_>
113auto hxminmax(range_t_&& range_) -> hxminmax_result<decltype(range_.begin())> {
114 const auto begin_ = range_.begin();
115 return hxminmax<range_t_>(hxforward<range_t_>(range_), hxkey_less_t<decltype(*begin_)>{});
116}
117
128template<hxrandom_range_concept_ range0_t_, hxrandom_range_concept_ range1_t_,
129 typename output_iterator_t_, typename less_t_>
131output_iterator_t_ hxset_difference(range0_t_&& range0_, range1_t_&& range1_,
132 output_iterator_t_&& output_, const less_t_& less_) noexcept {
133 hxrestrict_t<decltype(range0_.begin())> src0_(range0_.begin());
134 const auto end0_ = range0_.end();
135 hxrestrict_t<decltype(range1_.begin())> src1_(range1_.begin());
136 const auto end1_ = range1_.end();
138 while(src0_ != end0_ && src1_ != end1_) {
139 const bool lt_ = less_(*src0_, *src1_);
140 const bool gt_ = less_(*src1_, *src0_);
141 if(lt_) {
142 *output_r_ = hxforward_like<range0_t_>(*src0_);
143 ++output_r_;
144 }
145 src0_ = src0_ + static_cast<ptrdiff_t>(!gt_);
146 src1_ = src1_ + static_cast<ptrdiff_t>(!lt_);
147 }
148 while(src0_ != end0_) {
149 *output_r_ = hxforward_like<range0_t_>(*src0_);
150 ++output_r_; ++src0_;
151 }
152 return output_r_;
153}
154
158template<hxsorted_range_concept_ range0_t_, hxsorted_range_concept_ range1_t_,
159 typename output_iterator_t_>
161output_iterator_t_ hxset_difference(range0_t_&& range0_, range1_t_&& range1_,
162 output_iterator_t_&& output_) noexcept {
163 const auto begin0_ = range0_.begin();
166 hxkey_less_t<decltype(*begin0_)>{});
167}
168
179template<hxrandom_range_concept_ range0_t_, hxrandom_range_concept_ range1_t_,
180 typename output_iterator_t_, typename less_t_>
182output_iterator_t_ hxset_intersection(range0_t_&& range0_, range1_t_&& range1_,
183 output_iterator_t_&& output_, const less_t_& less_) noexcept {
184 hxrestrict_t<decltype(range0_.begin())> src0_(range0_.begin());
185 const auto end0_ = range0_.end();
186 hxrestrict_t<decltype(range1_.begin())> src1_(range1_.begin());
187 const auto end1_ = range1_.end();
189 while(src0_ != end0_ && src1_ != end1_) {
190 const bool lt_ = less_(*src0_, *src1_);
191 const bool gt_ = less_(*src1_, *src0_);
192 if(!lt_ && !gt_) {
193 *output_r_ = hxforward_like<range0_t_>(*src0_);
194 ++output_r_;
195 }
196 src0_ = src0_ + static_cast<ptrdiff_t>(!gt_);
197 src1_ = src1_ + static_cast<ptrdiff_t>(!lt_);
198 }
199 return output_r_;
200}
201
205template<hxsorted_range_concept_ range0_t_, hxsorted_range_concept_ range1_t_,
206 typename output_iterator_t_>
208output_iterator_t_ hxset_intersection(range0_t_&& range0_, range1_t_&& range1_,
209 output_iterator_t_&& output_) noexcept {
210 const auto begin0_ = range0_.begin();
213 hxkey_less_t<decltype(*begin0_)>{});
214}
215
226template<hxrandom_range_concept_ range0_t_, hxrandom_range_concept_ range1_t_,
227 typename output_iterator_t_, typename less_t_>
229output_iterator_t_ hxset_union(range0_t_&& range0_, range1_t_&& range1_,
230 output_iterator_t_&& output_, const less_t_& less_) noexcept {
231 hxrestrict_t<decltype(range0_.begin())> src0_(range0_.begin());
232 const auto end0_ = range0_.end();
233 hxrestrict_t<decltype(range1_.begin())> src1_(range1_.begin());
234 const auto end1_ = range1_.end();
236 while(src0_ != end0_ && src1_ != end1_) {
237 const bool take1_ = less_(*src1_, *src0_);
238 const bool less0_ = less_(*src0_, *src1_);
239 if(take1_) { *output_r_ = hxforward_like<range1_t_>(*src1_); }
240 else { *output_r_ = hxforward_like<range0_t_>(*src0_); }
241 ++output_r_;
242 src0_ = src0_ + static_cast<ptrdiff_t>(!take1_);
243 src1_ = src1_ + static_cast<ptrdiff_t>(!less0_);
244 }
245 while(src0_ != end0_) {
246 *output_r_ = hxforward_like<range0_t_>(*src0_);
247 ++output_r_; ++src0_;
248 }
249 while(src1_ != end1_) {
250 *output_r_ = hxforward_like<range1_t_>(*src1_);
251 ++output_r_; ++src1_;
252 }
253 return output_r_;
254}
255
259template<hxsorted_range_concept_ range0_t_, hxsorted_range_concept_ range1_t_,
260 typename output_iterator_t_>
262output_iterator_t_ hxset_union(range0_t_&& range0_, range1_t_&& range1_,
263 output_iterator_t_&& output_) noexcept {
264 const auto begin0_ = range0_.begin();
267 hxkey_less_t<decltype(*begin0_)>{});
268}
269
277template<hxrandom_iterator_concept_ iterator_t_, typename equal_t_>
279iterator_t_ hxunique(iterator_t_ begin_, iterator_t_ end_, const equal_t_& equal_) noexcept {
280 if(begin_ == end_) { return end_; }
281 iterator_t_ dst_ = begin_;
282 for(++begin_; begin_ != end_; ++begin_, ++dst_) {
283 if(equal_(*dst_, *begin_)) { break; }
284 }
285 if(begin_ == end_) { return end_; }
286 hxrestrict_t<iterator_t_> dst_r_(dst_);
287 hxrestrict_t<iterator_t_> src_r_(begin_);
288 for(++src_r_; src_r_ != end_; ++src_r_) {
289 if(!equal_(*dst_r_, *src_r_)) {
290 ++dst_r_;
291 *dst_r_ = hxmove(*src_r_);
292 }
293 }
294 return ++dst_r_;
295}
296
299template<hxsorted_iterator_concept_ iterator_t_>
301iterator_t_ hxunique(iterator_t_ begin_, iterator_t_ end_) noexcept {
302 return hxunique<iterator_t_>(begin_, end_, hxkey_equal_t<decltype(*begin_)>{});
303}
304
305HX_NS_END_
hxkey_equal_t<T> - A constexpr callable that returns true if two objects are equivalent.
Definition hxkey.hpp:57
hxkey_less_t<T> - A constexpr callable that returns true if the first object is less than the second.
Definition hxkey.hpp:91
hxminmax_result - Return type of hxminmax holding iterators to the minimum and maximum elements of a ...
Definition hxset_algorithms.hpp:79
iterator_t_ max
Definition hxset_algorithms.hpp:82
iterator_t_ min
Definition hxset_algorithms.hpp:81
Read-only range utilities for libhatchet.
constexpr iterator_t_ hxunique(iterator_t_ begin_, iterator_t_ end_, const equal_t_ &equal_) noexcept
hxunique - Removes consecutive duplicate elements from the range [begin, end) using equal to identify...
Definition hxset_algorithms.hpp:279
constexpr output_iterator_t_ hxset_difference(range0_t_ &&range0_, range1_t_ &&range1_, output_iterator_t_ &&output_, const less_t_ &less_) noexcept
hxset_difference - Forms the difference of the two ordered ranges range0 and range1 into output.
Definition hxset_algorithms.hpp:131
constexpr auto hxminmax(range_t_ &&range_, const less_t_ &less_) -> hxminmax_result< decltype(range_.begin())>
hxminmax - Returns an hxminmax_result with iterators to the smallest and largest elements in range as...
Definition hxset_algorithms.hpp:93
HX_NS_BEGIN_ constexpr output_iterator_t_ hxmerge(range0_t_ &&range0_, range1_t_ &&range1_, output_iterator_t_ &&output_, const less_t_ &less_) noexcept
hxmerge - Performs a stable merge of the two ordered ranges range0 and range1 -> output.
Definition hxset_algorithms.hpp:36
constexpr output_iterator_t_ hxset_intersection(range0_t_ &&range0_, range1_t_ &&range1_, output_iterator_t_ &&output_, const less_t_ &less_) noexcept
hxset_intersection - Forms the intersection of the two ordered ranges range0 and range1 into output.
Definition hxset_algorithms.hpp:182
constexpr output_iterator_t_ hxset_union(range0_t_ &&range0_, range1_t_ &&range1_, output_iterator_t_ &&output_, const less_t_ &less_) noexcept
hxset_union - Forms the union of the two ordered ranges range0 and range1 into output.
Definition hxset_algorithms.hpp:229
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:98
#define hxattr_flatten
hxattr_flatten - Inline every call inside a function's body into it, recursively, regardless of the c...
Definition hxsettings.h:90
#define hxconstexpr
hxconstexpr - Enables C++23 compatable constexpr usage for functions as that has support for destruct...
Definition hxsettings.h:266
typename hxrestrict_t_< T >::type hxrestrict_t
hxrestrict_t - Adds the __restrict keyword to C++ pointers.
Definition hxutility.h:287
constexpr T && hxforward(hxremove_reference_t< T > &&x_)
hxforward - Implements std::forward.
Definition hxutility.h:353
constexpr hxremove_reference_t< T > && hxmove(T &&t_)
hxmove - Implements std::move.
Definition hxutility.h:407
constexpr hxforward_like_t_< like_t_, value_t_ > hxforward_like(value_t_ &value_)
hxforward_like<T> - Returns value with the constness and value category of T.
Definition hxutility.h:387