1 /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 3 /* 4 Copyright (C) 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 disposable.hpp 21 \brief generic disposable object with move semantics 22 */ 23 24 #ifndef quantlib_disposable_hpp 25 #define quantlib_disposable_hpp 26 27 #include <ql/qldefines.hpp> 28 29 namespace QuantLib { 30 31 //! generic disposable object with move semantics 32 /*! This class can be used for returning a value by copy. It relies 33 on the returned object exposing a <tt>swap(T\&)</tt> method through 34 which the copy constructor and assignment operator are implemented, 35 thus resulting in actual move semantics. Typical use of this 36 class is along the following lines: 37 \code 38 Disposable<Foo> bar(Integer i) { 39 Foo f(i*2); 40 return f; 41 } 42 \endcode 43 44 \warning In order to avoid copies in code such as shown above, 45 the conversion from <tt>T</tt> to <tt>Disposable\<T\></tt> 46 is destructive, i.e., it does <b>not</b> preserve the 47 state of the original object. Therefore, it is necessary 48 for the developer to avoid code such as 49 \code 50 Disposable<Foo> bar(Foo& f) { 51 return f; 52 } 53 \endcode 54 which would likely render the passed object unusable. 55 The correct way to obtain the desired behavior would be: 56 \code 57 Disposable<Foo> bar(Foo& f) { 58 Foo temp = f; 59 return temp; 60 } 61 \endcode 62 */ 63 template <class T> 64 class Disposable : public T { 65 public: 66 Disposable(T& t); 67 Disposable(const Disposable<T>& t); 68 Disposable<T>& operator=(const Disposable<T>& t); 69 }; 70 71 72 // inline definitions 73 74 template <class T> Disposable(T & t)75 inline Disposable<T>::Disposable(T& t) { 76 this->swap(t); 77 } 78 79 template <class T> Disposable(const Disposable<T> & t)80 inline Disposable<T>::Disposable(const Disposable<T>& t) : T() { 81 this->swap(const_cast<Disposable<T>&>(t)); 82 } 83 84 template <class T> operator =(const Disposable<T> & t)85 inline Disposable<T>& Disposable<T>::operator=(const Disposable<T>& t) { 86 this->swap(const_cast<Disposable<T>&>(t)); 87 return *this; 88 } 89 90 } 91 92 93 #endif 94