QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.38
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_v
65 <OtherIterator, Iterator>>* = nullptr)
66 : base_(i.base_), step_(static_cast<BigInteger>(i.step())) {}
67
68 Size step() const { return static_cast<Size>(this->step_); }
69
70 step_iterator& operator=(const step_iterator& other) = default;
71
73 base_ += step_;
74 return *this;
75 }
76
78 auto tmp = *this;
79 base_ += step_;
80 return tmp;
81 }
82
84 return *base_;
85 }
86
88 base_ -= step_;
89 return *this;
90 }
91
93 auto tmp = *this;
94 base_ -= step_;
95 return tmp;
96 }
97
99 base_ += n * step_;
100 return *this;
101 }
102
104 base_ -= n * step_;
105 return *this;
106 }
107
109 return *(base_ + n * step_);
110 }
111
113 return step_iterator(i.base_ + n * i.step_, i.step_);
114 }
115
117 return step_iterator(i.base_ + n * i.step_, i.step_);
118 }
119
121 return step_iterator(i.base_ - n * i.step_, i.step_);
122 }
123
124 friend difference_type operator-(const step_iterator& lhs, const step_iterator& rhs) {
125#ifdef QL_EXTRA_SAFETY_CHECKS
126 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be added or subtracted");
127#endif
128 return (lhs.base_ - rhs.base_) / lhs.step_;
129 }
130
131 friend bool operator==(const step_iterator& lhs, const step_iterator& rhs) {
132 return lhs.base_ == rhs.base_ && lhs.step_ == rhs.step_;
133 }
134
135 friend bool operator!=(const step_iterator& lhs, const step_iterator& rhs) {
136 return lhs.base_ != rhs.base_ || lhs.step_ != rhs.step_;
137 }
138
139 friend bool operator<(const step_iterator& lhs, const step_iterator& rhs) {
140#ifdef QL_EXTRA_SAFETY_CHECKS
141 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be compared");
142#endif
143 return lhs.base_ < rhs.base_;
144 }
145
146 friend bool operator>(const step_iterator& lhs, const step_iterator& rhs) {
147#ifdef QL_EXTRA_SAFETY_CHECKS
148 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be compared");
149#endif
150 return lhs.base_ > rhs.base_;
151 }
152
153 friend bool operator<=(const step_iterator& lhs, const step_iterator& rhs) {
154#ifdef QL_EXTRA_SAFETY_CHECKS
155 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be compared");
156#endif
157 return lhs.base_ <= rhs.base_;
158 }
159
160 friend bool operator>=(const step_iterator& lhs, const step_iterator& rhs) {
161#ifdef QL_EXTRA_SAFETY_CHECKS
162 QL_REQUIRE(lhs.step_ == rhs.step_, "step_iterators with different step cannot be compared");
163#endif
164 return lhs.base_ >= rhs.base_;
165 }
166 };
167
168 //! helper function to create step iterators
169 /*! \relates step_iterator */
170 template <class Iterator>
172 return step_iterator<Iterator>(it,step);
173 }
174
175}
176
177
178#endif
Iterator advancing in constant steps.
step_iterator & operator++()
step_iterator operator++(int)
step_iterator & operator=(const step_iterator &other)=default
step_iterator & operator--()
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_v< OtherIterator, Iterator > > *=nullptr)
typename std::iterator_traits< Iterator >::reference reference
friend step_iterator operator-(const step_iterator &i, Size n)
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 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:37
Custom types.