diff options
Diffstat (limited to 'src/libs/utils/ranges.h')
-rw-r--r-- | src/libs/utils/ranges.h | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/libs/utils/ranges.h b/src/libs/utils/ranges.h new file mode 100644 index 0000000000..8b574e08d6 --- /dev/null +++ b/src/libs/utils/ranges.h @@ -0,0 +1,95 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#if __cplusplus >= 202002L +#include <ranges> + +namespace Utils { + +namespace ranges { +using std::ranges::reverse_view; +} + +namespace views { +using std::views::reverse; +} + +} // namespace Utils +#else +#include <stdexcept> + +namespace Utils { + +namespace ranges { + +template <typename Container> +class reverse_view +{ +public: + using value_type = typename Container::value_type; + using size_type = typename Container::size_type; + using Type = value_type; + using pointer = Type *; + using const_pointer = const Type *; + using reference = Type &; + using const_reference = const Type &; + + using reverse_iterator = typename Container::iterator; + using iterator = std::reverse_iterator<reverse_iterator>; + + using const_reverse_iterator = typename Container::const_iterator; + using const_iterator = std::reverse_iterator<const_reverse_iterator>; + + using Iterator = iterator; + using ConstIterator = const_iterator; + + reverse_view(const Container &k) : d(&k) {} + + const_reverse_iterator rbegin() const noexcept { return d->begin(); } + const_reverse_iterator rend() const noexcept { return d->end(); } + const_reverse_iterator crbegin() const noexcept { return d->begin(); } + const_reverse_iterator crend() const noexcept { return d->end(); } + + const_iterator begin() const noexcept { return const_iterator(rend()); } + const_iterator end() const noexcept { return const_iterator(rbegin()); } + const_iterator cbegin() const noexcept { return const_iterator(rend()); } + const_iterator cend() const noexcept { return const_iterator(rbegin()); } + const_iterator constBegin() const noexcept { return const_iterator(rend()); } + const_iterator constEnd() const noexcept { return const_iterator(rbegin()); } + + const_reference front() const noexcept { return *cbegin(); } + const_reference back() const noexcept { return *crbegin(); } + + [[nodiscard]] size_type size() const noexcept { return d->size(); } + [[nodiscard]] bool empty() const noexcept { return d->size() == 0; } + explicit operator bool() const { return d->size(); } + + const_reference operator[](size_type idx) const + { + if (idx < size()) + return *(begin() + idx); + + throw std::out_of_range("bad index in reverse side"); + } + +private: + const Container *d; +}; +} // namespace ranges + +namespace views { + +constexpr struct {} reverse; + +template <typename T> +inline ranges::reverse_view<T> operator|(const T &container, const decltype(reverse)&) +{ + return ranges::reverse_view(container); +} + +} // namsepace views +} // namespace Utils + +#endif |