forked from OctaForge/libostd
more complete relational operator sets + add lexicographical comparison
This commit is contained in:
parent
4a871db249
commit
a77f983015
|
@ -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>
|
||||||
|
|
|
@ -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
|
|
@ -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,17 +459,15 @@ 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,
|
||||||
pair.second);
|
pair.second);
|
||||||
|
@ -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,8 +805,8 @@ 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;
|
||||||
detail::WriteSpec spec(fmt, escape);
|
detail::WriteSpec spec(fmt, escape);
|
||||||
|
@ -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,8 +878,8 @@ 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...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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];
|
||||||
|
|
24
octa/io.hh
24
octa/io.hh
|
@ -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);
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
const StringBase<T, A> &rhs) {
|
return !(rhs == lhs);
|
||||||
return !!rhs.compare(lhs);
|
}
|
||||||
|
|
||||||
|
template<typename T, typename A>
|
||||||
|
inline bool operator<(const StringBase<T, A> &lhs,
|
||||||
|
const StringBase<T, A> &rhs) {
|
||||||
|
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 *,
|
||||||
|
|
|
@ -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,14 +159,50 @@ 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,
|
||||||
typename detail::MakePairRet<U>::Type
|
typename detail::MakePairRet<U>::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> {};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue