Scarab  v2.4.7
Project 8 C++ Utility Library
singleton.hh
Go to the documentation of this file.
1 #ifndef SCARAB_SINGLETON_HH_
2 #define SCARAB_SINGLETON_HH_
3 
4 #include "destroyer.hh"
5 #include "error.hh"
6 
7 #include <cstddef>
8 #include <mutex>
9 
10 namespace scarab
11 {
12 
13 #define allow_singleton_access( class_name ) \
14  friend class scarab::singleton< class_name >; \
15  friend class scarab::destroyer< class_name >;
16 
17  template< class x_type >
18  class singleton
19  {
20  public:
21  static x_type* get_instance();
22  static void kill_instance();
23 
24  template< class... x_args >
25  static x_type* create_instance( x_args... args );
26 
27  private:
28  static void construct_instance();
29  static void delete_instance();
30 
31  private:
32  static x_type* f_instance;
34  static std::mutex f_mutex;
35 
36  protected:
37  singleton();
38 
39  friend class destroyer< x_type >;
40  ~singleton();
41  };
42 
43  template< class x_type >
44  x_type* singleton< x_type >::f_instance = nullptr;
45 
46  template< class x_type >
48 
49  template< class x_type >
51 
52  template< class x_type >
54  {
55  if( f_instance == nullptr )
56  {
57  std::unique_lock< std::mutex > t_lock( f_mutex );
59  }
60  return f_instance;
61  }
62 
63  template< class x_type >
65  {
66  if( f_instance != nullptr )
67  {
68  std::unique_lock< std::mutex > t_lock( f_mutex );
70  }
71  return;
72  }
73 
74  template< class x_type >
75  template< class... x_args >
76  x_type* singleton< x_type >::create_instance( x_args... args )
77  {
78  if( f_instance != nullptr )
79  {
80  throw error() << "Instance already exists; create_instance can only be called before the instance exists";
81  }
82  std::unique_lock< std::mutex > t_lock( f_mutex );
83  f_instance = new x_type( args... );
85  return f_instance;
86  }
87 
88  template< class x_type >
90  {
91  if( f_instance == nullptr )
92  {
93  f_instance = new x_type();
95  }
96  }
97 
98  template< class x_type >
100  {
101  if( f_instance != nullptr )
102  {
103  delete f_instance;
104  f_instance = nullptr;
105  f_destroyer.set_doomed( nullptr );
106  }
107  }
108 
109  template< class x_type >
111  {
112  }
113  template< class x_type >
115  {
116  }
117 
118 } /* namespace scarab */
119 
120 #endif /* SCARAB_SINGLETON_HH_ */
void set_doomed(XDoomed *)
Definition: destroyer.hh:46
static void kill_instance()
Definition: singleton.hh:64
static void construct_instance()
Definition: singleton.hh:89
static x_type * f_instance
Definition: singleton.hh:32
static destroyer< x_type > f_destroyer
Definition: singleton.hh:33
static x_type * get_instance()
Definition: singleton.hh:53
static x_type * create_instance(x_args... args)
Definition: singleton.hh:76
static void delete_instance()
Definition: singleton.hh:99
static std::mutex f_mutex
Definition: singleton.hh:34