This repository has been archived by the owner on Jan 3, 2024. It is now read-only.
forked from fnc12/sqlite_orm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstorage_lookup.h
144 lines (120 loc) · 5.83 KB
/
storage_lookup.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#pragma once
#include <type_traits> // std::true_type, std::false_type, std::remove_const, std::enable_if, std::is_base_of, std::is_void
#include <tuple>
#include <utility> // std::index_sequence, std::make_index_sequence
#include "functional/cxx_universal.h"
#include "functional/cxx_type_traits_polyfill.h"
#include "type_traits.h"
namespace sqlite_orm {
namespace internal {
template<class... DBO>
struct storage_t;
template<class... DBO>
using db_objects_tuple = std::tuple<DBO...>;
template<class T>
struct is_storage : std::false_type {};
template<class... DBO>
struct is_storage<storage_t<DBO...>> : std::true_type {};
template<class... DBO>
struct is_storage<const storage_t<DBO...>> : std::true_type {};
template<class T>
struct is_db_objects : std::false_type {};
template<class... DBO>
struct is_db_objects<db_objects_tuple<DBO...>> : std::true_type {};
template<class... DBO>
struct is_db_objects<const db_objects_tuple<DBO...>> : std::true_type {};
/**
* std::true_type if given object is mapped, std::false_type otherwise.
*
* Note: unlike table_t<>, index_t<>::object_type and trigger_t<>::object_type is always void.
*/
template<typename DBO, typename Lookup>
struct object_type_matches : polyfill::conjunction<polyfill::negation<std::is_void<object_type_t<DBO>>>,
std::is_same<Lookup, object_type_t<DBO>>> {};
/**
* std::true_type if given lookup type (object) is mapped, std::false_type otherwise.
*/
template<typename DBO, typename Lookup>
struct lookup_type_matches : polyfill::disjunction<object_type_matches<DBO, Lookup>> {};
}
// pick/lookup metafunctions
namespace internal {
/**
* Indirect enabler for DBO, accepting an index to disambiguate non-unique DBOs
*/
template<class Lookup, size_t Ix, class DBO>
struct enable_found_table : std::enable_if<lookup_type_matches<DBO, Lookup>::value, DBO> {};
/**
* SFINAE friendly facility to pick a table definition (`table_t`) from a tuple of database objects.
*
* Lookup - mapped data type
* Seq - index sequence matching the number of DBOs
* DBOs - db_objects_tuple type
*/
template<class Lookup, class Seq, class DBOs>
struct storage_pick_table;
template<class Lookup, size_t... Ix, class... DBO>
struct storage_pick_table<Lookup, std::index_sequence<Ix...>, db_objects_tuple<DBO...>>
: enable_found_table<Lookup, Ix, DBO>... {};
/**
* SFINAE friendly facility to pick a table definition (`table_t`) from a tuple of database objects.
*
* Lookup - 'table' type, mapped data type
* DBOs - db_objects_tuple type, possibly const-qualified
*/
template<class Lookup, class DBOs>
using storage_pick_table_t = typename storage_pick_table<Lookup,
std::make_index_sequence<std::tuple_size<DBOs>::value>,
std::remove_const_t<DBOs>>::type;
/**
* Find a table definition (`table_t`) from a tuple of database objects;
* `std::nonesuch` if not found.
*
* DBOs - db_objects_tuple type
* Lookup - mapped data type
*/
template<class Lookup, class DBOs>
struct storage_find_table : polyfill::detected_or<polyfill::nonesuch, storage_pick_table_t, Lookup, DBOs> {};
/**
* Find a table definition (`table_t`) from a tuple of database objects;
* `std::nonesuch` if not found.
*
* DBOs - db_objects_tuple type, possibly const-qualified
* Lookup - mapped data type
*/
template<class Lookup, class DBOs>
using storage_find_table_t = typename storage_find_table<Lookup, std::remove_const_t<DBOs>>::type;
#ifndef SQLITE_ORM_BROKEN_VARIADIC_PACK_EXPANSION
template<class DBOs, class Lookup, class SFINAE = void>
struct is_mapped : std::false_type {};
template<class DBOs, class Lookup>
struct is_mapped<DBOs, Lookup, polyfill::void_t<storage_pick_table_t<Lookup, DBOs>>> : std::true_type {};
#else
template<class DBOs, class Lookup, class SFINAE = storage_find_table_t<Lookup, DBOs>>
struct is_mapped : std::true_type {};
template<class DBOs, class Lookup>
struct is_mapped<DBOs, Lookup, polyfill::nonesuch> : std::false_type {};
#endif
template<class DBOs, class Lookup>
SQLITE_ORM_INLINE_VAR constexpr bool is_mapped_v = is_mapped<DBOs, Lookup>::value;
}
}
// runtime lookup functions
namespace sqlite_orm {
namespace internal {
/**
* Pick the table definition for the specified lookup type from the given tuple of schema objects.
*
* Note: This function requires Lookup to be mapped, otherwise it is removed from the overload resolution set.
*/
template<class Lookup, class DBOs, satisfies<is_mapped, DBOs, Lookup> = true>
auto& pick_table(DBOs& dbObjects) {
using table_type = storage_pick_table_t<Lookup, DBOs>;
return std::get<table_type>(dbObjects);
}
template<class Lookup, class DBOs, satisfies<is_db_objects, DBOs> = true>
auto lookup_table(const DBOs& dbObjects);
template<class Lookup, class DBOs, satisfies<is_db_objects, DBOs> = true>
decltype(auto) lookup_table_name(const DBOs& dbObjects);
}
}