Remove dynamic exceptions
[anna.git] / include / anna / core / Singleton.hpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #ifndef anna_core_Singleton_hpp
10 #define anna_core_Singleton_hpp
11
12 #include <typeinfo>
13
14 #include <anna/core/mt/Mutex.hpp>
15 #include <anna/core/mt/Guard.hpp>
16
17 namespace anna {
18
19 /**
20  Singleton pattern. Limits the use to a unique class instance.
21
22  Default constructor for T must be private in order to avoid
23  external instantiation. Following, an example using class A:
24
25
26  On A class header file, we will have:
27  \code
28
29  ...
30  ...
31
32  #include <anna/core/Singleton.hpp>
33
34  class A : public anna::Singleton <A> {
35  public:
36     // getters
37     int getData () const { return a_data; }
38
39     // setters
40     void setOtherData (const ASD& otherData) { a_otherData = otherData; }
41
42     // operators
43        ....
44
45     // methods
46        ...
47
48  private:
49     int a_data;
50     ASD a_otherData;
51
52     A ();
53
54     friend class functions::Singleton <A>;
55  };
56
57 \endcode
58
59  To use A class:
60
61  \code
62 #include <A.h>
63
64 ...
65 ...
66
67  void anyClass::anyFunction () noexcept(false)
68  {
69     A& a (A::instantiate ());
70
71     cout << a.getData () << endl;
72  }
73
74  \endcode
75 */
76 template <class T> class Singleton {
77 public:
78   /**
79      @return Class instance provided on template creation.
80   */
81   static T& instantiate() { return *alloc(true); }
82
83   /**
84      Release the class instance provided in this template creation.
85      If no instance has been created, this will be ignored.
86      This method only have to be used during the program termination.
87   */
88   static void release() { alloc(false); }
89
90 private:
91   static T* alloc(const bool allocate) {
92     static Mutex mutex;
93     static T* result(NULL);
94
95     if(allocate == true) {
96       if(result == NULL) {
97         Guard guard(mutex, "Singleton<T>::allocate");
98
99         if(result == NULL)
100           result = new T;
101       }
102     } else {
103       if(result != NULL) {
104         Guard guard(mutex, "Singleton<T>::deallocate");
105
106         if(result != NULL) {
107           delete result;
108           result = NULL;
109         }
110       }
111     }
112
113     return result;
114   }
115 };
116
117 } //namespace anna
118
119 #endif
120