Templates -- Meow  1.2.9
A C++ template contains kinds of interesting classes and functions
Self.h
Go to the documentation of this file.
1 #ifndef Self_h__
2 #define Self_h__
3 
4 #include <cstdlib>
5 #include <algorithm>
6 
7 namespace meow {
8 
9 #define DO_NOT_USE_SELF
10 #ifdef DO_NOT_USE_SELF
11 
12 template<class Data>
13 class Self {
14 public:
17  };
18 private:
19  Data data_;
20 public:
21  Self( ) { }
22  Self(Data const& d ): data_(d) { }
23  Self(Self const& b, DuplicateType d): data_(b.data_) { }
24  Self(Self const& b);
25  ~Self() { }
26  Data const* operator->() const { return &data_; }
27  Data * operator->() { return &data_; }
28  Self& operator()() const { return *((Self*)this); }
29  Self const& copyFrom(Self const& s) { data_ = s.data_; return *this; }
30  Self const& referenceFrom(Self const& s) {
31  return copyFrom(s);
32  }
33  Self const& duplicateFrom(Self const& s, DuplicateType t) {
34  return copyFrom(s);
35  }
36  bool same(Self const& s) const { return false; }
37  bool equal(Self const& s) const { return data_ == s.data_; }
38  bool referenceLess(Self const& s) const { return (this < &s); }
39  void operator=(Self const& a);
40 };
41 
42 #else
43 
139 template<class Data>
140 class Self {
141 public:
145  enum DuplicateType {
146  COPY_FROM,
147  REFERENCE_FROM
148  };
149 private:
150  class Body {
151  private:
152  struct Kernel {
153  Data* data_;
154  size_t counter_;
155  Body const* master_;
156 
157  Kernel(Body const* master):
158  data_(new Data( )), counter_(1), master_(master) {
159  }
160 
161  Kernel(Body const* master, Data const& d):
162  data_(new Data(d)), counter_(1), master_(master) {
163  }
164 
165  ~Kernel() {
166  delete data_;
167  }
168  };
169 
170  Kernel* pointer_;
171  size_t counter_;
172 
173  void clear() {
174  --(pointer_->counter_);
175  if (pointer_->counter_ <= 0) {
176  delete pointer_;
177  }
178  else if (pointer_->master_ == this) {
179  pointer_->master_ = NULL;
180  }
181  }
182  public:
183  Body( ): pointer_(new Kernel(this )), counter_(1) { }
184  Body(Data const& d): pointer_(new Kernel(this, d)), counter_(1) { }
185  Body(Body const& b): pointer_(b.pointer_ ), counter_(1) {
186  ++(pointer_->counter_);
187  }
188 
189  ~Body() {
190  clear();
191  }
192 
193  Body& copyFrom(Body const& b) {
194  clear();
195  pointer_ = b.pointer_;
196  ++(pointer_->counter_);
197  return *this;
198  }
199 
200  Data const* access() const {
201  return pointer_->data_;
202  }
203 
204  Data* modify() {
205  if (pointer_->counter_ > 1) {
206  --(pointer_->counter_);
207  Kernel* dupl = new Kernel(this, *pointer_->data_);
208  if (pointer_->master_ == this) {
209  std::swap(pointer_->data_, dupl->data_);
210  pointer_->master_ = NULL;
211  }
212  pointer_ = dupl;
213  }
214  else if (pointer_->master_ == NULL) {
215  pointer_->master_ = this;
216  }
217  return pointer_->data_;
218  }
219 
220  int attach() {
221  return ++counter_;
222  }
223 
224  int detach() {
225  return --counter_;
226  }
227  };
228 
229  Body* body_;
230 
231  void clear() {
232  if (body_->detach() <= 0) {
233  delete body_;
234  }
235  }
236 public:
240  Self(): body_(new Body()) {
241  }
242 
248  Self(Data const& d): body_(new Body(d)) {
249  }
250 
257  Self(Self const& b, DuplicateType d) {
258  switch(d) {
259  case COPY_FROM:
260  body_ = new Body(*b.body_);
261  break;
262  case REFERENCE_FROM:
263  body_ = b.body_;
264  body_->attach();
265  break;
266  }
267  }
268 
270  Self(Self const& b);
271 
273  ~Self() {
274  clear();
275  }
276 
278  Data const* operator->() const {
279  return body_->access();
280  }
281 
285  Data* operator->() {
286  return body_->modify();
287  }
288 
290  Self& operator()() const {
291  return *((Self*)this);
292  }
293 
300  Self const& copyFrom(Self const& s) {
301  if (body_->access() != s.body_->access()) {
302  body_->copyFrom(*s.body_);
303  }
304  return *this;
305  }
306 
313  Self const& referenceFrom(Self const& s) {
314  if (body_ != s.body_) {
315  clear();
316  body_ = s.body_;
317  body_->attach();
318  }
319  return *this;
320  }
321 
329  Self const& duplicateFrom(Self const& s, DuplicateType t) {
330  switch(t) {
331  case COPY_FROM : return copyFrom(s);
332  case REFERENCE_FROM: return referenceFrom(s);
333  }
334  return *this;
335  }
336 
344  bool same(Self const& s) const {
345  return (body_ == s.body_);
346  }
347 
356  bool equal(Self const& s) const {
357  if (same(s) || body_->access() == s.body_->access()) return true;
358  return (*body_->access() == *s.body_->access());
359  }
360 
366  bool referenceLess(Self const& s) const {
367  return (body_ < s.body_);
368  }
369 
371  void operator=(Self const& a);
372 };
373 
374 #endif
375 
376 } // meow
377 
378 #endif // Self_h__
Data const * operator->() const
Definition: Self.h:26
Self const & copyFrom(Self const &s)
Definition: Self.h:29
bool referenceLess(Self const &s) const
Definition: Self.h:38
Self(Self const &b, DuplicateType d)
Definition: Self.h:23
void operator=(Self const &a)
Self()
Definition: Self.h:21
Data * operator->()
Definition: Self.h:27
~Self()
Definition: Self.h:25
bool same(Self const &s) const
Definition: Self.h:36
bool equal(Self const &s) const
Definition: Self.h:37
Self & operator()() const
Definition: Self.h:28
Self const & referenceFrom(Self const &s)
Definition: Self.h:30
Self const & duplicateFrom(Self const &s, DuplicateType t)
Definition: Self.h:33
Self(Data const &d)
Definition: Self.h:22