8#ifndef BOOST_SQLITE_RESULT_HPP
9#define BOOST_SQLITE_RESULT_HPP
11#include <boost/sqlite/blob.hpp>
12#include <boost/sqlite/detail/config.hpp>
13#include <boost/sqlite/value.hpp>
15#include <boost/variant2/variant.hpp>
18BOOST_SQLITE_BEGIN_NAMESPACE
21struct set_result_tag {};
24inline void tag_invoke(set_result_tag, sqlite3_context * ctx, blob b)
27 sqlite3_result_blob(ctx, std::move(b).release(), sz, &
operator delete);
31inline void tag_invoke(set_result_tag, sqlite3_context * ctx, zero_blob zb)
33 sqlite3_result_zeroblob64(ctx,
static_cast<sqlite3_uint64
>(zb));
36inline void tag_invoke(set_result_tag, sqlite3_context * ctx,
double dbl) { sqlite3_result_double(ctx, dbl); }
39 typename =
typename std::enable_if<std::is_integral<I>::value>::type>
40inline void tag_invoke(set_result_tag, sqlite3_context * ctx, I value)
42 BOOST_IF_CONSTEXPR ((
sizeof(I) ==
sizeof(
int) && std::is_unsigned<I>::value) || (
sizeof(I) >
sizeof(
int)))
43 sqlite3_result_int64(ctx,
static_cast<sqlite3_int64
>(value));
45 sqlite3_result_int(ctx,
static_cast<int>(value));
48inline void tag_invoke(set_result_tag, sqlite3_context * ctx, std::nullptr_t) { sqlite3_result_null(ctx); }
49inline void tag_invoke(set_result_tag, sqlite3_context * ctx, string_view str)
51 sqlite3_result_text(ctx, str.data(), str.size(), SQLITE_TRANSIENT);
53template<
typename String>
54inline auto tag_invoke(set_result_tag, sqlite3_context * ctx, String && str)
55 ->
typename std::enable_if<std::is_convertible<String, string_view>::value>::type
57 return tag_invoke(set_result_tag{}, ctx, string_view(str));
61inline void tag_invoke(set_result_tag, sqlite3_context * ctx, variant2::monostate) { }
62inline void tag_invoke(set_result_tag, sqlite3_context * ctx,
const value & val)
64 sqlite3_result_value(ctx, val.handle());
67struct set_variant_result
69 sqlite3_context * ctx;
71 void operator()(T && val)
73 tag_invoke(set_result_tag{}, ctx, std::forward<T>(val));
77template<
typename ... Args>
78inline void tag_invoke(set_result_tag, sqlite3_context * ctx,
const variant2::variant<Args...> & var)
80 visit(set_variant_result{ctx}, var);
84inline void tag_invoke(set_result_tag, sqlite3_context * ctx, std::unique_ptr<T> ptr)
86 sqlite3_result_pointer(ctx, ptr.release(),
typeid(T).name(), +[](
void * ptr){delete static_cast<T*>(ptr);});
90inline void tag_invoke(set_result_tag, sqlite3_context * ctx, std::unique_ptr<T,
void(*)(T*)> ptr)
92 sqlite3_result_pointer(ctx, ptr.release(),
typeid(T).name(),
static_cast<void(*)(
void*)
>(ptr.get_deleter()));
95template<
typename T,
typename Deleter>
96inline auto tag_invoke(set_result_tag, sqlite3_context * ctx, std::unique_ptr<T> ptr)
97 ->
typename std::enable_if<std::is_empty<Deleter>::value &&
98 std::is_default_constructible<Deleter>::value>::type
100 sqlite3_result_pointer(ctx, ptr.release(),
typeid(T).name(), +[](
void * ptr){Deleter()(static_cast<T*>(ptr));});
103inline void tag_invoke(set_result_tag tag, sqlite3_context * ctx, error err)
105 sqlite3_result_error_code(ctx, err.code);
107 sqlite3_result_error(ctx, err.info.message().c_str(), -1);
112inline void tag_invoke(set_result_tag tag, sqlite3_context * ctx, result<T> res)
115 tag_invoke(tag, ctx, std::move(res).value());
117 tag_invoke(tag, ctx, std::move(res).error());
120inline void tag_invoke(set_result_tag tag, sqlite3_context * ctx, result<void> res)
123 tag_invoke(tag, ctx, std::move(res).error());
130template<
typename Value>
131inline auto set_result(sqlite3_context * ctx, Value && value)
132 ->
decltype(tag_invoke(set_result_tag{}, ctx, std::forward<Value>(value)))
134 tag_invoke(set_result_tag{}, ctx, std::forward<Value>(value));
141BOOST_SQLITE_END_NAMESPACE