QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.38
Loading...
Searching...
No Matches
handle.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 Copyright (C) 2003, 2004, 2005, 2006, 2007 StatPro Italia srl
6
7 This file is part of QuantLib, a free-software/open-source library
8 for financial quantitative analysts and developers - http://quantlib.org/
9
10 QuantLib is free software: you can redistribute it and/or modify it
11 under the terms of the QuantLib license. You should have received a
12 copy of the license along with this program; if not, please email
13 <quantlib-dev@lists.sf.net>. The license is also available online at
14 <http://quantlib.org/license.shtml>.
15
16 This program is distributed in the hope that it will be useful, but WITHOUT
17 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 FOR A PARTICULAR PURPOSE. See the license for more details.
19*/
20
21/*! \file handle.hpp
22 \brief Globally accessible relinkable pointer
23*/
24
25#ifndef quantlib_handle_hpp
26#define quantlib_handle_hpp
27
29
30namespace QuantLib {
31
32 //! Shared handle to an observable
33 /*! All copies of an instance of this class refer to the same
34 observable by means of a relinkable smart pointer. When such
35 pointer is relinked to another observable, the change will be
36 propagated to all the copies.
37
38 \pre Class T must inherit from Observable
39 */
40 template <class T>
41 class Handle {
42 protected:
43 class Link : public Observable, public Observer {
44 public:
45 Link(const ext::shared_ptr<T>& h,
46 bool registerAsObserver);
47 Link(ext::shared_ptr<T>&& h,
48 bool registerAsObserver);
49 void linkTo(ext::shared_ptr<T>,
50 bool registerAsObserver);
51 bool empty() const { return !h_; }
52 const ext::shared_ptr<T>& currentLink() const { return h_; }
53 void update() override { notifyObservers(); }
54
55 private:
56 ext::shared_ptr<T> h_;
57 bool isObserver_ = false;
58 };
59 ext::shared_ptr<Link> link_;
60 public:
61 /*! \name Constructors
62
63 \warning <tt>registerAsObserver</tt> is left as a backdoor
64 in case the programmer cannot guarantee that the
65 object pointed to will remain alive for the whole
66 lifetime of the handle---namely, it should be set
67 to <tt>false</tt> when the passed shared pointer
68 does not own the pointee (this should only happen
69 in a controlled environment, so that the
70 programmer is aware of it). Failure to do so can
71 very likely result in a program crash. If the
72 programmer does want the handle to register as
73 observer of such a shared pointer, it is his
74 responsibility to ensure that the handle gets
75 destroyed before the pointed object does.
76 */
77 //@{
79 : Handle(ext::shared_ptr<T>()) {}
80 explicit Handle(const ext::shared_ptr<T>& p,
81 bool registerAsObserver = true)
82 : link_(new Link(p, registerAsObserver)) {}
83 explicit Handle(ext::shared_ptr<T>&& p,
84 bool registerAsObserver = true)
85 : link_(new Link(std::move(p), registerAsObserver)) {}
86 //@}
87 //! dereferencing
88 const ext::shared_ptr<T>& currentLink() const;
89 const ext::shared_ptr<T>& operator->() const;
90 const ext::shared_ptr<T>& operator*() const;
91 //! checks if the contained shared pointer points to anything
92 bool empty() const;
93 //! allows registration as observable
94 operator ext::shared_ptr<Observable>() const;
95 //! equality test
96 template <class U>
97 bool operator==(const Handle<U>& other) const { return link_==other.link_; }
98 //! disequality test
99 template <class U>
100 bool operator!=(const Handle<U>& other) const { return link_!=other.link_; }
101 //! strict weak ordering
102 template <class U>
103 bool operator<(const Handle<U>& other) const { return link_ < other.link_; }
104 };
105
106 //! Relinkable handle to an observable
107 /*! An instance of this class can be relinked so that it points to
108 another observable. The change will be propagated to all
109 handles that were created as copies of such instance.
110
111 \pre Class T must inherit from Observable
112
113 \warning see the Handle documentation for issues
114 relatives to <tt>registerAsObserver</tt>.
115 */
116 template <class T>
117 class RelinkableHandle : public Handle<T> {
118 public:
120 : RelinkableHandle(ext::shared_ptr<T>()) {}
122 const ext::shared_ptr<T>& p,
123 bool registerAsObserver = true);
125 ext::shared_ptr<T>&& p,
126 bool registerAsObserver = true);
127 /*! \deprecated Use one of the constructors taking shared_ptr.
128 Deprecated in version 1.35.
129 */
130 [[deprecated("Use one of the constructors taking shared_ptr.")]]
132 T* p,
133 bool registerAsObserver = true);
134 void linkTo(const ext::shared_ptr<T>& h,
135 bool registerAsObserver = true);
136 void linkTo(ext::shared_ptr<T>&& h,
137 bool registerAsObserver = true);
138 void reset();
139 };
140
141
142 // inline definitions
143
144 template <class T>
145 inline Handle<T>::Link::Link(const ext::shared_ptr<T>& h, bool registerAsObserver) {
146 linkTo(h, registerAsObserver);
147 }
148
149 template <class T>
150 inline Handle<T>::Link::Link(ext::shared_ptr<T>&& h, bool registerAsObserver) {
151 linkTo(std::move(h), registerAsObserver);
152 }
153
154 template <class T>
155 inline void Handle<T>::Link::linkTo(ext::shared_ptr<T> h,
156 bool registerAsObserver) {
157 if ((h != h_) || (isObserver_ != registerAsObserver)) {
158 if (h_ && isObserver_)
159 unregisterWith(h_);
160 h_ = std::move(h);
161 isObserver_ = registerAsObserver;
162 if (h_ && isObserver_)
163 registerWith(h_);
164 notifyObservers();
165 }
166 }
167
168
169 template <class T>
170 inline const ext::shared_ptr<T>& Handle<T>::currentLink() const {
171 QL_REQUIRE(!empty(), "empty Handle cannot be dereferenced");
172 return link_->currentLink();
173 }
174
175 template <class T>
176 inline const ext::shared_ptr<T>& Handle<T>::operator->() const {
177 QL_REQUIRE(!empty(), "empty Handle cannot be dereferenced");
178 return link_->currentLink();
179 }
180
181 template <class T>
182 inline const ext::shared_ptr<T>& Handle<T>::operator*() const {
183 QL_REQUIRE(!empty(), "empty Handle cannot be dereferenced");
184 return link_->currentLink();
185 }
186
187 template <class T>
188 inline bool Handle<T>::empty() const {
189 return link_->empty();
190 }
191
192 template <class T>
193 inline Handle<T>::operator ext::shared_ptr<Observable>() const {
194 return link_;
195 }
196
197
198 template <class T>
199 inline RelinkableHandle<T>::RelinkableHandle(const ext::shared_ptr<T>& p,
200 bool registerAsObserver)
201 : Handle<T>(p,registerAsObserver) {}
202
203 template <class T>
204 inline RelinkableHandle<T>::RelinkableHandle(ext::shared_ptr<T>&& p,
205 bool registerAsObserver)
206 : Handle<T>(std::move(p), registerAsObserver) {}
207
208 template <class T>
210 bool registerAsObserver)
211 : Handle<T>(p,registerAsObserver) {}
212
213 template <class T>
214 inline void RelinkableHandle<T>::linkTo(const ext::shared_ptr<T>& h,
215 bool registerAsObserver) {
216 this->link_->linkTo(h, registerAsObserver);
217 }
218
219 template <class T>
220 inline void RelinkableHandle<T>::linkTo(ext::shared_ptr<T>&& h,
221 bool registerAsObserver) {
222 this->link_->linkTo(std::move(h), registerAsObserver);
223 }
224
225 template <class T>
227 this->link_->linkTo(nullptr, true);
228 }
229
230}
231
232#endif
Shared handle to an observable.
Definition: handle.hpp:41
const ext::shared_ptr< T > & operator*() const
Definition: handle.hpp:182
Handle(const ext::shared_ptr< T > &p, bool registerAsObserver=true)
Definition: handle.hpp:80
bool operator<(const Handle< U > &other) const
strict weak ordering
Definition: handle.hpp:103
const ext::shared_ptr< T > & operator->() const
Definition: handle.hpp:176
bool operator==(const Handle< U > &other) const
equality test
Definition: handle.hpp:97
Handle(ext::shared_ptr< T > &&p, bool registerAsObserver=true)
Definition: handle.hpp:83
bool operator!=(const Handle< U > &other) const
disequality test
Definition: handle.hpp:100
bool empty() const
checks if the contained shared pointer points to anything
Definition: handle.hpp:188
const ext::shared_ptr< T > & currentLink() const
dereferencing
Definition: handle.hpp:170
ext::shared_ptr< Link > link_
Definition: handle.hpp:59
Object that notifies its changes to a set of observers.
Definition: observable.hpp:62
Object that gets notified when a given observable changes.
Definition: observable.hpp:116
Relinkable handle to an observable.
Definition: handle.hpp:117
void linkTo(const ext::shared_ptr< T > &h, bool registerAsObserver=true)
Definition: handle.hpp:214
void linkTo(ext::shared_ptr< T > &&h, bool registerAsObserver=true)
Definition: handle.hpp:220
RelinkableHandle(ext::shared_ptr< T > &&p, bool registerAsObserver=true)
Definition: handle.hpp:204
RelinkableHandle(T *p, bool registerAsObserver=true)
Definition: handle.hpp:209
RelinkableHandle(const ext::shared_ptr< T > &p, bool registerAsObserver=true)
Definition: handle.hpp:199
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
Definition: any.hpp:37
STL namespace.
observer/observable pattern