Scarab  v3.4.0
Project 8 C++ Utility Library
singleton.hh
Go to the documentation of this file.
1 /*
2  * singleton.hh
3  *
4  * Created on: Nov 7, 2011
5  * Author: nsoblath
6  */
7 
8 #ifndef SCARAB_SINGLETON_HH_
9 #define SCARAB_SINGLETON_HH_
10 
11 #include "destroyer.hh"
12 #include "error.hh"
13 
14 #include <cstddef>
15 #include <mutex>
16 
17 namespace scarab
18 {
24 #define allow_singleton_access( class_name ) \
25  friend class scarab::singleton< class_name >; \
26  friend class scarab::destroyer< class_name >;
27 
42  template< class x_type >
43  class singleton
44  {
45  public:
46  static x_type* get_instance();
47  static void kill_instance();
48 
49  template< class... x_args >
50  static x_type* create_instance( x_args... args );
51 
52  private:
53  static void construct_instance();
54  static void delete_instance();
55 
56  private:
57  static x_type* f_instance;
59 
60  protected:
61  static std::mutex f_mutex;
62 
63  protected:
64  singleton();
65 
66  friend class destroyer< x_type >;
67  ~singleton();
68  };
69 
70  template< class x_type >
71  x_type* singleton< x_type >::f_instance = nullptr;
72 
73  template< class x_type >
75 
76  template< class x_type >
78 
79  template< class x_type >
81  {
82  if( f_instance == nullptr )
83  {
84  std::unique_lock< std::mutex > t_lock( f_mutex );
86  }
87  return f_instance;
88  }
89 
90  template< class x_type >
92  {
93  if( f_instance != nullptr )
94  {
95  std::unique_lock< std::mutex > t_lock( f_mutex );
97  }
98  return;
99  }
100 
101  template< class x_type >
102  template< class... x_args >
103  x_type* singleton< x_type >::create_instance( x_args... args )
104  {
105  if( f_instance != nullptr )
106  {
107  throw error() << "Instance already exists; create_instance can only be called before the instance exists";
108  }
109  std::unique_lock< std::mutex > t_lock( f_mutex );
110  f_instance = new x_type( args... );
112  return f_instance;
113  }
114 
115  template< class x_type >
117  {
118  if( f_instance == nullptr )
119  {
120  f_instance = new x_type();
122  }
123  }
124 
125  template< class x_type >
127  {
128  if( f_instance != nullptr )
129  {
130  delete f_instance;
131  f_instance = nullptr;
132  f_destroyer.set_doomed( nullptr );
133  }
134  }
135 
136  template< class x_type >
138  {
139  }
140  template< class x_type >
142  {
143  }
144 
145 } /* namespace scarab */
146 
147 #endif /* SCARAB_SINGLETON_HH_ */
void set_doomed(XDoomed *)
Definition: destroyer.hh:46
static void kill_instance()
Definition: singleton.hh:91
static void construct_instance()
Definition: singleton.hh:116
static x_type * f_instance
Definition: singleton.hh:57
static destroyer< x_type > f_destroyer
Definition: singleton.hh:58
static x_type * get_instance()
Definition: singleton.hh:80
static x_type * create_instance(x_args... args)
Definition: singleton.hh:103
Base class that turns a class into a singleton.
Definition: singleton.hh:43
static void delete_instance()
Definition: singleton.hh:126
static std::mutex f_mutex
Definition: singleton.hh:61