shared_object.cpp
Go to the documentation of this file.
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 #include "shared_object.hpp"
00024 #include "casadi_exception.hpp"
00025 
00026 #include <typeinfo>
00027 #include <cassert>
00028 
00029 using namespace std;
00030 namespace CasADi{
00031 
00032 SharedObject::SharedObject(){
00033   node = 0;
00034 }
00035 
00036 SharedObjectNode::SharedObjectNode(const SharedObjectNode& node){
00037   is_init_ = node.is_init_;
00038   count = 0; // reference counter is _not_ copied
00039 }
00040 
00041 SharedObjectNode& SharedObjectNode::operator=(const SharedObjectNode& node){
00042   is_init_ = node.is_init_;
00043   // do _not_ copy the reference counter
00044   return *this;
00045 }
00046 
00047 SharedObject::SharedObject(const SharedObject& ref){
00048   node = ref.node;
00049   count_up();
00050 }
00051 
00052 SharedObject::~SharedObject(){
00053   count_down();
00054 }
00055 
00056 void SharedObject::assignNode(SharedObjectNode* node_){
00057   count_down();
00058   node = node_;
00059   count_up();
00060 }
00061 
00062 void SharedObject::assignNodeNoCount(SharedObjectNode* node_){
00063   node = node_;
00064 }
00065 
00066 SharedObject& SharedObject::operator=(const SharedObject& ref){
00067   // quick return if the old and new pointers point to the same object
00068   if(node == ref.node) return *this;
00069 
00070   // decrease the counter and delete if this was the last pointer       
00071   count_down();
00072 
00073   // save the new pointer
00074   node = ref.node;
00075   count_up();
00076   return *this;
00077 }
00078 
00079 const SharedObjectNode* SharedObject::get() const{
00080   return node;
00081 }
00082 
00083 SharedObjectNode* SharedObject::get(){
00084   return node;
00085 }
00086 
00087 bool SharedObject::isNull() const{
00088   return node==0;
00089 }
00090 
00091 void SharedObject::count_up(){
00092   if(node) node->count++;  
00093 }
00094 
00095 void SharedObject::count_down(){
00096   if(node && --node->count == 0){
00097     delete node;
00098     node = 0;
00099   }  
00100 }
00101 
00102 const SharedObjectNode* SharedObject::operator->() const{
00103   casadi_assert(!isNull());
00104   return node;
00105 }
00106 
00107 SharedObjectNode* SharedObject::operator->(){
00108   casadi_assert(!isNull());
00109   return node;
00110 }
00111     
00112 SharedObjectNode::SharedObjectNode(){
00113   is_init_ = false;
00114   count = 0;
00115 }
00116 
00117 SharedObjectNode::~SharedObjectNode(){
00118    assert(count==0);
00119 }
00120 
00121 void SharedObject::init(){
00122   (*this)->init();
00123 }
00124 
00125 void SharedObjectNode::init(){
00126 }
00127     
00128 bool SharedObject::checkNode() const{
00129   return dynamic_cast<const SharedObjectNode*>(get());
00130 }
00131 
00132 void SharedObject::repr(std::ostream &stream) const{
00133   if(isNull())
00134     stream << 0;
00135   else
00136     (*this)->repr(stream);
00137 }
00138 
00139 void SharedObjectNode::repr(std::ostream &stream) const{
00140   // Print description by default
00141   print(stream);
00142 }
00143 
00144 void SharedObject::print(std::ostream &stream) const{
00145   if(isNull())    stream << "Null pointer of class \"" << typeid(this).name() << "\"";
00146   else           (*this)->print(stream);
00147 }
00148 
00149 void SharedObjectNode::print(std::ostream &stream) const{
00150   // Print the name of the object by default
00151   stream << typeid(this).name();
00152 }
00153 
00154 void SharedObject::makeUnique(bool clone_members){
00155   std::map<SharedObjectNode*,SharedObject> already_copied;
00156   makeUnique(already_copied,clone_members);
00157 }
00158 
00159 void SharedObject::makeUnique(std::map<SharedObjectNode*,SharedObject>& already_copied, bool clone_members){
00160   if(node && node->count>1){
00161     // First find out if the expression has already been copied
00162     std::map<SharedObjectNode*,SharedObject>::iterator it = already_copied.find(node);
00163     
00164     if(it==already_copied.end()){
00165       // If the expression has not yet been copied
00166       SharedObjectNode *newnode = node->clone();
00167       
00168       // Copy the data members
00169       if(clone_members) newnode->deepCopyMembers(already_copied);
00170       
00171       // Initialize object if parent was initialized
00172       if(isInit() && !newnode->is_init_){
00173         newnode->init();
00174       }
00175       
00176       // Assign cloned node to object
00177       assignNode(newnode);
00178     } else {
00179       // Use an existing copy
00180       assignNode(it->second.get());
00181     }
00182   }
00183 }
00184 
00185 SharedObject SharedObject::clone() const{
00186   SharedObject ret;
00187   if(!isNull()){
00188     ret.assignNode((*this)->clone());
00189   }
00190   return ret;
00191 }
00192 
00193 void SharedObject::swap(SharedObject& other){
00194   SharedObject temp = *this;
00195   *this = other;
00196   other = temp;
00197 }
00198 
00199 int SharedObject::getCount() const{
00200   return (*this)->getCount();
00201 }
00202 
00203 int SharedObjectNode::getCount() const{
00204   return count;
00205 }
00206 
00207 void SharedObjectNode::deepCopyMembers(std::map<SharedObjectNode*,SharedObject>& already_copied){
00208 }
00209 
00210 bool SharedObject::isInit() const{
00211   return (*this)->isInit();
00212 }
00213 
00214 void SharedObject::assertInit() const{
00215   (*this)->assertInit();
00216 }
00217 
00218 bool SharedObjectNode::isInit() const{
00219   return is_init_;
00220 }
00221 
00222 void SharedObjectNode::assertInit() const{
00223   casadi_assert_message(isInit(),"You must first initialize a Shared Object before you can use it." << std::endl <<  "Use something like f.init()");
00224 }
00225 
00226 
00227 } // namespace CasADi
00228     
00229     


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Thu Aug 27 2015 12:00:00