diff --git a/hdr/sqlite_modern_cpp/utility/function_traits.h b/hdr/sqlite_modern_cpp/utility/function_traits.h index 88561ef1..8f482f39 100644 --- a/hdr/sqlite_modern_cpp/utility/function_traits.h +++ b/hdr/sqlite_modern_cpp/utility/function_traits.h @@ -31,5 +31,26 @@ namespace sqlite { static const std::size_t arity = sizeof...(Arguments); }; + /* support the non-const operator () + * this will work with user defined functors */ + template < + typename ClassType, + typename ReturnType, + typename... Arguments + > + struct function_traits< + ReturnType(ClassType::*)(Arguments...) + > { + typedef ReturnType result_type; + + template + using argument = typename std::tuple_element< + Index, + std::tuple + >::type; + + static const std::size_t arity = sizeof...(Arguments); + }; + } } diff --git a/tests/functors.cc b/tests/functors.cc new file mode 100644 index 00000000..cc8b8a86 --- /dev/null +++ b/tests/functors.cc @@ -0,0 +1,57 @@ +#include +#include +#include +#include +#include + +using namespace sqlite; +using namespace std; + +struct tbl_functor { + explicit tbl_functor(vector > &vec_) : vec(vec_) { } + + void operator() ( int id, string name) { + vec.push_back(make_pair(id, move(name))); + } + vector > &vec; +}; + +int main() { + + try { + database db(":memory:"); + db << "CREATE TABLE tbl (id integer, name string);"; + db << "INSERT INTO tbl VALUES (?, ?);" << 1 << "hello"; + db << "INSERT INTO tbl VALUES (?, ?);" << 2 << "world"; + + vector > vec; + db << "select id,name from tbl;" >> tbl_functor(vec); + + if(vec.size() != 2) { + cout << "Bad result on line " << __LINE__ << endl; + exit(EXIT_FAILURE); + } + + vec.clear(); + + tbl_functor functor(vec); + db << "select id,name from tbl;" >> functor; + + if(vec.size() != 2 || vec[0].first != 1 || vec[0].second != "hello") { + cout << "Bad result on line " << __LINE__ << endl; + exit(EXIT_FAILURE); + } + + } + catch(sqlite_exception e) { + cout << "Unexpected error " << e.what() << endl; + exit(EXIT_FAILURE); + } + catch(...) { + cout << "Unknown error\n"; + exit(EXIT_FAILURE); + } + + cout << "OK\n"; + exit(EXIT_SUCCESS); +}