Import CStringView from the Babeltrace tree
[lttng-tools.git] / src / common / container-wrapper.hpp
index bccb23ddaeaf05efc27c51985ddd5a67004ceaa9..25385fc43837961ec4301dd9f7254f0b89ccc3b6 100644 (file)
@@ -8,6 +8,8 @@
 #ifndef LTTNG_CONTAINER_WRAPPER_H
 #define LTTNG_CONTAINER_WRAPPER_H
 
+#include <common/exception.hpp>
+#include <common/format.hpp>
 #include <common/macros.hpp>
 
 #include <cstddef>
@@ -58,6 +60,11 @@ class random_access_container_wrapper {
                        return *this;
                }
 
+               ptrdiff_t operator-(const _iterator& other) const
+               {
+                       return _index - other._index;
+               }
+
                bool operator==(const _iterator& other) const noexcept
                {
                        return _index == other._index;
@@ -71,7 +78,7 @@ class random_access_container_wrapper {
                typename std::conditional<std::is_pointer<IteratorElementType>::value,
                                          IteratorElementType,
                                          IteratorElementType&>::type
-               operator*() const noexcept
+               operator*() const
                {
                        return _container[_index];
                }
@@ -95,9 +102,9 @@ public:
                return iterator(*this);
        }
 
-       iterator end() noexcept
+       iterator end()
        {
-               return iterator(*this, ContainerOperations::size(_container));
+               return iterator(*this, size());
        }
 
        const_iterator begin() const noexcept
@@ -105,21 +112,40 @@ public:
                return const_iterator(*this);
        }
 
-       const_iterator end() const noexcept
+       const_iterator end() const
        {
-               return const_iterator(*this, ContainerOperations::size(_container));
+               return const_iterator(*this, size());
        }
 
-       std::size_t size() const noexcept
+       std::size_t size() const
        {
                return ContainerOperations::size(_container);
        }
 
+       bool empty() const
+       {
+               return size() == 0;
+       }
+
        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);
+               /*
+                * To share code between the const and mutable versions of this operator, 'this'
+                * is casted to a const reference. A const_cast then ensures that a mutable
+                * reference (or pointer) is returned.
+                *
+                * We typically avoid const_cast, but this is safe: if the user is calling the
+                * mutable version of this operator, it had a mutable object anyhow.
+                *
+                * For more information, see Item 3 of Effective C++.
+                */
+               const auto& const_this = static_cast<const random_access_container_wrapper&>(*this);
+
+               /* NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast) */
+               return const_cast<typename std::conditional<std::is_pointer<ElementType>::value,
+                                                           ElementType,
+                                                           ElementType&>::type>(const_this[index]);
        }
 
        typename std::conditional<std::is_pointer<ElementType>::value,
@@ -127,7 +153,13 @@ public:
                                  const ElementType&>::type
        operator[](std::size_t index) const
        {
-               LTTNG_ASSERT(index < ContainerOperations::size(_container));
+               if (index >= ContainerOperations::size(_container)) {
+                       throw std::invalid_argument(lttng::format(
+                               "Out of bound access through random_access_container_wrapper: index={}, size={}",
+                               index,
+                               size()));
+               }
+
                return ContainerOperations::get(_container, index);
        }
 
This page took 0.024516 seconds and 4 git commands to generate.