From 18ca73481919aa635efc2df80aa414e7f7fdaab0 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 24 Apr 2020 15:58:09 +0200 Subject: [PATCH] util/DereferenceIterator: new utility class --- src/util/DereferenceIterator.hxx | 116 +++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 src/util/DereferenceIterator.hxx diff --git a/src/util/DereferenceIterator.hxx b/src/util/DereferenceIterator.hxx new file mode 100644 index 000000000..85838d1ed --- /dev/null +++ b/src/util/DereferenceIterator.hxx @@ -0,0 +1,116 @@ +/* + * Copyright 2012-2020 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DEREFERENCE_ITERATOR_HXX +#define DEREFERENCE_ITERATOR_HXX + +#include +#include + +/** + * An iterator wrapper that dereferences the values returned by the + * original iterator. + */ +template::type> +class DereferenceIterator { + using Traits = std::iterator_traits; + + IT original; + +public: + using iterator_category = typename Traits::iterator_category; + using difference_type = typename Traits::difference_type; + using value_type = VT; + using pointer = VT *; + using reference = VT &; + + DereferenceIterator() = default; + + constexpr DereferenceIterator(const IT _original) noexcept + :original(_original) {} + + reference operator*() const noexcept { + return static_cast(**original); + } + + pointer operator->() const noexcept { + return static_cast(*original.IT::operator->()); + } + + auto &operator++() noexcept { + ++original; + return *this; + } + + auto operator++(int) noexcept { + auto old = *this; + original++; + return old; + } + + auto &operator+=(difference_type n) noexcept { + original += n; + return *this; + } + + auto &operator+(difference_type n) noexcept { + return original + n; + } + + auto &operator--() noexcept { + original = --original; + return *this; + } + + auto operator--(int) noexcept { + auto old = *this; + original--; + return old; + } + + auto &operator-=(difference_type n) noexcept { + original -= n; + return *this; + } + + auto &operator-(difference_type n) noexcept { + return original - n; + } + + bool operator==(const DereferenceIterator &other) const noexcept { + return original == other.original; + } + + bool operator!=(const DereferenceIterator &other) const noexcept { + return original != other.original; + } +}; + +#endif