1 /************************************************************************************
2 *                                                                                   *
3 *   Copyright (c) 2014 - 2018 Axel Menzel <info@rttr.org>                           *
4 *                                                                                   *
5 *   This file is part of RTTR (Run Time Type Reflection)                            *
6 *   License: MIT License                                                            *
7 *                                                                                   *
8 *   Permission is hereby granted, free of charge, to any person obtaining           *
9 *   a copy of this software and associated documentation files (the "Software"),    *
10 *   to deal in the Software without restriction, including without limitation       *
11 *   the rights to use, copy, modify, merge, publish, distribute, sublicense,        *
12 *   and/or sell copies of the Software, and to permit persons to whom the           *
13 *   Software is furnished to do so, subject to the following conditions:            *
14 *                                                                                   *
15 *   The above copyright notice and this permission notice shall be included in      *
16 *   all copies or substantial portions of the Software.                             *
17 *                                                                                   *
18 *   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR      *
19 *   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,        *
20 *   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE     *
21 *   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER          *
22 *   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,   *
23 *   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE   *
24 *   SOFTWARE.                                                                       *
25 *                                                                                   *
26 *************************************************************************************/
27 
28 #ifndef RTTR_SEQUENTIAL_CONTAINER_TYPE_TRAITS_H_
29 #define RTTR_SEQUENTIAL_CONTAINER_TYPE_TRAITS_H_
30 
31 #include "rttr/detail/base/core_prerequisites.h"
32 
33 #include "rttr/detail/misc/misc_type_traits.h"
34 
35 #include <type_traits>
36 #include <vector>
37 #include <tuple>
38 
39 namespace rttr
40 {
41 class type;
42 
43 namespace detail
44 {
45 
46 /////////////////////////////////////////////////////////////////////////////////////
47 
48 template <typename... T>
49 struct concat_sequiantials_types;
50 
51 
52 template <template <typename ...> class List, typename ...Types, typename T>
53 struct concat_sequiantials_types<List<Types...>, T, std::true_type>
54 {
55     using type = List<Types...>;
56 };
57 
58 template <template <typename... > class List, typename... Types, typename T>
59 struct concat_sequiantials_types<List<Types...>, T, std::false_type>
60 {
61     using sub_type  = typename sequential_container_mapper<T>::value_t;
62     using type      = typename concat_sequiantials_types< List<Types..., T>, sub_type, typename std::is_same<invalid_type, sub_type>::type >::type;
63 };
64 
65 //////////////////////////////////////////////////////////////////////////////////////
66 
67 template<typename T>
68 struct sequential_rank_type_list
69 {
70     using sub_type  = typename sequential_container_mapper<T>::value_t;
71     using types     = typename concat_sequiantials_types< std::tuple<>, T, typename std::is_same<invalid_type, sub_type>::type >::type;
72 };
73 
74 //////////////////////////////////////////////////////////////////////////////////////
75 
76 template<typename T, size_t N>
77 struct sequential_container_ranke_type
78 {
79     using type = typename std::tuple_element<N, typename sequential_rank_type_list<T>::types>::type;
80 };
81 
82 /////////////////////////////////////////////////////////////////////////////////////
83 // rank<T>::value
84 //
85 // rank<int[2][10][4]>::value => 3
86 // rank<std::vector<std::vector<int>>>::value => 2
87 template<typename T>
88 using rank_count = typename count_types< typename sequential_rank_type_list<T>::types >::type;
89 
90 //////////////////////////////////////////////////////////////////////////////////////
91 template<typename T, std::size_t N>
92 struct get_ranke_type
93 {
94     static ::rttr::type get_type(std::size_t index)
95     {
96         if (N == index)
97             return type::get<typename sequential_container_ranke_type<T, N>::type>();
98         else
99             return get_ranke_type<T, N - 1>::get_type(index);
100     }
101 };
102 
103 template<typename T>
104 struct get_ranke_type<T, 0>
105 {
106     static ::rttr::type get_type(std::size_t index)
107     {
108         return type::get<typename sequential_container_ranke_type<T, 0>::type>();
109     }
110 };
111 
112 /////////////////////////////////////////////////////////////////////////////////////
113 
114 } // end namespace detail
115 } // end namespace rttr
116 
117 #endif // RTTR_SEQUENTIAL_CONTAINER_TYPE_TRAITS_H_
118