alpaqa 1.0.0a8
Nonconvex constrained optimization
Loading...
Searching...
No Matches
iter-adapter.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <concepts>
4#include <iterator>
5#include <ranges>
6#include <type_traits>
7#include <utility>
8
9#if defined(__clang_major__) && __clang_major__ <= 15 && !defined(__clangd__)
10#error "Better ranges support required"
11#endif
12
13namespace alpaqa::util {
14
15template <class It>
17 // P2325R3: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2325r3.html
18 iter_range_adapter() = default;
19 iter_range_adapter(It it) : it{std::forward<It>(it)} {}
20 It it;
21
22 struct sentinel_t {};
23
24 struct iter_t : std::remove_cvref_t<It> {
25 // P2325R3: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2325r3.html
26 iter_t() = default;
27 iter_t(It it) : std::remove_cvref_t<It>{std::forward<It>(it)} {}
28
29 bool operator!=(sentinel_t) const { return static_cast<bool>(*this); }
30 bool operator==(sentinel_t) const { return !static_cast<bool>(*this); }
31 // TODO: For Clang bug
32 friend bool operator!=(sentinel_t s, const iter_t &i) { return i != s; }
33 friend bool operator==(sentinel_t s, const iter_t &i) { return i == s; }
34
36 this->std::remove_cvref_t<It>::operator++();
37 return *this;
38 }
39 iter_t operator++(int i) const {
40 this->std::remove_cvref_t<It>::operator++(i);
41 return *this;
42 }
43 const iter_t &operator*() const { return *this; }
45 using pointer = iter_t *;
46 using reference = iter_t &;
47 using difference_type = std::ptrdiff_t;
48 };
49
50 auto begin() const & -> std::input_or_output_iterator auto{
51 return iter_t{it};
52 }
53 auto begin() && -> std::input_or_output_iterator auto{
54 return iter_t{std::forward<It>(it)};
55 }
56 auto end() const -> std::sentinel_for<iter_t> auto{ return sentinel_t{}; }
57};
58
59} // namespace alpaqa::util
60
61// Make iter_range_adapter available as an std::ranges view.
62// Iterators remain valid even if the range is destroyed.
63// Assume that the user takes care of lifetime, similar to std::span.
64#ifndef DOXYGEN
65template <class It>
66inline constexpr bool ::std::ranges::enable_borrowed_range<
68#endif
friend bool operator==(sentinel_t s, const iter_t &i)
friend bool operator!=(sentinel_t s, const iter_t &i)
auto begin() &&-> std::input_or_output_iterator auto
auto end() const -> std::sentinel_for< iter_t > auto
auto begin() const &-> std::input_or_output_iterator auto