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