ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/ermyth/include/ermyth/phoenix.h
Revision: 1.1
Committed: Tue Aug 28 17:14:43 2007 UTC (16 years, 9 months ago) by pippijn
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Log Message:
added new files

File Contents

# Content
1 #ifndef ERMYTH_PHOENIX_H
2 #define ERMYTH_PHOENIX_H
3
4 #include <stdlib.h> // atexit()
5
6
7 namespace impl
8 {
9 struct no_op_phoenix_initialiser
10 {
11 template<typename T>
12 void operator () (T &)
13 {
14 return;
15 }
16 };
17
18 template<typename BaseType, typename ContextType = BaseType, typename initialiserType = no_op_phoenix_initialiser>
19 struct phoenix : public BaseType
20 {
21 typedef ContextType context_type;
22 typedef BaseType base_type;
23 typedef initialiserType initialiser_type;
24
25 static base_type &instance ()
26 {
27 static this_type meyers;
28 static bool donethat = false;
29
30 if (this_type::m_destroyed)
31 {
32 // phoenix_CERR << "Phoenixing!" << std::endl;
33 donethat = false;
34 new (&meyers) this_type;
35 atexit (this_type::do_atexit);
36 }
37
38 if (!donethat)
39 {
40 // phoenix_CERR << "initialising instance" << std::endl;
41 donethat = true;
42 initialiser_type () (meyers);
43 }
44
45 // phoenix_CERR << "instance() == " <<std::hex<<&meyers<<std::endl;
46 return meyers;
47 }
48
49 private:
50 typedef phoenix<base_type,context_type,initialiser_type> this_type;
51
52 static bool m_destroyed;
53
54 phoenix ()
55 {
56 // phoenix_CERR << "phoenix() @" << std::hex<< this << std::endl;
57 m_destroyed = false;
58 }
59
60 virtual ~phoenix () throw ()
61 {
62 // phoenix_CERR << "~phoenix() @" << std::hex<< this << std::endl;
63 m_destroyed = true;
64 }
65
66 // Destroys the shared object via a manual call to it's dtor.
67 static void do_atexit()
68 {
69 if (m_destroyed)
70 return;
71 // phoenix_CERR << "::do_atexit() @ " << std::hex << &instance() << std::endl;
72 static_cast<this_type &> (instance ()).~phoenix (); // will eventually trigger the BaseType dtor
73 }
74 };
75
76 template<typename T, typename C, typename I>
77 bool phoenix<T, C, I>::m_destroyed = false;
78 } // namespace
79
80 #endif // ERMYTH_PHOENIX_H