#include "common/assert.h"
#include "cpp-common/bt2s/string-view.hpp"
-#include "cpp-common/vendor/fmt/core.h"
+#include "cpp-common/vendor/fmt/format.h" /* IWYU pragma: keep */
+
+#include "type-traits.hpp"
namespace bt2c {
*
* Intentionally not explicit.
*/
- CStringView() noexcept = default;
+ constexpr CStringView() noexcept = default;
/*
* Builds a view of the C string `str` (may be `nullptr`).
*
* Intentionally not explicit.
*/
- CStringView(const char * const str) noexcept : _mStr {str}
+ constexpr CStringView(const char * const str) noexcept : _mStr {str}
+ {
+ }
+
+ /*
+ * Builds a view of the string `str`.
+ *
+ * Intentionally not explicit.
+ */
+ CStringView(const std::string& str) noexcept : _mStr {str.c_str()}
{
}
return _mStr[i];
}
+ bool startsWith(const bt2c::CStringView prefix) const noexcept
+ {
+ BT_ASSERT_DBG(_mStr);
+ BT_ASSERT_DBG(prefix);
+ return std::strncmp(_mStr, prefix, prefix.len()) == 0;
+ }
+
private:
const char *_mStr = nullptr;
};
-} /* namespace bt2c */
+inline const char *format_as(const CStringView& str)
+{
+ return str ? *str : "(null)";
+}
-namespace fmt {
+namespace internal {
-template <>
-struct formatter<bt2c::CStringView>
+template <typename StrT>
+const char *asConstCharPtr(StrT&& val) noexcept
{
- constexpr auto parse(format_parse_context& ctx) const -> format_parse_context::iterator
- {
- return ctx.end();
- }
+ return val.data();
+}
- auto format(const bt2c::CStringView& str, format_context& ctx) const -> format_context::iterator
- {
- return str ? fmt::format_to(ctx.out(), "{}", *str) : fmt::format_to(ctx.out(), "(null)");
- }
-};
+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 fmt */
+} /* 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,
+ 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
+{
+ return !(std::forward<LhsT>(lhs) == std::forward<RhsT>(rhs));
+}
+
+} /* namespace bt2c */
+
+/*
+ * Appends `rhs` to `lhs`.
+ */
+inline void operator+=(std::string& lhs, bt2c::CStringView rhs)
+{
+ lhs += rhs.data();
+}
#endif /* BABELTRACE_CPP_COMMON_BT2C_C_STRING_VIEW_HPP */