QuantLib: a free/open-source library for quantitative finance
fully annotated source code - version 1.34
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#if defined(_MSC_VER) && (_MSC_VER < 1916)
132#else
133 [[deprecated("Use one of the constructors taking shared_ptr.")]]
134#endif
136 T* p,
137 bool registerAsObserver = true);
138 void linkTo(const ext::shared_ptr<T>& h,
139 bool registerAsObserver = true);
140 void linkTo(ext::shared_ptr<T>&& h,
141 bool registerAsObserver = true);
142 };
143
144
145 // inline definitions
146
147 template <class T>
148 inline Handle<T>::Link::Link(const ext::shared_ptr<T>& h, bool registerAsObserver) {
149 linkTo(h, registerAsObserver);
150 }
151
152 template <class T>
153 inline Handle<T>::Link::Link(ext::shared_ptr<T>&& h, bool registerAsObserver) {
154 linkTo(std::move(h), registerAsObserver);
155 }
156
157 template <class T>
158 inline void Handle<T>::Link::linkTo(ext::shared_ptr<T> h,
159 bool registerAsObserver) {
160 if ((h != h_) || (isObserver_ != registerAsObserver)) {
161 if (h_ && isObserver_)
162 unregisterWith(h_);
163 h_ = std::move(h);
164 isObserver_ = registerAsObserver;
165 if (h_ && isObserver_)
166 registerWith(h_);
167 notifyObservers();
168 }
169 }
170
171
172 template <class T>
173 inline const ext::shared_ptr<T>& Handle<T>::currentLink() const {
174 QL_REQUIRE(!empty(), "empty Handle cannot be dereferenced");
175 return link_->currentLink();
176 }
177
178 template <class T>
179 inline const ext::shared_ptr<T>& Handle<T>::operator->() const {
180 QL_REQUIRE(!empty(), "empty Handle cannot be dereferenced");
181 return link_->currentLink();
182 }
183
184 template <class T>
185 inline const ext::shared_ptr<T>& Handle<T>::operator*() const {
186 QL_REQUIRE(!empty(), "empty Handle cannot be dereferenced");
187 return link_->currentLink();
188 }
189
190 template <class T>
191 inline bool Handle<T>::empty() const {
192 return link_->empty();
193 }
194
195 template <class T>
196 inline Handle<T>::operator ext::shared_ptr<Observable>() const {
197 return link_;
198 }
199
200
201 template <class T>
202 inline RelinkableHandle<T>::RelinkableHandle(const ext::shared_ptr<T>& p,
203 bool registerAsObserver)
204 : Handle<T>(p,registerAsObserver) {}
205
206 template <class T>
207 inline RelinkableHandle<T>::RelinkableHandle(ext::shared_ptr<T>&& p,
208 bool registerAsObserver)
209 : Handle<T>(std::move(p), registerAsObserver) {}
210
211 template <class T>
213 bool registerAsObserver)
214 : Handle<T>(p,registerAsObserver) {}
215
216 template <class T>
217 inline void RelinkableHandle<T>::linkTo(const ext::shared_ptr<T>& h,
218 bool registerAsObserver) {
219 this->link_->linkTo(h, registerAsObserver);
220 }
221
222 template <class T>
223 inline void RelinkableHandle<T>::linkTo(ext::shared_ptr<T>&& h,
224 bool registerAsObserver) {
225 this->link_->linkTo(std::move(h), registerAsObserver);
226 }
227
228}
229
230#endif
Shared handle to an observable.
Definition: handle.hpp:41
const ext::shared_ptr< T > & operator*() const
Definition: handle.hpp:185
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:179
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:191
const ext::shared_ptr< T > & currentLink() const
dereferencing
Definition: handle.hpp:173
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:217
void linkTo(ext::shared_ptr< T > &&h, bool registerAsObserver=true)
Definition: handle.hpp:223
RelinkableHandle(ext::shared_ptr< T > &&p, bool registerAsObserver=true)
Definition: handle.hpp:207
RelinkableHandle(T *p, bool registerAsObserver=true)
Definition: handle.hpp:212
RelinkableHandle(const ext::shared_ptr< T > &p, bool registerAsObserver=true)
Definition: handle.hpp:202
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
Definition: errors.hpp:117
Definition: any.hpp:35
STL namespace.
observer/observable pattern
#define QL_DEPRECATED
Definition: qldefines.hpp:215