0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-05-29 00:03:45 +02:00

ircd::tokens: Simplify interface w/ closure template; eliminate named closure.

ircd::tokens: Minor interface cleanup; inline linkages.
This commit is contained in:
Jason Volk 2020-11-27 16:56:56 -08:00
parent 266e617e36
commit ded8f05064
4 changed files with 52 additions and 79 deletions

View file

@ -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)

View file

@ -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;
}});
});
}

View file

@ -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
//

View file

@ -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