#include "errors.h" #include #include #include #include namespace sqlite { namespace detail { template using void_t = void; template struct is_callable : std::false_type {}; template struct is_callable()(std::declval()...))>> : std::true_type {}; template class FunctorOverload: public Functor, public FunctorOverload { public: template FunctorOverload(Functor1 &&functor, Remaining &&... remaining): Functor(std::forward(functor)), FunctorOverload(std::forward(remaining)...) {} using Functor::operator(); using FunctorOverload::operator(); }; template class FunctorOverload: public Functor { public: template FunctorOverload(Functor1 &&functor): Functor(std::forward(functor)) {} using Functor::operator(); }; template class WrapIntoFunctor: public Functor { public: template WrapIntoFunctor(Functor1 &&functor): Functor(std::forward(functor)) {} using Functor::operator(); }; template class WrapIntoFunctor { ReturnType(*ptr)(Arguments...); public: WrapIntoFunctor(ReturnType(*ptr)(Arguments...)): ptr(ptr) {} ReturnType operator()(Arguments... arguments) { return (*ptr)(std::forward(arguments)...); } }; inline void store_error_log_data_pointer(std::shared_ptr ptr) { static std::shared_ptr stored; stored = std::move(ptr); } template std::shared_ptr::type> make_shared_inferred(T &&t) { return std::make_shared::type>(std::forward(t)); } } template typename std::enable_if::value>::type error_log(Handler &&handler); template typename std::enable_if::value>::type error_log(Handler &&handler); template typename std::enable_if=2>::type error_log(Handler &&...handler) { return error_log(detail::FunctorOverload::type>...>(std::forward(handler)...)); } template typename std::enable_if::value>::type error_log(Handler &&handler) { return error_log(std::forward(handler), [](const sqlite_exception&) {}); } template typename std::enable_if::value>::type error_log(Handler &&handler) { auto ptr = detail::make_shared_inferred([handler = std::forward(handler)](int error_code, const char *errstr) mutable { switch(error_code & 0xFF) { #define SQLITE_MODERN_CPP_ERROR_CODE(NAME,name,derived) \ case SQLITE_ ## NAME: switch(error_code) { \ derived \ default: handler(errors::name(errstr, "", error_code)); \ };break; #define SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED(BASE,SUB,base,sub) \ case SQLITE_ ## BASE ## _ ## SUB: \ handler(errors::base ## _ ## sub(errstr, "", error_code)); \ break; #include "lists/error_codes.h" #undef SQLITE_MODERN_CPP_ERROR_CODE_EXTENDED #undef SQLITE_MODERN_CPP_ERROR_CODE default: handler(sqlite_exception(errstr, "", error_code)); \ } }); sqlite3_config(SQLITE_CONFIG_LOG, (void(*)(void*,int,const char*))[](void *functor, int error_code, const char *errstr) { (*static_cast(functor))(error_code, errstr); }, ptr.get()); detail::store_error_log_data_pointer(std::move(ptr)); } }