Protium
Math and Design Features
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
DeletionPolicies.h
Go to the documentation of this file.
1 #ifndef Protium_DeletionPolicies_h_
2 #define Protium_DeletionPolicies_h_
3 
4 #include <list>
5 #include <vector>
6 #include <algorithm>
7 #include <stdexcept>
8 
9 namespace Protium{
10 
11  namespace Singleton{
12 
14  typedef void (*exit_function_pointer_type)();
15 
17  void AtExitFn();
18 
21  template <typename T>
22  struct Deleter{
24  typedef void (*Type)(T*);
26  static void Delete(T* pObj)
27  { delete pObj; }
28  };
29 
31  template <class T>
32  struct Adapter{
36  void operator()(T*) { return fFun(); }
37  };
38 
39 
43  unsigned int fPriority;
44  public:
46  DeletionTracker(unsigned int x) : fPriority(x) {}
47 
49  virtual ~DeletionTracker() = 0;
50 
52  static bool Compare(const DeletionTracker* lhs, const DeletionTracker* rhs){
53  return lhs->fPriority > rhs->fPriority;
54  }
55  };
56 
59 
61  static std::list<DeletionTracker*> TrackerList;
62 
66  template <typename Host, typename Destroyer>
69  Host* fHost;
71  Destroyer fDestroyer;
72 
73  public:
78  ConcreteDeletionTracker(Host* p , unsigned int priority, Destroyer d)
79  : DeletionTracker(priority)
80  , fHost(p)
81  , fDestroyer(d)
82  {}
83 
86  { fDestroyer(fHost); }
87 
88  };
89 
91  template <typename Host, typename Destroyer>
92  void SetPriority(Host* pDynObject, unsigned int priority, Destroyer d){
93  DeletionTracker* p = new ConcreteDeletionTracker<Host, Destroyer>(pDynObject, priority, d);
94  std::list<DeletionTracker*>::iterator pos = std::upper_bound( TrackerList.begin(), TrackerList.end(), p, DeletionTracker::Compare );
95  TrackerList.insert(pos, p);
96  std::atexit(AtExitFn);
97  }
98 
100  template <typename Host>
101  void SetPriority(Host* pDynObject, unsigned int priority,typename Deleter< Host >::Type d = Deleter< Host >::Delete ){
102  SetPriority<Host, typename Deleter< Host >::Type >(pDynObject, priority, d);
103  }
104 
105  template <class Host>
106  struct DeleteNever{
108  static void OnDeadReference(){}
109  };
110 
111  template <class Host>
112  struct DeleteOnce{
113  static void ScheduleDestruction(Host*, exit_function_pointer_type pFun) { std::atexit(pFun); }
114  static void OnDeadReference() { throw std::logic_error("Dead Singleton Reference Detected"); }
115  };
116 
117 
118  template <class Host>
119  class DeleteTwice{
120  static bool fDestroyed;
121  public:
123  if(! fDestroyed ) std::atexit(pFun);
124  }
125  static void OnDeadReference(){
126  fDestroyed=true;
127  }
128  };
129 
130  template<class Host>
131  bool DeleteTwice<Host>::fDestroyed = false;
132 
133  template <class Host>
135  protected:
136  static bool fDead;
137  static bool fNeedsCallback;
139  public:
141  static bool firstTime = true;
142  fDead = false;
143  deleter = pFun;
144  if(firstTime || fNeedsCallback){
145  std::atexit(atexitCallback);
146  firstTime=false;
147  fNeedsCallback = false;
148  }
149 
150  }
151  static void OnDeadReference(){}
152 
153  static void GracefulDelete(){
154  if(fDead) return;
155  fDead = true;
156  deleter();
157  }
158 
159  static void atexitCallback(){
160  fNeedsCallback = true;
161  GracefulDelete();
162 
163  }
164  };
165 
166  template <class Host>
167  exit_function_pointer_type DeleteRandom<Host>::deleter = NULL;
168 
169  template <class Host>
170  bool DeleteRandom<Host>::fDead = true;
171 
172  template <class Host>
173  bool DeleteRandom<Host>::fNeedsCallback = true;
174 
175 
176  template <class Host>
178  public:
179  static void ScheduleDestruction(Host* pObj, exit_function_pointer_type pFun){
180 
181  Adapter<Host> adapter = { pFun };
182  SetPriority(pObj, GetLongevity(pObj) , adapter);
183  }
184  static void OnDeadReference() { throw std::logic_error("Dead Reference Detected"); }
185  };
186 
187  template <unsigned int priority, class Host>
189  public:
191 
192  static void ScheduleDestruction(Host* pObj, exit_function_pointer_type pFun){
193  Adapter<Host> adapter = { pFun };
194  SetPriority(pObj, priority , adapter);
195  }
196 
197  static void OnDeadReference() { throw std::logic_error("Dead Reference Detected"); }
198  };
199 
200  template <class Host>
201  struct DeleteLast : DeleteWithFixedPriority<0xFFFFFFFF ,Host>{};
202 
203  template <class Host>
204  struct DeleteNextToLast : DeleteWithFixedPriority<0xFFFFFFFE ,Host>{};
205 
206  template <class Host>
207  struct DeleteFirst : DeleteWithFixedPriority<0x0,Host>{};
208 
209 
211 
212  template<class Host>
213  class Composite{
214  typedef std::vector<exit_function_pointer_type> Container;
215  typedef typename Container::iterator iterator;
217  public:
218  static void Initialize(){
219  static bool done = false;
220  if(!done){
221  fContainer = new Container;
222  done=true;
223  }
224  }
226  Initialize();
227  fContainer->push_back(pFun);
228  }
229  static bool Destruct(){
230  Initialize();
231  for(iterator it = fContainer->begin(); it!= fContainer->end(); ++it)
232  (*it)();
233  delete fContainer;
234  }
235 
236  };
237  public:
238  template<template <class> class DestructionPolicy >
239  struct DestroyWith{
240  template<class Host>
242  static void ScheduleDestruction(Host* pObj, exit_function_pointer_type pFun){
244  DestructionPolicy<Host>::ScheduleDestruction(pObj, pFun);
245  DestructionPolicy<Host>::ScheduleDestruction(0,Composite<Host>::Destruct);
246  }
247  static void OnDeadReference() { throw std::logic_error("Dead Reference Detected"); }
248  };
249  };
250  template<template <class> class DestructionPolicy >
251  struct DestroyAfter{
252  template<class Host>
253  struct IsDestroyed{
254  static void ScheduleDestruction(Host* pObj, exit_function_pointer_type pFun){
256  }
257  static void OnDeadReference() { throw std::logic_error("Dead Reference Detected"); }
258  };
259  };
260 
261  };
262 
263 
264  template<class Host>
265  typename DeleteComposite::Composite<Host>::Container* DeleteComposite::Composite<Host>::fContainer = NULL;
266 
267 
268  }
269 }
270 
271 
272 #endif //File Guardian
static bool Compare(const DeletionTracker *lhs, const DeletionTracker *rhs)
For Comparing priority of deletion.
Abstract class to hold priority for deletion.
unsigned int fPriority
Priority of this class to be deleted (higher implies greater priority)
static void Delete(T *pObj)
Default deletion method.
void(* exit_function_pointer_type)()
Defines the type of functions to be called at exit.
std::vector< exit_function_pointer_type > Container
Destroyer fDestroyer
instance of destroyer
void operator()(T *)
To be used as a callback.
static void ScheduleDestruction(Host *, exit_function_pointer_type pFun)
virtual ~DeletionTracker()=0
Abstract definition.
DeletionTracker(unsigned int x)
Default constructor.
static exit_function_pointer_type deleter
~ConcreteDeletionTracker()
Calls the deletion method.
void AtExitFn()
Gets added to the std::atexit queue every time a singleton get created. Called once for every singlet...
Host * fHost
Pointer to the host object.
Deletion Adapter class.
static void ScheduleDestruction(Host *pObj, exit_function_pointer_type pFun)
static void ScheduleDestruction(Host *, exit_function_pointer_type pFun)
ConcreteDeletionTracker(Host *p, unsigned int priority, Destroyer d)
static void ScheduleDestruction(Host *, exit_function_pointer_type)
void SetPriority(Host *pDynObject, unsigned int priority, Destroyer d)
Helper function for putting an object into the deletion queue.
static void ScheduleDestruction(Host *pObj, exit_function_pointer_type pFun)
static void ScheduleDestruction(Host *pObj, exit_function_pointer_type pFun)
exit_function_pointer_type fFun
The Function to be called when the object is deleted.
static void ScheduleDestruction(Host *pObj, exit_function_pointer_type pFun)
static bool Insert(exit_function_pointer_type pFun)
static void ScheduleDestruction(Host *, exit_function_pointer_type pFun)
void(* Type)(T *)
Convenience typedef.