libzypp 17.37.17
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#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
83template <typename T> inline T *zyppGetPtrHelper(T *ptr) { return ptr; }
84template <typename Ptr> inline auto zyppGetPtrHelper(const Ptr &ptr) -> decltype(ptr.operator->()) { return ptr.operator->(); }
85template <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
108namespace 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 = ::zyppng::Ref<T>; \
121 using T##WeakRef = ::zyppng::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
std::weak_ptr< T > WeakRef
Definition zyppglobal.h:113
T * zyppGetPtrHelper(T *ptr)
Definition zyppglobal.h:83