5#ifndef BOOST_SQLITE_DETAIL_SCALAR_FUNCTION_HPP
6#define BOOST_SQLITE_DETAIL_SCALAR_FUNCTION_HPP
8#include <boost/sqlite/detail/config.hpp>
9#include <boost/sqlite/cstring_ref.hpp>
10#include <boost/sqlite/memory.hpp>
11#include <boost/sqlite/result.hpp>
12#include <boost/sqlite/value.hpp>
14#include <boost/callable_traits/args.hpp>
15#include <boost/callable_traits/return_type.hpp>
16#include <boost/callable_traits/has_void_return.hpp>
17#include <boost/core/span.hpp>
20BOOST_SQLITE_BEGIN_NAMESPACE
22template<
typename ... Args>
28template<
typename Func,
typename ... Args, std::size_t Extent>
29auto create_scalar_function_impl(sqlite3 * db,
32 std::tuple<context<Args...>, boost::span<value, Extent>> * ,
34 std::false_type ) ->
int
36 using func_type =
typename std::decay<Func>::type;
37 return sqlite3_create_function_v2(
39 Extent == boost::dynamic_extent ? -1 : static_cast<int>(Extent),
41 new (memory_tag{}) func_type(std::forward<Func>(func)),
42 +[](sqlite3_context* ctx, int len, sqlite3_value** args)
44 auto cc = context<Args...>(ctx);
45 auto aa =
reinterpret_cast<value*
>(args);
46 auto &f = *
reinterpret_cast<func_type*
>(sqlite3_user_data(ctx));
47 boost::span<value, Extent> vals{aa,
static_cast<std::size_t
>(len)};
49 execute_context_function(ctx, f, cc, vals);
51 +[](
void * ptr)
noexcept {delete_(
static_cast<func_type*
>(ptr));}
55template<
typename Func,
typename ... Args, std::size_t Extent>
56auto create_scalar_function_impl(sqlite3 * db,
59 std::tuple<context<Args...>, boost::span<value, Extent>> * ,
61 std::false_type ) ->
int
63 using func_type =
typename std::decay<Func>::type;
64 return sqlite3_create_function_v2(
67 (Extent == boost::dynamic_extent) ? -1 : static_cast<int>(Extent),
69 new (memory_tag{}) func_type(std::forward<Func>(func)),
70 +[](sqlite3_context* ctx, int len, sqlite3_value** args)
72 auto cc = context<Args...>(ctx);
73 auto aa =
reinterpret_cast<value*
>(args);
74 auto &f = *
reinterpret_cast<func_type*
>(sqlite3_user_data(ctx));
75 boost::span<value, Extent> vals{aa,
static_cast<std::size_t
>(len)};
77 execute_context_function(
82 return result<void>();
86 +[](
void * ptr){delete_(
static_cast<func_type*
>(ptr));}
91template<
typename Func,
typename ... Args, std::size_t Extent>
92auto create_scalar_function_impl(sqlite3 * db,
95 std::tuple<context<Args...>, boost::span<value, Extent>> * ,
97 std::true_type ) ->
int
99 return sqlite3_create_function_v2(
101 Extent == boost::dynamic_extent ? -1 : static_cast<int>(Extent),
103 reinterpret_cast<void*>(func),
104 +[](sqlite3_context* ctx, int len, sqlite3_value** args)
106 auto cc = context<Args...>(ctx);
107 auto aa =
reinterpret_cast<value*
>(args);
108 auto &f = *
reinterpret_cast<Func*
>(sqlite3_user_data(ctx));
110 boost::span<value, Extent> vals{aa,
static_cast<std::size_t
>(len)};
112 execute_context_function(
114 },
nullptr,
nullptr,
nullptr);
117template<
typename Func,
typename ... Args, std::size_t Extent>
118auto create_scalar_function_impl(sqlite3 * db,
121 std::tuple<context<Args...>, boost::span<value, Extent>> * ,
123 std::true_type ) ->
int
125 return sqlite3_create_function_v2(
128 (Extent == boost::dynamic_extent) ? -1 : static_cast<int>(Extent),
130 reinterpret_cast<void*>(func),
131 +[](sqlite3_context* ctx, int len, sqlite3_value** args)
133 auto cc = context<Args...>(ctx);
134 auto aa =
reinterpret_cast<value*
>(args);
135 auto &f = *
reinterpret_cast<Func*
>(sqlite3_user_data(ctx));
136 boost::span<value, Extent> vals{aa,
static_cast<std::size_t
>(len)};
137 execute_context_function(
142 return result<void>();
145 },
nullptr,
nullptr,
nullptr);
148template<
typename Func>
149auto create_scalar_function(sqlite3 * db,
152 ->
decltype(create_scalar_function_impl(
153 db, name, std::forward<Func>(func),
154 static_cast<callable_traits::args_t<Func>*
>(
nullptr),
155 callable_traits::has_void_return<Func>{},
156 std::is_pointer<typename std::decay<Func>::type>{}
159 return create_scalar_function_impl(db, name, std::forward<Func>(func),
160 static_cast<callable_traits::args_t<Func>*
>(
nullptr),
161 callable_traits::has_void_return<Func>{},
162 std::is_pointer<typename std::decay<Func>::type>{});
168BOOST_SQLITE_END_NAMESPACE