Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot convert condition to tuple in mapped_view #1346

Open
stevenwdv opened this issue Sep 2, 2024 · 2 comments · Fixed by #1347
Open

Cannot convert condition to tuple in mapped_view #1346

stevenwdv opened this issue Sep 2, 2024 · 2 comments · Fixed by #1347
Assignees
Labels

Comments

@stevenwdv
Copy link

stevenwdv commented Sep 2, 2024

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 added a commit to stevenwdv/sqlite_orm that referenced this issue Sep 2, 2024
@trueqbit trueqbit added bug and removed investigation labels Sep 2, 2024
stevenwdv added a commit to stevenwdv/sqlite_orm that referenced this issue Sep 3, 2024
stevenwdv added a commit to stevenwdv/sqlite_orm that referenced this issue Sep 3, 2024
stevenwdv added a commit to stevenwdv/sqlite_orm that referenced this issue Sep 3, 2024
@fnc12
Copy link
Owner

fnc12 commented Oct 9, 2024

@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

@stevenwdv
Copy link
Author

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';
    }
}

Working demo on Compiler Explorer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants