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. */
|
2011-04-13 18:22:10 +00:00
|
|
|
#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
|
2011-04-13 18:37:12 +00:00
|
|
|
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);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2009-06-15 06:45:44 +00:00
|
|
|
if(range.empty())
|
|
|
|
return range;
|
|
|
|
if(range.back() < value)
|
|
|
|
return R();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2009-06-15 06:45:44 +00:00
|
|
|
while(range.size() > 1)
|
|
|
|
{
|
2020-09-26 19:41:58 +00:00
|
|
|
unsigned pivot = (range.size() - 1) / 2;
|
2009-06-15 06:45:44 +00:00
|
|
|
if(range.index(pivot) < value)
|
2020-09-26 19:41:58 +00:00
|
|
|
range = range.slice(pivot + 1, range.size() - 1);
|
2009-06-15 06:45:44 +00:00
|
|
|
else
|
2020-09-26 19:41:58 +00:00
|
|
|
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);
|
2020-09-26 19:41:58 +00:00
|
|
|
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);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2009-06-15 06:45:44 +00:00
|
|
|
// slow bubblesort :/
|
|
|
|
for(; !range.empty(); range.pop_back())
|
|
|
|
{
|
|
|
|
R section = range;
|
|
|
|
typename R::type *prev = §ion.front();
|
|
|
|
section.pop_front();
|
|
|
|
for(; !section.empty(); section.pop_front())
|
|
|
|
{
|
|
|
|
typename R::type *cur = §ion.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);
|
2011-04-13 18:37:12 +00:00
|
|
|
|
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();
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2009-06-15 06:45:44 +00:00
|
|
|
if(*cur < *prev)
|
|
|
|
return false;
|
|
|
|
prev = cur;
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2009-06-15 06:45:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-02-27 13:53:12 +00:00
|
|
|
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
|