0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2025-01-13 08:23:56 +01:00

ircd: Add more stringops tokenizer overloads.

This commit is contained in:
Jason Volk 2016-10-23 18:15:19 -07:00
parent 9ecb26d27e
commit c704c67aa5
2 changed files with 107 additions and 18 deletions

View file

@ -26,12 +26,19 @@
#ifdef __cplusplus
namespace ircd {
size_t token_count(const std::string &str, const char *const &sep);
const std::string &token(const std::string &str, const char *const &sep, const size_t &at);
const std::string &token_last(const std::string &str, const char *const &sep);
using token_closure_cstr = std::function<void (char *const &)>;
void tokens(char *const &str, const char *const &sep, const token_closure_cstr &);
void tokens(const char *const &str, const char *const &sep, char *const &buf, const size_t &max, const token_closure_cstr &);
void tokens(const char *const &str, const char *const &sep, const token_closure_cstr &);
void tokensa(const char *const &str, const char *const &sep, const token_closure_cstr &);
std::vector<char *> tokens(const char *const &str, const char *const &sep, char *const &buf, const size_t &max, const size_t &reserve = 16);
using token_closure_string = std::function<void (const std::string &)>;
void tokens(const std::string &str, const char *const &sep, const token_closure_string &);
std::vector<std::string> tokens(const std::string &str, const char *const &sep, const size_t &reserve = 16);
size_t token_count(const std::string &str, const char *const &sep);
std::string token(const std::string &str, const char *const &sep, const size_t &at);
std::string token_last(const std::string &str, const char *const &sep);
std::string chomp(const std::string &str, const std::string &c = " "s);
std::pair<std::string, std::string> split(const std::string &str, const std::string &delim = " "s);

View file

@ -140,19 +140,7 @@ ircd::reconstruct_parv(int parc, const char *parv[])
return tmpbuf;
}
void
ircd::tokens(const std::string &str,
const char *const &sep,
const token_closure_string &closure)
{
using delim = boost::char_separator<char>;
const delim d(sep);
const boost::tokenizer<delim> view(str, d);
std::for_each(begin(view), end(view), closure);
}
const std::string &
std::string
ircd::token(const std::string &str,
const char *const &sep,
const size_t &at)
@ -168,12 +156,15 @@ ircd::token(const std::string &str,
if(i == at)
return *it;
if(str.empty())
return str;
// Moving the iterator may cause a parse, so there is no pre-check on the bounds;
// the valid token is returned in the loop, and exiting the loop is an error.
throw std::out_of_range("token out of range");
}
const std::string &
std::string
ircd::token_last(const std::string &str,
const char *const &sep)
{
@ -184,7 +175,7 @@ ircd::token_last(const std::string &str,
auto it(begin(view));
if(it == end(view))
throw std::out_of_range("token out of range");
return str.empty()? str : throw std::out_of_range("token out of range");
auto ret(it);
while(it != end(view))
@ -203,3 +194,94 @@ ircd::token_count(const std::string &str,
const boost::tokenizer<delim> view(str, d);
return std::distance(begin(view), end(view));
}
std::vector<std::string>
ircd::tokens(const std::string &str,
const char *const &sep,
const size_t &reserve)
{
using delim = boost::char_separator<char>;
std::vector<std::string> ret;
ret.reserve(reserve);
const delim d(sep);
const boost::tokenizer<delim> view(str, d);
std::copy(begin(view), end(view), std::back_inserter(ret));
return ret;
}
void
ircd::tokens(const std::string &str,
const char *const &sep,
const token_closure_string &closure)
{
using delim = boost::char_separator<char>;
const delim d(sep);
const boost::tokenizer<delim> view(str, d);
std::for_each(begin(view), end(view), closure);
}
std::vector<char *>
ircd::tokens(const char *const &str,
const char *const &sep,
char *const &buf,
const size_t &max,
const size_t &reserve)
{
std::vector<char *> ret;
ret.reserve(reserve);
rb_strlcpy(buf, str, max);
tokens(buf, sep, [&ret]
(char *const &token)
{
ret.emplace_back(token);
});
return ret;
}
void
ircd::tokensa(const char *const &str,
const char *const &sep,
const token_closure_cstr &closure)
{
custom_ptr<char> cpy(strdup(str), std::free);
tokens(cpy.get(), sep, closure);
}
void
ircd::tokens(const char *const &str,
const char *const &sep,
const token_closure_cstr &closure)
{
const auto len(strlen(str));
char buf[strlen(str) + 1];
tokens(str, sep, buf, sizeof(buf), closure);
}
void
ircd::tokens(const char *const &str,
const char *const &sep,
char *const &buf,
const size_t &max,
const token_closure_cstr &closure)
{
rb_strlcpy(buf, str, max);
tokens(buf, sep, closure);
}
void
ircd::tokens(char *const &str,
const char *const &sep,
const token_closure_cstr &closure)
{
char *ctx;
char *tok(strtok_r(str, sep, &ctx)); do
{
closure(tok);
}
while((tok = strtok_r(NULL, sep, &ctx)) != NULL);
}