Provide an idiomatic c++ interface for action lists
[lttng-tools.git] / src / common / container-wrapper.hpp
diff --git a/src/common/container-wrapper.hpp b/src/common/container-wrapper.hpp
new file mode 100644 (file)
index 0000000..09097e9
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2023 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+#ifndef LTTNG_CONTAINER_WRAPPER_H
+#define LTTNG_CONTAINER_WRAPPER_H
+
+#include <common/macros.hpp>
+
+#include <cstddef>
+#include <iterator>
+
+namespace lttng {
+namespace utils {
+
+/*
+ * random_access_container_wrapper is a helper to provide an idiomatic C++ interface
+ * from a C container API. ElementAccessorCallable and ElementCountAccessorCallable
+ * are two functors which must be provided to allow access to the underlying elements
+ * of the container and to its size.
+ */
+template <typename ContainerType, typename ElementType, typename ContainerOperations>
+class random_access_container_wrapper {
+       class _iterator : public std::iterator<std::random_access_iterator_tag, std::size_t> {
+       public:
+               explicit _iterator(const random_access_container_wrapper& container,
+                                  std::size_t start_index = 0) :
+                       _container(container), _index(start_index)
+               {
+               }
+
+               _iterator& operator++() noexcept
+               {
+                       ++_index;
+                       return *this;
+               }
+
+               _iterator& operator--() noexcept
+               {
+                       --_index;
+                       return *this;
+               }
+
+               _iterator& operator++(int) noexcept
+               {
+                       auto this_before_increment = *this;
+
+                       _index++;
+                       return this_before_increment;
+               }
+
+               _iterator& operator--(int) noexcept
+               {
+                       _index--;
+                       return *this;
+               }
+
+               bool operator==(const _iterator& other) const noexcept
+               {
+                       return _index == other._index;
+               }
+
+               bool operator!=(const _iterator& other) const noexcept
+               {
+                       return !(*this == other);
+               }
+
+               typename std::conditional<std::is_pointer<ElementType>::value,
+                                         ElementType,
+                                         ElementType&>::type
+               operator*() const noexcept
+               {
+                       return _container[_index];
+               }
+
+       private:
+               const random_access_container_wrapper& _container;
+               std::size_t _index;
+       };
+
+       using iterator = _iterator;
+
+public:
+       explicit random_access_container_wrapper(ContainerType container) : _container{ container }
+       {
+       }
+
+       iterator begin() noexcept
+       {
+               return iterator(*this);
+       }
+
+       iterator end() noexcept
+       {
+               return iterator(*this, ContainerOperations::size(_container));
+       }
+
+       std::size_t size() const noexcept
+       {
+               return ContainerOperations::size(_container);
+       }
+
+       typename std::conditional<std::is_pointer<ElementType>::value, ElementType, ElementType&>::type
+       operator[](std::size_t index)
+       {
+               LTTNG_ASSERT(index < ContainerOperations::size(_container));
+               return ContainerOperations::get(_container, index);
+       }
+
+       typename std::conditional<std::is_pointer<ElementType>::value,
+                                 const ElementType,
+                                 const ElementType&>::type
+       operator[](std::size_t index) const
+       {
+               LTTNG_ASSERT(index < ContainerOperations::size(_container));
+               return ContainerOperations::get(_container, index);
+       }
+
+private:
+       ContainerType _container;
+};
+} /* namespace utils */
+} /* namespace lttng */
+
+#endif /* LTTNG_CONTAINER_WRAPPER_H */
This page took 0.028693 seconds and 4 git commands to generate.