-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstructural_bindable.hpp
More file actions
33 lines (23 loc) · 1.28 KB
/
structural_bindable.hpp
File metadata and controls
33 lines (23 loc) · 1.28 KB
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
#include <concepts>
#include <utility>
template <typename T, std::size_t N>
concept has_global_get_N = requires (T t) { std::get<N>(t); };
template <typename T, std::size_t N>
concept has_member_get_N = requires (T t) { t.template get<N>(); };
template <typename T, std::size_t N>
concept has_get_N = has_global_get_N<T, N> or has_member_get_N<T, N>;
template <typename T, std::size_t N>
struct has_get_for_size : public std::false_type {};
template <typename T, std::size_t N>
requires (N <= std::tuple_size_v<T> && has_get_N < T, N <= std::tuple_size_v<T> ? N - 1 : 0 >)
struct has_get_for_size<T, N> {
static constexpr bool value = has_get_N<T, N - 1> && has_get_for_size<T, N - 1>::value;
};
template <typename T, std::size_t N>
concept structure_bindable = (std::tuple_size_v<T> == N) && has_get_for_size<T, N>::value;
template <typename T, size_t N, typename Expected>
concept global_get_N = requires (T t) { requires std::same_as<std::decay_t<decltype(std::get<N>(t))>, Expected>; };
template <typename T, size_t N, typename Expected>
concept member_get_N = requires (T t) { requires std::same_as<std::decay_t<decltype(t.template get<N>())>, Expected>; };
template <typename T, size_t N, typename Expected>
concept get_N = global_get_N<T, N, Expected> or member_get_N<T, N, Expected>;