ddnet/src/base/tl/algorithm.h

149 lines
2.8 KiB
C
Raw Normal View History

2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef BASE_TL_ALGORITHM_H
#define BASE_TL_ALGORITHM_H
2009-06-15 06:45:44 +00:00
2014-06-16 11:29:18 +00:00
#include "base/tl/range.h"
2020-10-08 05:28:53 +00:00
#include <algorithm>
2020-02-27 13:56:40 +00:00
#include <functional>
2009-06-15 06:45:44 +00:00
/*
insert 4
v
2009-06-15 06:45:44 +00:00
1 2 3 4 5 6
*/
template<class R, class T>
R partition_linear(R range, T value)
{
concept_empty::check(range);
concept_forwarditeration::check(range);
concept_sorted::check(range);
for(; !range.empty(); range.pop_front())
{
if(!(range.front() < value))
return range;
}
return range;
}
template<class R, class T>
R partition_binary(R range, T value)
{
concept_empty::check(range);
concept_index::check(range);
concept_size::check(range);
concept_slice::check(range);
concept_sorted::check(range);
2009-06-15 06:45:44 +00:00
if(range.empty())
return range;
if(range.back() < value)
return R();
2009-06-15 06:45:44 +00:00
while(range.size() > 1)
{
unsigned pivot = (range.size() - 1) / 2;
2009-06-15 06:45:44 +00:00
if(range.index(pivot) < value)
range = range.slice(pivot + 1, range.size() - 1);
2009-06-15 06:45:44 +00:00
else
range = range.slice(0, pivot + 1);
2009-06-15 06:45:44 +00:00
}
return range;
}
template<class R, class T>
R find_linear(R range, T value)
{
concept_empty::check(range);
concept_forwarditeration::check(range);
for(; !range.empty(); range.pop_front())
2010-05-29 07:25:38 +00:00
if(value == range.front())
2009-06-15 06:45:44 +00:00
break;
return range;
}
template<class R, class T>
R find_binary(R range, T value)
{
range = partition_linear(range, value);
if(range.empty())
return range;
if(range.front() == value)
return range;
2009-06-15 06:45:44 +00:00
return R();
}
template<class R>
void sort_bubble(R range)
{
concept_empty::check(range);
concept_forwarditeration::check(range);
concept_backwarditeration::check(range);
2009-06-15 06:45:44 +00:00
// slow bubblesort :/
for(; !range.empty(); range.pop_back())
{
R section = range;
typename R::type *prev = &section.front();
section.pop_front();
for(; !section.empty(); section.pop_front())
{
typename R::type *cur = &section.front();
if(*cur < *prev)
swap(*cur, *prev);
prev = cur;
}
}
}
/*
template<class R>
void sort_quick(R range)
{
concept_index::check(range);
}*/
template<class R>
void sort(R range)
{
2020-10-08 05:28:53 +00:00
std::sort(&range.front(), &range.back() + 1);
2009-06-15 06:45:44 +00:00
}
template<class R>
bool sort_verify(R range)
{
concept_empty::check(range);
concept_forwarditeration::check(range);
2009-06-15 06:45:44 +00:00
typename R::type *prev = &range.front();
range.pop_front();
for(; !range.empty(); range.pop_front())
{
typename R::type *cur = &range.front();
2009-06-15 06:45:44 +00:00
if(*cur < *prev)
return false;
prev = cur;
}
2009-06-15 06:45:44 +00:00
return true;
}
template<class R>
void for_each(R range, std::function<void(typename R::type)> fcn)
{
concept_empty::check(range);
concept_forwarditeration::check(range);
for(; !range.empty(); range.pop_front())
{
typename R::type *cur = &range.front();
fcn(*cur);
}
}
2009-06-15 06:45:44 +00:00
#endif // TL_FILE_ALGORITHMS_HPP