This is an automated email from the ASF dual-hosted git repository.
phrocker pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi-minifi-cpp.git
The following commit(s) were added to refs/heads/master by this push:
new ca2a68d MINIFICPP-910 - Extend StringUtils with string join capability
ca2a68d is described below
commit ca2a68d6ec53924351ae1262c09cb47f28c0579c
Author: Arpad Boda <[email protected]>
AuthorDate: Wed Jun 19 01:08:01 2019 +0200
MINIFICPP-910 - Extend StringUtils with string join capability
This closes #585.
Signed-off-by: Marc Parisi <[email protected]>
---
libminifi/include/utils/StringUtils.h | 85 ++++++++++++++++++++++++++++++++
libminifi/test/unit/StringUtilsTests.cpp | 19 +++++++
2 files changed, 104 insertions(+)
diff --git a/libminifi/include/utils/StringUtils.h
b/libminifi/include/utils/StringUtils.h
index daf3a20..326a048 100644
--- a/libminifi/include/utils/StringUtils.h
+++ b/libminifi/include/utils/StringUtils.h
@@ -47,6 +47,26 @@ namespace nifi {
namespace minifi {
namespace utils {
+namespace {
+ template<class Char>
+ struct string_traits;
+ template<>
+ struct string_traits<char>{
+ template<class T>
+ static std::string convert_to_string(T&& t){
+ return std::to_string(std::forward<T>(t));
+ }
+ };
+
+ template<>
+ struct string_traits<wchar_t>{
+ template<class T>
+ static std::wstring convert_to_string(T&& t){
+ return std::to_wstring(std::forward<T>(t));
+ }
+ };
+}
+
/**
* Stateless String utility class.
*
@@ -262,6 +282,71 @@ class StringUtils {
return result_string;
}
+ /**
+ * Concatenates strings stored in an arbitrary container using the provided
separator.
+ * @tparam TChar char type of the string (char or wchar_t)
+ * @tparam U arbitrary container which has string or wstring value type
+ * @param separator that is inserted between each elements. Type should match
the type of strings in container.
+ * @param container that contains the strings to be concatenated
+ * @return the result string
+ */
+ template<class TChar, class U, typename std::enable_if<std::is_same<typename
U::value_type, std::basic_string<TChar>>::value>::type* = nullptr>
+ static std::basic_string<TChar> join(const std::basic_string<TChar>&
separator, const U& container) {
+ typedef typename U::const_iterator ITtype;
+ ITtype it = container.cbegin();
+ std::basic_stringstream<TChar> sstream;
+ while(it != container.cend()) {
+ sstream << (*it);
+ ++it;
+ if(it != container.cend()) {
+ sstream << separator;
+ }
+ }
+ return sstream.str();
+ };
+
+ /**
+ * Just a wrapper for the above function to be able to create separator from
const char* or const wchar_t*
+ */
+ template<class TChar, class U, typename std::enable_if<std::is_same<typename
U::value_type, std::basic_string<TChar>>::value>::type* = nullptr>
+ static std::basic_string<TChar> join(const TChar* separator, const U&
container) {
+ return join(std::basic_string<TChar>(separator), container);
+ };
+
+
+ /**
+ * Concatenates string representation of integrals stored in an arbitrary
container using the provided separator.
+ * @tparam TChar char type of the string (char or wchar_t)
+ * @tparam U arbitrary container which has any integral value type
+ * @param separator that is inserted between each elements. Type of this
determines the result type. (wstring separator -> wstring)
+ * @param container that contains the integrals to be concatenated
+ * @return the result string
+ */
+ template<class TChar, class U, typename
std::enable_if<std::is_integral<typename U::value_type>::value>::type* =
nullptr,
+ typename std::enable_if<!std::is_same<U,
std::basic_string<TChar>>::value>::type* = nullptr>
+ static std::basic_string<TChar> join(const std::basic_string<TChar>&
separator, const U& container) {
+ typedef typename U::const_iterator ITtype;
+ ITtype it = container.cbegin();
+ std::basic_stringstream<TChar> sstream;
+ while(it != container.cend()) {
+ sstream << string_traits<TChar>::convert_to_string(*it);
+ ++it;
+ if(it != container.cend()) {
+ sstream << separator;
+ }
+ }
+ return sstream.str();
+ }
+
+ /**
+ * Just a wrapper for the above function to be able to create separator from
const char* or const wchar_t*
+ */
+ template<class TChar, class U, typename
std::enable_if<std::is_integral<typename U::value_type>::value>::type* =
nullptr,
+ typename std::enable_if<!std::is_same<U,
std::basic_string<TChar>>::value>::type* = nullptr>
+ static std::basic_string<TChar> join(const TChar* separator, const U&
container) {
+ return join(std::basic_string<TChar>(separator), container);
+ };
+
};
} /* namespace utils */
diff --git a/libminifi/test/unit/StringUtilsTests.cpp
b/libminifi/test/unit/StringUtilsTests.cpp
index 3abf339..6486f29 100644
--- a/libminifi/test/unit/StringUtilsTests.cpp
+++ b/libminifi/test/unit/StringUtilsTests.cpp
@@ -17,6 +17,7 @@
*/
#include <string>
+#include <list>
#include <vector>
#include <cstdlib>
#include "../TestBase.h"
@@ -93,3 +94,21 @@ TEST_CASE("TestStringUtils::testEnv5", "[test split
classname]") {
REQUIRE(expected == StringUtils::replaceEnvironmentVariables(test_string));
}
+
+TEST_CASE("TestStringUtils::testJoin", "[test string join]") {
+ std::set<std::string> strings = {"3", "2", "1"};
+ REQUIRE(StringUtils::join(",", strings) == "1,2,3");
+
+ std::wstring sep = L"é";
+ std::vector<std::wstring> wstrings = {L"1", L"2"};
+ REQUIRE(StringUtils::join(sep, wstrings) == L"1é2");
+
+ std::list<uint64_t> ulist = {1, 2};
+ REQUIRE(StringUtils::join(sep, ulist) == L"1é2");
+
+ REQUIRE(StringUtils::join(">", ulist) == "1>2");
+
+ REQUIRE(StringUtils::join("", ulist) == "12");
+
+ REQUIRE(StringUtils::join("this separator wont appear",
std::vector<std::string>()) == "");
+}