util: move spanparsing.h Split functions to string.h

This will help move the miniscript / descriptor parsing functions out of the
util library in an upcoming commit, so they are not exposed to libbitcoinkernel
applications. Moving the Split functions should also make them more
discoverable since they now close to related functions like Join.

The functions are moved verbatim without any changes.
This commit is contained in:
Ryan Ofsky 2023-12-06 15:37:49 -05:00
parent 23cc8ddff4
commit 6dd2ad4792
3 changed files with 46 additions and 40 deletions

View file

@ -7,6 +7,7 @@
#include <script/sign.h> #include <script/sign.h>
#include <test/util/setup_common.h> #include <test/util/setup_common.h>
#include <util/strencodings.h> #include <util/strencodings.h>
#include <util/string.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
@ -400,7 +401,6 @@ void CheckInferDescriptor(const std::string& script_hex, const std::string& expe
provider.pubkeys.emplace(origin_pubkey.GetID(), origin_pubkey); provider.pubkeys.emplace(origin_pubkey.GetID(), origin_pubkey);
if (!origin_str.empty()) { if (!origin_str.empty()) {
using namespace spanparsing;
KeyOriginInfo info; KeyOriginInfo info;
Span<const char> origin_sp{origin_str}; Span<const char> origin_sp{origin_str};
std::vector<Span<const char>> origin_split = Split(origin_sp, "/"); std::vector<Span<const char>> origin_split = Split(origin_sp, "/");

View file

@ -6,10 +6,9 @@
#define BITCOIN_UTIL_SPANPARSING_H #define BITCOIN_UTIL_SPANPARSING_H
#include <span.h> #include <span.h>
#include <util/string.h>
#include <string> #include <string>
#include <string_view>
#include <vector>
namespace spanparsing { namespace spanparsing {
@ -37,41 +36,11 @@ bool Func(const std::string& str, Span<const char>& sp);
*/ */
Span<const char> Expr(Span<const char>& sp); Span<const char> Expr(Span<const char>& sp);
/** Split a string on any char found in separators, returning a vector. /** Split alias for backwards compatibility */
* template <typename... Args>
* If sep does not occur in sp, a singleton with the entirety of sp is returned. auto Split(Args&&... args)
*
* Note that this function does not care about braces, so splitting
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
*/
template <typename T = Span<const char>>
std::vector<T> Split(const Span<const char>& sp, std::string_view separators)
{ {
std::vector<T> ret; return ::Split(std::forward<Args>(args)...);
auto it = sp.begin();
auto start = it;
while (it != sp.end()) {
if (separators.find(*it) != std::string::npos) {
ret.emplace_back(start, it);
start = it + 1;
}
++it;
}
ret.emplace_back(start, it);
return ret;
}
/** Split a string on every instance of sep, returning a vector.
*
* If sep does not occur in sp, a singleton with the entirety of sp is returned.
*
* Note that this function does not care about braces, so splitting
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
*/
template <typename T = Span<const char>>
std::vector<T> Split(const Span<const char>& sp, char sep)
{
return Split<T>(sp, std::string_view{&sep, 1});
} }
} // namespace spanparsing } // namespace spanparsing

View file

@ -5,7 +5,7 @@
#ifndef BITCOIN_UTIL_STRING_H #ifndef BITCOIN_UTIL_STRING_H
#define BITCOIN_UTIL_STRING_H #define BITCOIN_UTIL_STRING_H
#include <util/spanparsing.h> #include <span.h>
#include <array> #include <array>
#include <cstdint> #include <cstdint>
@ -18,14 +18,51 @@
void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute); void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute);
/** Split a string on any char found in separators, returning a vector.
*
* If sep does not occur in sp, a singleton with the entirety of sp is returned.
*
* Note that this function does not care about braces, so splitting
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
*/
template <typename T = Span<const char>>
std::vector<T> Split(const Span<const char>& sp, std::string_view separators)
{
std::vector<T> ret;
auto it = sp.begin();
auto start = it;
while (it != sp.end()) {
if (separators.find(*it) != std::string::npos) {
ret.emplace_back(start, it);
start = it + 1;
}
++it;
}
ret.emplace_back(start, it);
return ret;
}
/** Split a string on every instance of sep, returning a vector.
*
* If sep does not occur in sp, a singleton with the entirety of sp is returned.
*
* Note that this function does not care about braces, so splitting
* "foo(bar(1),2),3) on ',' will return {"foo(bar(1)", "2)", "3)"}.
*/
template <typename T = Span<const char>>
std::vector<T> Split(const Span<const char>& sp, char sep)
{
return Split<T>(sp, std::string_view{&sep, 1});
}
[[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep) [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, char sep)
{ {
return spanparsing::Split<std::string>(str, sep); return Split<std::string>(str, sep);
} }
[[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, std::string_view separators) [[nodiscard]] inline std::vector<std::string> SplitString(std::string_view str, std::string_view separators)
{ {
return spanparsing::Split<std::string>(str, separators); return Split<std::string>(str, separators);
} }
[[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v") [[nodiscard]] inline std::string_view TrimStringView(std::string_view str, std::string_view pattern = " \f\n\r\t\v")