rename string range types to new style
parent
296345f18e
commit
3edcafd9a6
|
@ -4,7 +4,7 @@
|
|||
|
||||
using namespace ostd;
|
||||
|
||||
void list_dirs(ConstCharRange path, int off = 0) {
|
||||
void list_dirs(string_range path, int off = 0) {
|
||||
DirectoryStream ds{path};
|
||||
/* iterate all items in directory */
|
||||
for (auto v: iter(ds)) {
|
||||
|
|
|
@ -9,8 +9,8 @@ struct SignalTest {
|
|||
* can actually emit (in that case, the reference passed to each
|
||||
* callback will always be const to make sure nothing changes)
|
||||
*/
|
||||
Signal<SignalTest const, int, ConstCharRange> on_simple = this;
|
||||
Signal<SignalTest , float > on_param = this;
|
||||
Signal<SignalTest const, int, string_range> on_simple = this;
|
||||
Signal<SignalTest , float > on_param = this;
|
||||
|
||||
SignalTest(): p_param(3.14f) {
|
||||
/* we can connect methods */
|
||||
|
@ -31,7 +31,7 @@ struct SignalTest {
|
|||
on_simple.emit(150, "hello world");
|
||||
}
|
||||
|
||||
void simple_method(int v, ConstCharRange str) const {
|
||||
void simple_method(int v, string_range str) const {
|
||||
writefln("simple method handler: %d, %s", v, str);
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ int main() {
|
|||
* this callback can access "test" easily and it will still work
|
||||
*/
|
||||
auto idx = st.on_simple.connect([&](
|
||||
SignalTest const &, int v, ConstCharRange str
|
||||
SignalTest const &, int v, string_range str
|
||||
) {
|
||||
writefln("and lambda test: %d, %s (%d)", v, str, test);
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
namespace ostd {
|
||||
|
||||
inline std::optional<std::string> env_get(ConstCharRange name) {
|
||||
inline std::optional<std::string> env_get(string_range name) {
|
||||
char buf[256];
|
||||
auto tbuf = to_temp_cstr(name, buf, sizeof(buf));
|
||||
#ifndef OSTD_PLATFORM_WIN32
|
||||
|
@ -48,7 +48,7 @@ inline std::optional<std::string> env_get(ConstCharRange name) {
|
|||
}
|
||||
|
||||
inline bool env_set(
|
||||
ConstCharRange name, ConstCharRange value, bool update = true
|
||||
string_range name, string_range value, bool update = true
|
||||
) {
|
||||
char sbuf[2048];
|
||||
char *buf = sbuf;
|
||||
|
@ -74,7 +74,7 @@ inline bool env_set(
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline bool env_unset(ConstCharRange name) {
|
||||
inline bool env_unset(string_range name) {
|
||||
char buf[256];
|
||||
if (name.size() < sizeof(buf)) {
|
||||
memcpy(buf, name.data(), name.size());
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace detail {
|
|||
}
|
||||
#endif
|
||||
|
||||
inline void path_normalize(CharRange) {
|
||||
inline void path_normalize(char_range) {
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ struct FileInfo {
|
|||
i.p_atime = i.p_ctime = i.p_mtime = 0;
|
||||
}
|
||||
|
||||
FileInfo(ConstCharRange path) {
|
||||
FileInfo(string_range path) {
|
||||
init_from_str(path);
|
||||
}
|
||||
|
||||
|
@ -93,24 +93,24 @@ struct FileInfo {
|
|||
return *this;
|
||||
}
|
||||
|
||||
ConstCharRange path() const { return ostd::iter(p_path); }
|
||||
string_range path() const { return ostd::iter(p_path); }
|
||||
|
||||
ConstCharRange filename() const {
|
||||
string_range filename() const {
|
||||
return path().slice(
|
||||
(p_slash == std::string::npos) ? 0 : (p_slash + 1), p_path.size()
|
||||
);
|
||||
}
|
||||
|
||||
ConstCharRange stem() const {
|
||||
string_range stem() const {
|
||||
return path().slice(
|
||||
(p_slash == std::string::npos) ? 0 : (p_slash + 1),
|
||||
(p_dot == std::string::npos) ? p_path.size() : p_dot
|
||||
);
|
||||
}
|
||||
|
||||
ConstCharRange extension() const {
|
||||
string_range extension() const {
|
||||
return (p_dot == std::string::npos)
|
||||
? ConstCharRange()
|
||||
? string_range()
|
||||
: path().slice(p_dot, p_path.size());
|
||||
}
|
||||
|
||||
|
@ -137,7 +137,7 @@ struct FileInfo {
|
|||
}
|
||||
|
||||
private:
|
||||
void init_from_str(ConstCharRange path) {
|
||||
void init_from_str(string_range path) {
|
||||
/* TODO: implement a version that will follow symbolic links */
|
||||
p_path = path;
|
||||
#ifdef OSTD_PLATFORM_WIN32
|
||||
|
@ -155,9 +155,9 @@ private:
|
|||
p_atime = p_mtime = p_ctime = 0;
|
||||
return;
|
||||
}
|
||||
ConstCharRange r = p_path;
|
||||
string_range r = p_path;
|
||||
|
||||
ConstCharRange found = find_last(r, PathSeparator);
|
||||
string_range found = find_last(r, PathSeparator);
|
||||
if (found.empty()) {
|
||||
p_slash = std::string::npos;
|
||||
} else {
|
||||
|
@ -240,7 +240,7 @@ struct DirectoryStream {
|
|||
s.p_de = nullptr;
|
||||
}
|
||||
|
||||
DirectoryStream(ConstCharRange path): DirectoryStream() {
|
||||
DirectoryStream(string_range path): DirectoryStream() {
|
||||
open(path);
|
||||
}
|
||||
|
||||
|
@ -253,7 +253,7 @@ struct DirectoryStream {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool open(ConstCharRange path) {
|
||||
bool open(string_range path) {
|
||||
if (p_d || (path.size() > FILENAME_MAX)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -377,7 +377,7 @@ struct DirectoryStream {
|
|||
memset(&s.p_data, 0, sizeof(s.p_data));
|
||||
}
|
||||
|
||||
DirectoryStream(ConstCharRange path): DirectoryStream() {
|
||||
DirectoryStream(string_range path): DirectoryStream() {
|
||||
open(path);
|
||||
}
|
||||
|
||||
|
@ -390,7 +390,7 @@ struct DirectoryStream {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool open(ConstCharRange path) {
|
||||
bool open(string_range path) {
|
||||
if (p_handle != INVALID_HANDLE_VALUE) {
|
||||
return false;
|
||||
}
|
||||
|
@ -597,7 +597,7 @@ inline FileInfo path_join(A const &...args) {
|
|||
return FileInfo(path);
|
||||
}
|
||||
|
||||
inline bool directory_change(ConstCharRange path) {
|
||||
inline bool directory_change(string_range path) {
|
||||
char buf[1024];
|
||||
if (path.size() >= 1024) {
|
||||
return false;
|
||||
|
|
|
@ -32,7 +32,7 @@ struct format_error: std::runtime_error {
|
|||
};
|
||||
|
||||
namespace detail {
|
||||
inline int parse_fmt_flags(ConstCharRange &fmt, int ret) {
|
||||
inline int parse_fmt_flags(string_range &fmt, int ret) {
|
||||
while (!fmt.empty()) {
|
||||
switch (fmt.front()) {
|
||||
case '-': ret |= FMT_FLAG_DASH; fmt.pop_front(); break;
|
||||
|
@ -47,7 +47,7 @@ namespace detail {
|
|||
return ret;
|
||||
}
|
||||
|
||||
inline size_t read_digits(ConstCharRange &fmt, char *buf) {
|
||||
inline size_t read_digits(string_range &fmt, char *buf) {
|
||||
size_t ret = 0;
|
||||
for (; !fmt.empty() && isdigit(fmt.front()); ++ret) {
|
||||
*buf++ = fmt.front();
|
||||
|
@ -134,7 +134,7 @@ namespace detail {
|
|||
|
||||
struct FormatSpec {
|
||||
FormatSpec(): p_nested_escape(false), p_fmt() {}
|
||||
FormatSpec(ConstCharRange fmt, bool escape = false):
|
||||
FormatSpec(string_range fmt, bool escape = false):
|
||||
p_nested_escape(escape), p_fmt(fmt)
|
||||
{}
|
||||
|
||||
|
@ -192,12 +192,12 @@ struct FormatSpec {
|
|||
return r;
|
||||
}
|
||||
|
||||
ConstCharRange rest() const {
|
||||
string_range rest() const {
|
||||
return p_fmt;
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
size_t build_spec(R &&out, ConstCharRange spec) const {
|
||||
size_t build_spec(R &&out, string_range spec) const {
|
||||
size_t ret = out.put('%');
|
||||
if (p_flags & FMT_FLAG_DASH ) {
|
||||
ret += out.put('-');
|
||||
|
@ -244,15 +244,15 @@ struct FormatSpec {
|
|||
|
||||
byte index() const { return p_index; }
|
||||
|
||||
ConstCharRange nested() const { return p_nested; }
|
||||
ConstCharRange nested_sep() const { return p_nested_sep; }
|
||||
string_range nested() const { return p_nested; }
|
||||
string_range nested_sep() const { return p_nested_sep; }
|
||||
|
||||
bool is_nested() const { return p_is_nested; }
|
||||
bool nested_escape() const { return p_nested_escape; }
|
||||
|
||||
protected:
|
||||
ConstCharRange p_nested;
|
||||
ConstCharRange p_nested_sep;
|
||||
string_range p_nested;
|
||||
string_range p_nested_sep;
|
||||
|
||||
int p_flags = 0;
|
||||
|
||||
|
@ -291,21 +291,21 @@ protected:
|
|||
int sflags = p_flags;
|
||||
p_nested_escape = !(sflags & FMT_FLAG_DASH);
|
||||
p_fmt.pop_front();
|
||||
ConstCharRange begin_inner(p_fmt);
|
||||
string_range begin_inner(p_fmt);
|
||||
if (!read_until_dummy()) {
|
||||
p_is_nested = false;
|
||||
return false;
|
||||
}
|
||||
/* skip to the last spec in case multiple specs are present */
|
||||
ConstCharRange curfmt(p_fmt);
|
||||
string_range curfmt(p_fmt);
|
||||
while (read_until_dummy()) {
|
||||
curfmt = p_fmt;
|
||||
}
|
||||
p_fmt = curfmt;
|
||||
p_flags = sflags;
|
||||
/* find delimiter or ending */
|
||||
ConstCharRange begin_delim(p_fmt);
|
||||
ConstCharRange p = find(begin_delim, '%');
|
||||
string_range begin_delim(p_fmt);
|
||||
string_range p = find(begin_delim, '%');
|
||||
for (; !p.empty(); p = find(p, '%')) {
|
||||
p.pop_front();
|
||||
/* escape, skip */
|
||||
|
@ -428,7 +428,7 @@ protected:
|
|||
return (sp >= 65) && (detail::fmt_specs[sp - 65] != 0);
|
||||
}
|
||||
|
||||
ConstCharRange p_fmt;
|
||||
string_range p_fmt;
|
||||
char p_buf[32];
|
||||
};
|
||||
|
||||
|
@ -502,14 +502,14 @@ namespace detail {
|
|||
|
||||
template<typename R, typename ...A>
|
||||
static size_t format_impl(
|
||||
R &writer, bool escape, ConstCharRange fmt, A const &...args
|
||||
R &writer, bool escape, string_range fmt, A const &...args
|
||||
);
|
||||
|
||||
template<size_t I>
|
||||
struct FmtTupleUnpacker {
|
||||
template<typename R, typename T, typename ...A>
|
||||
static inline size_t unpack(
|
||||
R &writer, bool esc, ConstCharRange fmt,
|
||||
R &writer, bool esc, string_range fmt,
|
||||
T const &item, A const &...args
|
||||
) {
|
||||
return FmtTupleUnpacker<I - 1>::unpack(
|
||||
|
@ -522,7 +522,7 @@ namespace detail {
|
|||
struct FmtTupleUnpacker<0> {
|
||||
template<typename R, typename T, typename ...A>
|
||||
static inline size_t unpack(
|
||||
R &writer, bool esc, ConstCharRange fmt,
|
||||
R &writer, bool esc, string_range fmt,
|
||||
T const &, A const &...args
|
||||
) {
|
||||
return format_impl(writer, esc, fmt, args...);
|
||||
|
@ -543,7 +543,7 @@ namespace detail {
|
|||
|
||||
template<typename R, typename T>
|
||||
inline size_t format_ritem(
|
||||
R &writer, bool esc, bool, ConstCharRange fmt,
|
||||
R &writer, bool esc, bool, string_range fmt,
|
||||
T const &item, std::enable_if_t<!is_tuple_like<T>, bool> = true
|
||||
) {
|
||||
return format_impl(writer, esc, fmt, item);
|
||||
|
@ -551,7 +551,7 @@ namespace detail {
|
|||
|
||||
template<typename R, typename T>
|
||||
inline size_t format_ritem(
|
||||
R &writer, bool esc, bool expandval, ConstCharRange fmt,
|
||||
R &writer, bool esc, bool expandval, string_range fmt,
|
||||
T const &item, std::enable_if_t<is_tuple_like<T>, bool> = true
|
||||
) {
|
||||
if (expandval) {
|
||||
|
@ -565,7 +565,7 @@ namespace detail {
|
|||
template<typename R, typename T>
|
||||
inline size_t write_range(
|
||||
R &writer, FormatSpec const *fl, bool escape, bool expandval,
|
||||
ConstCharRange sep, T const &val,
|
||||
string_range sep, T const &val,
|
||||
std::enable_if_t<detail::IterableTest<T>, bool> = true
|
||||
) {
|
||||
/* XXX: maybe handle error cases? */
|
||||
|
@ -591,7 +591,7 @@ namespace detail {
|
|||
|
||||
template<typename R, typename T>
|
||||
inline size_t write_range(
|
||||
R &, FormatSpec const *, bool, bool, ConstCharRange,
|
||||
R &, FormatSpec const *, bool, bool, string_range,
|
||||
T const &, std::enable_if_t<!detail::IterableTest<T>, bool> = true
|
||||
) {
|
||||
throw format_error{"invalid value for ranged format"};
|
||||
|
@ -629,7 +629,7 @@ namespace detail {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
inline std::string escape_fmt_str(ConstCharRange val) {
|
||||
inline std::string escape_fmt_str(string_range val) {
|
||||
std::string ret;
|
||||
ret.push_back('"');
|
||||
while (!val.empty()) {
|
||||
|
@ -662,7 +662,7 @@ namespace detail {
|
|||
|
||||
/* string base writer */
|
||||
template<typename R>
|
||||
size_t write_str(R &writer, bool escape, ConstCharRange val) const {
|
||||
size_t write_str(R &writer, bool escape, string_range val) const {
|
||||
if (escape) {
|
||||
return write_str(writer, false, escape_fmt_str(val));
|
||||
}
|
||||
|
@ -688,7 +688,7 @@ namespace detail {
|
|||
size_t elen = strlen(esc);
|
||||
memcpy(buf + 1, esc, elen);
|
||||
buf[elen + 1] = '\'';
|
||||
return write_val(writer, false, ostd::ConstCharRange{
|
||||
return write_val(writer, false, ostd::string_range{
|
||||
buf, buf + elen + 2
|
||||
});
|
||||
}
|
||||
|
@ -763,7 +763,7 @@ namespace detail {
|
|||
return sink.get_written();
|
||||
}
|
||||
/* second best, we can convert to string slice */
|
||||
if constexpr(std::is_constructible_v<ConstCharRange, T const &>) {
|
||||
if constexpr(std::is_constructible_v<string_range, T const &>) {
|
||||
if (this->spec() != 's') {
|
||||
throw format_error{"strings need the '%s' spec"};
|
||||
}
|
||||
|
@ -844,7 +844,7 @@ namespace detail {
|
|||
/* range writer */
|
||||
template<typename R, typename T, typename ...A>
|
||||
size_t write_range(
|
||||
R &writer, size_t idx, bool expandval, ConstCharRange sep,
|
||||
R &writer, size_t idx, bool expandval, string_range sep,
|
||||
T const &val, A const &...args
|
||||
) const {
|
||||
if (idx) {
|
||||
|
@ -863,7 +863,7 @@ namespace detail {
|
|||
|
||||
template<typename R, typename ...A>
|
||||
inline size_t format_impl(
|
||||
R &writer, bool escape, ConstCharRange fmt, A const &...args
|
||||
R &writer, bool escape, string_range fmt, A const &...args
|
||||
) {
|
||||
size_t argidx = 1, twr = 0, written = 0;
|
||||
detail::WriteSpec spec(fmt, escape);
|
||||
|
@ -914,7 +914,7 @@ namespace detail {
|
|||
}
|
||||
|
||||
template<typename R>
|
||||
inline ptrdiff_t format_impl(R &writer, bool, ConstCharRange fmt) {
|
||||
inline ptrdiff_t format_impl(R &writer, bool, string_range fmt) {
|
||||
size_t written = 0;
|
||||
detail::WriteSpec spec(fmt, false);
|
||||
if (spec.read_until_spec(writer, &written)) {
|
||||
|
@ -925,7 +925,7 @@ namespace detail {
|
|||
} /* namespace detail */
|
||||
|
||||
template<typename R, typename ...A>
|
||||
inline size_t format(R &&writer, ConstCharRange fmt, A const &...args) {
|
||||
inline size_t format(R &&writer, string_range fmt, A const &...args) {
|
||||
return detail::format_impl(writer, false, fmt, args...);
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ struct FileStream: Stream {
|
|||
s.p_owned = false;
|
||||
}
|
||||
|
||||
FileStream(ConstCharRange path, StreamMode mode = StreamMode::read): p_f() {
|
||||
FileStream(string_range path, StreamMode mode = StreamMode::read): p_f() {
|
||||
open(path, mode);
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ struct FileStream: Stream {
|
|||
return *this;
|
||||
}
|
||||
|
||||
bool open(ConstCharRange path, StreamMode mode = StreamMode::read) {
|
||||
bool open(string_range path, StreamMode mode = StreamMode::read) {
|
||||
if (p_f || (path.size() > FILENAME_MAX)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -199,12 +199,12 @@ inline void writeln(T const &v, A const &...args) {
|
|||
}
|
||||
|
||||
template<typename ...A>
|
||||
inline void writef(ConstCharRange fmt, A const &...args) {
|
||||
inline void writef(string_range fmt, A const &...args) {
|
||||
format(detail::StdoutRange{}, fmt, args...);
|
||||
}
|
||||
|
||||
template<typename ...A>
|
||||
inline void writefln(ConstCharRange fmt, A const &...args) {
|
||||
inline void writefln(string_range fmt, A const &...args) {
|
||||
writef(fmt, args...);
|
||||
if (putchar('\n') == EOF) {
|
||||
throw format_error{"stream EOF"};
|
||||
|
|
|
@ -100,10 +100,10 @@ struct Stream {
|
|||
}
|
||||
|
||||
template<typename ...A>
|
||||
void writef(ConstCharRange fmt, A const &...args);
|
||||
void writef(string_range fmt, A const &...args);
|
||||
|
||||
template<typename ...A>
|
||||
void writefln(ConstCharRange fmt, A const &...args) {
|
||||
void writefln(string_range fmt, A const &...args) {
|
||||
writef(fmt, args...);
|
||||
if (!putchar('\n')) {
|
||||
throw format_error{"stream EOF"};
|
||||
|
@ -234,7 +234,7 @@ inline void Stream::write(T const &v) {
|
|||
}
|
||||
|
||||
template<typename ...A>
|
||||
inline void Stream::writef(ConstCharRange fmt, A const &...args) {
|
||||
inline void Stream::writef(string_range fmt, A const &...args) {
|
||||
format(detail::FmtStreamRange{*this}, fmt, args...);
|
||||
}
|
||||
|
||||
|
|
250
ostd/string.hh
250
ostd/string.hh
|
@ -23,7 +23,7 @@
|
|||
namespace ostd {
|
||||
|
||||
template<typename T, typename TR = std::char_traits<std::remove_const_t<T>>>
|
||||
struct CharRangeBase: InputRange<CharRangeBase<T>> {
|
||||
struct basic_char_range: InputRange<basic_char_range<T>> {
|
||||
using Category = ContiguousRangeTag;
|
||||
using Value = T;
|
||||
using Reference = T &;
|
||||
|
@ -34,47 +34,47 @@ private:
|
|||
struct Nat {};
|
||||
|
||||
public:
|
||||
CharRangeBase(): p_beg(nullptr), p_end(nullptr) {};
|
||||
CharRangeBase(T *beg, T *end): p_beg(beg), p_end(end) {}
|
||||
basic_char_range(): p_beg(nullptr), p_end(nullptr) {};
|
||||
basic_char_range(T *beg, T *end): p_beg(beg), p_end(end) {}
|
||||
|
||||
template<typename U>
|
||||
CharRangeBase(
|
||||
basic_char_range(
|
||||
U beg, std::enable_if_t<
|
||||
std::is_convertible_v<U, T *> && !std::is_array_v<U>, Nat
|
||||
> = Nat()
|
||||
): p_beg(beg), p_end(static_cast<T *>(beg) + (beg ? TR::length(beg) : 0)) {}
|
||||
|
||||
CharRangeBase(std::nullptr_t): p_beg(nullptr), p_end(nullptr) {}
|
||||
basic_char_range(std::nullptr_t): p_beg(nullptr), p_end(nullptr) {}
|
||||
|
||||
template<typename U, size_t N>
|
||||
CharRangeBase(U (&beg)[N], std::enable_if_t<
|
||||
basic_char_range(U (&beg)[N], std::enable_if_t<
|
||||
std::is_convertible_v<U *, T *>, Nat
|
||||
> = Nat()):
|
||||
p_beg(beg), p_end(beg + N - (beg[N - 1] == '\0'))
|
||||
{}
|
||||
|
||||
template<typename STR, typename A>
|
||||
CharRangeBase(std::basic_string<std::remove_const_t<T>, STR, A> const &s):
|
||||
basic_char_range(std::basic_string<std::remove_const_t<T>, STR, A> const &s):
|
||||
p_beg(s.data()), p_end(s.data() + s.size())
|
||||
{}
|
||||
|
||||
template<typename U, typename = std::enable_if_t<
|
||||
std::is_convertible_v<U *, T *>
|
||||
>>
|
||||
CharRangeBase(CharRangeBase<U> const &v):
|
||||
basic_char_range(basic_char_range<U> const &v):
|
||||
p_beg(&v[0]), p_end(&v[v.size()])
|
||||
{}
|
||||
|
||||
CharRangeBase &operator=(CharRangeBase const &v) {
|
||||
basic_char_range &operator=(basic_char_range const &v) {
|
||||
p_beg = v.p_beg; p_end = v.p_end; return *this;
|
||||
}
|
||||
|
||||
template<typename STR, typename A>
|
||||
CharRangeBase &operator=(std::basic_string<T, STR, A> const &s) {
|
||||
basic_char_range &operator=(std::basic_string<T, STR, A> const &s) {
|
||||
p_beg = s.data(); p_end = s.data() + s.size(); return *this;
|
||||
}
|
||||
|
||||
CharRangeBase &operator=(T *s) {
|
||||
basic_char_range &operator=(T *s) {
|
||||
p_beg = s; p_end = s + (s ? TR::length(s) : 0); return *this;
|
||||
}
|
||||
|
||||
|
@ -103,11 +103,11 @@ public:
|
|||
|
||||
T &front() const { return *p_beg; }
|
||||
|
||||
bool equals_front(CharRangeBase const &range) const {
|
||||
bool equals_front(basic_char_range const &range) const {
|
||||
return p_beg == range.p_beg;
|
||||
}
|
||||
|
||||
ptrdiff_t distance_front(CharRangeBase const &range) const {
|
||||
ptrdiff_t distance_front(basic_char_range const &range) const {
|
||||
return range.p_beg - p_beg;
|
||||
}
|
||||
|
||||
|
@ -134,18 +134,18 @@ public:
|
|||
|
||||
T &back() const { return *(p_end - 1); }
|
||||
|
||||
bool equals_back(CharRangeBase const &range) const {
|
||||
bool equals_back(basic_char_range const &range) const {
|
||||
return p_end == range.p_end;
|
||||
}
|
||||
|
||||
ptrdiff_t distance_back(CharRangeBase const &range) const {
|
||||
ptrdiff_t distance_back(basic_char_range const &range) const {
|
||||
return range.p_end - p_end;
|
||||
}
|
||||
|
||||
size_t size() const { return p_end - p_beg; }
|
||||
|
||||
CharRangeBase slice(size_t start, size_t end) const {
|
||||
return CharRangeBase(p_beg + start, p_beg + end);
|
||||
basic_char_range slice(size_t start, size_t end) const {
|
||||
return basic_char_range(p_beg + start, p_beg + end);
|
||||
}
|
||||
|
||||
T &operator[](size_t i) const { return p_beg[i]; }
|
||||
|
@ -162,7 +162,7 @@ public:
|
|||
T const *data() const { return p_beg; }
|
||||
|
||||
/* non-range */
|
||||
int compare(CharRangeBase<T const> s) const {
|
||||
int compare(basic_char_range<T const> s) const {
|
||||
size_t s1 = size(), s2 = s.size();
|
||||
int ret;
|
||||
if (!s1 || !s2) {
|
||||
|
@ -175,7 +175,7 @@ diffsize:
|
|||
return (s1 < s2) ? -1 : ((s1 > s2) ? 1 : 0);
|
||||
}
|
||||
|
||||
int case_compare(CharRangeBase<T const> s) const {
|
||||
int case_compare(basic_char_range<T const> s) const {
|
||||
size_t s1 = size(), s2 = s.size();
|
||||
for (size_t i = 0, ms = ostd::min(s1, s2); i < ms; ++i) {
|
||||
int d = toupper(p_beg[i]) - toupper(s[i]);
|
||||
|
@ -207,41 +207,186 @@ private:
|
|||
};
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline size_t range_put_n(CharRangeBase<T, TR> &range, T const *p, size_t n) {
|
||||
inline size_t range_put_n(basic_char_range<T, TR> &range, T const *p, size_t n) {
|
||||
size_t an = ostd::min(n, range.size());
|
||||
TR::copy(range.data(), p, an);
|
||||
range.pop_front_n(an);
|
||||
return an;
|
||||
}
|
||||
|
||||
using CharRange = CharRangeBase<char>;
|
||||
using ConstCharRange = CharRangeBase<char const>;
|
||||
using char_range = basic_char_range<char>;
|
||||
using string_range = basic_char_range<char const>;
|
||||
|
||||
inline bool operator==(ConstCharRange lhs, ConstCharRange rhs) {
|
||||
/* comparisons between ranges */
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator==(
|
||||
basic_char_range<T, TR> lhs, basic_char_range<T, TR> rhs
|
||||
) {
|
||||
return !lhs.compare(rhs);
|
||||
}
|
||||
|
||||
inline bool operator!=(ConstCharRange lhs, ConstCharRange rhs) {
|
||||
template<typename T, typename TR>
|
||||
inline bool operator!=(
|
||||
basic_char_range<T, TR> lhs, basic_char_range<T, TR> rhs
|
||||
) {
|
||||
return lhs.compare(rhs);
|
||||
}
|
||||
|
||||
inline bool operator<(ConstCharRange lhs, ConstCharRange rhs) {
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<(
|
||||
basic_char_range<T, TR> lhs, basic_char_range<T, TR> rhs
|
||||
) {
|
||||
return lhs.compare(rhs) < 0;
|
||||
}
|
||||
|
||||
inline bool operator>(ConstCharRange lhs, ConstCharRange rhs) {
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>(
|
||||
basic_char_range<T, TR> lhs, basic_char_range<T, TR> rhs
|
||||
) {
|
||||
return lhs.compare(rhs) > 0;
|
||||
}
|
||||
|
||||
inline bool operator<=(ConstCharRange lhs, ConstCharRange rhs) {
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<=(
|
||||
basic_char_range<T, TR> lhs, basic_char_range<T, TR> rhs
|
||||
) {
|
||||
return lhs.compare(rhs) <= 0;
|
||||
}
|
||||
|
||||
inline bool operator>=(ConstCharRange lhs, ConstCharRange rhs) {
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>=(
|
||||
basic_char_range<T, TR> lhs, basic_char_range<T, TR> rhs
|
||||
) {
|
||||
return lhs.compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
inline bool starts_with(ConstCharRange a, ConstCharRange b) {
|
||||
/* comparisons between mutable ranges and char arrays */
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator==(basic_char_range<T, TR> lhs, T const *rhs) {
|
||||
return !lhs.compare(rhs);
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator!=(basic_char_range<T, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs);
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<(basic_char_range<T, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs) < 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>(basic_char_range<T, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs) > 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<=(basic_char_range<T, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs) <= 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>=(basic_char_range<T, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator==(T const *lhs, basic_char_range<T, TR> rhs) {
|
||||
return !rhs.compare(lhs);
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator!=(T const *lhs, basic_char_range<T, TR> rhs) {
|
||||
return rhs.compare(lhs);
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<(T const *lhs, basic_char_range<T, TR> rhs) {
|
||||
return rhs.compare(lhs) > 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>(T const *lhs, basic_char_range<T, TR> rhs) {
|
||||
return rhs.compare(lhs) < 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<=(T const *lhs, basic_char_range<T, TR> rhs) {
|
||||
return rhs.compare(lhs) >= 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>=(T const *lhs, basic_char_range<T, TR> rhs) {
|
||||
return rhs.compare(lhs) <= 0;
|
||||
}
|
||||
|
||||
/* comparisons between immutable ranges and char arrays */
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator==(basic_char_range<T const, TR> lhs, T const *rhs) {
|
||||
return !lhs.compare(rhs);
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator!=(basic_char_range<T const, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs);
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<(basic_char_range<T const, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs) < 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>(basic_char_range<T const, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs) > 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<=(basic_char_range<T const, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs) <= 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>=(basic_char_range<T const, TR> lhs, T const *rhs) {
|
||||
return lhs.compare(rhs) >= 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator==(T const *lhs, basic_char_range<T const, TR> rhs) {
|
||||
return !rhs.compare(lhs);
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator!=(T const *lhs, basic_char_range<T const, TR> rhs) {
|
||||
return rhs.compare(lhs);
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<(T const *lhs, basic_char_range<T const, TR> rhs) {
|
||||
return rhs.compare(lhs) > 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>(T const *lhs, basic_char_range<T const, TR> rhs) {
|
||||
return rhs.compare(lhs) < 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator<=(T const *lhs, basic_char_range<T const, TR> rhs) {
|
||||
return rhs.compare(lhs) >= 0;
|
||||
}
|
||||
|
||||
template<typename T, typename TR>
|
||||
inline bool operator>=(T const *lhs, basic_char_range<T const, TR> rhs) {
|
||||
return rhs.compare(lhs) <= 0;
|
||||
}
|
||||
|
||||
inline bool starts_with(string_range a, string_range b
|
||||
) {
|
||||
if (a.size() < b.size()) {
|
||||
return false;
|
||||
}
|
||||
|
@ -250,7 +395,7 @@ inline bool starts_with(ConstCharRange a, ConstCharRange b) {
|
|||
|
||||
template<typename T, typename TR, typename A>
|
||||
struct ranged_traits<std::basic_string<T, TR, A>> {
|
||||
using range = CharRangeBase<T>;
|
||||
using range = basic_char_range<T, TR>;
|
||||
|
||||
static range iter(std::basic_string<T, TR, A> &v) {
|
||||
return range{v.data(), v.data() + v.size()};
|
||||
|
@ -259,7 +404,7 @@ struct ranged_traits<std::basic_string<T, TR, A>> {
|
|||
|
||||
template<typename T, typename TR, typename A>
|
||||
struct ranged_traits<std::basic_string<T, TR, A> const> {
|
||||
using range = CharRangeBase<T const>;
|
||||
using range = basic_char_range<T const, TR>;
|
||||
|
||||
static range iter(std::basic_string<T, TR, A> const &v) {
|
||||
return range{v.data(), v.data() + v.size()};
|
||||
|
@ -303,15 +448,15 @@ inline std::basic_string<std::remove_cv_t<RangeValue<R>>, TR, A> make_string(
|
|||
|
||||
inline namespace literals {
|
||||
inline namespace string_literals {
|
||||
inline ConstCharRange operator "" _sr(char const *str, size_t len) {
|
||||
return ConstCharRange(str, str + len);
|
||||
inline string_range operator "" _sr(char const *str, size_t len) {
|
||||
return string_range(str, str + len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
template<
|
||||
typename T, bool = std::is_convertible_v<T, ConstCharRange>,
|
||||
typename T, bool = std::is_convertible_v<T, string_range>,
|
||||
bool = std::is_convertible_v<T, char>
|
||||
>
|
||||
struct ConcatPut;
|
||||
|
@ -319,7 +464,7 @@ namespace detail {
|
|||
template<typename T, bool B>
|
||||
struct ConcatPut<T, true, B> {
|
||||
template<typename R>
|
||||
static bool put(R &sink, ConstCharRange v) {
|
||||
static bool put(R &sink, string_range v) {
|
||||
return v.size() && (range_put_n(sink, &v[0], v.size()) == v.size());
|
||||
}
|
||||
};
|
||||
|
@ -334,7 +479,7 @@ namespace detail {
|
|||
}
|
||||
|
||||
template<typename R, typename T, typename F>
|
||||
bool concat(R &&sink, T const &v, ConstCharRange sep, F func) {
|
||||
bool concat(R &&sink, T const &v, string_range sep, F func) {
|
||||
auto range = ostd::iter(v);
|
||||
if (range.empty()) {
|
||||
return true;
|
||||
|
@ -355,13 +500,13 @@ bool concat(R &&sink, T const &v, ConstCharRange sep, F func) {
|
|||
}
|
||||
|
||||
template<typename R, typename T>
|
||||
bool concat(R &&sink, T const &v, ConstCharRange sep = " ") {
|
||||
bool concat(R &&sink, T const &v, string_range sep = " ") {
|
||||
auto range = ostd::iter(v);
|
||||
if (range.empty()) {
|
||||
return true;
|
||||
}
|
||||
for (;;) {
|
||||
ConstCharRange ret = range.front();
|
||||
string_range ret = range.front();
|
||||
if (!ret.size() || (range_put_n(sink, &ret[0], ret.size()) != ret.size())) {
|
||||
return false;
|
||||
}
|
||||
|
@ -375,12 +520,12 @@ bool concat(R &&sink, T const &v, ConstCharRange sep = " ") {
|
|||
}
|
||||
|
||||
template<typename R, typename T, typename F>
|
||||
bool concat(R &&sink, std::initializer_list<T> v, ConstCharRange sep, F func) {
|
||||
bool concat(R &&sink, std::initializer_list<T> v, string_range sep, F func) {
|
||||
return concat(sink, ostd::iter(v), sep, func);
|
||||
}
|
||||
|
||||
template<typename R, typename T>
|
||||
bool concat(R &&sink, std::initializer_list<T> v, ConstCharRange sep = " ") {
|
||||
bool concat(R &&sink, std::initializer_list<T> v, string_range sep = " ") {
|
||||
return concat(sink, ostd::iter(v), sep);
|
||||
}
|
||||
|
||||
|
@ -402,7 +547,7 @@ namespace detail {
|
|||
p_written += ret;
|
||||
return ret;
|
||||
}
|
||||
size_t put_string(ConstCharRange r) {
|
||||
size_t put_string(string_range r) {
|
||||
size_t ret = range_put_n(p_out, r.data(), r.size());
|
||||
p_written += ret;
|
||||
return ret;
|
||||
|
@ -571,8 +716,8 @@ struct ToString<std::string> {
|
|||
};
|
||||
|
||||
template<>
|
||||
struct ToString<CharRange> {
|
||||
using Argument = CharRange;
|
||||
struct ToString<char_range> {
|
||||
using Argument = char_range;
|
||||
using Result = std::string;
|
||||
std::string operator()(Argument const &s) {
|
||||
return std::string{s};
|
||||
|
@ -580,8 +725,8 @@ struct ToString<CharRange> {
|
|||
};
|
||||
|
||||
template<>
|
||||
struct ToString<ConstCharRange> {
|
||||
using Argument = ConstCharRange;
|
||||
struct ToString<string_range> {
|
||||
using Argument = string_range;
|
||||
using Result = std::string;
|
||||
std::string operator()(Argument const &s) {
|
||||
return std::string{s};
|
||||
|
@ -719,17 +864,10 @@ inline TempCString<R> to_temp_cstr(
|
|||
|
||||
namespace std {
|
||||
|
||||
template<>
|
||||
struct hash<ostd::CharRange> {
|
||||
size_t operator()(ostd::CharRange const &v) const {
|
||||
return hash<std::string_view>{}(v);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct hash<ostd::ConstCharRange> {
|
||||
size_t operator()(ostd::ConstCharRange const &v) const {
|
||||
return hash<std::string_view>{}(v);
|
||||
template<typename T, typename TR>
|
||||
struct hash<ostd::basic_char_range<T, TR>> {
|
||||
size_t operator()(ostd::basic_char_range<T, TR> const &v) const {
|
||||
return hash<std::basic_string_view<std::remove_const_t<T>, TR>>{}(v);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue