1 /**
2  * @file    VariadicBind.h
3  * @ingroup SQLiteCpp
4  * @brief   Convenience function for Statement::bind(...)
5  *
6  * Copyright (c) 2016 Paul Dreik (github@pauldreik.se)
7  * Copyright (c) 2016-2020 Sebastien Rombauts (sebastien.rombauts@gmail.com)
8  * Copyright (c) 2019 Maximilian Bachmann (contact@maxbachmann.de)
9  *
10  * Distributed under the MIT License (MIT) (See accompanying file LICENSE.txt
11  * or copy at http://opensource.org/licenses/MIT)
12  */
13 #pragma once
14 
15 #include <SQLiteCpp/Statement.h>
16 
17 #if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
18 #include <tuple>
19 #endif // c++14
20 
21 /// @cond
22 #include <utility>
23 #include <initializer_list>
24 
25 namespace SQLite
26 {
27 /// @endcond
28 
29 /**
30  * \brief Convenience function for calling Statement::bind(...) once for each argument given.
31  *
32  * This takes care of incrementing the index between each calls to bind.
33  *
34  * This feature requires a c++11 capable compiler.
35  *
36  * \code{.cpp}
37  * SQLite::Statement stm("SELECT * FROM MyTable WHERE colA>? && colB=? && colC<?");
38  * SQLite::bind(stm,a,b,c);
39  * //...is equivalent to
40  * stm.bind(1,a);
41  * stm.bind(2,b);
42  * stm.bind(3,c);
43  * \endcode
44  * @param query     statement
45  * @param args      zero or more args to bind.
46  */
47 template<class ...Args>
bind(SQLite::Statement & query,const Args &...args)48 void bind(SQLite::Statement& query, const Args& ... args)
49 {
50     int pos = 0;
51     (void)std::initializer_list<int>{
52         ((void)query.bind(++pos, std::forward<decltype(args)>(args)), 0)...
53     };
54 }
55 
56 #if (__cplusplus >= 201402L) || ( defined(_MSC_VER) && (_MSC_VER >= 1900) ) // c++14: Visual Studio 2015
57 
58 /**
59  * \brief Convenience function for calling Statement::bind(...) once for each parameter of a tuple,
60  * by forwarding them to the variadic template
61  *
62  * This feature requires a c++14 capable compiler.
63  *
64  * \code{.cpp}
65  * SQLite::Statement stm("SELECT * FROM MyTable WHERE colA>? && colB=? && colC<?");
66  * SQLite::bind(stm, std::make_tuple(a, b, c));
67  * //...is equivalent to
68  * stm.bind(1,a);
69  * stm.bind(2,b);
70  * stm.bind(3,c);
71  * \endcode
72  * @param query     statement
73  * @param tuple     tuple with values to bind
74  */
75 template <typename ... Types>
bind(SQLite::Statement & query,const std::tuple<Types...> & tuple)76 void bind(SQLite::Statement& query, const std::tuple<Types...> &tuple)
77 {
78     bind(query, tuple, std::index_sequence_for<Types...>());
79 }
80 
81 /**
82  * \brief Convenience function for calling Statement::bind(...) once for each parameter of a tuple,
83  * by forwarding them to the variadic template. This function is just needed to convert the tuples
84  * to parameter packs
85  *
86  * This feature requires a c++14 capable compiler.
87  *
88  * @param query     statement
89  * @param tuple     tuple with values to bind
90  */
91 template <typename ... Types, std::size_t ... Indices>
bind(SQLite::Statement & query,const std::tuple<Types...> & tuple,std::index_sequence<Indices...>)92 void bind(SQLite::Statement& query, const std::tuple<Types...> &tuple, std::index_sequence<Indices...>)
93 {
94     bind(query, std::get<Indices>(tuple)...);
95 }
96 #endif // c++14
97 
98 } // namespace SQLite
99