3
3
#include < type_traits>
4
4
#include < memory>
5
5
#include < utility>
6
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
7
+ #include < concepts>
8
+ #endif
6
9
7
- #include " functional/cxx_universal .h"
10
+ #include " functional/cstring_literal .h"
8
11
#include " xdestroy_handling.h"
9
12
10
13
namespace sqlite_orm {
14
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
15
+ namespace internal {
16
+ template <char ... C>
17
+ struct pointer_type {
18
+ using value_type = const char [sizeof ...(C) + 1 ];
19
+ static inline constexpr value_type value = {C..., ' \0 ' };
20
+ };
21
+ }
22
+
23
+ inline namespace literals {
24
+ template <internal::cstring_literal tag>
25
+ [[nodiscard]] consteval auto operator " " _pointer_type() {
26
+ return internal::explode_into<internal::pointer_type, tag>(std::make_index_sequence<tag.size ()>{});
27
+ }
28
+ }
29
+
30
+ /* * @short Specifies that a type is an integral constant string usable as a pointer type.
31
+ */
32
+ template <class T >
33
+ concept orm_pointer_type = requires {
34
+ typename T::value_type;
35
+ { T::value } -> std::convertible_to<const char *>;
36
+ };
37
+ #endif
11
38
12
39
/* *
13
40
* Wraps a pointer and tags it with a pointer type,
@@ -16,14 +43,20 @@ namespace sqlite_orm {
16
43
*
17
44
* Template parameters:
18
45
* - P: The value type, possibly const-qualified.
19
- * - T: An integral constant string denoting the pointer type, e.g. `carray_pvt_name `.
46
+ * - T: An integral constant string denoting the pointer type, e.g. `carray_pointer_type `.
20
47
*
21
48
*/
22
49
template <typename P, typename T>
23
50
struct pointer_arg {
24
51
52
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
53
+ // note (internal): this is currently a static assertion instead of a type constraint because
54
+ // of forward declarations in other places (e.g. function.h)
55
+ static_assert (orm_pointer_type<T>, " The pointer type (tag) must be convertible to `const char*`" );
56
+ #else
25
57
static_assert (std::is_convertible<typename T::value_type, const char *>::value,
26
- " `std::integral_constant<>` must be convertible to `const char*`" );
58
+ " The pointer type (tag) must be convertible to `const char*`" );
59
+ #endif
27
60
28
61
using tag = T;
29
62
P* p_;
@@ -43,6 +76,8 @@ namespace sqlite_orm {
43
76
* as part of facilitating the 'pointer-passing interface'.
44
77
*
45
78
* Template parameters:
79
+ * - P: The value type, possibly const-qualified.
80
+ * - T: An integral constant string denoting the pointer type, e.g. `carray_pointer_type`.
46
81
* - D: The deleter for the pointer value;
47
82
* can be one of:
48
83
* - function pointer
@@ -68,11 +103,16 @@ namespace sqlite_orm {
68
103
D d_;
69
104
70
105
protected:
71
- // Constructing pointer bindings must go through bindable_pointer ()
106
+ // Constructing pointer bindings must go through bind_pointer ()
72
107
template <class T2 , class P2 , class D2 >
73
- friend auto bindable_pointer (P2*, D2) noexcept -> pointer_binding<P2, T2, D2>;
108
+ friend auto bind_pointer (P2*, D2) noexcept -> pointer_binding<P2, T2, D2>;
109
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
110
+ // Constructing pointer bindings must go through bind_pointer()
111
+ template <orm_pointer_type auto tag, class P2 , class D2 >
112
+ friend auto bind_pointer (P2*, D2) noexcept -> pointer_binding<P2, decltype(tag), D2>;
113
+ #endif
74
114
template <class B >
75
- friend B bindable_pointer (typename B::qualified_type*, typename B::deleter_type) noexcept ;
115
+ friend B bind_pointer (typename B::qualified_type*, typename B::deleter_type) noexcept ;
76
116
77
117
// Construct from pointer and deleter.
78
118
// Transfers ownership of the passed in object.
@@ -113,17 +153,33 @@ namespace sqlite_orm {
113
153
};
114
154
115
155
/* *
116
- * Template alias for a static pointer value binding.
156
+ * Alias template for a static pointer value binding.
117
157
* 'Static' means that ownership won't be transferred to sqlite,
118
158
* sqlite doesn't delete it, and sqlite assumes the object
119
159
* pointed to is valid throughout the lifetime of a statement.
120
160
*/
121
161
template <typename P, typename T>
122
162
using static_pointer_binding = pointer_binding<P, T, null_xdestroy_t >;
163
+
164
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
165
+ template <class P , orm_pointer_type auto tag>
166
+ using pointer_arg_t = pointer_arg<P, decltype (tag)>;
167
+
168
+ template <class P , orm_pointer_type auto tag, class D >
169
+ using pointer_binding_t = pointer_binding<P, decltype (tag), D>;
170
+
171
+ /* *
172
+ * Alias template for a static pointer value binding.
173
+ * 'Static' means that ownership won't be transferred to sqlite,
174
+ * sqlite doesn't delete it, and sqlite assumes the object
175
+ * pointed to is valid throughout the lifetime of a statement.
176
+ */
177
+ template <typename P, orm_pointer_type auto tag>
178
+ using static_pointer_binding_t = pointer_binding_t <P, tag, null_xdestroy_t >;
179
+ #endif
123
180
}
124
181
125
182
namespace sqlite_orm {
126
-
127
183
/* *
128
184
* Wrap a pointer, its type and its deleter function for binding it to a statement.
129
185
*
@@ -132,42 +188,105 @@ namespace sqlite_orm {
132
188
* the deleter when the statement finishes.
133
189
*/
134
190
template <class T , class P , class D >
135
- auto bindable_pointer (P* p, D d) noexcept -> pointer_binding<P, T, D> {
191
+ auto bind_pointer (P* p, D d) noexcept -> pointer_binding<P, T, D> {
136
192
return {p, std::move (d)};
137
193
}
138
194
139
195
template <class T , class P , class D >
140
- auto bindable_pointer (std::unique_ptr<P, D> p) noexcept -> pointer_binding<P, T, D> {
141
- return bindable_pointer <T>(p.release (), p.get_deleter ());
196
+ auto bind_pointer (std::unique_ptr<P, D> p) noexcept -> pointer_binding<P, T, D> {
197
+ return bind_pointer <T>(p.release (), p.get_deleter ());
142
198
}
143
199
144
200
template <typename B>
145
- B bindable_pointer (typename B::qualified_type* p, typename B::deleter_type d = {}) noexcept {
201
+ auto bind_pointer (typename B::qualified_type* p, typename B::deleter_type d = {}) noexcept -> B {
146
202
return B{p, std::move (d)};
147
203
}
148
204
205
+ template <class T , class P , class D >
206
+ [[deprecated(" Use the better named function `bind_pointer(...)`" )]] pointer_binding<P, T, D>
207
+ bindable_pointer (P* p, D d) noexcept {
208
+ return bind_pointer<T>(p, std::move (d));
209
+ }
210
+
211
+ template <class T , class P , class D >
212
+ [[deprecated(" Use the better named function `bind_pointer(...)`" )]] pointer_binding<P, T, D>
213
+ bindable_pointer (std::unique_ptr<P, D> p) noexcept {
214
+ return bind_pointer<T>(p.release (), p.get_deleter ());
215
+ }
216
+
217
+ template <typename B>
218
+ [[deprecated(" Use the better named function `bind_pointer(...)`" )]] B
219
+ bindable_pointer (typename B::qualified_type* p, typename B::deleter_type d = {}) noexcept {
220
+ return bind_pointer<B>(p, std::move (d));
221
+ }
222
+
223
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
224
+ /* *
225
+ * Wrap a pointer, its type (tag) and its deleter function for binding it to a statement.
226
+ *
227
+ * Unless the deleter yields a nullptr 'xDestroy' function the ownership of the pointed-to-object
228
+ * is transferred to the pointer binding, which will delete it through
229
+ * the deleter when the statement finishes.
230
+ */
231
+ template <orm_pointer_type auto tag, class P , class D >
232
+ auto bind_pointer (P* p, D d) noexcept -> pointer_binding<P, decltype(tag), D> {
233
+ return {p, std::move (d)};
234
+ }
235
+
236
+ template <orm_pointer_type auto tag, class P , class D >
237
+ auto bind_pointer (std::unique_ptr<P, D> p) noexcept -> pointer_binding<P, decltype(tag), D> {
238
+ return bind_pointer<tag>(p.release (), p.get_deleter ());
239
+ }
240
+ #endif
241
+
149
242
/* *
150
243
* Wrap a pointer and its type for binding it to a statement.
151
244
*
152
245
* Note: 'Static' means that ownership of the pointed-to-object won't be transferred
153
246
* and sqlite assumes the object pointed to is valid throughout the lifetime of a statement.
154
247
*/
155
248
template <class T , class P >
156
- auto statically_bindable_pointer (P* p) noexcept -> static_pointer_binding<P, T> {
157
- return bindable_pointer <T>(p, null_xdestroy_f);
249
+ auto bind_pointer_statically (P* p) noexcept -> static_pointer_binding<P, T> {
250
+ return bind_pointer <T>(p, null_xdestroy_f);
158
251
}
159
252
160
253
template <typename B>
161
- B statically_bindable_pointer (typename B::qualified_type* p,
162
- typename B::deleter_type* /* exposition*/ = nullptr ) noexcept {
163
- return bindable_pointer<B>(p);
254
+ B bind_pointer_statically (typename B::qualified_type* p,
255
+ typename B::deleter_type* /* exposition*/ = nullptr ) noexcept {
256
+ return bind_pointer<B>(p);
257
+ }
258
+
259
+ template <class T , class P >
260
+ [[deprecated(" Use the better named function `bind_pointer_statically(...)`" )]] static_pointer_binding<P, T>
261
+ statically_bindable_pointer (P* p) noexcept {
262
+ return bind_pointer<T>(p, null_xdestroy_f);
263
+ }
264
+
265
+ template <typename B>
266
+ [[deprecated(" Use the better named function `bind_pointer_statically(...)`" )]] B
267
+ statically_bindable_pointer (typename B::qualified_type* p,
268
+ typename B::deleter_type* /* exposition*/ = nullptr ) noexcept {
269
+ return bind_pointer<B>(p);
270
+ }
271
+
272
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
273
+ /* *
274
+ * Wrap a pointer and its type (tag) for binding it to a statement.
275
+ *
276
+ * Note: 'Static' means that ownership of the pointed-to-object won't be transferred
277
+ * and sqlite assumes the object pointed to is valid throughout the lifetime of a statement.
278
+ */
279
+ template <orm_pointer_type auto tag, class P >
280
+ auto bind_pointer_statically (P* p) noexcept -> static_pointer_binding<P, decltype(tag)> {
281
+ return bind_pointer<tag>(p, null_xdestroy_f);
164
282
}
283
+ #endif
165
284
166
285
/* *
167
286
* Forward a pointer value from an argument.
168
287
*/
169
288
template <class P , class T >
170
289
auto rebind_statically (const pointer_arg<P, T>& pv) noexcept -> static_pointer_binding<P, T> {
171
- return statically_bindable_pointer <T>(pv.ptr ());
290
+ return bind_pointer_statically <T>(pv.ptr ());
172
291
}
173
292
}
0 commit comments