1 /*
2  * Copyright 2019 by its authors. See AUTHORS.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef EOLIAN_CXX_TYPE_TRAITS_HH
17 #define EOLIAN_CXX_TYPE_TRAITS_HH
18 
19 #include <type_traits>
20 
21 namespace efl { namespace eolian { namespace grammar { namespace type_traits {
22 
23 template <typename G>
24 struct accepts_tuple : std::false_type {};
25 
26 template <typename G>
27 struct attributes_needed : std::integral_constant<int, 0> {};
28 template <typename G>
29 struct attributes_needed<G const> : attributes_needed<G> {};
30 template <typename G>
31 struct attributes_needed<G&> : attributes_needed<G> {};
32 template <typename G>
33 struct attributes_needed<G const&> : attributes_needed<G> {};
34 template <typename G>
35 struct attributes_needed<G volatile> : attributes_needed<G> {};
36 template <typename G>
37 struct attributes_needed<G volatile&> : attributes_needed<G> {};
38 template <typename G>
39 struct attributes_needed<G const volatile> : attributes_needed<G> {};
40 template <typename G>
41 struct attributes_needed<G const volatile&> : attributes_needed<G> {};
42 
43 template <typename T>
44 struct is_std_tuple : std::false_type {};
45 
46 template <typename...Args>
47 struct is_std_tuple<std::tuple<Args...> > : std::true_type {};
48 template <typename...Args>
49 struct is_std_tuple<std::tuple<Args...>&> : std::true_type {};
50 template <typename...Args>
51 struct is_std_tuple<const std::tuple<Args...> > : std::true_type {};
52 template <typename...Args>
53 struct is_std_tuple<const std::tuple<Args...>&> : std::true_type {};
54 
55 template <typename T, typename Enable = void>
56 struct is_explicit_tuple : std::false_type {};
57 template <typename T>
58 struct is_explicit_tuple<T, typename std::enable_if<is_std_tuple<T>::value>::type> : std::true_type {};
59 
60 template <typename T, typename Enable = void>
61 struct is_tuple : std::false_type {};
62 template <typename T>
63 struct is_tuple<T const> : is_tuple<T> {};
64 template <typename T>
65 struct is_tuple<T const&> : is_tuple<T> {};
66 template <typename T>
67 struct is_tuple<T const volatile> : is_tuple<T> {};
68 template <typename T>
69 struct is_tuple<T const volatile&> : is_tuple<T> {};
70 template <typename T>
71 struct is_tuple<T volatile> : is_tuple<T> {};
72 template <typename T>
73 struct is_tuple<T volatile&> : is_tuple<T> {};
74 
75 template <typename T>
76 struct is_tuple<T, typename std::enable_if<!std::is_const<T>::value && is_std_tuple<T>::value>::type> : std::true_type {};
77 
78 } } } }
79 
80 #endif
81