ultimatepp/uppsrc/Core/Range.h
2025-04-20 13:51:25 +02:00

219 lines
No EOL
8.2 KiB
C++

template <class T>
T *DeclPtr__();
template <class Range>
using ValueTypeOf = typename std::remove_reference<decltype(*DeclPtr__<typename std::remove_reference<Range>::type>()->begin())>::type;
template <class Range>
using IteratorOf = decltype(DeclPtr__<typename std::remove_reference<Range>::type>()->begin());
template <class Range>
using ConstIteratorOf = decltype(DeclPtr__<const typename std::remove_reference<Range>::type>()->begin());
template <class I>
class SubRangeClass {
I l;
int count;
public:
typedef typename std::remove_reference<decltype(*l)>::type value_type;
int GetCount() const { return count; }
SubRangeClass& Write() { return *this; }
value_type& operator[](int i) { ASSERT(i >= 0 && i < count); return l[i]; }
const value_type& operator[](int i) const { ASSERT(i >= 0 && i < count); return l[i]; }
I begin() const { return l; }
I end() const { return l + count; }
String ToString() const { return AsStringArray(*this); }
template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
#ifndef CPP_20
template <class B> bool operator!=(const B& b) const { return !operator==(b); }
#endif
template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
SubRangeClass(I begin, int count) : l(begin), count(count) {}
SubRangeClass(I begin, I end) : l(begin), count(int(end - begin)) {}
SubRangeClass() {} // MSC bug workaround
};
template <class I>
SubRangeClass<I> SubRange(I l, I h)
{
return SubRangeClass<I>(l, h);
}
template <class I>
SubRangeClass<I> SubRange(I l, int count)
{
return SubRangeClass<I>(l, count);
}
template <class C>
auto SubRange(C&& c, int pos, int count) -> decltype(SubRange(c.begin() + pos, count))
{
return SubRange(c.begin() + pos, count);
}
template <class C>
auto SubRangeFrom(C&& c, int pos) -> decltype(SubRange(c.begin() + pos, c.GetCount() - pos))
{
return SubRange(c.begin() + pos, c.GetCount() - pos);
}
template <class C> using SubRangeOf = decltype(SubRange(((C *)0)->begin(), ((C *)0)->end()));
template <class T>
struct ConstRangeClass {
T value;
int count;
typedef T value_type;
typedef value_type ValueType;
const value_type& operator[](int i) const { return value; }
int GetCount() const { return count; }
typedef ConstIIterator<ConstRangeClass> Iterator;
Iterator begin() const { return Iterator(*this, 0); }
Iterator end() const { return Iterator(*this, count); }
String ToString() const { return AsStringArray(*this); }
template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
#ifndef CPP_20
template <class B> bool operator!=(const B& b) const { return !operator==(b); }
#endif
template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
ConstRangeClass(const T& value, int count) : value(value), count(count) {}
ConstRangeClass(int count) : count(count) {}
ConstRangeClass() {} // MSC bug workaround
};
template <class T>
ConstRangeClass<T> ConstRange(const T& value, int count)
{
return ConstRangeClass<T>(value, count);
}
template <class T>
ConstRangeClass<T> ConstRange(int count)
{
return ConstRangeClass<T>(count);
}
template <class BaseRange>
struct ReverseRangeClass {
typename std::remove_reference<BaseRange>::type& r;
typedef ValueTypeOf<BaseRange> value_type;
typedef value_type ValueType;
const value_type& operator[](int i) const { return r[r.GetCount() - i - 1]; }
value_type& operator[](int i) { return r[r.GetCount() - i - 1]; }
int GetCount() const { return r.GetCount(); }
typedef IIterator<ReverseRangeClass> Iterator;
typedef ConstIIterator<ReverseRangeClass> ConstIterator;
ReverseRangeClass& Write() { return *this; }
ConstIterator begin() const { return ConstIterator(*this, 0); }
ConstIterator end() const { return ConstIterator(*this, r.GetCount()); }
Iterator begin() { return Iterator(*this, 0); }
Iterator end() { return Iterator(*this, r.GetCount()); }
String ToString() const { return AsStringArray(*this); }
template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
#ifndef CPP_20
template <class B> bool operator!=(const B& b) const { return !operator==(b); }
#endif
template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
ReverseRangeClass(BaseRange& r) : r(r) {}
ReverseRangeClass() {} // MSC bug workaround
};
template <class BaseRange>
ReverseRangeClass<BaseRange> ReverseRange(BaseRange&& r)
{
return ReverseRangeClass<BaseRange>(r);
}
template <class BaseRange>
struct ViewRangeClass {
typename std::remove_reference<BaseRange>::type *r;
Vector<int> ndx;
typedef ValueTypeOf<BaseRange> value_type;
typedef value_type ValueType;
const value_type& operator[](int i) const { return (*r)[ndx[i]]; }
value_type& operator[](int i) { return (*r)[ndx[i]]; }
int GetCount() const { return ndx.GetCount(); }
typedef IIterator<ViewRangeClass> Iterator;
typedef ConstIIterator<ViewRangeClass> ConstIterator;
ViewRangeClass& Write() { return *this; }
ConstIterator begin() const { return ConstIterator(*this, 0); }
ConstIterator end() const { return ConstIterator(*this, ndx.GetCount()); }
Iterator begin() { return Iterator(*this, 0); }
Iterator end() { return Iterator(*this, ndx.GetCount()); }
String ToString() const { return AsStringArray(*this); }
template <class B> bool operator==(const B& b) const { return IsEqualRange(*this, b); }
#ifndef CPP_20
template <class B> bool operator!=(const B& b) const { return !operator==(b); }
#endif
template <class B> int Compare(const B& b) const { return CompareRanges(*this, b); }
template <class B> bool operator<=(const B& x) const { return Compare(x) <= 0; }
template <class B> bool operator>=(const B& x) const { return Compare(x) >= 0; }
template <class B> bool operator<(const B& x) const { return Compare(x) < 0; }
template <class B> bool operator>(const B& x) const { return Compare(x) > 0; }
ViewRangeClass(BaseRange& r, Vector<int>&& ndx) : r(&r), ndx(pick(ndx)) {}
ViewRangeClass() {} // MSC bug workaround
};
template <class BaseRange>
ViewRangeClass<BaseRange> ViewRange(BaseRange&& r, Vector<int>&& ndx)
{
return ViewRangeClass<BaseRange>(r, pick(ndx));
}
template <class BaseRange, class Predicate>
ViewRangeClass<BaseRange> FilterRange(BaseRange&& r, Predicate p)
{
return ViewRangeClass<BaseRange>(r, FindAll(r, p));
}
template <class BaseRange, class Predicate>
ViewRangeClass<BaseRange> SortedRange(BaseRange&& r, Predicate p)
{
return ViewRangeClass<BaseRange>(r, GetSortOrder(r, p));
}
template <class BaseRange>
ViewRangeClass<BaseRange> SortedRange(BaseRange&& r)
{
return ViewRangeClass<BaseRange>(r, GetSortOrder(r));
}