1#pragma once
2#include <type_traits>
3#include "duckdb/common/vector.hpp"
4#include "duckdb/common/unordered_map.hpp"
5#include "duckdb/common/unordered_set.hpp"
6
7namespace duckdb {
8
9class FormatSerializer; // Forward declare
10class FormatDeserializer; // Forward declare
11
12// Backport to c++11
13template <class...>
14using void_t = void;
15
16// Check for anything implementing a `void FormatSerialize(FormatSerializer &FormatSerializer)` method
17template <typename T, typename = T>
18struct has_serialize : std::false_type {};
19template <typename T>
20struct has_serialize<
21 T, typename std::enable_if<
22 std::is_same<decltype(std::declval<T>().FormatSerialize(std::declval<FormatSerializer &>())), void>::value,
23 T>::type> : std::true_type {};
24
25template <typename T, typename = T>
26struct has_deserialize : std::false_type {};
27
28// Accept `static unique_ptr<T> FormatDeserialize(FormatDeserializer& deserializer)`
29template <typename T>
30struct has_deserialize<
31 T, typename std::enable_if<std::is_same<decltype(T::FormatDeserialize), unique_ptr<T>(FormatDeserializer &)>::value,
32 T>::type> : std::true_type {};
33
34// Accept `static shared_ptr<T> FormatDeserialize(FormatDeserializer& deserializer)`
35template <typename T>
36struct has_deserialize<
37 T, typename std::enable_if<std::is_same<decltype(T::FormatDeserialize), shared_ptr<T>(FormatDeserializer &)>::value,
38 T>::type> : std::true_type {};
39
40// Accept `static T FormatDeserialize(FormatDeserializer& deserializer)`
41template <typename T>
42struct has_deserialize<
43 T, typename std::enable_if<std::is_same<decltype(T::FormatDeserialize), T(FormatDeserializer &)>::value, T>::type>
44 : std::true_type {};
45
46// Check if T is a vector, and provide access to the inner type
47template <typename T>
48struct is_vector : std::false_type {};
49template <typename T>
50struct is_vector<typename duckdb::vector<T>> : std::true_type {
51 typedef T ELEMENT_TYPE;
52};
53
54// Check if T is a unordered map, and provide access to the inner type
55template <typename T>
56struct is_unordered_map : std::false_type {};
57template <typename... Args>
58struct is_unordered_map<typename std::unordered_map<Args...>> : std::true_type {
59 typedef typename std::tuple_element<0, std::tuple<Args...>>::type KEY_TYPE;
60 typedef typename std::tuple_element<1, std::tuple<Args...>>::type VALUE_TYPE;
61 typedef typename std::tuple_element<2, std::tuple<Args...>>::type HASH_TYPE;
62 typedef typename std::tuple_element<3, std::tuple<Args...>>::type EQUAL_TYPE;
63};
64
65template <typename T>
66struct is_unique_ptr : std::false_type {};
67
68template <typename T>
69struct is_unique_ptr<unique_ptr<T>> : std::true_type {
70 typedef T ELEMENT_TYPE;
71};
72
73template <typename T>
74struct is_shared_ptr : std::false_type {};
75
76template <typename T>
77struct is_shared_ptr<shared_ptr<T>> : std::true_type {
78 typedef T ELEMENT_TYPE;
79};
80
81template <typename T>
82struct is_pair : std::false_type {};
83
84template <typename T, typename U>
85struct is_pair<std::pair<T, U>> : std::true_type {
86 typedef T FIRST_TYPE;
87 typedef U SECOND_TYPE;
88};
89
90template <typename T>
91struct is_unordered_set : std::false_type {};
92template <typename... Args>
93struct is_unordered_set<std::unordered_set<Args...>> : std::true_type {
94 typedef typename std::tuple_element<0, std::tuple<Args...>>::type ELEMENT_TYPE;
95 typedef typename std::tuple_element<1, std::tuple<Args...>>::type HASH_TYPE;
96 typedef typename std::tuple_element<2, std::tuple<Args...>>::type EQUAL_TYPE;
97};
98
99template <typename T>
100struct is_set : std::false_type {};
101template <typename... Args>
102struct is_set<std::set<Args...>> : std::true_type {
103 typedef typename std::tuple_element<0, std::tuple<Args...>>::type ELEMENT_TYPE;
104 typedef typename std::tuple_element<1, std::tuple<Args...>>::type HASH_TYPE;
105 typedef typename std::tuple_element<2, std::tuple<Args...>>::type EQUAL_TYPE;
106};
107
108} // namespace duckdb
109