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