QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
Loading...
Searching...
No Matches
steppingiterator.hpp
Go to the documentation of this file.
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
3/*
4 Copyright (C) 2000, 2001, 2002, 2003 RiskMap srl
5
6 This file is part of QuantLib, a free-software/open-source library
7 for financial quantitative analysts and developers - http://quantlib.org/
8
9 QuantLib is free software: you can redistribute it and/or modify it
10 under the terms of the QuantLib license. You should have received a
11 copy of the license along with this program; if not, please email
12 <quantlib-dev@lists.sf.net>. The license is also available online at
13 <http://quantlib.org/license.shtml>.
14
15 This program is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17 FOR A PARTICULAR PURPOSE. See the license for more details.
18*/
19
20/*! \file steppingiterator.hpp
21 \brief Iterator advancing in constant steps
22*/
23
24#ifndef quantlib_stepping_iterator_hpp
25#define quantlib_stepping_iterator_hpp
26
27#include <ql/errors.hpp>
28#include <ql/types.hpp>
29#include <iterator>
30#include <type_traits>
31
32namespace QuantLib {
33
34 //! Iterator advancing in constant steps
35 /*! This iterator advances an underlying random-access iterator in
36 steps of \f$ n \f$ positions, where \f$ n \f$ is a positive
37 integer given upon construction.
38 */
39#ifdef __cpp_concepts
40 template <std::random_access_iterator Iterator>
41#else
42 template <class Iterator>
43#endif
44 class step_iterator { // NOLINT(cppcoreguidelines-special-member-functions)
45 private:
46 Iterator base_{};
47 // a Size would mess up integer division in distance_to
49
50 public:
51 using iterator_category = typename std::iterator_traits<Iterator>::iterator_category;
52 using difference_type = typename std::iterator_traits<Iterator>::difference_type;
53 using value_type = typename std::iterator_traits<Iterator>::value_type;
54 using pointer = typename std::iterator_traits<Iterator>::pointer;
55 using reference = typename std::iterator_traits<Iterator>::reference;
56
57 step_iterator() = default;
58
59 explicit step_iterator(const Iterator& base, Size step)
60 : base_(base), step_(static_cast<BigInteger>(step)) {}
61
62 template <class OtherIterator>
64 std::enable_if_t<std::is_convertible
65 <OtherIterator, Iterator>::value>* = nullptr)
66 : base_(i.base_), step_(static_cast<BigInteger>(i.step())) {}
67
68 // inspector
69 Size step() const { return static_cast<Size>(this->step_); }
70
71 /*! \deprecated This class no longer inherits from boost::iterator_adaptor`.
72 Deprecated in version 1.31.
73 */
74 [[deprecated("Do not use the boost::iterator_adaptor interface.")]]
75 Iterator base() const { return base_; }
76
77 /*! \deprecated This class no longer inherits from boost::iterator_adaptor`.
78 Deprecated in version 1.31.
79 */
80 [[deprecated("Do not use the boost::iterator_adaptor interface.")]]
81 void increment() {
82 std::advance(base_, step_);
83 }
84
85 /*! \deprecated This class no longer inherits from boost::iterator_adaptor`.
86 Deprecated in version 1.31.
87 */
88 [[deprecated("Do not use the boost::iterator_adaptor interface.")]]
89 void decrement() {
90 std::advance(base_, -step_);
91 }
92
93 /*! \deprecated This class no longer inherits from boost::iterator_adaptor`.
94 Deprecated in version 1.31.
95 */
96 [[deprecated("Do not use the boost::iterator_adaptor interface.")]]
97 void advance(typename std::iterator_traits<Iterator>::difference_type n) {
98 base_ += n*(this->step_);
99 }
100
101 /*! \deprecated This class no longer inherits from boost::iterator_adaptor`.
102 Deprecated in version 1.31.
103 */
104 [[deprecated("Do not use the boost::iterator_adaptor interface.")]]
105 typename std::iterator_traits<Iterator>::difference_type
106 distance_to(const step_iterator& i) const {
107 return (i.base_ - base_) / step_;
108 }
109
111 base_ = other.base_;
112 step_ = other.step_;
113 return *this;
114 }
115
117 base_ += step_;
118 return *this;
119 }
120
122 auto tmp = *this;
123 base_ += step_;
124 return tmp;
125 }
126
128 return *base_;
129 }
130
132 base_ -= step_;
133 return *this;
134 }
135
137 auto tmp = *this;
138 base_ -= step_;
139 return tmp;
140 }
141
143 base_ += n * step_;
144 return *this;
145 }
146
148 base_ -= n * step_;
149 return *this;
150 }
151
153 return *(base_ + n * step_);
154 }
155
157 return step_iterator(i.base_ + n * i.step_, i.step_);
158 }
159
161 return step_iterator(i.base_ + n * i.step_, i.step_);
162 }
163
165 return step_iterator(i.base_ - n * i.step_, i.step_);
166 }
167
168 friend difference_type operator-(const step_iterator& lhs, const step_iterator& rhs) {
169#ifdef QL_EXTRA_SAFETY_CHECKS
170 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be added or subtracted");
171#endif
172 return (lhs.base_ - rhs.base_) / lhs.step_;
173 }
174
175 friend bool operator==(const step_iterator& lhs, const step_iterator& rhs) {
176 return lhs.base_ == rhs.base_ && lhs.step_ == rhs.step_;
177 }
178
179 friend bool operator!=(const step_iterator& lhs, const step_iterator& rhs) {
180 return lhs.base_ != rhs.base_ || lhs.step_ != rhs.step_;
181 }
182
183 friend bool operator<(const step_iterator& lhs, const step_iterator& rhs) {
184#ifdef QL_EXTRA_SAFETY_CHECKS
185 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be compared");
186#endif
187 return lhs.base_ < rhs.base_;
188 }
189
190 friend bool operator>(const step_iterator& lhs, const step_iterator& rhs) {
191#ifdef QL_EXTRA_SAFETY_CHECKS
192 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be compared");
193#endif
194 return lhs.base_ > rhs.base_;
195 }
196
197 friend bool operator<=(const step_iterator& lhs, const step_iterator& rhs) {
198#ifdef QL_EXTRA_SAFETY_CHECKS
199 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be compared");
200#endif
201 return lhs.base_ <= rhs.base_;
202 }
203
204 friend bool operator>=(const step_iterator& lhs, const step_iterator& rhs) {
205#ifdef QL_EXTRA_SAFETY_CHECKS
206 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be compared");
207#endif
208 return lhs.base_ >= rhs.base_;
209 }
210 };
211
212 //! helper function to create step iterators
213 /*! \relates step_iterator */
214 template <class Iterator>
216 return step_iterator<Iterator>(it,step);
217 }
218
219}
220
221
222#endif
Iterator advancing in constant steps.
step_iterator & operator++()
step_iterator operator++(int)
step_iterator & operator--()
void advance(typename std::iterator_traits< Iterator >::difference_type n)
friend bool operator<=(const step_iterator &lhs, const step_iterator &rhs)
typename std::iterator_traits< Iterator >::reference reference
friend step_iterator operator-(const step_iterator &i, Size n)
step_iterator & operator=(const step_iterator &other)
reference operator[](Size n) const
friend step_iterator operator+(const step_iterator &i, Size n)
step_iterator< Iterator > make_step_iterator(Iterator it, Size step)
helper function to create step iterators
friend bool operator>=(const step_iterator &lhs, const step_iterator &rhs)
friend difference_type operator-(const step_iterator &lhs, const step_iterator &rhs)
friend bool operator<(const step_iterator &lhs, const step_iterator &rhs)
step_iterator & operator-=(Size n)
step_iterator & operator+=(Size n)
reference operator*() const
friend step_iterator operator+(Size n, const step_iterator &i)
friend bool operator>(const step_iterator &lhs, const step_iterator &rhs)
typename std::iterator_traits< Iterator >::difference_type difference_type
step_iterator(const Iterator &base, Size step)
friend bool operator!=(const step_iterator &lhs, const step_iterator &rhs)
typename std::iterator_traits< Iterator >::iterator_category iterator_category
typename std::iterator_traits< Iterator >::value_type value_type
typename std::iterator_traits< Iterator >::pointer pointer
friend bool operator==(const step_iterator &lhs, const step_iterator &rhs)
step_iterator(const step_iterator< OtherIterator > &i, std::enable_if_t< std::is_convertible< OtherIterator, Iterator >::value > *=nullptr)
std::iterator_traits< Iterator >::difference_type distance_to(const step_iterator &i) const
step_iterator operator--(int)
Classes and functions for error handling.
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
QL_BIG_INTEGER BigInteger
large integer number
Definition: types.hpp:39
std::size_t Size
size of a container
Definition: types.hpp:58
Definition: any.hpp:35
Custom types.