define size_type for ranges
parent
d7778cf259
commit
e98b8946ae
|
@ -14,6 +14,9 @@
|
|||
#include "octa/initializer_list.h"
|
||||
|
||||
namespace octa {
|
||||
template<typename T>
|
||||
using __OctaRangeSize = typename RangeTraits<T>::size_type;
|
||||
|
||||
/* partitioning */
|
||||
|
||||
template<typename R, typename U>
|
||||
|
@ -40,9 +43,9 @@ namespace octa {
|
|||
|
||||
template<typename R, typename C>
|
||||
void insertion_sort(R range, C compare) {
|
||||
size_t rlen = range.length();
|
||||
for (size_t i = 1; i < rlen; ++i) {
|
||||
size_t j = i, v = range[i];
|
||||
__OctaRangeSize<R> rlen = range.length();
|
||||
for (__OctaRangeSize<R> i = 1; i < rlen; ++i) {
|
||||
__OctaRangeSize<R> j = i, v = range[i];
|
||||
while (j > 0 && !compare(range[j - 1], v)) {
|
||||
range[j] = range[j - 1];
|
||||
--j;
|
||||
|
@ -66,11 +69,12 @@ namespace octa {
|
|||
};
|
||||
|
||||
template<typename R, typename C>
|
||||
void __octa_hs_sift_down(R range, size_t s, size_t e, C compare) {
|
||||
size_t r = s;
|
||||
void __octa_hs_sift_down(R range, __OctaRangeSize<R> s,
|
||||
__OctaRangeSize<R> e, C compare) {
|
||||
__OctaRangeSize<R> r = s;
|
||||
while ((r * 2 + 1) <= e) {
|
||||
size_t ch = r * 2 + 1;
|
||||
size_t sw = r;
|
||||
__OctaRangeSize<R> ch = r * 2 + 1;
|
||||
__OctaRangeSize<R> sw = r;
|
||||
if (compare(range[sw], range[ch]))
|
||||
sw = ch;
|
||||
if (((ch + 1) <= e) && compare(range[sw], range[ch + 1]))
|
||||
|
@ -84,13 +88,13 @@ namespace octa {
|
|||
|
||||
template<typename R, typename C>
|
||||
void __octa_heapsort(R range, C compare) {
|
||||
size_t len = range.length();
|
||||
size_t st = (len - 2) / 2;
|
||||
__OctaRangeSize<R> len = range.length();
|
||||
__OctaRangeSize<R> st = (len - 2) / 2;
|
||||
for (;;) {
|
||||
__octa_hs_sift_down(range, st, len - 1, compare);
|
||||
if (st-- == 0) break;
|
||||
}
|
||||
size_t e = len - 1;
|
||||
__OctaRangeSize<R> e = len - 1;
|
||||
while (e > 0) {
|
||||
swap(range[e], range[0]);
|
||||
--e;
|
||||
|
@ -99,7 +103,7 @@ namespace octa {
|
|||
}
|
||||
|
||||
template<typename R, typename C>
|
||||
void __octa_introloop(R range, C compare, size_t depth) {
|
||||
void __octa_introloop(R range, C compare, __OctaRangeSize<R> depth) {
|
||||
if (range.length() <= 10) {
|
||||
insertion_sort(range, compare);
|
||||
return;
|
||||
|
@ -119,7 +123,7 @@ namespace octa {
|
|||
|
||||
template<typename R, typename C>
|
||||
void __octa_introsort(R range, C compare) {
|
||||
__octa_introloop(range, compare, size_t(2
|
||||
__octa_introloop(range, compare, __OctaRangeSize<R>(2
|
||||
* (log(range.length()) / log(2))));
|
||||
}
|
||||
|
||||
|
@ -273,8 +277,8 @@ namespace octa {
|
|||
}
|
||||
|
||||
template<typename R, typename T>
|
||||
size_t count(R range, const T &v) {
|
||||
size_t ret = 0;
|
||||
__OctaRangeSize<R> count(R range, const T &v) {
|
||||
__OctaRangeSize<R> ret = 0;
|
||||
for (; !range.empty(); range.pop_first())
|
||||
if (range.first() == v)
|
||||
++ret;
|
||||
|
@ -282,8 +286,8 @@ namespace octa {
|
|||
}
|
||||
|
||||
template<typename R, typename P>
|
||||
size_t count_if(R range, P pred) {
|
||||
size_t ret = 0;
|
||||
__OctaRangeSize<R> count_if(R range, P pred) {
|
||||
__OctaRangeSize<R> ret = 0;
|
||||
for (; !range.empty(); range.pop_first())
|
||||
if (pred(range.first()))
|
||||
++ret;
|
||||
|
@ -291,8 +295,8 @@ namespace octa {
|
|||
}
|
||||
|
||||
template<typename R, typename P>
|
||||
size_t count_if_not(R range, P pred) {
|
||||
size_t ret = 0;
|
||||
__OctaRangeSize<R> count_if_not(R range, P pred) {
|
||||
__OctaRangeSize<R> ret = 0;
|
||||
for (; !range.empty(); range.pop_first())
|
||||
if (!pred(range.first()))
|
||||
++ret;
|
||||
|
|
95
octa/range.h
95
octa/range.h
|
@ -21,6 +21,7 @@ namespace octa {
|
|||
template<typename T>
|
||||
struct RangeTraits {
|
||||
typedef typename T::range_category range_category;
|
||||
typedef typename T::size_type size_type;
|
||||
typedef typename T::value_type value_type;
|
||||
typedef typename T::reference reference;
|
||||
};
|
||||
|
@ -44,9 +45,11 @@ namespace octa {
|
|||
T p_range;
|
||||
};
|
||||
|
||||
template<typename B, typename C, typename V, typename R = V &>
|
||||
struct InputRangeBase {
|
||||
template<typename B, typename C, typename V, typename R = V &,
|
||||
typename S = size_t
|
||||
> struct InputRangeBase {
|
||||
typedef C range_category;
|
||||
typedef S size_type;
|
||||
typedef V value_type;
|
||||
typedef R reference;
|
||||
|
||||
|
@ -58,9 +61,10 @@ namespace octa {
|
|||
}
|
||||
};
|
||||
|
||||
template<typename V, typename R = V &>
|
||||
template<typename V, typename R = V &, typename S = size_t>
|
||||
struct OutputRangeBase {
|
||||
typedef OutputRange range_category;
|
||||
typedef S size_type;
|
||||
typedef V value_type;
|
||||
typedef R reference;
|
||||
};
|
||||
|
@ -69,8 +73,14 @@ namespace octa {
|
|||
struct ReverseRange: InputRangeBase<ReverseRange<T>,
|
||||
typename RangeTraits<T>::range_category,
|
||||
typename RangeTraits<T>::value_type,
|
||||
typename RangeTraits<T>::reference
|
||||
typename RangeTraits<T>::reference,
|
||||
typename RangeTraits<T>::size_type
|
||||
> {
|
||||
private:
|
||||
typedef typename RangeTraits<T>::reference r_ref;
|
||||
typedef typename RangeTraits<T>::size_type r_size;
|
||||
|
||||
public:
|
||||
ReverseRange(): p_range() {}
|
||||
ReverseRange(const T &range): p_range(range) {}
|
||||
ReverseRange(const ReverseRange &it): p_range(it.p_range) {}
|
||||
|
@ -93,8 +103,9 @@ namespace octa {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool empty () const { return p_range.empty (); }
|
||||
size_t length() const { return p_range.length(); }
|
||||
bool empty() const { return p_range.empty(); }
|
||||
|
||||
r_size length() const { return p_range.length(); }
|
||||
|
||||
void pop_first() { p_range.pop_last (); }
|
||||
void pop_last () { p_range.pop_first(); }
|
||||
|
@ -106,21 +117,21 @@ namespace octa {
|
|||
return p_range != v.p_range;
|
||||
}
|
||||
|
||||
typename RangeTraits<T>::reference first() { return p_range.last(); }
|
||||
typename RangeTraits<T>::reference first() const { return p_range.last(); }
|
||||
r_ref first() { return p_range.last(); }
|
||||
r_ref first() const { return p_range.last(); }
|
||||
|
||||
typename RangeTraits<T>::reference last() { return p_range.first(); }
|
||||
typename RangeTraits<T>::reference last() const { return p_range.first(); }
|
||||
r_ref last() { return p_range.first(); }
|
||||
r_ref last() const { return p_range.first(); }
|
||||
|
||||
typename RangeTraits<T>::reference operator[](size_t i) {
|
||||
r_ref operator[](r_size i) {
|
||||
return p_range[length() - i - 1];
|
||||
}
|
||||
typename RangeTraits<T>::reference operator[](size_t i) const {
|
||||
r_ref operator[](r_size i) const {
|
||||
return p_range[length() - i - 1];
|
||||
}
|
||||
|
||||
ReverseRange<T> slice(size_t start, size_t end) {
|
||||
size_t len = p_range.length();
|
||||
ReverseRange<T> slice(r_size start, r_size end) {
|
||||
r_size len = p_range.length();
|
||||
return ReverseRange<T>(p_range.slice(len - end, len - start));
|
||||
}
|
||||
|
||||
|
@ -137,8 +148,15 @@ namespace octa {
|
|||
struct MoveRange: InputRangeBase<MoveRange<T>,
|
||||
typename RangeTraits<T>::range_category,
|
||||
typename RangeTraits<T>::value_type,
|
||||
typename RangeTraits<T>::value_type &&
|
||||
typename RangeTraits<T>::value_type &&,
|
||||
typename RangeTraits<T>::size_type
|
||||
> {
|
||||
private:
|
||||
typedef typename RangeTraits<T>::value_type r_val;
|
||||
typedef typename RangeTraits<T>::value_type &&r_ref;
|
||||
typedef typename RangeTraits<T>::size_type r_size;
|
||||
|
||||
public:
|
||||
MoveRange(): p_range() {}
|
||||
MoveRange(const T &range): p_range(range) {}
|
||||
MoveRange(const MoveRange &it): p_range(it.p_range) {}
|
||||
|
@ -162,7 +180,7 @@ namespace octa {
|
|||
}
|
||||
|
||||
bool empty () const { return p_range.empty (); }
|
||||
size_t length() const { return p_range.length(); }
|
||||
r_size length() const { return p_range.length(); }
|
||||
|
||||
void pop_first() { p_range.pop_first(); }
|
||||
void pop_last () { p_range.pop_last (); }
|
||||
|
@ -174,24 +192,18 @@ namespace octa {
|
|||
return p_range != v.p_range;
|
||||
}
|
||||
|
||||
typename RangeTraits<T>::value_type &&first() {
|
||||
return move(p_range.first());
|
||||
}
|
||||
typename RangeTraits<T>::value_type &&last () {
|
||||
return move(p_range.last());
|
||||
}
|
||||
r_ref first() { return move(p_range.first()); }
|
||||
r_ref last () { return move(p_range.last()); }
|
||||
|
||||
typename RangeTraits<T>::value_type &&operator[](size_t i) {
|
||||
r_ref operator[](r_size i) {
|
||||
return move(p_range[i]);
|
||||
}
|
||||
|
||||
MoveRange<T> slice(size_t start, size_t end) {
|
||||
MoveRange<T> slice(r_size start, r_size end) {
|
||||
return MoveRange<T>(p_range.slice(start, end));
|
||||
}
|
||||
|
||||
void put(const typename RangeTraits<T>::value_type &v) {
|
||||
p_range.put(v);
|
||||
}
|
||||
void put(r_val &v) { p_range.put(v); }
|
||||
|
||||
private:
|
||||
T p_range;
|
||||
|
@ -286,17 +298,24 @@ namespace octa {
|
|||
T *p_beg, *p_end;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
template<typename T, typename S>
|
||||
struct EnumeratedValue {
|
||||
size_t index;
|
||||
T value;
|
||||
S index;
|
||||
T value;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct EnumeratedRange: InputRangeBase<EnumeratedRange<T>,
|
||||
InputRange, typename RangeTraits<T>::value_type,
|
||||
EnumeratedValue<typename RangeTraits<T>::reference>
|
||||
EnumeratedValue<typename RangeTraits<T>::reference,
|
||||
typename RangeTraits<T>::size_type>,
|
||||
typename RangeTraits<T>::size_type
|
||||
> {
|
||||
private:
|
||||
typedef typename RangeTraits<T>::reference r_ref;
|
||||
typedef typename RangeTraits<T>::size_type r_size;
|
||||
|
||||
public:
|
||||
EnumeratedRange(): p_range(), p_index(0) {}
|
||||
EnumeratedRange(const T &range): p_range(range), p_index(0) {}
|
||||
EnumeratedRange(const EnumeratedRange &it): p_range(it.p_range),
|
||||
|
@ -329,15 +348,11 @@ namespace octa {
|
|||
|
||||
void pop_first() { ++p_index; p_range.pop_first(); }
|
||||
|
||||
EnumeratedValue<typename RangeTraits<T>::reference> first() {
|
||||
return EnumeratedValue<typename RangeTraits<T>::reference> {
|
||||
p_index, p_range.first()
|
||||
};
|
||||
EnumeratedValue<r_ref, r_size> first() {
|
||||
return EnumeratedValue<r_ref, r_size> { p_index, p_range.first() };
|
||||
}
|
||||
EnumeratedValue<typename RangeTraits<T>::reference> first() const {
|
||||
return EnumeratedValue<typename RangeTraits<T>::reference> {
|
||||
p_index, p_range.first()
|
||||
};
|
||||
EnumeratedValue<r_ref, r_size> first() const {
|
||||
return EnumeratedValue<r_ref, r_size> { p_index, p_range.first() };
|
||||
}
|
||||
|
||||
bool operator==(const EnumeratedRange &v) const {
|
||||
|
@ -349,7 +364,7 @@ namespace octa {
|
|||
|
||||
private:
|
||||
T p_range;
|
||||
size_t p_index;
|
||||
r_size p_index;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
|
Loading…
Reference in New Issue