[RFC,2/8] libcamera: base: utils: Add string_view concatenation operators
diff mbox series

Message ID 20241215230206.11002-3-laurent.pinchart@ideasonboard.com
State New
Headers show
Series
  • libcamera: Use std::string_view
Related show

Commit Message

Laurent Pinchart Dec. 15, 2024, 11:02 p.m. UTC
The operator+() overloads to concatenate std::string and
std::string_view instances have been introduced in C++26 only. Add a
local implementation in utils.cpp, conditioned by a meson check for
availability in the standard C++ library.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 include/libcamera/base/utils.h | 47 ++++++++++++++++++++++++++++++++++
 src/libcamera/base/meson.build | 12 +++++++++
 test/utils.cpp                 | 34 ++++++++++++++++++++++++
 3 files changed, 93 insertions(+)

Patch
diff mbox series

diff --git a/include/libcamera/base/utils.h b/include/libcamera/base/utils.h
index 780aeda6a0ce732a..dd012fd58501cd8d 100644
--- a/include/libcamera/base/utils.h
+++ b/include/libcamera/base/utils.h
@@ -433,6 +433,53 @@  private:
 template<class CharT, class Traits>
 std::basic_ostream<CharT, Traits> &operator<<(std::basic_ostream<CharT, Traits> &os,
 					      const utils::Duration &d);
+
+#if not HAVE_STD_STRING_VIEW_OPERATOR_PLUS
+template<class CharT, class Traits, class Alloc>
+std::basic_string<CharT, Traits, Alloc>
+operator+(const std::basic_string<CharT, Traits, Alloc> &lhs,
+	  std::basic_string_view<CharT, Traits> rhs)
+{
+	std::basic_string<CharT, Traits, Alloc> str;
+
+	str.reserve(lhs.size() + rhs.size());
+	str.append(lhs);
+	str.append(rhs);
+
+	return str;
+}
+
+template<class CharT, class Traits, class Alloc>
+std::basic_string<CharT, Traits, Alloc>
+operator+(std::basic_string_view<CharT, Traits> lhs,
+	  const std::basic_string<CharT, Traits, Alloc> &rhs)
+{
+	std::basic_string<CharT, Traits, Alloc> str;
+
+	str.reserve(lhs.size() + rhs.size());
+	str.append(lhs);
+	str.append(rhs);
+
+	return str;
+}
+
+template<class CharT, class Traits, class Alloc>
+std::basic_string<CharT, Traits, Alloc>
+operator+(std::basic_string<CharT, Traits, Alloc> &&lhs,
+	  std::basic_string_view<CharT, Traits> rhs)
+{
+	return std::move(lhs.append(rhs));
+}
+
+template<class CharT, class Traits, class Alloc>
+std::basic_string<CharT, Traits, Alloc>
+operator+(std::basic_string_view<CharT, Traits> lhs,
+	  std::basic_string<CharT, Traits, Alloc> &&rhs)
+{
+	return std::move(rhs.insert(0, lhs));
+}
+#endif /* HAVE_STD_STRING_VIEW_OPERATOR_PLUS */
+
 #endif
 
 } /* namespace libcamera */
diff --git a/src/libcamera/base/meson.build b/src/libcamera/base/meson.build
index a742dfdfeb24f9a9..1643d6034921a0cb 100644
--- a/src/libcamera/base/meson.build
+++ b/src/libcamera/base/meson.build
@@ -41,6 +41,18 @@  if libunwind.found()
     config_h.set('HAVE_UNWIND', 1)
 endif
 
+if cxx.compiles('''
+#include <string>
+#include <string_view>
+
+int main()
+{
+        std::string s = std::string() + std::string_view();
+        return s.size();
+}''', name : 'concatenation of std::string and std::string_view')
+    config_h.set('HAVE_STD_STRING_VIEW_OPERATOR_PLUS', 1)
+endif
+
 libcamera_base_deps = [
     libatomic,
     libdw,
diff --git a/test/utils.cpp b/test/utils.cpp
index d25475cb93b96a0a..29e3c26406b4f72e 100644
--- a/test/utils.cpp
+++ b/test/utils.cpp
@@ -170,6 +170,36 @@  protected:
 		return TestPass;
 	}
 
+	int testStringView()
+	{
+		std::string s{ "Hello" };
+		std::string_view sv{ "World!" };
+
+		if (s + sv != "HelloWorld!") {
+			cerr << "operator+(const std::string &, std::string_view) test failed";
+			return TestFail;
+		}
+
+		if (sv + s != "World!Hello") {
+			cerr << "operator+(std::string_view, const std::string &) test failed";
+			return TestFail;
+		}
+
+		if (std::move(s) + sv != "HelloWorld!") {
+			cerr << "operator+(std::string &&, std::string_view) test failed";
+			return TestFail;
+		}
+
+		s = "Hello";
+
+		if (sv + std::move(s) != "World!Hello") {
+			cerr << "operator+(std::string_view, std::string &&) test failed";
+			return TestFail;
+		}
+
+		return TestPass;
+	}
+
 	int run()
 	{
 		/* utils::hex() test. */
@@ -307,6 +337,10 @@  protected:
 		if (testDuration() != TestPass)
 			return TestFail;
 
+		/* std::string_view operator+() test. */
+		if (testStringView() != TestPass)
+			return TestFail;
+
 		return TestPass;
 	}
 };