shared_object.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of CasADi.
3  *
4  * CasADi -- A symbolic framework for dynamic optimization.
5  * Copyright (C) 2010 by Joel Andersson, Moritz Diehl, K.U.Leuven. All rights reserved.
6  *
7  * CasADi is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 3 of the License, or (at your option) any later version.
11  *
12  * CasADi is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with CasADi; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  *
21  */
22 
23 #include "shared_object.hpp"
24 #include "casadi_exception.hpp"
25 
26 #include <typeinfo>
27 #include <cassert>
28 
29 using namespace std;
30 namespace CasADi{
31 
32 SharedObject::SharedObject(){
33  node = 0;
34 }
35 
36 SharedObjectNode::SharedObjectNode(const SharedObjectNode& node){
37  is_init_ = node.is_init_;
38  count = 0; // reference counter is _not_ copied
39 }
40 
41 SharedObjectNode& SharedObjectNode::operator=(const SharedObjectNode& node){
42  is_init_ = node.is_init_;
43  // do _not_ copy the reference counter
44  return *this;
45 }
46 
47 SharedObject::SharedObject(const SharedObject& ref){
48  node = ref.node;
49  count_up();
50 }
51 
52 SharedObject::~SharedObject(){
53  count_down();
54 }
55 
56 void SharedObject::assignNode(SharedObjectNode* node_){
57  count_down();
58  node = node_;
59  count_up();
60 }
61 
62 void SharedObject::assignNodeNoCount(SharedObjectNode* node_){
63  node = node_;
64 }
65 
66 SharedObject& SharedObject::operator=(const SharedObject& ref){
67  // quick return if the old and new pointers point to the same object
68  if(node == ref.node) return *this;
69 
70  // decrease the counter and delete if this was the last pointer
71  count_down();
72 
73  // save the new pointer
74  node = ref.node;
75  count_up();
76  return *this;
77 }
78 
79 const SharedObjectNode* SharedObject::get() const{
80  return node;
81 }
82 
83 SharedObjectNode* SharedObject::get(){
84  return node;
85 }
86 
87 bool SharedObject::isNull() const{
88  return node==0;
89 }
90 
91 void SharedObject::count_up(){
92  if(node) node->count++;
93 }
94 
95 void SharedObject::count_down(){
96  if(node && --node->count == 0){
97  delete node;
98  node = 0;
99  }
100 }
101 
102 const SharedObjectNode* SharedObject::operator->() const{
103  casadi_assert(!isNull());
104  return node;
105 }
106 
107 SharedObjectNode* SharedObject::operator->(){
108  casadi_assert(!isNull());
109  return node;
110 }
111 
112 SharedObjectNode::SharedObjectNode(){
113  is_init_ = false;
114  count = 0;
115 }
116 
117 SharedObjectNode::~SharedObjectNode(){
118  assert(count==0);
119 }
120 
122  (*this)->init();
123 }
124 
126 }
127 
128 bool SharedObject::checkNode() const{
129  return dynamic_cast<const SharedObjectNode*>(get());
130 }
131 
132 void SharedObject::repr(std::ostream &stream) const{
133  if(isNull())
134  stream << 0;
135  else
136  (*this)->repr(stream);
137 }
138 
139 void SharedObjectNode::repr(std::ostream &stream) const{
140  // Print description by default
141  print(stream);
142 }
143 
144 void SharedObject::print(std::ostream &stream) const{
145  if(isNull()) stream << "Null pointer of class \"" << typeid(this).name() << "\"";
146  else (*this)->print(stream);
147 }
148 
149 void SharedObjectNode::print(std::ostream &stream) const{
150  // Print the name of the object by default
151  stream << typeid(this).name();
152 }
153 
154 void SharedObject::makeUnique(bool clone_members){
155  std::map<SharedObjectNode*,SharedObject> already_copied;
156  makeUnique(already_copied,clone_members);
157 }
158 
159 void SharedObject::makeUnique(std::map<SharedObjectNode*,SharedObject>& already_copied, bool clone_members){
160  if(node && node->count>1){
161  // First find out if the expression has already been copied
162  std::map<SharedObjectNode*,SharedObject>::iterator it = already_copied.find(node);
163 
164  if(it==already_copied.end()){
165  // If the expression has not yet been copied
166  SharedObjectNode *newnode = node->clone();
167 
168  // Copy the data members
169  if(clone_members) newnode->deepCopyMembers(already_copied);
170 
171  // Initialize object if parent was initialized
172  if(isInit() && !newnode->is_init_){
173  newnode->init();
174  }
175 
176  // Assign cloned node to object
177  assignNode(newnode);
178  } else {
179  // Use an existing copy
180  assignNode(it->second.get());
181  }
182  }
183 }
184 
185 SharedObject SharedObject::clone() const{
186  SharedObject ret;
187  if(!isNull()){
188  ret.assignNode((*this)->clone());
189  }
190  return ret;
191 }
192 
193 void SharedObject::swap(SharedObject& other){
194  SharedObject temp = *this;
195  *this = other;
196  other = temp;
197 }
198 
199 int SharedObject::getCount() const{
200  return (*this)->getCount();
201 }
202 
203 int SharedObjectNode::getCount() const{
204  return count;
205 }
206 
207 void SharedObjectNode::deepCopyMembers(std::map<SharedObjectNode*,SharedObject>& already_copied){
208 }
209 
210 bool SharedObject::isInit() const{
211  return (*this)->isInit();
212 }
213 
214 void SharedObject::assertInit() const{
215  (*this)->assertInit();
216 }
217 
218 bool SharedObjectNode::isInit() const{
219  return is_init_;
220 }
221 
222 void SharedObjectNode::assertInit() const{
223  casadi_assert_message(isInit(),"You must first initialize a Shared Object before you can use it." << std::endl << "Use something like f.init()");
224 }
225 
226 
227 } // namespace CasADi
228 
229 
Internal class for the reference counting framework, see comments on the public class.
void assignNode(SharedObjectNode *node)
Assign the node to a node class pointer (or null)
#define casadi_assert(x)
virtual void deepCopyMembers(std::map< SharedObjectNode *, SharedObject > &already_copied)
Deep copy data members.
virtual void init()
Initialize the object.
SharedObject implements a reference counting framework simular for effient and easily-maintained memo...
unsigned int count
Number of references pointing to the object.
virtual void repr(std::ostream &stream) const
Print a representation of the object.
#define assert(ignore)
#define casadi_assert_message(x, msg)
BEGIN_NAMESPACE_QPOASES returnValue print(const real_t *const v, int n)
SharedObjectNode * node
int getCount() const
Get the reference count.
void init(int nV, int nC, SymmetricMatrix *H, real_t *g, Matrix *A, const real_t *const lb, const real_t *const ub, const real_t *const lbA, const real_t *const ubA, int nWSR, const real_t *const x0, Options *options, int nOutputs, mxArray *plhs[])
bool is_init_
Has the function been initialized?
virtual SharedObjectNode * clone() const =0
Make a deep copy of the instance.


acado
Author(s): Milan Vukov, Rien Quirynen
autogenerated on Mon Jun 10 2019 12:35:04