libzypp 17.38.6
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>
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
76template <typename T> inline T *zyppGetPtrHelper(T *ptr) { return ptr; }
77template <typename Ptr> inline auto zyppGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
78template <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
101namespace 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
std::weak_ptr< T > WeakRef
Definition zyppglobal.h:106
T * zyppGetPtrHelper(T *ptr)
Definition zyppglobal.h:76