44#ifdef SQLITE_ORM_WITH_VIEW
55#include < type_traits> // std::remove_cvref
66#include < utility> // std::forward, std::move, std::index_sequence, std::make_index_sequence
7- #include < cstddef> // std::byte
8- #endif
9- #endif
10-
11- #ifdef SQLITE_ORM_WITH_VIEW
12- #ifndef SQLITE_ORM_REFLECTION_SUPPORTED
13- #ifdef SQLITE_ORM_HAS_BOOST_PFR
14- #include < boost/pfr.hpp>
15- #endif
167#endif
178#endif
189
2314#include " column.h"
2415#include " table_base.h"
2516
26- #ifdef SQLITE_ORM_WITH_VIEW
27- #ifdef SQLITE_ORM_REFLECTION_SUPPORTED
28- #elif BOOST_PFR_ENABLED == 1
29- namespace boost ::pfr {
30- namespace detail {
31- namespace sequence_tuple {
32- template <std::size_t N, class W >
33- consteval auto get_nth_base (const base_from_member<N, W>& t) noexcept {
34- // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
35- return t;
36- }
37-
38- template <std::size_t N, class Tpl >
39- constexpr auto * get_nth_relative_address () noexcept {
40- // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn)
41- static_assert (N < Tpl::size_v);
42- using nth_type = decltype (get_nth_base<N>(std::declval<Tpl>()));
43- using field_type = decltype (nth_type::value);
44-
45- return (field_type*)(std::byte*)
46- // offsetof - the official one cannot be used because of some implementations using the compiler intrinsic builtin
47- ((std::size_t )&reinterpret_cast <char const volatile &>((((Tpl*)0 )->nth_type ::value)));
48- }
49- }
50- }
51-
52- template <class O , std::size_t I, class TS >
53- constexpr auto * get_relative_address () {
54- static_assert (sizeof (O) == sizeof (TS),
55- " ====================> Boost.PFR: Member sequence does not indicate correct size for struct "
56- " type! Maybe the user-provided type is not a SimpleAggregate?" );
57- static_assert (
58- alignof (O) == alignof (TS),
59- " ====================> Boost.PFR: Member sequence does not indicate correct alignment for struct type!" );
60-
61- return detail::sequence_tuple::get_nth_relative_address<I, TS>();
62- }
63- }
64- #endif
65- #endif
66-
6717namespace sqlite_orm ::internal {
6818#ifdef SQLITE_ORM_WITH_VIEW
6919 /* *
@@ -93,7 +43,7 @@ namespace sqlite_orm::internal {
9343#ifdef SQLITE_ORM_WITH_VIEW
9444#ifdef SQLITE_ORM_REFLECTION_SUPPORTED
9545namespace sqlite_orm ::internal {
96- template <class O , class Select , std:: size_t ... I>
46+ template <class O , class Select , size_t ... I>
9747 auto make_view (std::string name, std::index_sequence<I...>, Select select) {
9848 constexpr auto memberNames = extract_member_names<O>();
9949 constexpr auto memberPointers = extract_member_pointers<O>();
@@ -110,107 +60,12 @@ namespace sqlite_orm::internal {
11060}
11161
11262SQLITE_ORM_EXPORT namespace sqlite_orm {
113- template <class O , class Select >
114- requires (internal::is_select_expression_v<Select>)
115- auto make_view (std::string name, Select select) {
116- using namespace ::sqlite_orm::internal;
117-
118- if constexpr (is_select_v<Select>) {
119- select.highest_level = true ;
120- }
121- return internal::make_view<O>(std::move (name),
122- std::make_index_sequence<count_members<O>()>{},
123- std::move (select));
124- }
125- }
126- #elif BOOST_PFR_ENABLED == 1
127- namespace sqlite_orm ::internal {
12863 /* *
129- * Factory function for a column definition from a relative pointer to an object of the object to be mapped.
130- */
131- template <class C , class ... Op>
132- requires (internal::is_column_pointer_v<C>)
133- internal::column_t <C, internal::empty_setter, Op...>
134- make_column (std::string name, C relativeField, Op... constraints) {
135- static_assert (polyfill::conjunction_v<internal::is_column_constraint<Op>...>, " Incorrect constraints pack" );
136-
137- // attention: do not use `std::make_tuple()` for constructing the tuple member `[[no_unique_address]] column_constraints::constraints`,
138- // as this will lead to UB with Clang on MinGW!
139- return {std::move (name), relativeField, {}, std::tuple<Op...>{std::move (constraints)...}};
140- }
141-
142- /*
143- * A column field carrying a relative address to a member of an object.
64+ * Factory function for a view definition.
14465 *
145- * Internal note: According to my tests msvc or compilers in general have a hard time to use pointer-to-members at compile-time .
146- * That's why we use a relative address .
66+ * The mapped object type is explicitly specified, columns and their names are deferred from the object type .
67+ * The object type must be an aggregate .
14768 */
148- template <class O , class F >
149- struct column_field <column_pointer<O, F*>, empty_setter> {
150- using member_pointer_t = F O::*;
151- using setter_type = empty_setter;
152- using object_type = O;
153- using field_type = F;
154-
155- /* *
156- * Relative pointer to member (offset) used to read and write a field value.
157- */
158- const column_pointer<O, F*> member_pointer;
159-
160- SQLITE_ORM_NOUNIQUEADDRESS
161- const empty_setter setter;
162-
163- /* *
164- * Simplified interface for `NOT NULL` constraint
165- */
166- constexpr bool is_not_null () const {
167- return !type_is_nullable<field_type>::value;
168- }
169- };
170-
171- template <class O , class F >
172- bool compare_fields (F O::* m, const column_pointer<O, F*>& relative) {
173- constexpr O* object = nullptr ;
174- return &(object->*m) == relative.field ;
175- }
176-
177- template <class O , class F >
178- bool compare_fields (const column_pointer<O, F*>& relative, F O::* m) {
179- constexpr O* object = nullptr ;
180- return relative.field == &(object->*m);
181- }
182-
183- template <class O , size_t ... I, class Select >
184- auto make_view (std::string name, std::index_sequence<I...>, Select select) {
185- namespace pfr = boost::pfr;
186- namespace pfrd = pfr::detail;
187- namespace pfrs = pfrd::sequence_tuple;
188-
189- #if __cpp_lib_is_aggregate >= 201703L
190- static_assert (std::is_aggregate_v<O>);
191- #endif
192-
193- using PfrTpl = decltype (pfrd::tie_as_tuple (pfrd::fake_object<O>()));
194- // object's member types as a tuple
195- using TS = pfrs::tuple<polyfill::remove_cvref_t <typename pfrs::tuple_element<I, PfrTpl>::type>...>;
196-
197- using view_type = query_view<O,
198- Select,
199- decltype (internal::make_column<>(
200- std::string (pfr::get_name<I, O>()),
201- column_pointer<O, decltype (pfr::get_relative_address<O, I, TS>())>{
202- pfr::get_relative_address<O, I, TS>()}))...>;
203-
204- return view_type{
205- std::move (name),
206- std::tuple{internal::make_column<>(std::string (pfr::get_name<I, O>()),
207- column_pointer<O, decltype (pfr::get_relative_address<O, I, TS>())>{
208- pfr::get_relative_address<O, I, TS>()})...},
209- std::move (select)};
210- }
211- }
212-
213- SQLITE_ORM_EXPORT namespace sqlite_orm {
21469 template <class O , class Select >
21570 requires (internal::is_select_expression_v<Select>)
21671 auto make_view (std::string name, Select select) {
@@ -220,13 +75,10 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
22075 select.highest_level = true ;
22176 }
22277 return internal::make_view<O>(std::move (name),
223- std::make_index_sequence<boost::pfr::tuple_size_v <O>>{},
78+ std::make_index_sequence<count_members <O>() >{},
22479 std::move (select));
22580 }
226- }
227- #endif
22881
229- SQLITE_ORM_EXPORT namespace sqlite_orm {
23082#ifdef SQLITE_ORM_WITH_CPP20_ALIASES
23183 /* *
23284 * Factory function for a view definition.
@@ -241,3 +93,4 @@ SQLITE_ORM_EXPORT namespace sqlite_orm {
24193#endif
24294}
24395#endif
96+ #endif
0 commit comments