Cannot convert condition to tuple in `mapped_view`
Opened this issue · 2 comments
This is a regression since v1.9.
When using iterate
(or more generally, mapped_view
) with where()
(or more generally, a condition), I get an error:
sqlite_orm.h:15971:75: error: no viable conversion from 'sqlite_orm::internal::where_t<sqlite_orm::internal::is_equal_t<std::basic_string<char> MyRecord::*, std::basic_string<char>>>' to 'conditions_type' (aka 'tuple<sqlite_orm::internal::where_t<sqlite_orm::internal::is_equal_t<std::basic_string<char, std::char_traits<char>, std::allocator<char>> MyRecord::*, std::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, sqlite_orm::internal::order_by_t<long MyRecord::*>>')
15971 | storage(storage), connection(std::move(conn)), expression{std::forward<Args>(args)...} {}
| ^~~~~~~~~~~~~~~~~~~~~~~~
sqlite_orm.h:22161:24: note: in instantiation of member function 'sqlite_orm::internal::mapped_view<MyRecord, sqlite_orm::internal::storage_t<...>, sqlite_orm::internal::where_t<sqlite_orm::internal::is_equal_t<std::basic_string<char> MyRecord::*, std::basic_string<char>>>, sqlite_orm::internal::order_by_t<long MyRecord::*>>::mapped_view' requested here
22161 | return {*this, std::move(con), std::forward<Args>(args)...};
| ^
MyStorage.cpp:377:35: note: in instantiation of function template specialization 'sqlite_orm::internal::storage_t<...>::iterate<MyRecord, MyRecord, sqlite_orm::internal::where_t<sqlite_orm::internal::is_equal_t<std::basic_string<char> MyRecord::*, std::basic_string<char>>>, sqlite_orm::internal::order_by_t<long MyRecord::*>>' requested here
377 | for (auto& record : mStorage->m.iterate<MyRecord>(
| ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1356:17: note: candidate constructor not viable: no known conversion from 'sqlite_orm::internal::where_t<sqlite_orm::internal::is_equal_t<std::basic_string<char> MyRecord::*, std::basic_string<char>>>' to 'const tuple<where_t<is_equal_t<basic_string<char> MyRecord::*, basic_string<char>>>, order_by_t<long MyRecord::*>> &' for 1st argument
1356 | constexpr tuple(const tuple&) = default;
| ^ ~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1358:17: note: candidate constructor not viable: no known conversion from 'sqlite_orm::internal::where_t<sqlite_orm::internal::is_equal_t<std::basic_string<char> MyRecord::*, std::basic_string<char>>>' to 'tuple<where_t<is_equal_t<basic_string<char> MyRecord::*, basic_string<char>>>, order_by_t<long MyRecord::*>> &&' for 1st argument
1358 | constexpr tuple(tuple&&) = default;
| ^ ~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1363:2: note: candidate template ignored: could not match 'tuple' against 'where_t'
1363 | tuple(const tuple<_U1, _U2>& __in)
| ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1377:2: note: candidate template ignored: could not match 'tuple' against 'where_t'
1377 | tuple(tuple<_U1, _U2>&& __in)
| ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1409:2: note: candidate template ignored: could not match 'pair' against 'where_t'
1409 | tuple(const pair<_U1, _U2>& __in)
| ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1423:2: note: candidate template ignored: could not match 'pair' against 'where_t'
1423 | tuple(pair<_U1, _U2>&& __in)
| ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1370:2: note: explicit constructor is not a candidate
1370 | tuple(const tuple<_U1, _U2>& __in)
| ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1384:2: note: explicit constructor is not a candidate
1384 | tuple(tuple<_U1, _U2>&& __in)
| ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1416:2: note: explicit constructor is not a candidate
1416 | tuple(const pair<_U1, _U2>& __in)
| ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/tuple:1431:2: note: explicit constructor is not a candidate
1431 | tuple(pair<_U1, _U2>&& __in)
| ^
This is caused by the constructor of mapped_view
constructing expression
as expression{std::forward<Args>(args)...}
, while it should be expression{{std::forward<Args>(args)...}}
(construct a struct with a tuple
inside).
I can reproduce this with clang 20.0.0, clang 14.0.0, Apple clang 15.0.0, MSVC 19.39.33523, all with C++20.
@stevenwdv could you please show the least code which can repro this issue? It will help a lot in creating a unit test which covers this issue to avoid it firing in future again
Hi! Apparently the issue occurs when using iterate
with where
+ order_by
, not with only one:
#include <iostream>
#include <string>
#include <sqlite_orm.h> // v1.9
struct Person {
std::string name;
bool dead{};
};
void listPeople(const std::string &path) {
using namespace sqlite_orm;
auto storage = make_storage(path,
make_table("People",
make_column("name", &Person::name)
)
);
for (const auto &person : storage.iterate<Person>(
where(c(&Person::dead) == false),
order_by(&Person::name).asc()
)) {
std::cout << person.name << '\n';
}
}