libzypp  17.38.7
zyppglobal.h
Go to the documentation of this file.
1 #ifndef ZYPP_NG_BASE_ZYPPGLOBAL_H_INCLUDED
2 #define ZYPP_NG_BASE_ZYPPGLOBAL_H_INCLUDED
3 
4 #include <memory>
5 #include <zypp-core/base/Easy.h>
6 
7 /*
8  * Convenience helpers to automatically generate boilerplate code
9  * for pimpl classes.
10  *
11  * Libzypp is using the PIMPL pattern to ensure binary compatiblity between
12  * different version releases. This keeps rebuilds of applications
13  * that link against libzypp to a minimum. A PIMPL class simply hides the
14  * data members and functions that are not part of the public API/ABI in a
15  * hidden private class, that is only accessible in the implementation files.
16  * This allows even bigger refactorings to happen behind the scenes.
17  *
18  * A simple example would be:
19  *
20  * \code
21  *
22  * // MyClass.h
23  *
24  * // forward declare the private class, always use the public classname
25  * // with a "Private" postfix:
26  * class MyClassPrivate;
27  *
28  * class MyClass
29  * {
30  * public:
31  * // add all public API functions here
32  * void doSomething();
33  * int getSomething() const;
34  * private:
35  * // generate the forward declarations for the pimpl access functions
36  * ZYPP_DECLARE_PRIVATE(MyClass)
37  * // the only data member in the public class should be a pointer to the private type
38  * // named d_ptr
39  * std::unique_ptr<MyClassPrivate> d_ptr;
40  * };
41  *
42  * // MyClass.cc
43  *
44  * // in the implementation file we can now define the private class:
45  * class MyClassPrivate
46  * {
47  * public:
48  * // add the data members and private functions here
49  * int something = 0;
50  * };
51  *
52  * // in the constructor make sure that the private part of the class
53  * // is initialized too
54  * MyClass::MyClass() : d_ptr( new MyClassPrivate )
55  * {}
56  *
57  * int MyClass::getSomething() const
58  * {
59  * // automatically generates a pointer named "d" to the
60  * // pimpl object
61  * Z_D();
62  * return d->something;
63  * }
64  *
65  * void MyClass::doSomething()
66  * {
67  * // It is also possible to use the d_func() to access the pointer:
68  * d_func()->something = 10;
69  * }
70  *
71  * \endcode
72  *
73  * \note those macros are inspired by the Qt framework
74  */
75 
76 template <typename T> inline T *zyppGetPtrHelper(T *ptr) { return ptr; }
77 template <typename Ptr> inline auto zyppGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
78 template <typename Ptr> inline auto zyppGetPtrHelper(Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
79 
80 #define ZYPP_DECLARE_PRIVATE(Class) \
81  Class##Private* d_func();\
82  const Class##Private* d_func() const; \
83  friend class Class##Private;
84 
85 #define ZYPP_IMPL_PRIVATE(Class) \
86  Class##Private* Class::d_func() \
87  { return static_cast<Class##Private *>(zyppGetPtrHelper(d_ptr)); } \
88  const Class##Private* Class::d_func() const \
89  { return static_cast<const Class##Private *>(zyppGetPtrHelper(d_ptr)); }
90 
91 #define ZYPP_DECLARE_PUBLIC(Class) \
92  public: \
93  inline Class* z_func() { return static_cast<Class *>(z_ptr); } \
94  inline const Class* z_func() const { return static_cast<const Class *>(z_ptr); } \
95  friend class Class; \
96  private:
97 
98 #define Z_D() auto const d = d_func()
99 #define Z_Z() auto const z = z_func()
100 
101 namespace zyppng {
102  template <typename T>
103  using Ref = std::shared_ptr<T>;
104 
105  template <typename T>
106  using WeakRef = std::weak_ptr<T>;
107 }
108 
112 #define ZYPP_FWD_DECL_REFS(T) \
113  using T##Ref = ::zyppng::Ref<T>; \
114  using T##WeakRef = ::zyppng::WeakRef<T>
115 
116 /*
117  * Helper Macro to forward declare types and ref types
118  */
119 #define ZYPP_FWD_DECL_TYPE_WITH_REFS(T) \
120  class T; \
121  ZYPP_FWD_DECL_REFS(T)
122 
123 #define ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS_ARG1(T, TArg1) \
124  template< typename TArg1> \
125  class T; \
126  template< typename TArg1> \
127  using T##Ref = Ref<T<TArg1>>; \
128  template< typename TArg1> \
129  using T##WeakRef = WeakRef<T<TArg1>>
130 
131 
132 //@TODO enable for c++20
133 #if 0
134 #define ZYPP_FWD_DECL_TEMPL_TYPE_WITH_REFS(T, TArg1, ...) \
135  template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \
136  class T; \
137  template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \
138  using T##Ref = std::shared_ptr<T<TArg1 __VA_OPT__(,) __VA_ARGS__>>; \
139  template< typename TArg1 __VA_OPT__(, typename) __VA_ARGS__ > \
140  using T##WeakRef = std::weak_ptr<T<TArg1 __VA_OPT__(,) __VA_ARGS__ >>
141 #endif
142 
147 #define ZYPP_ADD_PRIVATE_CONSTR_HELPER() \
148  struct private_constr_t { private_constr_t () noexcept = default; }
149 
153 #define ZYPP_PRIVATE_CONSTR_ARG \
154  private_constr_t
155 
159 #define ZYPP_PRIVATE_CONSTR_ARG_VAL \
160  private_constr_t{}
161 
198 #define ZYPP_ADD_CREATE_FUNC(Class) \
199  private: \
200  ZYPP_ADD_PRIVATE_CONSTR_HELPER(); \
201  public: \
202  template < typename ...Args > \
203  inline static auto create ( Args &&... args ) { \
204  return std::make_shared< Class >( private_constr_t{}, std::forward<Args>(args)... ); \
205  } \
206  private:
207 
208 /*
209  * Convenience macros to implement public but private constructors that can be called from Class::create() but
210  * not by user code.
211  *
212  * \sa ZYPP_ADD_CONSTR_FUNC
213  */
214 #define ZYPP_DECL_PRIVATE_CONSTR(Class) Class( private_constr_t )
215 #define ZYPP_IMPL_PRIVATE_CONSTR(Class) Class::Class( private_constr_t )
216 #define ZYPP_DECL_PRIVATE_CONSTR_ARGS(Class,...) Class( private_constr_t, __VA_ARGS__ )
217 #define ZYPP_IMPL_PRIVATE_CONSTR_ARGS(Class,...) Class::Class( private_constr_t, __VA_ARGS__ )
218 
219 #define ZYPP_NODISCARD [[nodiscard]]
220 
221 #endif
std::shared_ptr< T > Ref
Definition: zyppglobal.h:103
T * zyppGetPtrHelper(T *ptr)
Definition: zyppglobal.h:76
std::weak_ptr< T > WeakRef
Definition: zyppglobal.h:106