more complete relational operator sets + add lexicographical comparison

This commit is contained in:
q66 2015-07-11 16:07:52 +01:00
parent 4a871db249
commit a77f983015
9 changed files with 243 additions and 105 deletions

View file

@ -214,6 +214,30 @@ inline T clamp(const T &v, const U &lo, const U &hi, C compare) {
return octa::max(T(lo), octa::min(v, T(hi), compare), compare); return octa::max(T(lo), octa::min(v, T(hi), compare), compare);
} }
/* lexicographical compare */
template<typename R1, typename R2>
bool lexicographical_compare(R1 range1, R2 range2) {
while (!range1.empty() && !range2.empty()) {
if (range1.front() < range2.front()) return true;
if (range2.front() < range1.front()) return false;
range1.pop_front();
range2.pop_front();
}
return (range1.empty() && !range2.empty());
}
template<typename R1, typename R2, typename C>
bool lexicographical_compare(R1 range1, R2 range2, C compare) {
while (!range1.empty() && !range2.empty()) {
if (compare(range1.front(), range2.front())) return true;
if (compare(range2.front(), range1.front())) return false;
range1.pop_front();
range2.pop_front();
}
return (range1.empty() && !range2.empty());
}
/* algos that don't change the range */ /* algos that don't change the range */
template<typename R, typename F> template<typename R, typename F>

View file

@ -99,6 +99,36 @@ TupleElement<I, Array<T, N>> &&get(Array<T, N> &&a) {
return a[I]; return a[I];
} }
template<typename T, Size N>
inline bool operator==(const Array<T, N> &x, const Array<T, N> &y) {
return equal(x.iter(), y.iter());
}
template<typename T, Size N>
inline bool operator!=(const Array<T, N> &x, const Array<T, N> &y) {
return !(x == y);
}
template<typename T, Size N>
inline bool operator<(const Array<T, N> &x, const Array<T, N> &y) {
return lexicographical_compare(x.iter(), y.iter());
}
template<typename T, Size N>
inline bool operator>(const Array<T, N> &x, const Array<T, N> &y) {
return (y < x);
}
template<typename T, Size N>
inline bool operator<=(const Array<T, N> &x, const Array<T, N> &y) {
return !(y < x);
}
template<typename T, Size N>
inline bool operator>=(const Array<T, N> &x, const Array<T, N> &y) {
return !(x < y);
}
} /* namespace octa */ } /* namespace octa */
#endif #endif

View file

@ -26,7 +26,7 @@ enum FormatFlags {
}; };
namespace detail { namespace detail {
static inline int parse_fmt_flags(const char *&fmt, int ret) { inline int parse_fmt_flags(const char *&fmt, int ret) {
while (*fmt) { while (*fmt) {
switch (*fmt) { switch (*fmt) {
case '-': ret |= FMT_FLAG_DASH; ++fmt; break; case '-': ret |= FMT_FLAG_DASH; ++fmt; break;
@ -41,7 +41,7 @@ namespace detail {
return ret; return ret;
} }
static inline Size read_digits(const char *&fmt, char *buf) { inline Size read_digits(const char *&fmt, char *buf) {
Size ret = 0; Size ret = 0;
for (; isdigit(*fmt); ++ret) for (; isdigit(*fmt); ++ret)
*buf++ = *fmt++; *buf++ = *fmt++;
@ -398,8 +398,7 @@ protected:
namespace detail { namespace detail {
template<typename R, typename T> template<typename R, typename T>
static inline Ptrdiff write_u(R &writer, const FormatSpec *fl, inline Ptrdiff write_u(R &writer, const FormatSpec *fl, bool neg, T val) {
bool neg, T val) {
char buf[20]; char buf[20];
Ptrdiff r = 0; Ptrdiff r = 0;
Size n = 0; Size n = 0;
@ -460,16 +459,14 @@ namespace detail {
using FmtRangeTest = decltype(test_fmt_range<T>(0)); using FmtRangeTest = decltype(test_fmt_range<T>(0));
template<typename R, typename T> template<typename R, typename T>
static inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc, inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc, bool,
bool, const char *fmt, const char *fmt, const T &item) {
const T &item) {
return format_impl(writer, fmtn, esc, fmt, item); return format_impl(writer, fmtn, esc, fmt, item);
} }
template<typename R, typename T, typename U> template<typename R, typename T, typename U>
static inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc, inline Ptrdiff format_ritem(R &writer, Size &fmtn, bool esc,
bool expandval, bool expandval, const char *fmt,
const char *fmt,
const Pair<T, U> &pair) { const Pair<T, U> &pair) {
if (expandval) { if (expandval) {
return format_impl(writer, fmtn, esc, fmt, pair.first, return format_impl(writer, fmtn, esc, fmt, pair.first,
@ -479,12 +476,12 @@ namespace detail {
} }
template<typename R, typename T> template<typename R, typename T>
static inline Ptrdiff write_range(R &writer, const FormatSpec *fl, inline Ptrdiff write_range(R &writer, const FormatSpec *fl,
bool escape, bool expandval, bool escape, bool expandval,
const char *sep, Size seplen, const char *sep, Size seplen,
const T &val, const T &val,
EnableIf<FmtRangeTest<T>::value, EnableIf<FmtRangeTest<T>::value, bool>
bool> = true) { = true) {
auto range = octa::iter(val); auto range = octa::iter(val);
if (range.empty()) return 0; if (range.empty()) return 0;
Ptrdiff ret = 0; Ptrdiff ret = 0;
@ -510,10 +507,10 @@ namespace detail {
} }
template<typename R, typename T> template<typename R, typename T>
static inline Ptrdiff write_range(R &, const FormatSpec *, bool, bool, inline Ptrdiff write_range(R &, const FormatSpec *, bool, bool,
const char *, Size, const T &, const char *, Size, const T &,
EnableIf<!FmtRangeTest<T>::value, EnableIf<!FmtRangeTest<T>::value, bool>
bool> = true) { = true) {
assert(false && "invalid value for ranged format"); assert(false && "invalid value for ranged format");
return -1; return -1;
} }
@ -539,7 +536,7 @@ namespace detail {
nullptr, "\\\'" nullptr, "\\\'"
}; };
static inline const char *escape_fmt_char(char v, char quote) { inline const char *escape_fmt_char(char v, char quote) {
if ((v >= 0 && v < 0x20) || (v == quote)) { if ((v >= 0 && v < 0x20) || (v == quote)) {
return fmt_escapes[Size(v)]; return fmt_escapes[Size(v)];
} else if (v == 0x7F) { } else if (v == 0x7F) {
@ -548,7 +545,7 @@ namespace detail {
return nullptr; return nullptr;
} }
static inline String escape_fmt_str(const char *val) { inline String escape_fmt_str(const char *val) {
String ret; String ret;
ret.push('"'); ret.push('"');
while (*val) { while (*val) {
@ -808,7 +805,7 @@ namespace detail {
}; };
template<typename R, typename ...A> template<typename R, typename ...A>
static inline Ptrdiff format_impl(R &writer, Size &fmtn, bool escape, inline Ptrdiff format_impl(R &writer, Size &fmtn, bool escape,
const char *fmt, const A &...args) { const char *fmt, const A &...args) {
Size argidx = 1, retn = 0, twr = 0; Size argidx = 1, retn = 0, twr = 0;
Ptrdiff written = 0; Ptrdiff written = 0;
@ -871,8 +868,7 @@ namespace detail {
} }
template<typename R, typename ...A> template<typename R, typename ...A>
static inline Ptrdiff format_impl(R &writer, Size &fmtn, bool, inline Ptrdiff format_impl(R &writer, Size &fmtn, bool, const char *fmt) {
const char *fmt) {
Size written = 0; Size written = 0;
detail::WriteSpec spec(fmt, false); detail::WriteSpec spec(fmt, false);
if (spec.read_until_spec(writer, &written)) return -1; if (spec.read_until_spec(writer, &written)) return -1;
@ -882,7 +878,7 @@ namespace detail {
} /* namespace detail */ } /* namespace detail */
template<typename R, typename ...A> template<typename R, typename ...A>
static inline Ptrdiff format(R &&writer, Size &fmtn, const char *fmt, inline Ptrdiff format(R &&writer, Size &fmtn, const char *fmt,
const A &...args) { const A &...args) {
return detail::format_impl(writer, fmtn, false, fmt, args...); return detail::format_impl(writer, fmtn, false, fmt, args...);
} }

View file

@ -218,7 +218,7 @@ OCTA_HASH_BASIC(Wchar)
#undef OCTA_HASH_BASIC #undef OCTA_HASH_BASIC
namespace detail { namespace detail {
static inline Size mem_hash(const void *p, Size l) { inline Size mem_hash(const void *p, Size l) {
const byte *d = (const byte *)p; const byte *d = (const byte *)p;
Size h = 5381; Size h = 5381;
for (Size i = 0; i < l; ++i) h = ((h << 5) + h) ^ d[i]; for (Size i = 0; i < l; ++i) h = ((h << 5) + h) ^ d[i];

View file

@ -142,44 +142,44 @@ static FileStream err(::stderr);
/* no need to call anything from FileStream, prefer simple calls... */ /* no need to call anything from FileStream, prefer simple calls... */
static inline void write(const char *s) { inline void write(const char *s) {
fputs(s, ::stdout); fputs(s, ::stdout);
} }
template<typename A> template<typename A>
static inline void write(const AnyString<A> &s) { inline void write(const AnyString<A> &s) {
fwrite(s.data(), 1, s.size(), ::stdout); fwrite(s.data(), 1, s.size(), ::stdout);
} }
template<typename T> template<typename T>
static inline void write(const T &v) { inline void write(const T &v) {
write(octa::to_string(v)); write(octa::to_string(v));
} }
template<typename T, typename ...A> template<typename T, typename ...A>
static inline void write(const T &v, const A &...args) { inline void write(const T &v, const A &...args) {
write(v); write(v);
write(args...); write(args...);
} }
static inline void writeln(const char *s) { inline void writeln(const char *s) {
write(s); write(s);
putc('\n', ::stdout); putc('\n', ::stdout);
} }
template<typename A> template<typename A>
static inline void writeln(const AnyString<A> &s) { inline void writeln(const AnyString<A> &s) {
write(s); write(s);
putc('\n', ::stdout); putc('\n', ::stdout);
} }
template<typename T> template<typename T>
static inline void writeln(const T &v) { inline void writeln(const T &v) {
writeln(octa::to_string(v)); writeln(octa::to_string(v));
} }
template<typename T, typename ...A> template<typename T, typename ...A>
static inline void writeln(const T &v, const A &...args) { inline void writeln(const T &v, const A &...args) {
write(v); write(v);
write(args...); write(args...);
putc('\n', ::stdout); putc('\n', ::stdout);
@ -197,7 +197,7 @@ namespace detail {
} }
template<typename ...A> template<typename ...A>
static inline void writef(const char *fmt, const A &...args) { inline void writef(const char *fmt, const A &...args) {
char buf[512]; char buf[512];
Ptrdiff need = format(detail::FormatOutRange<sizeof(buf)>(buf), Ptrdiff need = format(detail::FormatOutRange<sizeof(buf)>(buf),
fmt, args...); fmt, args...);
@ -213,19 +213,19 @@ static inline void writef(const char *fmt, const A &...args) {
} }
template<typename AL, typename ...A> template<typename AL, typename ...A>
static inline void writef(const AnyString<AL> &fmt, inline void writef(const AnyString<AL> &fmt,
const A &...args) { const A &...args) {
writef(fmt.data(), args...); writef(fmt.data(), args...);
} }
template<typename ...A> template<typename ...A>
static inline void writefln(const char *fmt, const A &...args) { inline void writefln(const char *fmt, const A &...args) {
writef(fmt, args...); writef(fmt, args...);
putc('\n', ::stdout); putc('\n', ::stdout);
} }
template<typename AL, typename ...A> template<typename AL, typename ...A>
static inline void writefln(const AnyString<AL> &fmt, inline void writefln(const AnyString<AL> &fmt,
const A &...args) { const A &...args) {
writef(fmt, args...); writef(fmt, args...);
putc('\n', ::stdout); putc('\n', ::stdout);

View file

@ -261,163 +261,163 @@ public:
/* maybe vs maybe */ /* maybe vs maybe */
template<typename T> template<typename T>
static inline constexpr bool operator==(const Maybe<T> &a, const Maybe<T> &b) { inline constexpr bool operator==(const Maybe<T> &a, const Maybe<T> &b) {
return (bool(a) != bool(b)) ? false : (!bool(a) ? true : (*a == *b)); return (bool(a) != bool(b)) ? false : (!bool(a) ? true : (*a == *b));
} }
template<typename T> template<typename T>
static inline constexpr bool operator!=(const Maybe<T> &a, const Maybe<T> &b) { inline constexpr bool operator!=(const Maybe<T> &a, const Maybe<T> &b) {
return !(a == b); return !(a == b);
} }
template<typename T> template<typename T>
static inline constexpr bool operator<(const Maybe<T> &a, const Maybe<T> &b) { inline constexpr bool operator<(const Maybe<T> &a, const Maybe<T> &b) {
return !bool(b) ? false : (!bool(a) ? true : (*a < *b)); return !bool(b) ? false : (!bool(a) ? true : (*a < *b));
} }
template<typename T> template<typename T>
static inline constexpr bool operator>(const Maybe<T> &a, const Maybe<T> &b) { inline constexpr bool operator>(const Maybe<T> &a, const Maybe<T> &b) {
return b < a; return b < a;
} }
template<typename T> template<typename T>
static inline constexpr bool operator<=(const Maybe<T> &a, const Maybe<T> &b) { inline constexpr bool operator<=(const Maybe<T> &a, const Maybe<T> &b) {
return !(b < a); return !(b < a);
} }
template<typename T> template<typename T>
static inline constexpr bool operator>=(const Maybe<T> &a, const Maybe<T> &b) { inline constexpr bool operator>=(const Maybe<T> &a, const Maybe<T> &b) {
return !(a < b); return !(a < b);
} }
/* maybe vs nothing */ /* maybe vs nothing */
template<typename T> template<typename T>
static inline constexpr bool operator==(const Maybe<T> &v, Nothing) { inline constexpr bool operator==(const Maybe<T> &v, Nothing) {
return !bool(v); return !bool(v);
} }
template<typename T> template<typename T>
static inline constexpr bool operator==(Nothing, const Maybe<T> &v) { inline constexpr bool operator==(Nothing, const Maybe<T> &v) {
return !bool(v); return !bool(v);
} }
template<typename T> template<typename T>
static inline constexpr bool operator!=(const Maybe<T> &v, Nothing) { inline constexpr bool operator!=(const Maybe<T> &v, Nothing) {
return bool(v); return bool(v);
} }
template<typename T> template<typename T>
static inline constexpr bool operator!=(Nothing, const Maybe<T> &v) { inline constexpr bool operator!=(Nothing, const Maybe<T> &v) {
return bool(v); return bool(v);
} }
template<typename T> template<typename T>
static inline constexpr bool operator<(const Maybe<T> &, Nothing) { inline constexpr bool operator<(const Maybe<T> &, Nothing) {
return false; return false;
} }
template<typename T> template<typename T>
static inline constexpr bool operator<(Nothing, const Maybe<T> &v) { inline constexpr bool operator<(Nothing, const Maybe<T> &v) {
return bool(v); return bool(v);
} }
template<typename T> template<typename T>
static inline constexpr bool operator<=(const Maybe<T> &v, Nothing) { inline constexpr bool operator<=(const Maybe<T> &v, Nothing) {
return !bool(v); return !bool(v);
} }
template<typename T> template<typename T>
static inline constexpr bool operator<=(Nothing, const Maybe<T> &) { inline constexpr bool operator<=(Nothing, const Maybe<T> &) {
return true; return true;
} }
template<typename T> template<typename T>
static inline constexpr bool operator>(const Maybe<T> &v, Nothing) { inline constexpr bool operator>(const Maybe<T> &v, Nothing) {
return bool(v); return bool(v);
} }
template<typename T> template<typename T>
static inline constexpr bool operator>(Nothing, const Maybe<T> &) { inline constexpr bool operator>(Nothing, const Maybe<T> &) {
return false; return false;
} }
template<typename T> template<typename T>
static inline constexpr bool operator>=(const Maybe<T> &, Nothing) { inline constexpr bool operator>=(const Maybe<T> &, Nothing) {
return true; return true;
} }
template<typename T> template<typename T>
static inline constexpr bool operator>=(Nothing, const Maybe<T> &v) { inline constexpr bool operator>=(Nothing, const Maybe<T> &v) {
return !bool(v); return !bool(v);
} }
/* maybe vs T */ /* maybe vs T */
template<typename T> template<typename T>
static inline constexpr bool operator==(const Maybe<T> &a, const T &b) { inline constexpr bool operator==(const Maybe<T> &a, const T &b) {
return bool(a) ? (*a == b) : false; return bool(a) ? (*a == b) : false;
} }
template<typename T> template<typename T>
static inline constexpr bool operator==(const T &b, const Maybe<T> &a) { inline constexpr bool operator==(const T &b, const Maybe<T> &a) {
return bool(a) ? (*a == b) : false; return bool(a) ? (*a == b) : false;
} }
template<typename T> template<typename T>
static inline constexpr bool operator!=(const Maybe<T> &a, const T &b) { inline constexpr bool operator!=(const Maybe<T> &a, const T &b) {
return bool(a) ? !(*a == b) : true; return bool(a) ? !(*a == b) : true;
} }
template<typename T> template<typename T>
static inline constexpr bool operator!=(const T &b, const Maybe<T> &a) { inline constexpr bool operator!=(const T &b, const Maybe<T> &a) {
return bool(a) ? !(*a == b) : true; return bool(a) ? !(*a == b) : true;
} }
template<typename T> template<typename T>
static inline constexpr bool operator<(const Maybe<T> &a, const T &b) { inline constexpr bool operator<(const Maybe<T> &a, const T &b) {
return bool(a) ? Less<T>()(*a, b) : true; return bool(a) ? Less<T>()(*a, b) : true;
} }
template<typename T> template<typename T>
static inline constexpr bool operator<(const T &b, const Maybe<T> &a) { inline constexpr bool operator<(const T &b, const Maybe<T> &a) {
return bool(a) ? Less<T>()(b, *a) : false; return bool(a) ? Less<T>()(b, *a) : false;
} }
template<typename T> template<typename T>
static inline constexpr bool operator<=(const Maybe<T> &a, const T &b) { inline constexpr bool operator<=(const Maybe<T> &a, const T &b) {
return !(a > b); return !(a > b);
} }
template<typename T> template<typename T>
static inline constexpr bool operator<=(const T &b, const Maybe<T> &a) { inline constexpr bool operator<=(const T &b, const Maybe<T> &a) {
return !(b > a); return !(b > a);
} }
template<typename T> template<typename T>
static inline constexpr bool operator>(const Maybe<T> &a, const T &b) { inline constexpr bool operator>(const Maybe<T> &a, const T &b) {
return bool(a) ? (b < a) : true; return bool(a) ? (b < a) : true;
} }
template<typename T> template<typename T>
static inline constexpr bool operator>(const T &b, const Maybe<T> &a) { inline constexpr bool operator>(const T &b, const Maybe<T> &a) {
return bool(a) ? (a < b) : true; return bool(a) ? (a < b) : true;
} }
template<typename T> template<typename T>
static inline constexpr bool operator>=(const Maybe<T> &a, const T &b) { inline constexpr bool operator>=(const Maybe<T> &a, const T &b) {
return !(a < b); return !(a < b);
} }
template<typename T> template<typename T>
static inline constexpr bool operator>=(const T &b, const Maybe<T> &a) { inline constexpr bool operator>=(const T &b, const Maybe<T> &a) {
return !(b < a); return !(b < a);
} }
/* make maybe */ /* make maybe */
template<typename T> template<typename T>
constexpr Maybe<Decay<T>> make_maybe(T &&v) { inline constexpr Maybe<Decay<T>> make_maybe(T &&v) {
return Maybe<Decay<T>>(forward<T>(v)); return Maybe<Decay<T>>(forward<T>(v));
} }

View file

@ -76,40 +76,40 @@ namespace octa {
#if defined(OCTA_TOOLCHAIN_GNU) #if defined(OCTA_TOOLCHAIN_GNU)
/* using gcc/clang builtins */ /* using gcc/clang builtins */
static inline uint16_t endian_swap16(uint16_t x) { inline uint16_t endian_swap16(uint16_t x) {
return __builtin_bswap16(x); return __builtin_bswap16(x);
} }
static inline uint32_t endian_swap32(uint32_t x) { inline uint32_t endian_swap32(uint32_t x) {
return __builtin_bswap32(x); return __builtin_bswap32(x);
} }
static inline uint64_t endian_swap64(uint64_t x) { inline uint64_t endian_swap64(uint64_t x) {
return __builtin_bswap64(x); return __builtin_bswap64(x);
} }
#elif defined(OCTA_TOOLCHAIN_MSVC) #elif defined(OCTA_TOOLCHAIN_MSVC)
/* using msvc builtins */ /* using msvc builtins */
static inline uint16_t endian_swap16(uint16_t x) { inline uint16_t endian_swap16(uint16_t x) {
return _byteswap_ushort(x); return _byteswap_ushort(x);
} }
static inline uint32_t endian_swap32(uint32_t x) { inline uint32_t endian_swap32(uint32_t x) {
/* win64 is llp64 */ /* win64 is llp64 */
return _byteswap_ulong(x); return _byteswap_ulong(x);
} }
static inline uint64_t endian_swap64(uint64_t x) { inline uint64_t endian_swap64(uint64_t x) {
return _byteswap_uint64(x); return _byteswap_uint64(x);
} }
#else #else
/* fallback */ /* fallback */
static inline uint16_t endian_swap16(uint16_t x) { inline uint16_t endian_swap16(uint16_t x) {
return (x << 8) | (x >> 8); return (x << 8) | (x >> 8);
} }
static inline uint32_t endian_swap32(uint32_t x) { inline uint32_t endian_swap32(uint32_t x) {
return (x << 24) | (x >> 24) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000); return (x << 24) | (x >> 24) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000);
} }
static inline uint64_t endian_swap64(uint64_t x) { inline uint64_t endian_swap64(uint64_t x) {
return endian_swap32(uint32_t(x >> 32)) | (uint64_t(endian_swap32(uint32_t(x))) << 32); return endian_swap32(uint32_t(x >> 32)) | (uint64_t(endian_swap32(uint32_t(x))) << 32);
} }

View file

@ -352,35 +352,87 @@ using ConstStringRange = StringRangeBase<const char>;
template<typename A> using AnyString = StringBase<char, A>; template<typename A> using AnyString = StringBase<char, A>;
template<typename T, typename A> template<typename T, typename A>
static inline bool operator==(const StringBase<T, A> &lhs, inline bool operator==(const StringBase<T, A> &lhs,
const StringBase<T, A> &rhs) { const StringBase<T, A> &rhs) {
return !lhs.compare(rhs); return !lhs.compare(rhs);
} }
template<typename T, typename A> template<typename T, typename A>
static inline bool operator==(const StringBase<T, A> &lhs, inline bool operator==(const StringBase<T, A> &lhs, const char *rhs) {
const char *rhs) {
return !lhs.compare(rhs); return !lhs.compare(rhs);
} }
template<typename T, typename A> template<typename T, typename A>
static inline bool operator==(const char *lhs, inline bool operator==(const char *lhs, const StringBase<T, A> &rhs) {
const StringBase<T, A> &rhs) {
return !rhs.compare(lhs); return !rhs.compare(lhs);
} }
template<typename T, typename A> template<typename T, typename A>
static inline bool operator!=(const StringBase<T, A> &lhs, inline bool operator!=(const StringBase<T, A> &lhs,
const StringBase<T, A> &rhs) { const StringBase<T, A> &rhs) {
return !!lhs.compare(rhs); return !(lhs == rhs);
} }
template<typename T, typename A> template<typename T, typename A>
static inline bool operator!=(const StringBase<T, A> &lhs, inline bool operator!=(const StringBase<T, A> &lhs, const char *rhs) {
const char *rhs) { return !(lhs == rhs);
return !!lhs.compare(rhs);
} }
template<typename T, typename A> template<typename T, typename A>
static inline bool operator!=(const char *lhs, inline bool operator!=(const char *lhs, const StringBase<T, A> &rhs) {
return !(rhs == lhs);
}
template<typename T, typename A>
inline bool operator<(const StringBase<T, A> &lhs,
const StringBase<T, A> &rhs) { const StringBase<T, A> &rhs) {
return !!rhs.compare(lhs); return lhs.compare(rhs) < 0;
}
template<typename T, typename A>
inline bool operator<(const StringBase<T, A> &lhs, const char *rhs) {
return lhs.compare(rhs) < 0;
}
template<typename T, typename A>
inline bool operator<(const char *lhs, const StringBase<T, A> &rhs) {
return rhs.compare(lhs) > 0;
}
template<typename T, typename A>
inline bool operator>(const StringBase<T, A> &lhs,
const StringBase<T, A> &rhs) {
return rhs < lhs;
}
template<typename T, typename A>
inline bool operator>(const StringBase<T, A> &lhs, const char *rhs) {
return rhs < lhs;
}
template<typename T, typename A>
inline bool operator>(const char *lhs, const StringBase<T, A> &rhs) {
return rhs < lhs;
}
template<typename T, typename A>
inline bool operator<=(const StringBase<T, A> &lhs,
const StringBase<T, A> &rhs) {
return !(rhs < lhs);
}
template<typename T, typename A>
inline bool operator<=(const StringBase<T, A> &lhs, const char *rhs) {
return !(rhs < lhs);
}
template<typename T, typename A>
inline bool operator<=(const char *lhs, const StringBase<T, A> &rhs) {
return !(rhs < lhs);
}
template<typename T, typename A>
inline bool operator>=(const StringBase<T, A> &lhs,
const StringBase<T, A> &rhs) {
return !(lhs < rhs);
}
template<typename T, typename A>
inline bool operator>=(const StringBase<T, A> &lhs, const char *rhs) {
return !(lhs < rhs);
}
template<typename T, typename A>
inline bool operator>=(const char *lhs, const StringBase<T, A> &rhs) {
return !(lhs < rhs);
} }
template<typename T, typename F, typename S = const char *, template<typename T, typename F, typename S = const char *,

View file

@ -16,26 +16,26 @@ namespace octa {
/* move */ /* move */
template<typename T> template<typename T>
static inline constexpr RemoveReference<T> &&move(T &&v) { inline constexpr RemoveReference<T> &&move(T &&v) {
return static_cast<RemoveReference<T> &&>(v); return static_cast<RemoveReference<T> &&>(v);
} }
/* forward */ /* forward */
template<typename T> template<typename T>
static inline constexpr T &&forward(RemoveReference<T> &v) { inline constexpr T &&forward(RemoveReference<T> &v) {
return static_cast<T &&>(v); return static_cast<T &&>(v);
} }
template<typename T> template<typename T>
static inline constexpr T &&forward(RemoveReference<T> &&v) { inline constexpr T &&forward(RemoveReference<T> &&v) {
return static_cast<T &&>(v); return static_cast<T &&>(v);
} }
/* exchange */ /* exchange */
template<typename T, typename U = T> template<typename T, typename U = T>
T exchange(T &v, U &&nv) { inline T exchange(T &v, U &&nv) {
T old = move(v); T old = move(v);
v = forward<U>(nv); v = forward<U>(nv);
return old; return old;
@ -71,11 +71,11 @@ namespace detail {
} }
} }
template<typename T> void swap(T &a, T &b) { template<typename T> inline void swap(T &a, T &b) {
detail::swap(a, b); detail::swap(a, b);
} }
template<typename T, Size N> void swap(T (&a)[N], T (&b)[N]) { template<typename T, Size N> inline void swap(T (&a)[N], T (&b)[N]) {
for (Size i = 0; i < N; ++i) { for (Size i = 0; i < N; ++i) {
octa::swap(a[i], b[i]); octa::swap(a[i], b[i]);
} }
@ -159,7 +159,7 @@ namespace detail {
} /* namespace detail */ } /* namespace detail */
template<typename T, typename U> template<typename T, typename U>
Pair<typename detail::MakePairRet<T>::Type, inline Pair<typename detail::MakePairRet<T>::Type,
typename detail::MakePairRet<U>::Type typename detail::MakePairRet<U>::Type
> make_pair(T &&a, U &&b) { > make_pair(T &&a, U &&b) {
return Pair<typename detail::MakePairRet<T>::Type, return Pair<typename detail::MakePairRet<T>::Type,
@ -167,6 +167,42 @@ Pair<typename detail::MakePairRet<T>::Type,
>(forward<T>(a), forward<U>(b));; >(forward<T>(a), forward<U>(b));;
} }
template<typename T, typename U>
inline constexpr bool operator==(const Pair<T, U> &x, const Pair<T, U> &y) {
return (x.first == y.first) && (x.second == y.second);
}
template<typename T, typename U>
inline constexpr bool operator!=(const Pair<T, U> &x, const Pair<T, U> &y) {
return (x.first != y.first) || (x.second != y.second);
}
template<typename T, typename U>
inline constexpr bool operator<(const Pair<T, U> &x, const Pair<T, U> &y) {
return (x.first < y.first)
? true
: ((y.first < x.first)
? false
: ((x.second < y.second)
? true
: false));
}
template<typename T, typename U>
inline constexpr bool operator>(const Pair<T, U> &x, const Pair<T, U> &y) {
return (y < x);
}
template<typename T, typename U>
inline constexpr bool operator<=(const Pair<T, U> &x, const Pair<T, U> &y) {
return !(y < x);
}
template<typename T, typename U>
inline constexpr bool operator>=(const Pair<T, U> &x, const Pair<T, U> &y) {
return !(x < y);
}
template<typename T, typename U> template<typename T, typename U>
struct TupleSize<Pair<T, U>>: IntegralConstant<Size, 2> {}; struct TupleSize<Pair<T, U>>: IntegralConstant<Size, 2> {};