libzypp 17.34.0
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
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
82template <typename T> inline T *zyppGetPtrHelper(T *ptr) { return ptr; }
83template <typename Ptr> inline auto zyppGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
84template <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