From 5e816dfdd7f73b1bf58533c4f5aa3f78d8de2a58 Mon Sep 17 00:00:00 2001 From: Rainer Kuemmerle Date: Tue, 13 Aug 2024 12:53:39 +0200 Subject: [PATCH 1/2] Implement joining iterator ranges into a string --- g2o/stuff/string_tools.h | 26 ++++++++++++++++++++++++++ unit_test/stuff/string_tools_tests.cpp | 8 ++++++++ 2 files changed, 34 insertions(+) diff --git a/g2o/stuff/string_tools.h b/g2o/stuff/string_tools.h index 08cecaf12..d97011469 100644 --- a/g2o/stuff/string_tools.h +++ b/g2o/stuff/string_tools.h @@ -27,6 +27,8 @@ #ifndef G2O_STRING_TOOLS_H #define G2O_STRING_TOOLS_H +#include +#include #include #include #include @@ -115,6 +117,30 @@ G2O_STUFF_API std::string strExpandFilename(const std::string& filename); G2O_STUFF_API std::vector strSplit(const std::string& s, const std::string& delim); +/** + * @brief Join into a string using a delimeter + * + * @tparam Iterator + * @tparam std::iterator_traits::value_type + * @param b begin of the range for output + * @param e end of the range for output + * @param delimiter will be inserted in between elements + * @return std::string joined string + */ +template ::value_type> +std::string strJoin(Iterator b, Iterator e, const std::string& delimiter = "") { + if (b == e) return ""; + std::ostringstream os; + std::copy(b, std::prev(e), + std::ostream_iterator(os, delimiter.c_str())); + b = std::prev(e); + if (b != e) { + os << *b; + } + return os.str(); +} + /** * read a line from is into currentLine. * @return the number of characters read into currentLine (excluding newline), diff --git a/unit_test/stuff/string_tools_tests.cpp b/unit_test/stuff/string_tools_tests.cpp index b5dbc5f42..9d2251d44 100644 --- a/unit_test/stuff/string_tools_tests.cpp +++ b/unit_test/stuff/string_tools_tests.cpp @@ -79,6 +79,14 @@ TEST(Stuff, StrSplit) { ASSERT_EQ(std::to_string(i + 1), tokens[i]); } +TEST(Stuff, StrJoin) { + std::vector int_data = {1, 2, 3}; + EXPECT_EQ("123", g2o::strJoin(int_data.begin(), int_data.end())); + EXPECT_EQ("1", g2o::strJoin(int_data.begin(), std::next(int_data.begin()))); + EXPECT_EQ("", g2o::strJoin(int_data.begin(), int_data.begin())); + EXPECT_EQ("1, 2, 3", g2o::strJoin(int_data.begin(), int_data.end(), ", ")); +} + TEST(Stuff, StrStartsWith) { ASSERT_FALSE(g2o::strStartsWith("Hello World!", "World!")); ASSERT_TRUE(g2o::strStartsWith("Hello World!", "Hello")); From b6ebf6f68754b6a91deb16a24b2a557658967dbc Mon Sep 17 00:00:00 2001 From: Rainer Kuemmerle Date: Tue, 13 Aug 2024 12:54:27 +0200 Subject: [PATCH 2/2] Use strJoin instead of fmt::join Fix #825 --- g2o/core/optimizable_graph.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/g2o/core/optimizable_graph.cpp b/g2o/core/optimizable_graph.cpp index 7fbbe30d1..7fc350281 100644 --- a/g2o/core/optimizable_graph.cpp +++ b/g2o/core/optimizable_graph.cpp @@ -473,14 +473,14 @@ bool OptimizableGraph::load(istream& is) { } if (!vertsOkay) { G2O_ERROR("Unable to find vertices for edge {} at line {} IDs: {}", - token, lineNumber, fmt::join(ids, " ")); + token, lineNumber, strJoin(ids.begin(), ids.end(), " ")); delete e; e = nullptr; } else { bool r = e->read(currentLine); if (!r || !addEdge(e)) { G2O_ERROR("Unable to add edge {} at line {} IDs: {}", token, - lineNumber, fmt::join(ids, " ")); + lineNumber, strJoin(ids.begin(), ids.end(), " ")); delete e; e = nullptr; }