Scopira  20080306
object.h
1 
2 /*
3  * Copyright (c) 2001-2003 National Research Council
4  *
5  * All rights reserved.
6  *
7  * This material is confidential and proprietary information of
8  * National Research Council Canada ("Confidential Information").
9  * This Confidential Information may only be used and reproduced
10  * in accordance with the terms of the license agreement.
11  *
12  */
13 
14 #ifndef __INCLUDED__SCOPIRA_TOOL_OBJECT_H__
15 #define __INCLUDED__SCOPIRA_TOOL_OBJECT_H__
16 
17 #include <assert.h>
18 
19 #include <scopira/tool/mutex.h>
20 #include <scopira/tool/export.h>
21 
22 // THIS FILE HAS BEEN FULLY DOCUMENTED
23 
29 namespace scopira
30 {
38  namespace tool
39  {
40  class object; // obj for short
41 
42  template <class T> class count_ptr;
43  template <class T> class count2_ptr;
44  //typedef count_ptr<object> objauto; //this is dangerous, dont use it (as it slices t_object's into simple object)
45 
46  // forward decl
47  class oflow_i;
48  class oobjflow_i;
49  class iobjflow_i;
50  }
51 }
52 
72 {
73  private:
74 
75  mutable volatile int dm_refcount; // current ref count, mutal and transient
76  mutable mutex dm_refcount_mutex;
77 #ifndef NDEBUG
78  volatile int dm_object_magic; // magic key for object class
79  volatile bool dm_use_debug_ref_counter; // when created, was the ref counter debug thing available?
80 #endif
81 
82  public:
83 
89  SCOPIRA_EXPORT virtual ~object();
90 
91  //
92  // reference stuff
93  //
94 
102  SCOPIRA_EXPORT int add_ref(void) const;
103 
114  SCOPIRA_EXPORT bool sub_ref(void) const;
115 
123  SCOPIRA_EXPORT void auto_ref(void) const;
124 
130  SCOPIRA_EXPORT int current_ref(void) const;
131 
132  //
133  // serialization stuff
134  //
135 
144  SCOPIRA_EXPORT virtual scopira::tool::oflow_i & print(scopira::tool::oflow_i &o) const;
145 
159  SCOPIRA_EXPORT virtual bool load(scopira::tool::iobjflow_i& in);
172  SCOPIRA_EXPORT virtual void save(scopira::tool::oobjflow_i& out) const;
173 
174 #ifndef NDEBUG
175 
180  bool is_alive_object(void) const { return this && (dm_object_magic == -236944); }
185  bool is_dead_object(void) const { return dm_object_magic == 5529022; }
186 #endif
187 
188  protected:
194  SCOPIRA_EXPORT object(void);
195 
209  SCOPIRA_EXPORT explicit object(bool neverusecounter);
210 
211  private:
221  object(const object &o);
222 
231  void operator = (const object &rhs);
232 };
233 
265 template <class T> class scopira::tool::count_ptr
266 {
267  public:
268  typedef T data_type;
269 
270  protected:
271  T *dm_ptr;
272 
273  public:
279  count_ptr(void)
280  : dm_ptr(0) { }
286  count_ptr(T *o)
287  : dm_ptr(o) { if (o) o->add_ref(); }
294  : dm_ptr(o.dm_ptr) { if (dm_ptr) dm_ptr->add_ref(); }
300  template <class Y> count_ptr(const count_ptr<Y> &o)
301  : dm_ptr(o.get()) { if (dm_ptr) dm_ptr->add_ref(); }
307  { if (dm_ptr) dm_ptr->sub_ref(); }
308 
315  void set(T* o)
316  { if (o) o->add_ref(); if (dm_ptr) dm_ptr->sub_ref(); dm_ptr = o; }
322  count_ptr & operator = (T *o)
323  { set(o); return *this; }
324 
330  count_ptr & operator = (const count_ptr<T> &o)
331  { set(o.dm_ptr); return *this; }
337  bool operator == (const count_ptr<T> &rhs) const { return dm_ptr == rhs.dm_ptr; }
343  bool operator == (const T* rhs) const { return dm_ptr == rhs; }
349  bool operator != (const count_ptr<T> &rhs) const { return dm_ptr != rhs.dm_ptr; }
355  bool operator != (const T* rhs) const { return dm_ptr != rhs; }
361  bool operator < (const count_ptr<T> &rhs) const { return dm_ptr < rhs.dm_ptr; }
362 
369  { if (dm_ptr) dm_ptr->print(o); /*else o<<"(null)";*/ return o; }
370 
371  // do save and load like the above?
372 
378  T* get(void) const { return dm_ptr; }
379 
385  T& ref(void) const
386  { assert("[NULL pointer dereferenced in count_ptr]" && dm_ptr); return *dm_ptr; }
387  //T& ref(void)
388  //{ assert(dm_ptr); return *dm_ptr; }
389 
395  T* operator ->(void) const
396  { assert("[NULL pointer dereferenced in count_ptr]" && dm_ptr); return dm_ptr; }
397  //T* operator ->(void)
398  //{ assert(dm_ptr); return dm_ptr; }
399 
405  T & operator *(void) const
406  { assert("[NULL pointer dereferenced in count_ptr]" && dm_ptr); return *dm_ptr; }
407 
414  bool is_null(void) const { return dm_ptr == 0; }
415 };
416 
434 template <class T> class scopira::tool::count2_ptr
435 {
436  protected:
437  T* dm_ptr;
438  bool dm_doref;
439 
440  public:
441  typedef T ptr_type;
442 
448  /*count2_ptr(bool doref)
449  : dm_ptr(0), dm_doref(doref) { }*/
457  count2_ptr(bool doref, T* o)
458  : dm_ptr(o), dm_doref(doref) { if (doref && o) o->add_ref(); }
465  : dm_ptr(o.dm_ptr), dm_doref(o.dm_doref) { if (dm_doref && dm_ptr) dm_ptr->add_ref(); }
471  { if (dm_doref && dm_ptr) dm_ptr->sub_ref(); }
472 
478  void set(T* o)
479  { if (dm_doref && o) o->add_ref(); if (dm_doref && dm_ptr) dm_ptr->sub_ref(); dm_ptr = o; }
486  { set(o); return *this; }
487 
494  { set(o.dm_ptr); return *this; }
500  bool operator == (const count2_ptr<T>& rhs) const { return dm_ptr == rhs.dm_ptr; }
506  bool operator == (const T* rhs) const { return dm_ptr == rhs; }
512  bool operator != (const count2_ptr<T>& rhs) const { return dm_ptr != rhs.dm_ptr; }
518  bool operator != (const T* rhs) const { return dm_ptr != rhs; }
524  bool operator < (const count2_ptr<T>& rhs) const { return dm_ptr < rhs.dm_ptr; }
525 
531  oflow_i& print(oflow_i& o) const
532  { if (dm_ptr) dm_ptr->print(o); return o; }
533 
534  // do save and load like the above?
535 
541  T* get(void) const { return dm_ptr; }
542 
549  operator T*(void) const { return dm_ptr; }
550  //T* get(void)
551  //{ return dm_ptr; }
552 
558  T& ref(void) const
559  { assert("[NULL pointer dereferenced in count_ptr]" && dm_ptr); return *dm_ptr; }
560  //T& ref(void)
561  //{ assert(dm_ptr); return *dm_ptr; }
562 
568  T* operator ->(void) const
569  { assert("[NULL pointer dereferenced in count_ptr]" && dm_ptr); return dm_ptr; }
570  //T* operator ->(void)
571  //{ assert(dm_ptr); return dm_ptr; }
572 
578  T & operator *(void) const
579  { assert("[NULL pointer dereferenced in count_ptr]" && dm_ptr); return *dm_ptr; }
580 
587  bool is_null(void) const { return dm_ptr == 0; }
588 };
589 
599 SCOPIRA_EXPORT scopira::tool::oflow_i & operator << (scopira::tool::oflow_i &o, const scopira::tool::object &vl);
600 
609 SCOPIRA_EXPORT scopira::tool::oflow_i & operator << (scopira::tool::oflow_i &o, const scopira::tool::object *vl);
610 
619 template <class C>
620  inline scopira::tool::oflow_i & operator << (scopira::tool::oflow_i &o, const scopira::tool::count_ptr<C> &ptr)
621 {
622  return o << ptr.get();
623 }
624 
625 
626 
627 //
628 // *** DEBUG ROUTINES
629 //
630 
631 #ifndef NDEBUG
632 namespace scopira
633 {
634  namespace tool
635  {
636  class objrefcounter;
637  }
638 }
639 
651 {
652  protected:
653  static int dm_ref;
654  static int dm_peak;
655  static int dm_tot;
656  static int dm_baddel;
657  static int dm_real;
658 
659  public:
666  SCOPIRA_EXPORT objrefcounter(void);
673  SCOPIRA_EXPORT ~objrefcounter();
674 
675  public:
681  void foo(void) const { }
682 
683  private:
684  friend class object;
685 
686  static bool has_counter(void);
687  static void add_ref(void);
688  static void sub_ref(void);
689  static void bad_del(void);
690  static void add_real(void);
691  static void sub_real(void);
692 
693  static void output(void);
694 };
695 
696 // NDEBUG
697 #endif
698 
778 #endif
779 
Definition: mutex_pthreads.h:40
virtual bool load(scopira::tool::iobjflow_i &in)
Definition: archiveflow.h:20
Definition: object.h:650
T & ref(void) const
Definition: object.h:385
Definition: object.h:43
Definition: flow.h:352
oflow_i & print(oflow_i &o) const
Definition: object.h:531
count2_ptr & operator=(T *o)
Definition: object.h:485
Definition: object.h:71
void auto_ref(void) const
bool is_alive_object(void) const
Definition: object.h:180
int current_ref(void) const
bool is_dead_object(void) const
Definition: object.h:185
Definition: object.h:42
void foo(void) const
Definition: object.h:681
count_ptr(void)
Definition: object.h:279
count_ptr(const count_ptr< Y > &o)
Definition: object.h:300
virtual void save(scopira::tool::oobjflow_i &out) const
bool sub_ref(void) const
scopira::tool::oflow_i & print(scopira::tool::oflow_i &o) const
Definition: object.h:368
bool is_null(void) const
Definition: object.h:414
count_ptr(const count_ptr< T > &o)
Definition: object.h:293
count2_ptr & operator=(const count2_ptr< T > &o)
Definition: object.h:493
Definition: flow.h:421
T & ref(void) const
Definition: object.h:558
~count_ptr()
Definition: object.h:306
count_ptr(T *o)
Definition: object.h:286
count2_ptr(bool doref, T *o)
Definition: object.h:457
count2_ptr(const count_ptr< T > &o)
Definition: object.h:464
bool is_null(void) const
Definition: object.h:587
virtual scopira::tool::oflow_i & print(scopira::tool::oflow_i &o) const
int add_ref(void) const
~count2_ptr()
Definition: object.h:470
Definition: flow.h:159