Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New strConcat concatenates strings in O(n) time. #337

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 29 additions & 2 deletions src/ripple_basics/utility/StringUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,41 @@ class StringUtilities_test : public beast::unit_test::suite
"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
82 changes: 81 additions & 1 deletion src/ripple_basics/utility/StringUtilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -131,6 +131,86 @@ bool parseUrl (const std::string& strUrl, std::string& strScheme, std::string& s
extern beast::StringPairArray
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 T>
std::string 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.insert(result.end(), a.data_, a.data_ + a.size_);
return result;
}

} // ripple

#endif