3 * Copyright 1999 Karl Nelson <kenelson@ece.ucdavis.edu>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 #include <sigc++/scope.h>
20 #include <sigc++/object.h>
22 #ifdef SIGC_CXX_NAMESPACES
25 #endif //SIGC_CXX_NAMESPACES
27 /*********************************************************/
29 Reference::~Reference() {if (obj_) obj_->unreference();}
30 void Reference::set_sink() {if (obj_) obj_->set_sink();}
32 void Reference::init(ObjectReferenced *obj)
38 obj_->register_ref(this);
43 void Reference::set(ObjectReferenced *obj,void* cache,bool is_ptr)
47 if (obj_) obj_->unreference();
52 obj_->register_ref(this);
54 if (is_ptr) obj_->set_sink();
58 /*********************************************************/
59 // object interaction properties
60 void Scope::reference() {if (obj_) obj_->reference();}
61 void Scope::unreference() {if (obj_) obj_->unreference();}
62 void Scope::set_sink() {if (obj_) obj_->set_sink();}
70 void Scope::register_scope(ObjectScoped *obj)
73 obj->register_scope(this);
76 void Scope::register_scope(const Scope *parent)
78 if (parent&&parent->obj_)
79 parent->object()->register_scope(this,parent);
82 void Scope::unregister_scope()
85 object()->unregister_scope(this);
89 /*********************************************************/
90 // object interaction properties
91 void Scope::set(ObjectScoped *obj,void* cache,bool)
97 cache_=(obj_?cache:0);
100 void ScopeNode::disconnect(bool dummy)
112 /*********************************************************/
114 // These are here because they are virtual
116 void Scopes::Uncounted::disconnect(bool l)
121 Scopes::Uncounted::~Uncounted()
126 void Scopes::Extend::set(ObjectScoped *obj,void* cache,bool is_ptr)
128 Scope::set(obj,cache,is_ptr);
129 if (is_ptr) set_sink();
132 void Scopes::Extend::on_connect()
137 void Scopes::Extend::erase()
143 void Scopes::Extend::disconnect(bool l)
148 Scopes::Extend::~Extend()
153 void Scopes::Limit::set(ObjectScoped *obj,void* cache,bool is_ptr)
155 Scope::set(obj,cache,is_ptr);
156 if (is_ptr) set_sink();
159 void Scopes::Limit::on_connect()
164 void Scopes::Limit::erase()
170 void Scopes::Limit::disconnect(bool l)
176 Scopes::Limit::~Limit()
181 /*****************************************************************/
183 inline void splice_node(ScopeNode *n1,ScopeNode *n2)
189 inline void unlink_node(ScopeNode *n)
191 if (n->next_==n) return;
192 splice_node(n->prev_,n->next_);
196 void ScopeNode::remove_self() {unlink_node(this);}
197 ScopeNode::~ScopeNode() {unlink_node(this);}
198 void ScopeNode::erase() {}
200 DataNode::~DataNode() {}
201 void DataNode::erase() {delete this;}
205 ScopeIterator_ ScopeList::insert_direct(Iterator pos,NodeType *tmp)
207 if (!tmp) return tmp;
208 NodeType *after=pos.node();
209 NodeType *before=(NodeType*)(after->prev_);
211 splice_node(before,tmp);
212 splice_node(tmp,after);
216 ScopeIterator_ ScopeList::erase(Iterator pos)
218 NodeType* loc=pos.node();
220 if (!loc) return tmp;
228 void ScopeList::swap_elements(Iterator p1,Iterator p2)
230 NodeType *loc1=p1.node();
231 NodeType *loc2=p2.node();
233 if (!loc1||!loc2) return;
235 NodeType *before1=(NodeType*)loc1->prev_;
236 NodeType *after1=(NodeType*)loc1->next_;
237 NodeType *before2=(NodeType*)loc2->prev_;
238 NodeType *after2=(NodeType*)loc2->next_;
243 if (before2==loc2) return;
244 splice_node(loc2,loc2);
245 splice_node(before2,loc1);
246 splice_node(loc1,after2);
252 splice_node(loc1,loc1);
253 splice_node(before1,loc2);
254 splice_node(loc2,after1);
258 {// loc1 is right before loc2
259 splice_node(before1,loc2);
260 splice_node(loc2,loc1);
261 splice_node(loc1,after2);
265 {// loc2 is right before loc1
266 splice_node(before2,loc1);
267 splice_node(loc1,loc2);
268 splice_node(loc2,after1);
272 splice_node(before1,loc2);
273 splice_node(loc2,after1);
274 splice_node(before2,loc1);
275 splice_node(loc1,after2);
278 #ifdef SIGC_CXX_NAMESPACES