21#if HX_USE_MACROS_WITH_MODULE
22#error Header does not provide macros alone.
29#if HX_CPLUSPLUS >= 202002L
34concept hxforward_iterator_concept_ =
requires(T_& x_,
const T_& y_) {
42concept hxbidirectional_iterator_concept_ = hxforward_iterator_concept_<T_> &&
requires(T_& x_) {
47concept hxrandom_iterator_concept_ = hxbidirectional_iterator_concept_<T_> &&
requires(
48 const T_& x_,
const T_& y_, ptrdiff_t n_) {
55concept hxsorted_iterator_concept_ = hxrandom_iterator_concept_<T_> &&
requires(
const T_& x_) {
60concept hxrange_concept_ =
requires(T_& x_) {
61 { x_.begin() } -> hxforward_iterator_concept_;
62 { x_.end() } -> hxforward_iterator_concept_;
65concept hxrandom_range_concept_ =
requires(T_& x_) {
66 { x_.begin() } -> hxrandom_iterator_concept_;
67 { x_.end() } -> hxrandom_iterator_concept_;
70concept hxsorted_range_concept_ =
requires(T_& x_) {
71 { x_.begin() } -> hxsorted_iterator_concept_;
72 { x_.end() } -> hxsorted_iterator_concept_;
76#define hxforward_iterator_concept_ typename
77#define hxbidirectional_iterator_concept_ typename
78#define hxrandom_iterator_concept_ typename
79#define hxrange_concept_ typename
80#define hxrandom_range_concept_ typename
81#define hxsorted_iterator_concept_ typename
82#define hxsorted_range_concept_ typename
86template<hxrandom_range_concept_ range_t_,
typename value_t_,
typename less_t_>
hxconstexpr
87auto hxlower_bound(range_t_&& range_,
const value_t_& value_,
const less_t_& less_)
88 ->
decltype(range_.begin());
93template<
typename iterator_t_>
98 template<
typename T_,
size_t N_>
100 : m_begin_(+array_), m_end_(array_ + N_) { }
106 : m_begin_(begin_), m_end_(end_) { }
112 : m_begin_(begin_), m_end_(begin_ + size_) { }
118 : m_begin_(begin_), m_end_(begin_ + size_) { }
122 iterator_t_
begin(
void)
const {
return m_begin_; }
126 iterator_t_
end(
void)
const {
return m_end_; }
129 iterator_t_ m_begin_;
137template<
typename iterator_t_>
143template<
typename T_,
size_t N_>
150template<hxrange_concept_ range_t_,
typename callable_t_>
152bool hxall_of(range_t_&& range_, callable_t_&& callable_) {
153 hxrestrict_t<
decltype(range_.begin())> it_(range_.begin());
154 for(
const auto end_ = range_.end(); it_ != end_; ++it_) {
165template<hxrange_concept_ range_t_,
typename callable_t_>
167bool hxany_of(range_t_&& range_, callable_t_&& callable_) {
168 hxrestrict_t<
decltype(range_.begin())> it_(range_.begin());
169 for(
const auto end_ = range_.end(); it_ != end_; ++it_) {
182template<hxrandom_iterator_concept_ iterator_t_,
typename value_t_,
typename less_t_>
184iterator_t_
hxbinary_search(iterator_t_ begin_, iterator_t_ end_,
const value_t_& value_,
185 const less_t_& less_) {
187 return (it_ != end_ && !less_(value_, *it_)) ? it_ : end_;
192template<hxrandom_range_concept_ range_t_,
typename value_t_,
typename less_t_>
195 ->
decltype(range_.begin()) {
196 const auto end_ = range_.end();
198 return (it_ != end_ && !less_(value_, *it_)) ? it_ : end_;
204template<hxsorted_range_concept_ range_t_,
typename value_t_>
206auto hxbinary_search(range_t_&& range_,
const value_t_& value_) ->
decltype(range_.begin()) {
207 using less_t_ =
hxkey_less_t<
decltype(*range_.begin())>;
208 const auto end_ = range_.end();
210 return (it_ != end_ && !less_t_{}(value_, *it_)) ? it_ : end_;
215template<hxrange_concept_ range_t_,
typename callable_t_>
218 hxrestrict_t<
decltype(range_.begin())> it_(range_.begin());
220 for(
const auto end_ = range_.end(); it_ != end_; ++it_) {
231template<hxrange_concept_ range0_t_, hxrange_concept_ range1_t_,
typename equal_t_>
233bool hxequal_range(range0_t_&& range0_, range1_t_&& range1_,
const equal_t_& equal_) {
234 hxrestrict_t<
decltype(range0_.begin())> begin0_(range0_.begin());
235 const auto end0_ = range0_.end();
236 hxrestrict_t<
decltype(range1_.begin())> begin1_(range1_.begin());
237 const auto end1_ = range1_.end();
238#if HX_CPLUSPLUS >= 202002L
239 if constexpr(
requires(
const decltype(begin0_)& a_,
const decltype(begin0_)& b_) { { b_ - a_ }; }
240 &&
requires(
const decltype(begin1_)& a_,
const decltype(begin1_)& b_) { { b_ - a_ }; }) {
241 if((end0_ - begin0_) != (end1_ - begin1_)) {
return false; }
242 while(begin0_ != end0_) {
243 if(!equal_(*begin0_, *begin1_)) {
return false; }
244 ++begin0_; ++begin1_;
251 while(begin0_ != end0_ && begin1_ != end1_) {
252 if(!equal_(*begin0_, *begin1_)) {
return false; }
253 ++begin0_; ++begin1_;
255 return begin0_ == end0_ && begin1_ == end1_;
261template<hxrange_concept_ range0_t_, hxrange_concept_ range1_t_>
264 const auto begin0_ = range0_.begin();
272template<
typename T_,
typename... args_t_>
283template<hxrange_concept_ range_t_,
typename callable_t_>
285auto hxfind_if(range_t_&& range_, callable_t_&& callable_) ->
decltype(range_.begin()) {
286 hxrestrict_t<
decltype(range_.begin())> it_(range_.begin());
287 const auto end_ = range_.end();
288 for(; it_ != end_; ++it_) {
299template<hxrange_concept_ range_t_,
typename callable_t_>
301callable_t_
hxfor_each(range_t_&& range_, callable_t_&& callable_) {
302 hxrestrict_t<
decltype(range_.begin())> it_(range_.begin());
303 for(
const auto end_ = range_.end(); it_ != end_; ++it_) {
314template<hxrange_concept_ range0_t_, hxrange_concept_ range1_t_,
typename equal_t_,
typename less_t_>
316bool hxless_range(range0_t_&& range0_, range1_t_&& range1_,
const equal_t_& equal_,
317 const less_t_& less_) {
318 hxrestrict_t<
decltype(range0_.begin())> begin0_(range0_.begin());
319 const auto end0_ = range0_.end();
320 hxrestrict_t<
decltype(range1_.begin())> begin1_(range1_.begin());
321 const auto end1_ = range1_.end();
322 while(begin0_ != end0_ && begin1_ != end1_) {
323 if(!equal_(*begin0_, *begin1_)) {
return less_(*begin0_, *begin1_); }
324 ++begin0_; ++begin1_;
326 return begin0_ == end0_ && begin1_ != end1_;
332template<hxrange_concept_ range0_t_, hxrange_concept_ range1_t_>
335 const auto begin0_ = range0_.begin();
347template<hxrandom_range_concept_ range_t_,
typename value_t_,
typename less_t_>
349auto hxlower_bound(range_t_&& range_,
const value_t_& value_,
const less_t_& less_)
350 ->
decltype(range_.begin()) {
351 using iterator_t_ =
hxrestrict_t<
decltype(range_.begin())>;
352 iterator_t_ begin_ = range_.begin();
354 hxsize_t count_ = range_.end() - begin_;
357 const iterator_t_ mid_ = begin_ + step_;
358 if(less_(*mid_, value_)) {
371template<hxrandom_range_concept_ range_t_,
typename value_t_>
373auto hxlower_bound(range_t_&& range_,
const value_t_& value_) ->
decltype(range_.begin()) {
374 const auto begin_ = range_.begin();
384template<hxrandom_range_concept_ range_t_,
typename value_t_,
typename less_t_>
386auto hxupper_bound(range_t_&& range_,
const value_t_& value_,
const less_t_& less_)
387 ->
decltype(range_.begin()) {
388 using iterator_t_ =
hxrestrict_t<
decltype(range_.begin())>;
389 iterator_t_ begin_ = range_.begin();
391 hxsize_t count_ = range_.end() - begin_;
394 const iterator_t_ mid_ = begin_ + step_;
395 if(!less_(value_, *mid_)) {
408template<hxrandom_range_concept_ range_t_,
typename value_t_>
410auto hxupper_bound(range_t_&& range_,
const value_t_& value_) ->
decltype(range_.begin()) {
411 const auto begin_ = range_.begin();
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
hxrange - Wraps an iterator pair [begin, end) for use with algorithms on that pair.
Definition hxrange.hpp:94
constexpr iterator_t_ end(void) const
Returns an iterator one past the last element.
Definition hxrange.hpp:126
constexpr hxrange(iterator_t_ begin_, size_t size_)
Constructs from an iterator and a length.
Definition hxrange.hpp:117
constexpr hxrange(iterator_t_ begin_, hxsize_t size_)
Constructs from an iterator and a length.
Definition hxrange.hpp:111
constexpr hxrange(iterator_t_ begin_, iterator_t_ end_)
Constructs from the iterator pair [begin, end).
Definition hxrange.hpp:105
constexpr hxrange(T(&array_)[N_])
Constructs from the C array array.
Definition hxrange.hpp:99
constexpr iterator_t_ begin(void) const
Returns an iterator to the first element.
Definition hxrange.hpp:122
hxconvertible_to - A concept that requires one type to be convertible to another.
Definition hxutility.h:255
hxsame_as - A concept that requires two types to be the same.
Definition hxutility.h:265
User-specializable key-equal, key-less, and key-hash callables.
constexpr T hxexchange(T &obj_, args_t_ &&... args_) noexcept
hxexchange - Replaces obj with a T constructed from args and returns the old value of obj.
Definition hxrange.hpp:274
constexpr bool hxany_of(range_t_ &&range_, callable_t_ &&callable_)
hxany_of - Returns true if the predicate callable returns true for at least one element of range.
Definition hxrange.hpp:167
constexpr bool hxequal_range(range0_t_ &&range0_, range1_t_ &&range1_, const equal_t_ &equal_)
hxequal_range - Returns true if range0 and range1 have the same length and equal returns true for eve...
Definition hxrange.hpp:233
constexpr bool hxless_range(range0_t_ &&range0_, range1_t_ &&range1_, const equal_t_ &equal_, const less_t_ &less_)
hxless_range - Returns true if range0 is lexicographically less than range1, using equal to detect ma...
Definition hxrange.hpp:316
constexpr bool hxall_of(range_t_ &&range_, callable_t_ &&callable_)
hxall_of - Returns true if the predicate callable returns true for every element of range.
Definition hxrange.hpp:152
constexpr hxsize_t hxcount_if(range_t_ &&range_, callable_t_ &&callable_)
hxcount_if - Returns the number of elements of range for which the predicate callable returns true.
Definition hxrange.hpp:217
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 sorted range [begin, end).
Definition hxrange.hpp:184
constexpr auto hxfind_if(range_t_ &&range_, callable_t_ &&callable_) -> decltype(range_.begin())
hxfind_if - Returns an iterator to the first element of range for which the predicate callable return...
Definition hxrange.hpp:285
constexpr auto hxupper_bound(range_t_ &&range_, const value_t_ &value_, const less_t_ &less_) -> decltype(range_.begin())
hxupper_bound - Returns the first position in the sorted range whose element is ordered after value.
Definition hxrange.hpp:386
HX_NS_BEGIN_ constexpr auto hxlower_bound(range_t_ &&range_, const value_t_ &value_, const less_t_ &less_) -> decltype(range_.begin())
hxlower_bound - Returns the first position in the sorted range where value could be inserted without ...
Definition hxrange.hpp:349
constexpr callable_t_ hxfor_each(range_t_ &&range_, callable_t_ &&callable_)
hxfor_each - Applies the callable to each element of range in order.
Definition hxrange.hpp:301
constexpr hxrange< iterator_t_ > hxmake_range(iterator_t_ begin_, iterator_t_ end_)
hxmake_range - Returns an hxrange deduced from the iterator pair [begin, end).
Definition hxrange.hpp:139
#define hxinline
hxinline - Force a function to be inlined into its callers.
Definition hxsettings.h:125
#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
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:207