TRIQS/itertools 1.3.0
C++ range library
Loading...
Searching...
No Matches
transform.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Simons Foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0.txt
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// Authors: Thomas Hahn, Olivier Parcollet, Nils Wentzell, chuffa
16
22#ifndef _ITERTOOLS_TRANSFORM_HPP
23#define _ITERTOOLS_TRANSFORM_HPP
24
25#include "./iterator_facade.hpp"
26#include "./sentinel.hpp"
27
28#include <iterator>
29#include <optional>
30#include <type_traits>
31#include <utility>
32
33namespace itertools {
34
49 template <typename Iter, typename F, typename Value = std::invoke_result_t<F, typename std::iterator_traits<Iter>::value_type>>
50 struct transform_iter : iterator_facade<transform_iter<Iter, F>, Value> {
52 Iter it;
53
55 mutable std::optional<F> lambda;
56
58 transform_iter() = default;
59
66 transform_iter(Iter it, F lambda) : it(std::move(it)), lambda(std::move(lambda)) {}
67
69 void increment() { ++it; }
70
73
75 transform_iter(transform_iter const &) = default;
76
79
85 it = other.it;
86 if (other.lambda.has_value())
87 lambda.emplace(other.lambda.value());
88 else
89 lambda.reset();
90 return *this;
91 }
92
99 [[nodiscard]] bool operator==(transform_iter const &other) const { return it == other.it; }
100
108 template <typename SentinelIter> [[nodiscard]] bool operator==(sentinel_t<SentinelIter> const &s) const { return (it == s.it); }
109
114 [[nodiscard]] decltype(auto) dereference() const { return (*lambda)(*it); }
115 };
116
126 template <typename R, typename F> struct transformed {
128 R rg;
129
132
134 using const_iterator = transform_iter<decltype(std::cbegin(rg)), F>;
135
138
143 [[nodiscard]] const_iterator cbegin() const noexcept { return {std::cbegin(rg), lambda}; }
144
146 [[nodiscard]] const_iterator begin() const noexcept { return cbegin(); }
147
152 [[nodiscard]] auto cend() const noexcept { return make_sentinel(std::cend(rg)); }
153
155 [[nodiscard]] auto end() const noexcept { return cend(); }
156 };
157
188 template <typename R, typename F> [[nodiscard]] auto transform(R &&rg, F lambda) {
189 return transformed<R, F>{std::forward<R>(rg), std::move(lambda)};
190 }
191
192} // namespace itertools
193
194#endif // _ITERTOOLS_TRANSFORM_HPP
auto transform(R &&rg, F lambda)
Lazy-transform a given range by applying a unary callable object to every element of the original ran...
sentinel_t< Iter > make_sentinel(Iter it)
Create an itertools::sentinel_t from an iterator using template type deduction.
Definition sentinel.hpp:50
Provides a CRTP base class for various iterator types in itertools.
Provides a generic sentinel type for various iterator types in itertools.
Generic sentinel type that can be used to mark the end of a range.
Definition sentinel.hpp:38
Iter it
End iterator of some range.
Definition sentinel.hpp:40
Iterator for a itertools::transformed range.
Definition transform.hpp:50
transform_iter(Iter it, F lambda)
Construct a transformed iterator from a given iterator and callable.
Definition transform.hpp:66
decltype(auto) dereference() const
Dereference the iterator.
transform_iter()=default
Default constructor.
std::optional< F > lambda
Callable doing the transformation.
Definition transform.hpp:55
transform_iter & operator=(transform_iter &&)=default
Default move assignment operator.
Iter it
Iterator of the original range.
Definition transform.hpp:52
bool operator==(sentinel_t< SentinelIter > const &s) const
Equal-to operator for a itertools::transform_iter and an itertools::sentinel_t.
transform_iter(transform_iter const &)=default
Default copy constructor.
transform_iter(transform_iter &&)=default
Default move constructor.
bool operator==(transform_iter const &other) const
Equal-to operator for two itertools::transform_iter objects.
Definition transform.hpp:99
void increment()
Increment the iterator by incrementing the original iterator.
Definition transform.hpp:69
transform_iter & operator=(transform_iter const &other)
Custom copy assignment operator makes sure that the optional callable is correctly copied.
Definition transform.hpp:84
Represents a transformed range.
R rg
Original range.
F lambda
Callable doing the transformation.
const_iterator cbegin() const noexcept
Beginning of the transformed range.
const_iterator begin() const noexcept
The same as cbegin().
auto end() const noexcept
The same as cend().
auto cend() const noexcept
End of the transformed range.
transform_iter< decltype(std::cbegin(rg)), F > const_iterator
Const iterator type of the transformed range.