New strConcat concatenates strings in O(n) time.

* Accepts std::string and char const*.
* Also accepts numbers, bools and chars.
* New ripple::toString function augments std::to_string to handle
  bools and chars.
This commit is contained in:
Tom Swirly
2014-04-27 11:16:12 -04:00
committed by Vinnie Falco
parent 3c5e4e440b
commit 96e8cddfc2
2 changed files with 116 additions and 5 deletions

View File

@@ -412,14 +412,41 @@ public:
"parseUrl: Mixed://domain/path path failed");
}
void testStringConcat ()
{
testcase ("stringConcat");
auto result = stringConcat({});
expect(result == "", result);
result = stringConcat({"hello, ", std::string("world.")});
expect(result == "hello, world.", result);
result = stringConcat({"hello, ", 23});
expect(result == "hello, 23", result);
result = stringConcat({"hello, ", true});
expect(result == "hello, true", result);
result = stringConcat({"hello, ", 'x'});
expect(result == "hello, x", result);
}
void testToString ()
{
testcase ("toString");
auto result = toString("hello");
expect(result == "hello", result);
}
void run ()
{
testParseUrl ();
testUnHex ();
testStringConcat ();
testToString ();
}
};
BEAST_DEFINE_TESTSUITE(StringUtilities,ripple_basics,ripple);
BEAST_DEFINE_TESTSUITE(StringUtilities, ripple_basics, ripple);
} // ripple

View File

@@ -26,7 +26,7 @@ namespace ripple {
// Ripple specific constant used for parsing qualities and other things
//
// NIKB TODO Why is this here instead of somewhere more sensible? What
// NIKB TODO Why is this here instead of somewhere more sensible? What
// "other things" is this being used for?
#define QUALITY_ONE 1000000000 // 10e9
@@ -118,7 +118,8 @@ inline std::string strGetEnv (const std::string& strKey)
return getenv (strKey.c_str ()) ? getenv (strKey.c_str ()) : "";
}
bool parseUrl (const std::string& strUrl, std::string& strScheme, std::string& strDomain, int& iPort, std::string& strPath);
bool parseUrl (const std::string& strUrl, std::string& strScheme,
std::string& strDomain, int& iPort, std::string& strPath);
#define ADDRESS(p) strHex(uint64( ((char*) p) - ((char*) 0)))
@@ -129,7 +130,90 @@ bool parseUrl (const std::string& strUrl, std::string& strScheme, std::string& s
<key>=<value>['|'<key>=<value>]
*/
extern beast::StringPairArray
parseDelimitedKeyValueString (beast::String s, beast::beast_wchar delimiter='|');
parseDelimitedKeyValueString (
beast::String s, beast::beast_wchar delimiter='|');
/** toString() generalizes std::to_string to handle bools, chars, and strings.
It's also possible to provide implementation of toString for a class
which needs a string implementation.
*/
template <class T>
typename std::enable_if<std::is_arithmetic<T>::value,
std::string>::type
toString(T t)
{
return std::to_string(t);
}
inline std::string toString(bool b)
{
return b ? "true" : "false";
}
inline std::string toString(char c)
{
return std::string(1, c);
}
inline std::string toString(std::string s)
{
return s;
}
inline std::string toString(char const* s)
{
return s;
}
namespace detail {
// ConcatArg is used to represent arguments to stringConcat.
struct ConcatArg {
ConcatArg(std::string const& s) : data_(s.data()), size_(s.size())
{
}
ConcatArg(char const* s) : data_(s), size_(strlen(s))
{
}
template <typename T>
ConcatArg(T t) : string_(toString(t)),
data_(string_.data()),
size_(string_.size())
{
}
std::string string_;
char const* data_;
std::size_t size_;
};
} // namespace detail
/** Concatenate strings, numbers, bools and chars into one string in O(n) time.
Usage:
stringConcat({"hello ", 23, 'x', true});
Returns:
"hello 23xtrue"
*/
inline std::string stringConcat(std::vector<detail::ConcatArg> args)
{
int capacity = 0;
for (auto const& a: args)
capacity += a.size_;
std::string result;
result.reserve(capacity);
for (auto const& a: args)
result.append(a.data_, a.data_ + a.size_);
return result;
}
} // ripple