CARVIEW |
Select Language
HTTP/2 200
date: Sat, 19 Jul 2025 01:04:23 GMT
content-type: text/html; charset=utf-8
vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, X-Requested-With,Accept-Encoding, Accept, X-Requested-With
x-robots-tag: none
etag: W/"d04dc1c96a221db3299c3f26bdeb1316"
cache-control: max-age=0, private, must-revalidate
strict-transport-security: max-age=31536000; includeSubdomains; preload
x-frame-options: deny
x-content-type-options: nosniff
x-xss-protection: 0
referrer-policy: no-referrer-when-downgrade
content-security-policy: default-src 'none'; base-uri 'self'; child-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/; connect-src 'self' uploads.github.com www.githubstatus.com collector.github.com raw.githubusercontent.com api.github.com github-cloud.s3.amazonaws.com github-production-repository-file-5c1aeb.s3.amazonaws.com github-production-upload-manifest-file-7fdce7.s3.amazonaws.com github-production-user-asset-6210df.s3.amazonaws.com *.rel.tunnels.api.visualstudio.com wss://*.rel.tunnels.api.visualstudio.com objects-origin.githubusercontent.com copilot-proxy.githubusercontent.com proxy.individual.githubcopilot.com proxy.business.githubcopilot.com proxy.enterprise.githubcopilot.com *.actions.githubusercontent.com wss://*.actions.githubusercontent.com productionresultssa0.blob.core.windows.net/ productionresultssa1.blob.core.windows.net/ productionresultssa2.blob.core.windows.net/ productionresultssa3.blob.core.windows.net/ productionresultssa4.blob.core.windows.net/ productionresultssa5.blob.core.windows.net/ productionresultssa6.blob.core.windows.net/ productionresultssa7.blob.core.windows.net/ productionresultssa8.blob.core.windows.net/ productionresultssa9.blob.core.windows.net/ productionresultssa10.blob.core.windows.net/ productionresultssa11.blob.core.windows.net/ productionresultssa12.blob.core.windows.net/ productionresultssa13.blob.core.windows.net/ productionresultssa14.blob.core.windows.net/ productionresultssa15.blob.core.windows.net/ productionresultssa16.blob.core.windows.net/ productionresultssa17.blob.core.windows.net/ productionresultssa18.blob.core.windows.net/ productionresultssa19.blob.core.windows.net/ github-production-repository-image-32fea6.s3.amazonaws.com github-production-release-asset-2e65be.s3.amazonaws.com insights.github.com wss://alive.github.com api.githubcopilot.com api.individual.githubcopilot.com api.business.githubcopilot.com api.enterprise.githubcopilot.com; font-src github.githubassets.com; form-action 'self' github.com gist.github.com copilot-workspace.githubnext.com objects-origin.githubusercontent.com; frame-ancestors 'none'; frame-src viewscreen.githubusercontent.com notebooks.githubusercontent.com; img-src 'self' data: blob: github.githubassets.com media.githubusercontent.com camo.githubusercontent.com identicons.github.com avatars.githubusercontent.com private-avatars.githubusercontent.com github-cloud.s3.amazonaws.com objects.githubusercontent.com release-assets.githubusercontent.com secured-user-images.githubusercontent.com/ user-images.githubusercontent.com/ private-user-images.githubusercontent.com opengraph.githubassets.com copilotprodattachments.blob.core.windows.net/github-production-copilot-attachments/ github-production-user-asset-6210df.s3.amazonaws.com customer-stories-feed.github.com spotlights-feed.github.com objects-origin.githubusercontent.com *.githubusercontent.com; manifest-src 'self'; media-src github.com user-images.githubusercontent.com/ secured-user-images.githubusercontent.com/ private-user-images.githubusercontent.com github-production-user-asset-6210df.s3.amazonaws.com gist.github.com; script-src github.githubassets.com; style-src 'unsafe-inline' github.githubassets.com; upgrade-insecure-requests; worker-src github.githubassets.com github.com/assets-cdn/worker/ github.com/assets/ gist.github.com/assets-cdn/worker/
server: github.com
content-encoding: gzip
accept-ranges: bytes
set-cookie: _gh_sess=sMrSEocU8OEmDzORl%2FJAkdHv8t7sO5USUB5Wt%2FWCovRf0s01UHe7HVZ8x8pbLokVXm2%2BbBuE3lVhEXeghOXnESJbBVTemriNexC3k4V%2FBAtvKP8GD2u6EUJDIwMKOBNsoKHTz9T6osDDBYrkfC3JzEwPQNWODH2shq35fjFKxJJONWllvLsF%2Bs7AcgVQleI3QlYeGMHTHqfOxHwYY%2BXSpR%2BnFsq2dmQC6V9m1VGsnOunVPKjEIKVXSKvWSWdOxsrv3ZQLwT3vcjgIo0MebhJyw%3D%3D--zG1%2Fq6yoU%2FatdrvA--oyZ767GvPBg2Xt3fLn6PcQ%3D%3D; Path=/; HttpOnly; Secure; SameSite=Lax
set-cookie: _octo=GH1.1.1936004022.1752887062; Path=/; Domain=github.com; Expires=Sun, 19 Jul 2026 01:04:22 GMT; Secure; SameSite=Lax
set-cookie: logged_in=no; Path=/; Domain=github.com; Expires=Sun, 19 Jul 2026 01:04:22 GMT; HttpOnly; Secure; SameSite=Lax
x-github-request-id: 9BF6:1E2439:25AC84:34840F:687AEF16
Using variadic templates with function calls using tuple · iwongu/sqlite3pp Wiki · GitHub
Skip to content
Navigation Menu
{{ message }}
-
Notifications
You must be signed in to change notification settings - Fork 181
Using variadic templates with function calls using tuple
Wongoo Lee edited this page Feb 10, 2016
·
3 revisions
After this, I started working on this code.
template <class R>
void function0_impl(sqlite3_context* ctx, int nargs, sqlite3_value** values)
{
boost::function<R ()>* f =
static_cast<boost::function<R ()>*>(sqlite3_user_data(ctx));
context c(ctx, nargs, values);
c.result((*f)());
}
template <class R, class P1>
void function1_impl(sqlite3_context* ctx, int nargs, sqlite3_value** values)
{
boost::function<R (P1)>* f =
static_cast<boost::function<R (P1)>*>(sqlite3_user_data(ctx));
context c(ctx, nargs, values);
c.result((*f)(c.context::get<P1>(0)));
}
...
template <class R, class P1, class P2, class P3, class P4, class P5>
void function5_impl(sqlite3_context* ctx, int nargs, sqlite3_value** values)
{
boost::function<R (P1, P2, P3, P4, P5)>* f =
static_cast<boost::function<R (P1, P2, P3, P4, P5)>*>(sqlite3_user_data(ctx));
context c(ctx, nargs, values);
c.result((*f)(c.context::get<P1>(0), c.context::get<P2>(1), c.context::get<P3>(2), c.context::get<P4>(3), c.context::get<P5>(4)));
}
It was much harder since it had to be able to call a method per parameter using index.
(*f)(c.context::get<P1>(0),
c.context::get<P2>(1),
c.context::get<P3>(2),
...);
}
So, I made a plan to do this in two steps.
- make a tuple for the params.
- and call the function using the tuple.
template <class... Ts>
std::tuple<Ts...> to_tuple() {
return to_tuple_impl(0, *this, std::tuple<Ts...>());
}
template<class H, class... Ts>
static inline std::tuple<H, Ts...> to_tuple_impl(int index, const context& c, std::tuple<H, Ts...>&&)
{
auto h = std::make_tuple(c.context::get<H>(index));
return std::tuple_cat(h, to_tuple_impl(++index, c, std::tuple<Ts...>()));
}
static inline std::tuple<> to_tuple_impl(int index, const context& c, std::tuple<>&&)
{
return std::tuple<>();
}
This is not the most efficient code that can do this but the cleanest one that I could write. Frankly, in modern C++, I'm not sure if I'm helping compiler optimize the code or doing opposite.
I found the solution for this by googling.
template<size_t N>
struct Apply {
template<typename F, typename T, typename... A>
static inline auto apply(F&& f, T&& t, A&&... a)
-> decltype(Apply<N-1>::apply(std::forward<F>(f),
std::forward<T>(t),
std::get<N-1>(std::forward<T>(t)),
std::forward<A>(a)...))
{
return Apply<N-1>::apply(std::forward<F>(f),
std::forward<T>(t),
std::get<N-1>(std::forward<T>(t)),
std::forward<A>(a)...);
}
};
template<>
struct Apply<0> {
template<typename F, typename T, typename... A>
static inline auto apply(F&& f, T&&, A&&... a)
-> decltype(std::forward<F>(f)(std::forward<A>(a)...))
{
return std::forward<F>(f)(std::forward<A>(a)...);
}
};
template<typename F, typename T>
inline auto apply(F&& f, T&& t)
-> decltype(Apply<std::tuple_size<typename std::decay<T>::type>::value>::apply(std::forward<F>(f), std::forward<T>(t)))
{
return Apply<std::tuple_size<typename std::decay<T>::type>::value>::apply(
std::forward<F>(f), std::forward<T>(t));
}
Nice code, isn't it? See details in https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3915.pdf and https://stackoverflow.com/a/12650100. The second link has the version for C++14 too.
template <class R, class... Ps>
void functionx_impl(sqlite3_context* ctx, int nargs, sqlite3_value** values)
{
context c(ctx, nargs, values);
auto f = static_cast<std::function<R (Ps...)>*>(sqlite3_user_data(ctx));
c.result(apply(*f, c.to_tuple<Ps...>()));
}
You can’t perform that action at this time.