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
@@ -71,6 +106,11 @@ namespace sqlite_orm {
71
106
// Constructing pointer bindings must go through bindable_pointer()
72
107
template <class T2 , class P2 , class D2 >
73
108
friend auto bindable_pointer (P2*, D2) noexcept -> pointer_binding<P2, T2, D2>;
109
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
110
+ // Constructing pointer bindings must go through bindable_pointer()
111
+ template <orm_pointer_type auto tag, class P2 , class D2 >
112
+ friend auto bindable_pointer (P2*, D2) noexcept -> pointer_binding<P2, decltype(tag), D2>;
113
+ #endif
74
114
template <class B >
75
115
friend B bindable_pointer (typename B::qualified_type*, typename B::deleter_type) noexcept ;
76
116
@@ -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
*
@@ -146,6 +202,25 @@ namespace sqlite_orm {
146
202
return B{p, std::move (d)};
147
203
}
148
204
205
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
206
+ /* *
207
+ * Wrap a pointer, its type (tag) and its deleter function for binding it to a statement.
208
+ *
209
+ * Unless the deleter yields a nullptr 'xDestroy' function the ownership of the pointed-to-object
210
+ * is transferred to the pointer binding, which will delete it through
211
+ * the deleter when the statement finishes.
212
+ */
213
+ template <orm_pointer_type auto tag, class P , class D >
214
+ auto bindable_pointer (P* p, D d) noexcept -> pointer_binding<P, decltype(tag), D> {
215
+ return {p, std::move (d)};
216
+ }
217
+
218
+ template <orm_pointer_type auto tag, class P , class D >
219
+ auto bindable_pointer (std::unique_ptr<P, D> p) noexcept -> pointer_binding<P, decltype(tag), D> {
220
+ return bindable_pointer<tag>(p.release (), p.get_deleter ());
221
+ }
222
+ #endif
223
+
149
224
/* *
150
225
* Wrap a pointer and its type for binding it to a statement.
151
226
*
@@ -163,6 +238,19 @@ namespace sqlite_orm {
163
238
return bindable_pointer<B>(p);
164
239
}
165
240
241
+ #ifdef SQLITE_ORM_WITH_CPP20_ALIASES
242
+ /* *
243
+ * Wrap a pointer and its type (tag) for binding it to a statement.
244
+ *
245
+ * Note: 'Static' means that ownership of the pointed-to-object won't be transferred
246
+ * and sqlite assumes the object pointed to is valid throughout the lifetime of a statement.
247
+ */
248
+ template <orm_pointer_type auto tag, class P >
249
+ auto statically_bindable_pointer (P* p) noexcept -> static_pointer_binding<P, decltype(tag)> {
250
+ return bindable_pointer<tag>(p, null_xdestroy_f);
251
+ }
252
+ #endif
253
+
166
254
/* *
167
255
* Forward a pointer value from an argument.
168
256
*/
0 commit comments