2 * Copyright (C) 2023 Jérémie Galarneau <jeremie.galarneau@efficios.com>
4 * SPDX-License-Identifier: LGPL-2.1-only
8 #ifndef LTTNG_CONTAINER_WRAPPER_H
9 #define LTTNG_CONTAINER_WRAPPER_H
11 #include <common/macros.hpp>
20 * random_access_container_wrapper is a helper to provide an idiomatic C++ interface
21 * from a C container API. ElementAccessorCallable and ElementCountAccessorCallable
22 * are two functors which must be provided to allow access to the underlying elements
23 * of the container and to its size.
25 template <typename ContainerType, typename ElementType, typename ContainerOperations>
26 class random_access_container_wrapper {
27 template <typename IteratorContainerType, typename IteratorElementType>
28 class _iterator : public std::iterator<std::random_access_iterator_tag, std::size_t> {
30 explicit _iterator(IteratorContainerType& container, std::size_t start_index = 0) :
31 _container(container), _index(start_index)
35 _iterator& operator++() noexcept
41 _iterator& operator--() noexcept
47 _iterator& operator++(int) noexcept
49 auto this_before_increment = *this;
52 return this_before_increment;
55 _iterator& operator--(int) noexcept
61 bool operator==(const _iterator& other) const noexcept
63 return _index == other._index;
66 bool operator!=(const _iterator& other) const noexcept
68 return !(*this == other);
71 typename std::conditional<std::is_pointer<IteratorElementType>::value,
73 IteratorElementType&>::type
74 operator*() const noexcept
76 return _container[_index];
80 IteratorContainerType& _container;
84 using iterator = _iterator<random_access_container_wrapper, ElementType>;
85 using const_iterator = _iterator<const random_access_container_wrapper, const ElementType>;
88 explicit random_access_container_wrapper(ContainerType container) :
89 _container{ std::move(container) }
93 iterator begin() noexcept
95 return iterator(*this);
98 iterator end() noexcept
100 return iterator(*this, ContainerOperations::size(_container));
103 const_iterator begin() const noexcept
105 return const_iterator(*this);
108 const_iterator end() const noexcept
110 return const_iterator(*this, ContainerOperations::size(_container));
113 std::size_t size() const noexcept
115 return ContainerOperations::size(_container);
118 typename std::conditional<std::is_pointer<ElementType>::value, ElementType, ElementType&>::type
119 operator[](std::size_t index)
121 LTTNG_ASSERT(index < ContainerOperations::size(_container));
122 return ContainerOperations::get(_container, index);
125 typename std::conditional<std::is_pointer<ElementType>::value,
127 const ElementType&>::type
128 operator[](std::size_t index) const
130 LTTNG_ASSERT(index < ContainerOperations::size(_container));
131 return ContainerOperations::get(_container, index);
135 ContainerType _container;
137 } /* namespace utils */
138 } /* namespace lttng */
140 #endif /* LTTNG_CONTAINER_WRAPPER_H */