Skip to content

Commit 6193bef

Browse files
committed
The final result types of multiple columns must be transformed element-wise
1 parent 9ef8bb2 commit 6193bef

File tree

3 files changed

+54
-20
lines changed

3 files changed

+54
-20
lines changed

dev/column_result_proxy.h

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
#pragma once
22

3+
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
4+
#include <type_traits>
5+
#endif
6+
7+
#include "functional/cxx_type_traits_polyfill.h"
8+
#include "tuple_helper/tuple_transformer.h"
39
#include "type_traits.h"
410
#include "table_reference.h"
511

@@ -20,22 +26,30 @@ namespace sqlite_orm {
2026
namespace sqlite_orm {
2127
namespace internal {
2228

29+
/*
30+
* Determine the actual and final result type of an intermediate column result produced by `column_result_t`,
31+
* unwrapping `table_reference` and `structure`, and transforming tuples element-wise.
32+
*/
2333
template<class T, class SFINAE = void>
2434
struct column_result_proxy : std::remove_const<T> {};
2535

36+
template<class T>
37+
using column_result_proxy_t = typename column_result_proxy<T>::type;
38+
2639
/*
27-
* Unwrap `table_reference`
40+
* Unwrap `table_reference`, `structure`.
2841
*/
2942
template<class P>
30-
struct column_result_proxy<P, match_if<is_table_reference, P>> : decay_table_ref<P> {};
43+
struct column_result_proxy<
44+
P,
45+
std::enable_if_t<
46+
polyfill::disjunction_v<is_table_reference<P>, polyfill::is_specialization_of<P, structure>>>> : P {};
3147

3248
/*
33-
* Pass through `structure`
49+
* Calculate result of multiple columns.
3450
*/
35-
template<class P>
36-
struct column_result_proxy<P, match_specialization_of<P, structure>> : P {};
37-
38-
template<class T>
39-
using column_result_proxy_t = typename column_result_proxy<T>::type;
51+
template<class Tpl>
52+
struct column_result_proxy<Tpl, match_specialization_of<Tpl, std::tuple>>
53+
: tuple_transformer<Tpl, column_result_proxy_t> {};
4054
}
4155
}

include/sqlite_orm/sqlite_orm.h

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10662,6 +10662,14 @@ namespace sqlite_orm {
1066210662

1066310663
// #include "column_result_proxy.h"
1066410664

10665+
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
10666+
#include <type_traits>
10667+
#endif
10668+
10669+
// #include "functional/cxx_type_traits_polyfill.h"
10670+
10671+
// #include "tuple_helper/tuple_transformer.h"
10672+
1066510673
// #include "type_traits.h"
1066610674

1066710675
// #include "table_reference.h"
@@ -10683,23 +10691,31 @@ namespace sqlite_orm {
1068310691
namespace sqlite_orm {
1068410692
namespace internal {
1068510693

10694+
/*
10695+
* Determine the actual and final result type of an intermediate column result produced by `column_result_t`,
10696+
* unwrapping `table_reference` and `structure`, and transforming tuples element-wise.
10697+
*/
1068610698
template<class T, class SFINAE = void>
1068710699
struct column_result_proxy : std::remove_const<T> {};
1068810700

10701+
template<class T>
10702+
using column_result_proxy_t = typename column_result_proxy<T>::type;
10703+
1068910704
/*
10690-
* Unwrap `table_reference`
10705+
* Unwrap `table_reference`, `structure`.
1069110706
*/
1069210707
template<class P>
10693-
struct column_result_proxy<P, match_if<is_table_reference, P>> : decay_table_ref<P> {};
10708+
struct column_result_proxy<
10709+
P,
10710+
std::enable_if_t<
10711+
polyfill::disjunction_v<is_table_reference<P>, polyfill::is_specialization_of<P, structure>>>> : P {};
1069410712

1069510713
/*
10696-
* Pass through `structure`
10714+
* Calculate result of multiple columns.
1069710715
*/
10698-
template<class P>
10699-
struct column_result_proxy<P, match_specialization_of<P, structure>> : P {};
10700-
10701-
template<class T>
10702-
using column_result_proxy_t = typename column_result_proxy<T>::type;
10716+
template<class Tpl>
10717+
struct column_result_proxy<Tpl, match_specialization_of<Tpl, std::tuple>>
10718+
: tuple_transformer<Tpl, column_result_proxy_t> {};
1070310719
}
1070410720
}
1070510721

tests/static_tests/iterator_t.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,20 +169,24 @@ TEST_CASE("can view and iterate result set") {
169169
STATIC_REQUIRE(
170170
can_iterate_result_set<result_set_iterator<structure<Object, empty_db_objects_type>, empty_db_objects_type>,
171171
Object>);
172-
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
173172
STATIC_REQUIRE(can_iterate_result_set<result_set_iterator<table_reference<Object>, db_objects_type>, Object>);
174-
#endif
173+
STATIC_REQUIRE(can_iterate_result_set<
174+
result_set_iterator<std::tuple<table_reference<Object>, structure<Object, std::tuple<>>, int>,
175+
db_objects_type>,
176+
std::tuple<Object, Object, int>>);
175177

176178
STATIC_REQUIRE(storage_iterate_result_set<empty_storage_type, decltype(select(42)), int>);
177179
STATIC_REQUIRE(
178180
storage_iterate_result_set<empty_storage_type, decltype(select(columns(1, 42))), std::tuple<int, int>>);
179181
STATIC_REQUIRE(storage_iterate_result_set<empty_storage_type,
180182
decltype(select(struct_<Object>())),
181183
structure<Object, std::tuple<>>>);
182-
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
183184
STATIC_REQUIRE(
184185
storage_iterate_result_set<storage_type, decltype(select(object<Object>())), table_reference<Object>>);
185-
#endif
186+
STATIC_REQUIRE(
187+
storage_iterate_result_set<storage_type,
188+
decltype(select(columns(object<Object>(), struct_<Object>(), 42))),
189+
std::tuple<table_reference<Object>, structure<Object, std::tuple<>>, int>>);
186190

187191
#if (SQLITE_VERSION_NUMBER >= 3008003) && defined(SQLITE_ORM_WITH_CTE)
188192
#ifdef SQLITE_ORM_WITH_CPP20_ALIASES

0 commit comments

Comments
 (0)