mirror of
https://github.com/matrix-construct/construct
synced 2025-01-12 16:03:55 +01:00
ircd::tokens: Simplify interface w/ closure template; eliminate named closure.
ircd::tokens: Minor interface cleanup; inline linkages.
This commit is contained in:
parent
266e617e36
commit
ded8f05064
4 changed files with 52 additions and 79 deletions
|
@ -11,21 +11,16 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_TOKENS_H
|
||||
|
||||
//
|
||||
// String tokenization utils
|
||||
//
|
||||
namespace ircd
|
||||
{
|
||||
// Use the closure for best performance. Note that string_view's are not
|
||||
// required to be null terminated. Construct an std::string from the view
|
||||
// to allocate and copy the token with null termination.
|
||||
using token_view = std::function<void (const string_view &)>;
|
||||
using token_view_bool = std::function<bool (const string_view &)>;
|
||||
using token_view = closure_bool<std::function, const string_view &>;
|
||||
|
||||
bool tokens(const string_view &str, const char &sep, const token_view &);
|
||||
bool tokens(const string_view &str, const string_view &sep, const token_view &);
|
||||
|
||||
void tokens(const string_view &str, const char &sep, const token_view &);
|
||||
void tokens(const string_view &str, const string_view &sep, const token_view &);
|
||||
bool tokens(const string_view &str, const char &sep, const token_view_bool &);
|
||||
bool tokens(const string_view &str, const string_view &sep, const token_view_bool &);
|
||||
size_t tokens(const string_view &str, const char &sep, const size_t &limit, const token_view &);
|
||||
size_t tokens(const string_view &str, const string_view &sep, const size_t &limit, const token_view &);
|
||||
|
||||
|
@ -34,11 +29,19 @@ namespace ircd
|
|||
size_t tokens(const string_view &str, const string_view &sep, const mutable_buffer &buf, const token_view &);
|
||||
|
||||
// Receive token view into iterator range
|
||||
template<class it, class sep> it tokens(const string_view &str, const sep &, const it &b, const it &e);
|
||||
template<class it,
|
||||
class sep>
|
||||
it tokens(const string_view &str, const sep &, const it &b, const it &e);
|
||||
|
||||
// Receive token view into array
|
||||
template<size_t N, class sep> size_t tokens(const string_view &str, const sep &, string_view (&buf)[N]);
|
||||
template<size_t N, class sep> size_t tokens(const string_view &str, const sep &, std::array<string_view, N> &);
|
||||
template<size_t N,
|
||||
class sep>
|
||||
size_t tokens(const string_view &str, const sep &, string_view (&buf)[N]);
|
||||
|
||||
// Receive token view into std::array
|
||||
template<size_t N,
|
||||
class sep>
|
||||
size_t tokens(const string_view &str, const sep &, std::array<string_view, N> &);
|
||||
|
||||
// Receive token view into new container (custom allocator)
|
||||
template<template<class, class>
|
||||
|
@ -73,29 +76,39 @@ namespace ircd
|
|||
class A = std::allocator<T>,
|
||||
class sep>
|
||||
C<T, Comp, A> tokens(const string_view &str, const sep &);
|
||||
}
|
||||
|
||||
// Convenience to get individual tokens
|
||||
// Tools
|
||||
namespace ircd
|
||||
{
|
||||
size_t token_count(const string_view &str, const char &sep);
|
||||
size_t token_count(const string_view &str, const string_view &sep);
|
||||
|
||||
bool token_exists(const string_view &str, const char &sep, const string_view &token);
|
||||
bool token_exists(const string_view &str, const string_view &sep, const string_view &token);
|
||||
|
||||
string_view token(const string_view &str, const char &sep, const size_t &at);
|
||||
string_view token(const string_view &str, const string_view &sep, const size_t &at);
|
||||
|
||||
string_view token(const string_view &str, const char &sep, const size_t &at, const string_view &def);
|
||||
string_view token(const string_view &str, const string_view &sep, const size_t &at, const string_view &def);
|
||||
|
||||
string_view token_last(const string_view &str, const char &sep);
|
||||
string_view token_last(const string_view &str, const string_view &sep);
|
||||
|
||||
string_view token_first(const string_view &str, const char &sep);
|
||||
string_view token_first(const string_view &str, const string_view &sep);
|
||||
|
||||
string_view tokens_after(const string_view &str, const char &sep, const size_t &at = 0);
|
||||
string_view tokens_after(const string_view &str, const string_view &sep, const size_t &at = 0);
|
||||
|
||||
string_view tokens_before(const string_view &str, const char &sep, const size_t &at = 0);
|
||||
string_view tokens_before(const string_view &str, const string_view &sep, const size_t &at = 0);
|
||||
}
|
||||
|
||||
template<size_t N,
|
||||
class delim>
|
||||
size_t
|
||||
inline size_t
|
||||
ircd::tokens(const string_view &str,
|
||||
const delim &sep,
|
||||
string_view (&buf)[N])
|
||||
|
@ -106,7 +119,7 @@ ircd::tokens(const string_view &str,
|
|||
|
||||
template<size_t N,
|
||||
class delim>
|
||||
size_t
|
||||
inline size_t
|
||||
ircd::tokens(const string_view &str,
|
||||
const delim &sep,
|
||||
std::array<string_view, N> &buf)
|
||||
|
@ -117,7 +130,7 @@ ircd::tokens(const string_view &str,
|
|||
|
||||
template<class it,
|
||||
class delim>
|
||||
it
|
||||
inline it
|
||||
ircd::tokens(const string_view &str,
|
||||
const delim &sep,
|
||||
const it &b,
|
||||
|
@ -140,7 +153,7 @@ template<template<class, class, class>
|
|||
class Comp,
|
||||
class A,
|
||||
class delim>
|
||||
C<T, Comp, A>
|
||||
inline C<T, Comp, A>
|
||||
ircd::tokens(const string_view &str,
|
||||
const delim &sep)
|
||||
{
|
||||
|
@ -153,7 +166,7 @@ template<template<class, class, class>
|
|||
class Comp,
|
||||
class A,
|
||||
class delim>
|
||||
C<T, Comp, A>
|
||||
inline C<T, Comp, A>
|
||||
ircd::tokens(A&& allocator,
|
||||
const string_view &str,
|
||||
const delim &sep)
|
||||
|
@ -173,7 +186,7 @@ template<template<class, class>
|
|||
class T,
|
||||
class A,
|
||||
class delim>
|
||||
C<T, A>
|
||||
inline C<T, A>
|
||||
ircd::tokens(const string_view &str,
|
||||
const delim &sep)
|
||||
{
|
||||
|
@ -185,7 +198,7 @@ template<template<class, class>
|
|||
class T,
|
||||
class A,
|
||||
class delim>
|
||||
C<T, A>
|
||||
inline C<T, A>
|
||||
ircd::tokens(A&& allocator,
|
||||
const string_view &str,
|
||||
const delim &sep)
|
||||
|
|
|
@ -38,8 +38,8 @@ struct ircd::util::params
|
|||
const char *sep {" "};
|
||||
std::array<string_view, MAX> names;
|
||||
|
||||
bool for_each_pararg(const token_view_bool &) const;
|
||||
bool for_each_posarg(const token_view_bool &) const;
|
||||
bool for_each_pararg(const token_view &) const;
|
||||
bool for_each_posarg(const token_view &) const;
|
||||
string_view name(const size_t &i) const;
|
||||
size_t name(const string_view &) const;
|
||||
|
||||
|
@ -299,27 +299,27 @@ const
|
|||
}
|
||||
|
||||
inline bool
|
||||
ircd::util::params::for_each_posarg(const token_view_bool &closure)
|
||||
ircd::util::params::for_each_posarg(const token_view &closure)
|
||||
const
|
||||
{
|
||||
return tokens(in, sep, token_view_bool{[this, &closure]
|
||||
return tokens(in, sep, [this, &closure]
|
||||
(const string_view &token)
|
||||
{
|
||||
return !prefix || !startswith(token, prefix)?
|
||||
closure(token):
|
||||
true;
|
||||
}});
|
||||
});
|
||||
}
|
||||
|
||||
inline bool
|
||||
ircd::util::params::for_each_pararg(const token_view_bool &closure)
|
||||
ircd::util::params::for_each_pararg(const token_view &closure)
|
||||
const
|
||||
{
|
||||
return tokens(in, sep, token_view_bool{[this, &closure]
|
||||
return tokens(in, sep, [this, &closure]
|
||||
(const string_view &token)
|
||||
{
|
||||
return prefix && startswith(token, prefix)?
|
||||
closure(token):
|
||||
true;
|
||||
}});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -347,16 +347,16 @@ ircd::tokens(const string_view &str,
|
|||
char *ptr(data(buf));
|
||||
char *const stop(data(buf) + size(buf));
|
||||
tokens(str, sep, [&closure, &ptr, &stop]
|
||||
(const string_view &token)
|
||||
(const string_view &token) -> bool
|
||||
{
|
||||
const size_t terminated_size(token.size() + 1);
|
||||
const size_t remaining(std::distance(ptr, stop));
|
||||
if(remaining < terminated_size)
|
||||
return;
|
||||
return false;
|
||||
|
||||
char *const dest(ptr);
|
||||
ptr += strlcpy(dest, token.data(), terminated_size);
|
||||
closure(string_view(dest, token.size()));
|
||||
return closure(string_view(dest, token.size()));
|
||||
});
|
||||
|
||||
return std::distance(data(buf), ptr);
|
||||
|
@ -386,7 +386,8 @@ ircd::tokens(const string_view &str,
|
|||
|
||||
size_t i(0);
|
||||
for(auto it(begin(view)); i < limit && it != end(view); ++it, i++)
|
||||
closure(*it);
|
||||
if(!closure(*it))
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -409,7 +410,8 @@ ircd::tokens(const string_view &str,
|
|||
|
||||
size_t i(0);
|
||||
for(auto it(begin(view)); i < limit && it != end(view); ++it, i++)
|
||||
closure(*it);
|
||||
if(!closure(*it))
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
@ -417,7 +419,7 @@ ircd::tokens(const string_view &str,
|
|||
bool
|
||||
ircd::tokens(const string_view &str,
|
||||
const char &sep,
|
||||
const token_view_bool &closure)
|
||||
const token_view &closure)
|
||||
{
|
||||
using type = string_view;
|
||||
using iter = typename type::const_iterator;
|
||||
|
@ -445,7 +447,7 @@ ircd::tokens(const string_view &str,
|
|||
bool
|
||||
ircd::tokens(const string_view &str,
|
||||
const string_view &sep,
|
||||
const token_view_bool &closure)
|
||||
const token_view &closure)
|
||||
{
|
||||
using type = string_view;
|
||||
using iter = typename type::const_iterator;
|
||||
|
@ -464,48 +466,6 @@ ircd::tokens(const string_view &str,
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ircd::tokens(const string_view &str,
|
||||
const char &sep,
|
||||
const token_view &closure)
|
||||
{
|
||||
using type = string_view;
|
||||
using iter = typename type::const_iterator;
|
||||
using delim = boost::char_separator<char>;
|
||||
|
||||
assert(sep != '\0');
|
||||
const char _sep[2]
|
||||
{
|
||||
sep, '\0'
|
||||
};
|
||||
|
||||
const delim d{_sep};
|
||||
const boost::tokenizer<delim, iter, type> view
|
||||
{
|
||||
str, d
|
||||
};
|
||||
|
||||
std::for_each(begin(view), end(view), closure);
|
||||
}
|
||||
|
||||
void
|
||||
ircd::tokens(const string_view &str,
|
||||
const string_view &sep,
|
||||
const token_view &closure)
|
||||
{
|
||||
using type = string_view;
|
||||
using iter = typename type::const_iterator;
|
||||
using delim = string_separator;
|
||||
|
||||
const delim d{sep};
|
||||
const boost::tokenizer<delim, iter, type> view
|
||||
{
|
||||
str, d
|
||||
};
|
||||
|
||||
std::for_each(begin(view), end(view), closure);
|
||||
}
|
||||
|
||||
//
|
||||
// string_separator
|
||||
//
|
||||
|
|
|
@ -182,7 +182,7 @@ try
|
|||
json::get(event, top, json::object{})
|
||||
};
|
||||
|
||||
tokens(path, ".", token_view_bool{[&value]
|
||||
tokens(path, ".", [&value]
|
||||
(const string_view &key)
|
||||
{
|
||||
if(!json::type(value, json::OBJECT))
|
||||
|
@ -194,7 +194,7 @@ try
|
|||
|
||||
value = json::string(value);
|
||||
return false;
|
||||
}});
|
||||
});
|
||||
|
||||
//TODO: XXX spec leading/trailing; not imatch
|
||||
const globular_imatch pattern
|
||||
|
|
Loading…
Reference in a new issue