Files

277 lines
7.5 KiB
C++
Raw Permalink Normal View History

#ifndef _RSTL_ALGORITHM
#define _RSTL_ALGORITHM
2022-12-05 23:35:31 +02:00
#include "rstl/functional.hpp"
#include "rstl/pair.hpp"
#include "rstl/pointer_iterator.hpp"
namespace rstl {
2022-10-03 20:00:46 -04:00
template < class It, class T >
inline It find(It first, It last, const T& val) {
while (first != last && !(*first == val))
++first;
return first;
}
2022-10-03 20:00:46 -04:00
template < typename T >
inline void swap(T& a, T& b) {
T tmp(a);
a = b;
b = tmp;
}
template < typename I1, typename I2 >
inline void iter_swap(I1 a, I2 b) {
2026-03-12 22:21:45 -06:00
typename iterator_traits< I1 >::value_type tmp = *a;
*a = *b;
*b = tmp;
2022-10-03 20:00:46 -04:00
}
2022-11-27 05:04:19 +02:00
template < typename It, class Cmp >
void __insertion_sort(It first, It last, Cmp cmp) {
2025-05-23 03:05:25 -07:00
It next = first;
for (++next; next < last; ++next) {
2022-11-27 05:04:19 +02:00
typename iterator_traits< It >::value_type value = *next;
2022-11-28 17:00:16 +02:00
It t1 = next - 1;
It t2 = next;
while (first < t2 && cmp(value, *t1)) {
2026-01-16 01:51:56 -08:00
*t2-- = *t1;
--t1;
2022-11-27 05:04:19 +02:00
}
2022-11-28 17:00:16 +02:00
*t2 = value;
2022-11-27 05:04:19 +02:00
}
}
template < typename T, class Cmp >
2026-01-14 16:50:25 -08:00
void __sort3(T& a, T& b, T& c, const Cmp comp) {
2022-11-27 05:04:19 +02:00
if (comp(b, a)) {
swap(a, b);
}
if (comp(c, b)) {
T tmp(c);
c = b;
if (comp(tmp, a)) {
b = a;
a = tmp;
} else {
b = tmp;
}
}
}
template < typename It, class Cmp >
void sort(It first, It last, Cmp cmp) {
2026-03-12 22:21:45 -06:00
const int count = last - first;
2026-01-14 16:50:25 -08:00
if (count <= 1) {
return;
}
2026-03-12 22:21:45 -06:00
if (count <= 20) {
2026-01-14 16:50:25 -08:00
__insertion_sort(first, last, cmp);
2026-03-12 22:21:45 -06:00
return;
}
It mid = first + count / 2;
It end = last - 1;
__sort3(*first, *mid, *end, cmp);
typename iterator_traits< It >::value_type pivot = *mid;
It it = first + 1;
--end;
while (true) {
while (cmp(*it, pivot)) {
2026-01-16 01:51:56 -08:00
++it;
2022-11-27 05:04:19 +02:00
}
2026-03-12 22:21:45 -06:00
while (cmp(pivot, *end)) {
--end;
}
if (it >= end) {
break;
}
iter_swap(it, end);
++it;
--end;
2022-11-27 05:04:19 +02:00
}
2026-03-12 22:21:45 -06:00
sort(first, it, cmp);
sort(it, last, cmp);
2022-11-27 05:04:19 +02:00
}
2022-12-05 23:35:31 +02:00
template < typename It, typename T, typename Cmp >
It lower_bound(It start, It end, const T& value, Cmp cmp) {
int dist = distance(start, end);
It it = start;
while (dist > 0) {
int halfDist = dist / 2;
2022-12-07 18:46:34 +02:00
it = start;
2022-12-05 23:35:31 +02:00
advance(it, halfDist);
if (cmp(*it, value)) {
start = it;
++start;
dist = (dist - halfDist) - 1;
} else {
dist = halfDist;
}
}
return start;
}
2026-03-12 22:21:45 -06:00
template < typename Vec >
typename Vec::const_iterator lower_bound_const(typename Vec::const_iterator start,
typename Vec::const_iterator end,
const typename Vec::value_type& value) {
int dist = distance(start, end);
typename Vec::const_iterator it = start;
while (dist > 0) {
int halfDist = dist / 2;
it = start;
advance(it, halfDist);
if (*it < value) {
start = it;
++start;
dist = (dist - halfDist) - 1;
} else {
dist = halfDist;
}
}
return start;
}
template < typename Vec >
typename Vec::iterator lower_bound(typename Vec::iterator start, typename Vec::iterator end,
const typename Vec::value_type& value) {
int dist = distance(start, end);
typename Vec::iterator it = start;
while (dist > 0) {
int halfDist = dist / 2;
it = start;
advance(it, halfDist);
if (*it < value) {
start = it;
++start;
dist = (dist - halfDist) - 1;
} else {
dist = halfDist;
}
}
return start;
}
2022-12-05 23:35:31 +02:00
template < typename It, typename T, typename Cmp >
inline It binary_find(It start, It end, const T& value, Cmp cmp) {
2022-12-05 23:35:31 +02:00
It lower = lower_bound(start, end, value, cmp);
bool found = false;
if (lower != end && !cmp(value, *lower)) {
found = true;
}
2022-12-09 15:00:01 -03:00
return found ? lower : end;
2022-12-05 23:35:31 +02:00
}
2026-03-12 22:21:45 -06:00
template < typename Vec >
inline typename Vec::const_iterator binary_find_const(typename Vec::const_iterator start,
typename Vec::const_iterator end,
const typename Vec::value_type& value) {
typename Vec::const_iterator lower = lower_bound_const< Vec >(start, end, value);
bool found = (lower != end && !(value < *lower));
return found ? lower : end;
}
template < typename Vec >
inline typename Vec::iterator binary_find(typename Vec::iterator start, typename Vec::iterator end,
const typename Vec::value_type& value) {
typename Vec::iterator lower = lower_bound< Vec >(start, end, value);
bool found = (lower != end && !(value < *lower));
return found ? lower : end;
}
2022-12-05 23:35:31 +02:00
template < typename T, typename Cmp >
class pair_sorter_finder;
template < typename K, typename V, typename Cmp >
class pair_sorter_finder< pair< K, V >, Cmp > {
public:
typedef K key_type;
Cmp cmp;
pair_sorter_finder(const Cmp& cmp) : cmp(cmp) {}
bool operator()(const K& a, const pair< K, V >& b) const;
/* {
return cmp(a, b.first);
}*/
2022-12-05 23:35:31 +02:00
bool operator()(const pair< K, V >& a, const K& b) const;
/* {
return cmp(a.first, b);
}*/
2022-12-24 01:41:50 -03:00
bool operator()(const pair< K, V >& a, const pair< K, V >& b) const;
2022-12-05 23:35:31 +02:00
};
2025-05-23 03:05:25 -07:00
template < typename T >
inline pair_sorter_finder< typename T::value_type,
less< typename select1st< typename T::value_type >::value_type > >
default_pair_sorter_finder() {
less< typename select1st< typename T::value_type >::value_type > l;
pair_sorter_finder< typename T::value_type,
less< typename select1st< typename T::value_type >::value_type > >
a(l);
return a;
2022-12-09 14:05:49 -03:00
}
2022-12-05 23:35:31 +02:00
template < typename K, typename V, typename Cmp >
inline bool pair_sorter_finder< pair< K, V >, Cmp >::operator()(const K& a,
const pair< K, V >& b) const {
2025-05-23 03:05:25 -07:00
return !!cmp(a, b.first);
2022-12-05 23:35:31 +02:00
}
template < typename K, typename V, typename Cmp >
inline bool pair_sorter_finder< pair< K, V >, Cmp >::operator()(const pair< K, V >& a,
const K& b) const {
2022-12-05 23:35:31 +02:00
return cmp(a.first, b);
}
2022-12-24 01:41:50 -03:00
template < typename K, typename V, typename Cmp >
inline bool pair_sorter_finder< pair< K, V >, Cmp >::operator()(const pair< K, V >& a,
const pair< K, V >& b) const {
return cmp(a.first, b.first);
}
2022-12-05 23:35:31 +02:00
template < typename T >
typename T::const_iterator
find_by_key(const T& container,
const typename select1st< typename T::value_type >::value_type& key);
template < typename T >
typename T::const_iterator inline find_by_key(
const T& container, const typename select1st< typename T::value_type >::value_type& key) {
return binary_find(container.begin(), container.end(), key, default_pair_sorter_finder< T >());
}
2025-05-23 03:05:25 -07:00
template < typename T, class Cmp >
typename T::const_iterator inline find_by_key(
const T& container, const typename select1st< typename T::value_type >::value_type& key,
Cmp cmp) {
return binary_find(container.begin(), container.end(), key,
pair_sorter_finder< typename T::value_type, Cmp >(cmp));
}
template < typename T >
typename T::iterator
find_by_key_nc(T& container, const typename select1st< typename T::value_type >::value_type& key);
template < typename T >
typename T::iterator inline find_by_key_nc(
T& container, const typename select1st< typename T::value_type >::value_type& key) {
return binary_find(container.begin(), container.end(), key, default_pair_sorter_finder< T >());
2022-12-05 23:35:31 +02:00
}
2025-05-23 03:05:25 -07:00
template < typename T, class Cmp >
2026-01-14 16:50:25 -08:00
inline void sort_by_key(T& container, const Cmp& cmp) {
2025-05-23 03:05:25 -07:00
sort(container.begin(), container.end(), pair_sorter_finder< typename T::value_type, Cmp >(cmp));
}
} // namespace rstl
2022-10-03 20:00:46 -04:00
#endif // _RSTL_ALGORITHM