-
Notifications
You must be signed in to change notification settings - Fork 20
/
connection_callbacks.impl.hpp
82 lines (64 loc) · 2.11 KB
/
connection_callbacks.impl.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#if !defined(SQXX_CONNECTION_CALLBACKS_IMPL_HPP_INCLUDED)
#define SQXX_CONNECTION_CALLBACKS_IMPL_HPP_INCLUDED
#include "callable/callable.hpp"
#include "context.hpp"
#include "value.hpp"
// Function types with C calling convention for callbacks
// https://stackoverflow.com/a/5590050/
extern "C" typedef void sqxx_appdata_destroy_type(void*);
extern "C" void* sqlite3_user_data(sqlite3_context*);
namespace sqxx {
namespace detail {
// Apply an array of sqlite3_value's to a function
template<int I, int N, typename R, typename Fun>
struct apply_value_array_st {
template<typename... Values>
static R apply(Fun f, sqlite3_value **argv, Values&&... args) {
return apply_value_array_st<I+1, N, R, Fun>::template apply<Values..., value>(
std::forward<Fun>(f),
argv,
std::forward<Values>(args)...,
value(argv[I])
);
}
};
template<int I, typename R, typename Fun>
struct apply_value_array_st<I, I, R, Fun> {
template<typename... Values>
static R apply(Fun f, sqlite3_value** argv, Values&&... args) {
unused(argv);
return f(std::forward<Values>(args)...);
}
};
template<int N, typename R, typename Fun, typename... BaseArgs>
R apply_value_array(Fun &&f, sqlite3_value **argv, BaseArgs&&... baseargs) {
return apply_value_array_st<0, N, R, Fun>::apply(
std::forward<Fun>(f),
argv,
std::forward<BaseArgs>(baseargs)...
);
}
template<typename T>
sqxx_appdata_destroy_type appdata_destroy_object;
template<typename T>
void appdata_destroy_object(void *data) {
delete reinterpret_cast<T*>(data);
}
// This is useful when an object is stored in memory that is managed by sqlite.
template<typename T>
struct destruct_only {
void operator()(T *ptr) {
if (ptr) {
ptr->~T();
}
}
};
// A std::unique_ptr<> variant that takes ownership of the pointed-to object,
// but not the pointed-to memory. When the `ownedobj_ptr<>` goes out of scope,
// if calls the pointed-to object's destructor, but doesn't free the
// associated memory.
template<typename T>
using ownedobj_ptr = std::unique_ptr<T, destruct_only<T>>;
} // namespace detail
} // namespace sqxx
#endif // SQXX_CONNECTION_CALLBACKS_IMPL_HPP_INCLUDED