// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2018 Jason Volk // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice is present in all copies. The // full license for this software is available in the LICENSE file. #pragma once #define HAVE_IRCD_TOKENS_H 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 = closure_bool; bool tokens(const string_view &, const char sep, const token_view &) noexcept; bool tokens(const string_view &, const string_view &sep, const token_view &) noexcept; size_t tokens(const string_view &, const char sep, const size_t lim, const token_view &) noexcept; size_t tokens(const string_view &, const string_view &sep, const size_t lim, const token_view &) noexcept; // Copies tokens into your buffer and null terminates strtok() style. Returns BYTES of buf consumed. size_t tokens(const string_view &, const char sep, const mutable_buffer &, const token_view &) noexcept; size_t tokens(const string_view &, const string_view &sep, const mutable_buffer &, const token_view &) noexcept; // Receive token view into iterator range template it tokens(const string_view &str, const sep &, const it &b, const it &e); // Receive token view into array template size_t tokens(const string_view &str, const sep &, string_view (&buf)[N]); // Receive token view into std::array template size_t tokens(const string_view &str, const sep &, std::array &); // Receive token view into new container (custom allocator) template class C, //= std::vector, class T = string_view, class A, class sep> C tokens(A&& allocator, const string_view &str, const sep &); // Receive token view into new container template class C, //= std::vector, class T = string_view, class A = std::allocator, class sep> C tokens(const string_view &str, const sep &); // Receive token view into new associative container (custom allocator) template class C, class T = string_view, class Comp = std::less, class A, class sep> C tokens(A&& allocator, const string_view &str, const sep &); // Receive token view into new associative container template class C, class T = string_view, class Comp = std::less, class A = std::allocator, class sep> C tokens(const string_view &str, const sep &); } // Tools namespace ircd { size_t token_count(const string_view &str, const char sep) noexcept; size_t token_count(const string_view &str, const string_view &sep) noexcept; bool token_exists(const string_view &str, const char sep, const string_view &token) noexcept; bool token_exists(const string_view &str, const string_view &sep, const string_view &token) noexcept; 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) noexcept; string_view token(const string_view &str, const string_view &sep, const size_t at, const string_view &def) noexcept; 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 ssize_t at = 0) noexcept; string_view tokens_after(const string_view &str, const string_view &sep, const ssize_t at = 0) noexcept; string_view tokens_before(const string_view &str, const char sep, const size_t at = 0) noexcept; string_view tokens_before(const string_view &str, const string_view &sep, const size_t at = 0) noexcept; } template inline size_t ircd::tokens(const string_view &str, const delim &sep, string_view (&buf)[N]) { const auto e(tokens(str, sep, begin(buf), end(buf))); return std::distance(begin(buf), e); } template inline size_t ircd::tokens(const string_view &str, const delim &sep, std::array &buf) { const auto e(tokens(str, sep, begin(buf), end(buf))); return std::distance(begin(buf), e); } template inline it ircd::tokens(const string_view &str, const delim &sep, const it &b, const it &e) { it pos(b); tokens(str, sep, std::distance(b, e), [&pos] (const string_view &token) { *pos = token; ++pos; }); return pos; } template class C, class T, class Comp, class A, class delim> inline C ircd::tokens(const string_view &str, const delim &sep) { return tokens(A{}, str, sep); } template class C, class T, class Comp, class A, class delim> inline C ircd::tokens(A&& allocator, const string_view &str, const delim &sep) { C ret(std::forward(allocator)); tokens(str, sep, [&ret] (const string_view &token) { ret.emplace(ret.end(), token); return true; }); return ret; } template class C, class T, class A, class delim> inline C ircd::tokens(const string_view &str, const delim &sep) { return tokens(A{}, str, sep); } template class C, class T, class A, class delim> inline C ircd::tokens(A&& allocator, const string_view &str, const delim &sep) { C ret(std::forward(allocator)); tokens(str, sep, [&ret] (const string_view &token) { ret.emplace(ret.end(), token); return true; }); return ret; }