libhatchet
Loading...
Searching...
No Matches
hxsort.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
11
12#include "libhatchet.h"
13
14// HX_USE_MACROS_WITH_MODULE allows including macros alongside the module.
15#if HX_USE_MACROS_WITH_MODULE
16#error Header does not provide macros alone.
17#endif
18
19#include "hxkey.hpp"
20
21HX_NS_BEGIN_
22
23#include "detail/hxsort_detail.hpp"
24
31template<typename iterator_t_, typename value_t_, typename less_t_>
33iterator_t_ hxlower_bound(iterator_t_ begin_, iterator_t_ end_, const value_t_& value_, const less_t_& less_) {
34 // Does not dereference null pointer args.
35 hxsize_t count_ = end_ - begin_;
36 while(count_ > hxsize_t{0}) {
37 const hxsize_t step_ = count_ >> 1;
38 const iterator_t_ mid_ = begin_ + step_;
39 if(less_(*mid_, value_)) {
40 begin_ = mid_ + hxsize_t{1};
41 count_ -= step_ + hxsize_t{1};
42 }
43 else {
44 count_ = step_;
45 }
46 }
47 return begin_;
48}
49
52template<typename iterator_t_, typename value_t_>
54iterator_t_ hxlower_bound(iterator_t_ begin_, iterator_t_ end_, const value_t_& value_) {
55 return hxlower_bound<iterator_t_>(begin_, end_, value_,
56 hxkey_less_t<decltype(*begin_)>{});
57}
58
64template<typename iterator_t_, typename value_t_, typename less_t_>
66iterator_t_ hxupper_bound(iterator_t_ begin_, iterator_t_ end_, const value_t_& value_, const less_t_& less_) {
67 // Does not dereference null pointer args.
68 hxsize_t count_ = end_ - begin_;
69 while(count_ > hxsize_t{0}) {
70 const hxsize_t step_ = count_ >> 1;
71 const iterator_t_ mid_ = begin_ + step_;
72 if(!less_(value_, *mid_)) {
73 begin_ = mid_ + hxsize_t{1};
74 count_ -= step_ + hxsize_t{1};
75 }
76 else {
77 count_ = step_;
78 }
79 }
80 return begin_;
81}
82
85template<typename iterator_t_, typename value_t_>
87iterator_t_ hxupper_bound(iterator_t_ begin_, iterator_t_ end_, const value_t_& value_) {
88 return hxupper_bound<iterator_t_>(begin_, end_, value_,
89 hxkey_less_t<decltype(*begin_)>{});
90}
91
97template<typename iterator_t_, typename value_t_, typename less_t_>
99iterator_t_ hxbinary_search(iterator_t_ begin_, iterator_t_ end_, const value_t_& value_, const less_t_& less_) {
100 const iterator_t_ pos_ = hxlower_bound<iterator_t_>(begin_, end_, value_, less_);
101 return (pos_ != end_ && !less_(value_, *pos_)) ? pos_ : end_;
102}
103
107template<typename iterator_t_, typename value_t_>
109iterator_t_ hxbinary_search(iterator_t_ begin_, iterator_t_ end_, const value_t_& value_) {
110 return hxbinary_search<iterator_t_>(begin_, end_, value_,
111 hxkey_less_t<decltype(*begin_)>{});
112}
113
121template<typename iterator_t_, typename less_t_>
123void hxinsertion_sort(iterator_t_ begin_, iterator_t_ end_, const less_t_& less_) {
124 // Address sanitizer: Avoids adding 1 to null iterators.
125 if(begin_ == end_) { return; }
126 for(iterator_t_ i_ = begin_, j_ = begin_ + ptrdiff_t{1}; j_ < end_; i_ = j_, ++j_) {
127 if(less_(*j_, *i_)) {
128 auto t_ = hxmove(*j_);
129 *j_ = hxmove(*i_);
130 while(begin_ < i_ && less_(t_, *(i_ - ptrdiff_t{1}))) {
131 *i_ = hxmove(*(i_ - ptrdiff_t{1}));
132 --i_;
133 }
134 *i_ = hxmove(t_);
135 }
136 }
137}
138
142template<typename iterator_t_>
144void hxinsertion_sort(iterator_t_ begin_, iterator_t_ end_) {
145 hxinsertion_sort<iterator_t_>(begin_, end_, hxkey_less_t<decltype(*begin_)>{});
146}
147
151template<typename iterator_t_, typename less_t_>
153void hxheapsort(iterator_t_ begin_, iterator_t_ end_, const less_t_& less_) {
154 if(begin_ == end_) { return; } // Prevents UB.
155 hxdetail_::hxmake_heap_<iterator_t_>(begin_, end_, less_);
156 for(iterator_t_ it_ = end_ - ptrdiff_t{1}; begin_ < it_; --it_) {
157 hxswap(*begin_, *it_);
158 hxdetail_::hxheapsort_heapify_<iterator_t_>(begin_, begin_, it_, less_);
159 }
160}
161
164template<typename iterator_t_>
166void hxheapsort(iterator_t_ begin_, iterator_t_ end_) {
167 hxheapsort<iterator_t_>(begin_, end_, hxkey_less_t<decltype(*begin_)>{});
168}
169
175template<typename iterator_t_, typename less_t_>
177void hxsort(iterator_t_ begin_, iterator_t_ end_, const less_t_& less_) {
178 const hxsize_t size_ = end_ - begin_;
179 hxdetail_::hxintro_sort_<iterator_t_>(begin_, end_, less_,
180 size_ > 0 ? 2 * hxlog2i(static_cast<uint32_t>(size_)) : 0);
181}
182
186template<typename iterator_t_>
188void hxsort(iterator_t_ begin_, iterator_t_ end_) {
189 const hxsize_t size_ = end_ - begin_;
190 hxdetail_::hxintro_sort_<iterator_t_>(begin_, end_, hxkey_less_t<decltype(*begin_)>{},
191 size_ > 0 ? 2 * hxlog2i(static_cast<uint32_t>(size_)) : 0);
192}
193
194HX_NS_END_
hxkey_less_t<T> - A constexpr callable that invokes hxkey_less.
Definition hxkey.hpp:131
void hxswap(hxarray< T, hxallocator_dynamic_capacity > &x_, hxarray< T, hxallocator_dynamic_capacity > &y_) noexcept
void hxswap(hxarray<T>& x, hxarray<T>& y) - Exchanges the contents of x and y.
Definition hxarray.hpp:315
User-overloadable key-equal, key-less, and key-hash functions.
#define hxinline
hxinline - Force a function to be inlined into its callers.
Definition hxsettings.h:120
#define hxattr_nodiscard
hxattr_nodiscard - Indicates the caller should not discard the return value.
Definition hxsettings.h:89
#define hxattr_flatten
hxattr_flatten - Inline every call inside a function's body into it, recursively, regardless of the c...
Definition hxsettings.h:82
#define hxconstexpr
hxconstexpr - Enables C++23 compatable constexpr usage for functions as that has support for destruct...
Definition hxsettings.h:263
HX_NS_BEGIN_ constexpr iterator_t_ hxlower_bound(iterator_t_ begin_, iterator_t_ end_, const value_t_ &value_, const less_t_ &less_)
hxlower_bound - Returns the first position in the sorted range [begin, end) where value could be inse...
Definition hxsort.hpp:33
constexpr iterator_t_ hxupper_bound(iterator_t_ begin_, iterator_t_ end_, const value_t_ &value_, const less_t_ &less_)
hxupper_bound - Returns the first position in the sorted range [begin, end) whose element is ordered ...
Definition hxsort.hpp:66
constexpr void hxsort(iterator_t_ begin_, iterator_t_ end_, const less_t_ &less_)
hxsort - A general purpose sort routine using T::T(&&), T::~T(), T::operator=(&&),...
Definition hxsort.hpp:177
constexpr void hxheapsort(iterator_t_ begin_, iterator_t_ end_, const less_t_ &less_)
hxheapsort - Sorts the elements in the range [begin, end) using the heapsort algorithm.
Definition hxsort.hpp:153
constexpr void hxinsertion_sort(iterator_t_ begin_, iterator_t_ end_, const less_t_ &less_)
hxinsertion_sort - Sorts the elements in the range [begin, end) in comparison order using the inserti...
Definition hxsort.hpp:123
constexpr iterator_t_ hxbinary_search(iterator_t_ begin_, iterator_t_ end_, const value_t_ &value_, const less_t_ &less_)
hxbinary_search - Performs a binary search for value in the range [first, last).
Definition hxsort.hpp:99
constexpr hxremove_reference_t< T > && hxmove(T &&t_)
hxmove - Implements std::move.
Definition hxutility.h:333
int hxlog2i(uint32_t i_)
hxlog2i - Returns log2(n) as an integer which is the power of 2 of the largest bit in n.
Definition hxutility.h:263
Provides core macros, memory management and feature detection.
ptrdiff_t hxsize_t
hxsize_t - A signed size type, same as ssize_t or ptrdiff_t.
Definition libhatchet.h:209