get rid of __Octa/__octa in algorithm

master
Daniel Kolesa 2015-06-03 22:43:07 +01:00
parent 6c20f00494
commit ae05420994
1 changed files with 80 additions and 74 deletions

View File

@ -39,90 +39,92 @@ namespace octa {
/* sorting */ /* sorting */
template<typename _R, typename _C> namespace detail {
void __octa_insort(_R __range, _C __compare) { template<typename _R, typename _C>
octa::RangeSize<_R> __rlen = __range.size(); void insort(_R __range, _C __compare) {
for (octa::RangeSize<_R> __i = 1; __i < __rlen; ++__i) { octa::RangeSize<_R> __rlen = __range.size();
octa::RangeSize<_R> __j = __i; for (octa::RangeSize<_R> __i = 1; __i < __rlen; ++__i) {
octa::RangeReference<_R> __v = __range[__i]; octa::RangeSize<_R> __j = __i;
while (__j > 0 && !__compare(__range[__j - 1], __v)) { octa::RangeReference<_R> __v = __range[__i];
__range[__j] = __range[__j - 1]; while (__j > 0 && !__compare(__range[__j - 1], __v)) {
--__j; __range[__j] = __range[__j - 1];
--__j;
}
__range[__j] = __v;
} }
__range[__j] = __v;
} }
}
template<typename _T, typename _U> template<typename _T, typename _U>
struct __OctaUnaryCompare { struct UnaryCompare {
const _T &__val; const _T &__val;
_U __comp; _U __comp;
bool operator()(const _T &__v) const { return __comp(__v, __val); } bool operator()(const _T &__v) const { return __comp(__v, __val); }
}; };
template<typename _R, typename _C> template<typename _R, typename _C>
void __octa_hs_sift_down(_R __range, octa::RangeSize<_R> __s, void hs_sift_down(_R __range, octa::RangeSize<_R> __s,
octa::RangeSize<_R> __e, _C __compare) { octa::RangeSize<_R> __e, _C __compare) {
octa::RangeSize<_R> __r = __s; octa::RangeSize<_R> __r = __s;
while ((__r * 2 + 1) <= __e) { while ((__r * 2 + 1) <= __e) {
octa::RangeSize<_R> __ch = __r * 2 + 1; octa::RangeSize<_R> __ch = __r * 2 + 1;
octa::RangeSize<_R> __sw = __r; octa::RangeSize<_R> __sw = __r;
if (__compare(__range[__sw], __range[__ch])) if (__compare(__range[__sw], __range[__ch]))
__sw = __ch; __sw = __ch;
if (((__ch + 1) <= __e) && __compare(__range[__sw], __range[__ch + 1])) if (((__ch + 1) <= __e) && __compare(__range[__sw], __range[__ch + 1]))
__sw = __ch + 1; __sw = __ch + 1;
if (__sw != __r) { if (__sw != __r) {
octa::swap(__range[__r], __range[__sw]); octa::swap(__range[__r], __range[__sw]);
__r = __sw; __r = __sw;
} else return; } else return;
}
} }
}
template<typename _R, typename _C> template<typename _R, typename _C>
void __octa_heapsort(_R __range, _C __compare) { void heapsort(_R __range, _C __compare) {
octa::RangeSize<_R> __len = __range.size(); octa::RangeSize<_R> __len = __range.size();
octa::RangeSize<_R> __st = (__len - 2) / 2; octa::RangeSize<_R> __st = (__len - 2) / 2;
for (;;) { for (;;) {
__octa_hs_sift_down(__range, __st, __len - 1, __compare); octa::detail::hs_sift_down(__range, __st, __len - 1, __compare);
if (__st-- == 0) break; if (__st-- == 0) break;
}
octa::RangeSize<_R> __e = __len - 1;
while (__e > 0) {
octa::swap(__range[__e], __range[0]);
--__e;
octa::detail::hs_sift_down(__range, 0, __e, __compare);
}
} }
octa::RangeSize<_R> __e = __len - 1;
while (__e > 0) {
octa::swap(__range[__e], __range[0]);
--__e;
__octa_hs_sift_down(__range, 0, __e, __compare);
}
}
template<typename _R, typename _C> template<typename _R, typename _C>
void __octa_introloop(_R __range, _C __compare, RangeSize<_R> __depth) { void introloop(_R __range, _C __compare, RangeSize<_R> __depth) {
if (__range.size() <= 10) { if (__range.size() <= 10) {
__octa_insort(__range, __compare); octa::detail::insort(__range, __compare);
return; return;
}
if (__depth == 0) {
octa::detail::heapsort(__range, __compare);
return;
}
octa::RangeReference<_R> __p = __range[__range.size() / 2];
octa::swap(__p, __range.back());
_R __r = octa::partition(__range,
octa::detail::UnaryCompare<decltype(__p), _C>{ __p, __compare });
_R __l = __range.slice(0, __range.size() - __r.size());
octa::swap(__r.front(), __r.back());
octa::detail::introloop(__l, __compare, __depth - 1);
octa::detail::introloop(__r, __compare, __depth - 1);
} }
if (__depth == 0) {
__octa_heapsort(__range, __compare);
return;
}
octa::RangeReference<_R> __p = __range[__range.size() / 2];
octa::swap(__p, __range.back());
_R __r = octa::partition(__range,
__OctaUnaryCompare<decltype(__p), _C>{ __p, __compare });
_R __l = __range.slice(0, __range.size() - __r.size());
octa::swap(__r.front(), __r.back());
__octa_introloop(__l, __compare, __depth - 1);
__octa_introloop(__r, __compare, __depth - 1);
}
template<typename _R, typename _C> template<typename _R, typename _C>
void __octa_introsort(_R __range, _C __compare) { void introsort(_R __range, _C __compare) {
__octa_introloop(__range, __compare, octa::RangeSize<_R>(2 octa::detail::introloop(__range, __compare, octa::RangeSize<_R>(2
* (log(__range.size()) / log(2)))); * (log(__range.size()) / log(2))));
}
} }
template<typename _R, typename _C> template<typename _R, typename _C>
void sort(_R __range, _C __compare) { void sort(_R __range, _C __compare) {
__octa_introsort(__range, __compare); octa::detail::introsort(__range, __compare);
} }
template<typename _R> template<typename _R>
@ -489,12 +491,16 @@ namespace octa {
} }
}; };
template<typename _R, typename _F> using __OctaMapReturnType namespace detail {
= decltype(declval<_F>()(octa::declval<octa::RangeReference<_R>>())); template<typename _R, typename _F> using MapReturnType
= decltype(declval<_F>()(octa::declval<octa::RangeReference<_R>>()));
}
template<typename _R, typename _F> template<typename _R, typename _F>
MapRange<_R, __OctaMapReturnType<_R, _F>> map(_R __range, _F __func) { MapRange<_R, octa::detail::MapReturnType<_R, _F>> map(_R __range,
return octa::MapRange<_R, __OctaMapReturnType<_R, _F>>(__range, __func); _F __func) {
return octa::MapRange<_R, octa::detail::MapReturnType<_R, _F>>(__range,
__func);
} }
template<typename _T> template<typename _T>