From 96e8cddfc2ab69972bd73a5e96f98690b4130375 Mon Sep 17 00:00:00 2001 From: Tom Swirly Date: Sun, 27 Apr 2014 11:16:12 -0400 Subject: [PATCH] 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. --- src/ripple_basics/utility/StringUtilities.cpp | 31 ++++++- src/ripple_basics/utility/StringUtilities.h | 90 ++++++++++++++++++- 2 files changed, 116 insertions(+), 5 deletions(-) diff --git a/src/ripple_basics/utility/StringUtilities.cpp b/src/ripple_basics/utility/StringUtilities.cpp index 228b338285..c63e6249ec 100644 --- a/src/ripple_basics/utility/StringUtilities.cpp +++ b/src/ripple_basics/utility/StringUtilities.cpp @@ -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 diff --git a/src/ripple_basics/utility/StringUtilities.h b/src/ripple_basics/utility/StringUtilities.h index c7264e2840..1776540c3b 100644 --- a/src/ripple_basics/utility/StringUtilities.h +++ b/src/ripple_basics/utility/StringUtilities.h @@ -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 =['|'=] */ 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 +typename std::enable_if::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 + 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 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