ddnet/src/base/tl/algorithm.h
2020-10-11 08:39:29 +02:00

149 lines
2.8 KiB
C++

/* (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
#include "base/tl/range.h"
#include <algorithm>
#include <functional>
/*
insert 4
v
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);
if(range.empty())
return range;
if(range.back() < value)
return R();
while(range.size() > 1)
{
unsigned pivot = (range.size() - 1) / 2;
if(range.index(pivot) < value)
range = range.slice(pivot + 1, range.size() - 1);
else
range = range.slice(0, pivot + 1);
}
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())
if(value == range.front())
break;
return range;
}
template<class R, class T>
R find_binary(R range, T value)
{
range = partition_binary(range, value);
if(range.empty())
return range;
if(range.front() == value)
return range;
return R();
}
template<class R>
void sort_bubble(R range)
{
concept_empty::check(range);
concept_forwarditeration::check(range);
concept_backwarditeration::check(range);
// 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)
{
std::sort(&range.front(), &range.back() + 1);
}
template<class R>
bool sort_verify(R range)
{
concept_empty::check(range);
concept_forwarditeration::check(range);
typename R::type *prev = &range.front();
range.pop_front();
for(; !range.empty(); range.pop_front())
{
typename R::type *cur = &range.front();
if(*cur < *prev)
return false;
prev = cur;
}
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);
}
}
#endif // TL_FILE_ALGORITHMS_HPP