00001 /* 00002 * This file is part of CasADi. 00003 * 00004 * CasADi -- A symbolic framework for dynamic optimization. 00005 * Copyright (C) 2010 by Joel Andersson, Moritz Diehl, K.U.Leuven. All rights reserved. 00006 * 00007 * CasADi is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 3 of the License, or (at your option) any later version. 00011 * 00012 * CasADi is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with CasADi; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 * 00021 */ 00022 00023 #ifndef SHARED_OBJECT_HPP 00024 #define SHARED_OBJECT_HPP 00025 00026 #include "printable_object.hpp" 00027 #include "casadi_exception.hpp" 00028 #include <map> 00029 #include <vector> 00030 00031 namespace CasADi{ 00032 00033 // Forward declaration of internal class 00034 class SharedObjectNode; 00035 00066 class SharedObject : public PrintableObject{ 00067 #ifndef SWIG 00068 template<class B> friend B shared_cast(SharedObject& A); 00069 template<class B> friend const B shared_cast(const SharedObject& A); 00070 #endif // SWIG 00071 00072 public: 00073 #ifndef SWIG 00074 00075 SharedObject(); 00076 00078 SharedObject(const SharedObject& ref); 00079 00081 SharedObject clone() const; 00082 00084 ~SharedObject(); 00085 00087 SharedObject& operator=(const SharedObject& ref); 00088 00090 void assignNode(SharedObjectNode* node); 00091 00093 void assignNodeNoCount(SharedObjectNode* node); 00094 00096 const SharedObjectNode* get() const; 00097 00099 SharedObjectNode* get(); 00100 00102 int getCount() const; 00103 00105 void swap(SharedObject& other); 00106 00108 SharedObjectNode* operator->(); 00109 00111 const SharedObjectNode* operator->() const; 00112 00114 virtual void repr(std::ostream &stream) const; 00115 00117 virtual void print(std::ostream &stream=std::cout) const; 00118 00119 #endif // SWIG 00120 00122 void init(); 00123 00125 bool isInit() const; 00126 00128 void assertInit() const; 00129 00131 bool isNull() const; 00132 00134 virtual bool checkNode() const; 00135 00137 00138 void makeUnique(bool clone_members=true); 00139 #ifndef SWIG 00140 void makeUnique(std::map<SharedObjectNode*,SharedObject>& already_copied, bool clone_members=true); 00142 00143 private: 00144 SharedObjectNode *node; 00145 void count_up(); // increase counter of the node 00146 void count_down(); // decrease counter of the node 00147 #endif // SWIG 00148 }; 00149 00150 #ifndef SWIG 00151 00153 class SharedObjectNode{ 00154 friend class SharedObject; 00155 public: 00156 00158 SharedObjectNode(); 00159 00161 SharedObjectNode(const SharedObjectNode& node); 00162 00164 SharedObjectNode& operator=(const SharedObjectNode& node); 00165 00167 virtual ~SharedObjectNode() = 0; 00168 00170 virtual SharedObjectNode* clone() const=0; 00171 00173 virtual void deepCopyMembers(std::map<SharedObjectNode*,SharedObject>& already_copied); 00174 00176 int getCount() const; 00177 00179 virtual void init(); 00180 00182 bool isInit() const; 00183 00185 void assertInit() const; 00186 00188 virtual void repr(std::ostream &stream) const; 00189 00191 virtual void print(std::ostream &stream) const; 00192 00193 protected: 00195 template<class B> 00196 B shared_from_this(); 00197 00199 template<class B> 00200 const B shared_from_this() const; 00201 00203 bool is_init_; 00204 00205 private: 00207 unsigned int count; 00208 }; 00209 00211 template<class B> 00212 B shared_cast(SharedObject& A){ 00213 00215 SharedObjectNode* ptr = A.get(); 00216 00218 B ret; 00219 00221 ret.assignNode(ptr); 00222 00224 if(ptr && !ret.checkNode()) 00225 ret.assignNode(0); 00226 00227 return ret; 00228 } 00229 00231 template<class B> 00232 const B shared_cast(const SharedObject& A){ 00233 SharedObject A_copy = A; 00234 return shared_cast<B>(A_copy); 00235 } 00236 00238 template<class B> 00239 bool is_a(const SharedObject& A){ 00240 casadi_assert(!A.isNull()); 00241 return !shared_cast<B>(A).isNull(); 00242 } 00243 00245 00246 template<class A> 00247 A deepcopy(const A& a){ 00248 A ret = a; 00249 ret.makeUnique(); 00250 return ret; 00251 } 00252 00253 template<class A> 00254 A deepcopy(const A& a, std::map<SharedObjectNode*,SharedObject>& already_copied){ 00255 A ret = a; 00256 ret.makeUnique(already_copied); 00257 return ret; 00258 } 00259 00260 template<class A> 00261 std::vector<A> deepcopy(const std::vector<A>& a, std::map<SharedObjectNode*,SharedObject>& already_copied){ 00262 std::vector<A> ret = a; 00263 for(typename std::vector<A>::iterator it=ret.begin(); it!=ret.end(); ++it){ 00264 it->makeUnique(already_copied); 00265 } 00266 return ret; 00267 } 00269 00270 // Template function implementations 00271 template<class B> 00272 B SharedObjectNode::shared_from_this(){ 00273 B ret; 00274 ret.assignNode(this); 00275 00276 // Assert that the object is valid 00277 casadi_assert(ret.checkNode()); 00278 00279 return ret; 00280 } 00281 00282 template<class B> 00283 const B SharedObjectNode::shared_from_this() const{ 00284 B ret; 00285 ret.assignNode(const_cast<SharedObjectNode*>(this)); 00286 00287 // Assert that the object is valid 00288 casadi_assert(ret.checkNode()); 00289 00290 return ret; 00291 } 00292 00293 00294 #endif // SWIG 00295 00296 00297 } // namespace CasADi 00298 00299 00300 #endif // SHARED_OBJECT_HPP 00301