#include "cpp-common/bt2s/string-view.hpp"
#include "cpp-common/vendor/fmt/format.h"
+#include "type-traits.hpp"
+
namespace bt2c {
/*
return str ? *str : "(null)";
}
+namespace internal {
+
+template <typename StrT>
+const char *asConstCharPtr(StrT&& val) noexcept
+{
+ return val.data();
+}
+
+inline const char *asConstCharPtr(const char * const val) noexcept
+{
+ return val;
+}
+
+template <typename StrT>
+using ComparableWithCStringView =
+ IsOneOf<typename std::decay<StrT>::type, CStringView, std::string, const char *>;
+
+} /* namespace internal */
+
+/*
+ * Returns true if `lhs` is equal to `rhs`.
+ *
+ * `LhsT` and `RhsT` may be any of:
+ *
+ * • `const char *`
+ * • `std::string`
+ * • `CStringView`
+ *
+ * Both `lhs` and `rhs` must not have an underlying `nullptr` raw data.
+ */
+template <
+ typename LhsT, typename RhsT,
+ typename = typename std::enable_if<internal::ComparableWithCStringView<LhsT>::value>::type,
+ typename = typename std::enable_if<internal::ComparableWithCStringView<RhsT>::value>::type>
+bool operator==(LhsT&& lhs, RhsT&& rhs) noexcept
+{
+ const auto rawLhs = internal::asConstCharPtr(lhs);
+ const auto rawRhs = internal::asConstCharPtr(rhs);
+
+ BT_ASSERT_DBG(rawLhs);
+ BT_ASSERT_DBG(rawRhs);
+ return std::strcmp(rawLhs, rawRhs) == 0;
+}
+
+/*
+ * Returns true if `lhs` is not equal to `rhs`.
+ *
+ * `LhsT` and `RhsT` may be any of:
+ *
+ * • `const char *`
+ * • `std::string`
+ * • `CStringView`
+ *
+ * Both `lhs` and `rhs` must not have an underlying `nullptr` raw data.
+ */
+template <typename LhsT, typename RhsT>
+bool operator!=(LhsT&& lhs, RhsT&& rhs) noexcept
+{
+ return !(std::forward<LhsT>(lhs) == std::forward<RhsT>(rhs));
+}
+
} /* namespace bt2c */
#endif /* BABELTRACE_CPP_COMMON_BT2C_C_STRING_VIEW_HPP */
plugins \
param-validation
+AM_CPPFLAGS += -I$(top_srcdir)/tests/utils
+
+COMMON_TEST_LDADD = \
+ $(top_builddir)/tests/utils/tap/libtap.la \
+ $(top_builddir)/src/common/libcommon.la \
+ $(top_builddir)/src/logging/liblogging.la
+
# Directories added to EXTRA_DIST will be recursively copied to the distribution.
EXTRA_DIST = $(srcdir)/data \
bindings/python/bt2/.coveragerc
python-plugin-provider/test-python-plugin-provider.sh \
python-plugin-provider/test_python_plugin_provider.py
+noinst_PROGRAMS =
+
TESTS_BINDINGS =
if ENABLE_PYTHON_BINDINGS
cli/test-trace-read.sh \
cli/test-trimmer.sh
+noinst_PROGRAMS += \
+ cpp-common/test-c-string-view
+
+cpp_common_test_c_string_view_SOURCES = \
+ cpp-common/test-c-string-view.cpp
+
+cpp_common_test_c_string_view_LDADD = \
+ $(COMMON_TEST_LDADD)
+
+TESTS_CPP_COMMON = \
+ cpp-common/test-c-string-view
+
TESTS_LIB = \
lib/test-bt-uuid \
lib/test-bt-values \
TESTS_NO_BITFIELD = \
$(TESTS_BINDINGS) \
$(TESTS_CLI) \
+ $(TESTS_CPP_COMMON) \
$(TESTS_CTF_WRITER) \
$(TESTS_LIB) \
$(TESTS_PARAM_VALIDATION) \
$(eval $(call check_target,bindings,$(TESTS_BINDINGS)))
$(eval $(call check_target,bitfield,$(TESTS_BITFIELD)))
$(eval $(call check_target,cli,$(TESTS_CLI)))
+$(eval $(call check_target,cpp-common,$(TESTS_CPP_COMMON)))
$(eval $(call check_target,ctf-writer,$(TESTS_CTF_WRITER)))
$(eval $(call check_target,lib,$(TESTS_LIB)))
$(eval $(call check_target,plugins,$(TESTS_PLUGINS)))
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2024 EfficiOS, Inc.
+ */
+
+#include <string>
+
+#include "cpp-common/bt2c/c-string-view.hpp"
+
+#include "tap/tap.h"
+
+namespace {
+
+template <typename StrT>
+const char *asConstCharPtr(StrT&& val)
+{
+ return val.data();
+}
+
+const char *asConstCharPtr(const char * const val)
+{
+ return val;
+}
+
+const char *typeName(bt2c::CStringView)
+{
+ return "bt2c::CStringView";
+}
+
+const char *typeName(const char *)
+{
+ return "const char *";
+}
+
+const char *typeName(const std::string&)
+{
+ return "std::string";
+}
+
+template <typename Str1T, typename Str2T>
+void testEq(Str1T&& lhs, Str2T&& rhs)
+{
+ BT_ASSERT(asConstCharPtr(lhs) != asConstCharPtr(rhs));
+ ok(lhs == rhs, "`%s` == `%s`", typeName(lhs), typeName(rhs));
+}
+
+template <typename Str1T, typename Str2T>
+void testNe(Str1T&& lhs, Str2T&& rhs)
+{
+ BT_ASSERT(asConstCharPtr(lhs) != asConstCharPtr(rhs));
+ ok(lhs != rhs, "`%s` != `%s`", typeName(lhs), typeName(rhs));
+}
+
+void testEquality()
+{
+ const std::string foo1 = "foo", foo2 = "foo";
+ const std::string bar = "bar";
+
+ /* `CStringView` vs `CStringView` */
+ testEq(bt2c::CStringView {foo1}, bt2c::CStringView {foo2});
+ testNe(bt2c::CStringView {foo1}, bt2c::CStringView {bar});
+
+ /* `CStringView` vs `const char *` */
+ testEq(bt2c::CStringView {foo1}, foo2.c_str());
+ testNe(bt2c::CStringView {foo1}, bar.c_str());
+ testEq(foo1.c_str(), bt2c::CStringView {foo2});
+ testNe(foo1.c_str(), bt2c::CStringView {bar});
+
+ /* `StringView` vs `std::string` */
+ testEq(bt2c::CStringView {foo1}, foo2);
+ testNe(bt2c::CStringView {foo1}, bar);
+ testEq(foo1, bt2c::CStringView {foo2});
+ testNe(foo1, bt2c::CStringView {bar});
+}
+
+} // namespace
+
+int main()
+{
+ plan_tests(10);
+ testEquality();
+ return exit_status();
+}