e53162d64e44b4f3a4834ea8be6078013c7ef71f
[web/konrad/chester.git] / dptr_base.h
1 //d-ptr header
2 //
3 // (c) Konrad Rosenbaum, 2010-2011
4 // Copying and distribution of this file, with or without modification,
5 // are permitted in any medium without royalty provided the copyright
6 // notice and this notice are preserved.  This file is offered as-is,
7 // without any warranty.
8
9
10 #ifdef DPTR_CLASS_NAME
11 #undef DPTR_CLASS_NAME
12 #endif
13
14 #ifdef DPTR_NAME
15 #undef DPTR_NAME
16 #endif
17
18 #ifdef DPTR_WRAPPER_NAME
19 #undef DPTR_WRAPPER_NAME
20 #endif
21
22 /** \def DPTR_CLASS_NAME(Class)
23 \brief Expands to the fully qualified name of the d-pointer class.
24 \param Class the fully qualified name of the class the d-pointer was declared in.*/
25 #define DPTR_CLASS_NAME(Class) Class::Private
26 ///\def DPTR_NAME
27 ///Expands to the local name of d-pointer classes (Private).
28 #define DPTR_NAME Private
29 ///\def DPTR_WRAPPER_NAME
30 ///Expands to the local name of the d-pointer wrapper class (DPrivate).
31 #define DPTR_WRAPPER_NAME DPrivate
32
33 #ifdef DECLARE_DPTR
34 #undef DECLARE_DPTR
35 #endif
36
37 /** \def DECLARE_DPTR(dp)
38 \brief Declares a smart non-shared d-pointer, to be used inside class declaration.
39
40 It also declares the internal nested classes DPrivate and Private - Private is the actual d-pointer class, while DPrivate is a wrapper that automatically allocates, copies and deallocates the d-pointer.
41
42 The wrapper DPointer class contains these methods:
43    - constructor, copy constructor for creating instances of Private
44     - used by automatic and explicit constructors of the containing class
45    - destructor for deallocation of Private
46     - used by the destructor of the containing class
47    - assignment operator to copy the content of Private
48     - used by the assignment operator of the containing class
49    - pointer operator to actually access the Private data
50
51 You can use DEFINE_DPTR to define the necessary methods for a non-shared d-pointer. It is recommended (but not necessary) that non-shared d-pointer classes (Private) are derived from DPtr.
52
53 The d-pointer class Private is only forward declared, you have to fully declare and implement it in the code where you are using it, i.e. where you are implementing the containing class.
54
55 \param dp name of the d-pointer*/
56 #define DECLARE_DPTR(dp) \
57  private:\
58  class Private; \
59  class DPrivate{\
60   public:DPrivate();DPrivate(const DPrivate&);~DPrivate();\
61   DPrivate&operator=(const DPrivate&);\
62   const Private*operator->()const{return d;}\
63   Private*operator->(){return d;}\
64   DPrivate clone()const;\
65   private:Private*d;\
66  }; \
67  DPrivate dp;
68
69 #ifdef DECLARE_SHARED_DPTR
70 #undef DECLARE_SHARED_DPTR
71 #endif
72
73 /** \brief Declares a smart shared d-pointer, to be used inside class declaration.
74
75 It also declares the internal nested classes DPrivate and Private - Private is the actual d-pointer class, while DPrivate is a wrapper that automatically allocates, copies and deallocates the d-pointer.
76
77 The wrapper DPointer class contains these methods:
78    - constructor, copy constructor for creating instances of Private
79     - used by automatic and explicit constructors of the containing class
80    - destructor for deallocation of Private
81     - used by the destructor of the containing class
82    - assignment operator to copy the content of Private
83     - used by the assignment operator of the containing class
84    - pointer operator to actually access the Private data
85
86 You can use DEFINE_DPTR to define the necessary methods for a non-shared d-pointer or DEFINE_SHARED_DPTR if you want to share d-pointer data between instances of the containing class. It is recommended that non-shared d-pointer classes (Private) are derived from DPtr and the shared variants be derived from SharedDPtr.
87
88 The d-pointer class Private is only forward declared, you have to fully declare and implement it in the code where you are using it, i.e. where you are implementing the containing class.
89
90 Warning: shared d-pointers are not thread safe and they are only re-entrant if instances sharing the same d-pointer are only located in one thread, while instances with different d-pointers may be spread over different threads.
91
92 \param dp name of the d-pointer*/
93 #define DECLARE_SHARED_DPTR(dp) DECLARE_DPTR(dp)
94
95
96 #ifdef DECLARE_NONCOPY_DPTR
97 #undef DECLARE_NONCOPY_DPTR
98 #endif
99
100 /** \brief Declares a smart non-shared and non-copyable d-pointer, to be used inside class declaration.
101
102 It also declares the internal nested classes DPrivate and Private - Private is the actual d-pointer class, while DPrivate is a wrapper that automatically allocates, and deallocates the d-pointer. These are usable for content classes that do not allow copying (e.g. Qt's QObject and its subclasses).
103
104 The wrapper DPointer class contains these methods:
105    - constructor for creating instances of Private
106     - used by automatic and explicit constructors of the containing class
107    - destructor for deallocation of Private
108     - used by the destructor of the containing class
109    - private assignment operator and copy constructor
110     - effectively hiding and blocking them
111    - pointer operator to actually access the Private data
112
113 You can use DEFINE_NONCOPY_DPTR to define the necessary methods for a non-shared, non-copy d-pointer. It is recommended that d-pointer classes (Private) are derived from NonCopyDPtr.
114
115 The d-pointer class Private is only forward declared, you have to fully declare and implement it in the code where you are using it, i.e. where you are implementing the containing class.
116
117 \param dp name of the d-pointer*/
118 #define DECLARE_NONCOPY_DPTR(dp) \
119  private:\
120  class Private; \
121  class DPrivate{\
122   public:DPrivate();~DPrivate();\
123   const Private*operator->()const{return d;}\
124   Private*operator->(){return d;}\
125   private:Private*d;\
126   DPrivate(const DPrivate&);DPrivate&operator=(const DPrivate&);\
127  }; \
128  DPrivate dp;