Import CStringView from the Babeltrace tree
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Tue, 23 Apr 2024 20:46:47 +0000 (16:46 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 8 May 2024 19:52:29 +0000 (19:52 +0000)
The class is imported as of 1dcaf4b74 in the babeltrace tree. It is
renamed and reformated to fit the LTTng-tools conventions.

No changes in behaviour are intended.

Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
Change-Id: I8acc3833c52c4ac23a91af87157aade0b4bbb7c1

src/common/Makefile.am
src/common/string-utils/c-string-view.hpp [new file with mode: 0644]
src/common/type-traits.hpp [new file with mode: 0644]

index 34fd83452802f5b8caa21a347ce4264e693f1e88..8170e6e5add57dc5c66e459b9612e2bbbb2a2c4a 100644 (file)
@@ -115,6 +115,7 @@ libcommon_lgpl_la_SOURCES = \
        time.cpp \
        tracker.cpp tracker.hpp \
        trigger.cpp \
+       type-traits.hpp \
        unix.cpp unix.hpp \
        uri.cpp uri.hpp \
        userspace-probe.cpp \
@@ -432,6 +433,7 @@ endif
 # libstring-utils
 noinst_LTLIBRARIES += libstring-utils.la
 libstring_utils_la_SOURCES = \
+       string-utils/c-string-view.hpp \
        string-utils/format.hpp \
        string-utils/string-utils.cpp \
        string-utils/string-utils.hpp
diff --git a/src/common/string-utils/c-string-view.hpp b/src/common/string-utils/c-string-view.hpp
new file mode 100644 (file)
index 0000000..6b175ea
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef LTTNG_C_STRING_VIEW_HPP
+#define LTTNG_C_STRING_VIEW_HPP
+
+#include <common/format.hpp>
+#include <common/type-traits.hpp>
+
+#include <cstddef>
+#include <cstring>
+#include <functional>
+#include <string>
+
+namespace lttng {
+
+/*
+ * A view on a constant null-terminated C string.
+ */
+class c_string_view final {
+public:
+       /*
+        * Builds an empty view (data() returns `nullptr`).
+        *
+        * Intentionally not explicit.
+        */
+       constexpr c_string_view() noexcept = default;
+
+       /*
+        * Builds a view of the C string `str` (may be `nullptr`).
+        *
+        * Intentionally not explicit.
+        */
+       /* NOLINTBEGIN(google-explicit-constructor) */
+       constexpr c_string_view(const char *const str) noexcept : _str{ str }
+       {
+       }
+       /* NOLINTEND(google-explicit-constructor) */
+
+       /*
+        * Builds a view of the string `str`.
+        */
+       /* NOLINTBEGIN(google-explicit-constructor) */
+       c_string_view(const std::string& str) noexcept : _str{ str.c_str() }
+       {
+       }
+       /* NOLINTEND */
+
+       /*
+        * Makes this view view the C string `str` (may be `nullptr`).
+        */
+       c_string_view& operator=(const char *const str) noexcept
+       {
+               _str = str;
+               return *this;
+       }
+
+       /*
+        * Viewed null-terminated C string (may be `nullptr`).
+        */
+       const char *data() const noexcept
+       {
+               return _str;
+       }
+
+       /*
+        * Alias of data().
+        */
+       operator const char *() const noexcept /* NOLINT(google-explicit-constructor) */
+       {
+               return this->data();
+       }
+
+       /*
+        * Evaluate as boolean (false means an empty string).
+        */
+       operator bool() const noexcept /* NOLINT(google-explicit-constructor) */
+       {
+               return *this->data();
+       }
+
+       /*
+        * Alias of data().
+        */
+       const char *operator*() const noexcept
+       {
+               return this->data();
+       }
+
+       /*
+        * Alias of data().
+        *
+        * data() must not return `nullptr`.
+        */
+       const char *begin() const noexcept
+       {
+               return this->data();
+       }
+
+       /*
+        * Pointer to the null character of the viewed C string.
+        *
+        * data() must not return `nullptr`.
+        */
+       const char *end() const noexcept
+       {
+               return _str + this->len();
+       }
+
+       /*
+        * Length of the viewed C string, excluding the null character.
+        *
+        * data() must not return `nullptr`.
+        */
+       std::size_t len() const noexcept
+       {
+               return std::strlen(_str);
+       }
+
+       /*
+        * Returns an `std::string` instance containing a copy of the viewed
+        * C string.
+        *
+        * data() must not return `nullptr`.
+        */
+       std::string str() const
+       {
+               return std::string{ _str };
+       }
+
+       /*
+        * Alias of str().
+        */
+       operator std::string() const /* NOLINT(google-explicit-constructor) */
+       {
+               return this->str();
+       }
+
+       /*
+        * Returns the character at index `i`.
+        *
+        * `i` must be less than what len() returns.
+        *
+        * data() must not return `nullptr`.
+        */
+       char operator[](const std::size_t i) const noexcept
+       {
+               return _str[i];
+       }
+
+       bool startsWith(const lttng::c_string_view prefix) const noexcept
+       {
+               return std::strncmp(_str, (const char *) prefix, prefix.len()) == 0;
+       }
+
+private:
+       const char *_str = nullptr;
+};
+
+inline const char *format_as(const c_string_view& str)
+{
+       return str ? *str : "(null)";
+}
+
+namespace internal {
+
+template <typename StrT>
+const char *as_const_char_ptr(StrT&& val) noexcept
+{
+       return val.data();
+}
+
+inline const char *as_const_char_ptr(const char *const val) noexcept
+{
+       return val;
+}
+
+template <typename StrT>
+using comparable_with_c_string_view = lttng::traits::
+       is_one_of<typename std::decay<StrT>::type, c_string_view, 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`
+ * • `c_string_view`
+ *
+ * Both `lhs` and `rhs` must not have an underlying `nullptr` raw data.
+ */
+template <
+       typename LhsT,
+       typename RhsT,
+       typename =
+               typename std::enable_if<internal::comparable_with_c_string_view<LhsT>::value>::type,
+       typename =
+               typename std::enable_if<internal::comparable_with_c_string_view<RhsT>::value>::type>
+bool operator==(LhsT&& lhs, RhsT&& rhs) noexcept
+{
+       const auto raw_lhs = internal::as_const_char_ptr(lhs);
+       const auto raw_rhs = internal::as_const_char_ptr(rhs);
+
+       return std::strcmp(raw_lhs, raw_rhs) == 0;
+}
+
+/*
+ * Returns true if `lhs` is not equal to `rhs`.
+ *
+ * `LhsT` and `RhsT` may be any of:
+ *
+ * • `const char *`
+ * • `std::string`
+ * • `c_string_view`
+ *
+ * Both `lhs` and `rhs` must not have an underlying `nullptr` raw data.
+ */
+template <
+       typename LhsT,
+       typename RhsT,
+       typename =
+               typename std::enable_if<internal::comparable_with_c_string_view<LhsT>::value>::type,
+       typename =
+               typename std::enable_if<internal::comparable_with_c_string_view<RhsT>::value>::type>
+bool operator!=(LhsT&& lhs, RhsT&& rhs) noexcept
+{
+       return !(std::forward<LhsT>(lhs) == std::forward<RhsT>(rhs));
+}
+
+} /* namespace lttng */
+
+/*
+ * Appends `rhs` to `lhs`.
+ */
+inline void operator+=(std::string& lhs, lttng::c_string_view rhs)
+{
+       lhs += rhs.data();
+}
+
+namespace std {
+template <>
+struct hash<lttng::c_string_view> {
+       std::size_t operator()(const lttng::c_string_view& str) const
+       {
+               auto hash_value = std::hash<char>{}('\0');
+
+               for (auto character : str) {
+                       hash_value ^= std::hash<decltype(character)>{}(character);
+               }
+
+               return hash_value;
+       }
+};
+} /* namespace std */
+
+#endif /* LTTNG_C_STRING_VIEW_HPP */
diff --git a/src/common/type-traits.hpp b/src/common/type-traits.hpp
new file mode 100644 (file)
index 0000000..3801bf1
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2023 Philippe Proulx <pproulx@efficios.com>
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#ifndef LTTNG_TYPE_TRAITS_HPP
+#define LTTNG_TYPE_TRAITS_HPP
+
+#include <type_traits>
+
+namespace lttng {
+namespace traits {
+
+/*
+ * Provides the member constant `value` equal to:
+ *
+ * `T` is in the list of types `Ts`:
+ *     `true`
+ *
+ * Otherwise:
+ *     `false`
+ */
+template <typename T, typename... Ts>
+struct is_one_of : std::false_type {
+};
+
+template <typename T, typename... Ts>
+struct is_one_of<T, T, Ts...> : std::true_type {
+};
+
+template <typename T, typename U, typename... Ts>
+struct is_one_of<T, U, Ts...> : is_one_of<T, Ts...> {
+};
+} /* namespace traits */
+} /* namespace lttng */
+
+#endif /* LTTNG_TYPE_TRAITS_HPP */
This page took 0.028667 seconds and 4 git commands to generate.