stator
A math, geometry, and utility library
static_list.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2015 Severin Strobl <[email protected]>
3 
4  This file is part of stator.
5 
6  stator is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  stator is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with stator. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 
22 // C++
23 #include <cstddef>
24 
25 namespace stator {
26 
27  namespace orphan {
28 
31  template<typename T, T...>
32  struct static_list {
33  };
34 
35  namespace detail {
36 
37  template<typename T, typename StaticList, T... List>
39 
40  template<typename T, T... ListItems, T Head, T... Tail>
41  struct static_list_helper<T, static_list<T, ListItems...>, Head,
42  Tail...> {
43 
44  typedef typename static_list_helper<T, static_list<T, ListItems...,
45  Head>, Tail...>::type type;
46  };
47 
48  template<typename T, T... ListItems>
49  struct static_list_helper<T, static_list<T, ListItems...>> {
50  typedef static_list<T, ListItems...> type;
51  };
52 
53  template<size_t Index, size_t ListIndex, typename List>
55  static const int value = -1;
56  };
57 
58  template<size_t Index, typename T, size_t ListIndex, T Head, T... Tail>
59  struct get_static_list_item_helper<Index, ListIndex, static_list<T, Head,
60  Tail...>> {
61 
62  static const T value = (Index == ListIndex) ? Head :
63  get_static_list_item_helper<Index, ListIndex + 1, static_list<T,
64  Tail...>>::value;
65  };
66 
67  template<typename T, typename ReverseList, typename StaticList>
69 
70  template<typename T, T... ReverseItems, T Head, T... Tail>
71  struct reverse_static_list_helper<T, static_list<T, ReverseItems...>,
72  static_list<T, Head, Tail...>> {
73 
74  typedef typename reverse_static_list_helper<T, static_list<T, Head,
75  ReverseItems...>, static_list<T, Tail...>>::type type;
76  };
77 
78  template<typename T, T... ReverseItems>
79  struct reverse_static_list_helper<T, static_list<T, ReverseItems...>,
80  static_list<T>> {
81 
82  typedef static_list<T, ReverseItems...> type;
83  };
84 
85  template<typename T, size_t Index, size_t ListIndex, typename NewList,
86  typename OldList, T Value>
88 
89  template<typename T, size_t Index, size_t ListIndex, T... NewItems,
90  T Head, T... Tail, T Value>
91  struct replace_static_list_item_helper<T, Index, ListIndex,
92  static_list<T, NewItems...>, static_list<T, Head, Tail...>, Value> {
93 
94  typedef typename replace_static_list_item_helper<T, Index,
95  ListIndex + 1, static_list<T, NewItems..., Head>,
96  static_list<T, Tail...>, Value>::type type;
97  };
98 
99  template<typename T, size_t Index, T... NewItems, T Head, T... Tail,
100  T Value>
101  struct replace_static_list_item_helper<T, Index, Index, static_list<T,
102  NewItems...>, static_list<T, Head, Tail...>, Value> {
103 
104  typedef static_list<T, NewItems..., Value, Tail...> type;
105  };
106 
107  template<size_t Index, size_t ListIndex, typename FirstList, typename
108  SecondList, typename List, bool Split>
110 
111  template<size_t Index, size_t ListIndex, typename T, T... FirstItems,
112  T Head, T... Tail>
113  struct split_static_list_helper<Index, ListIndex, static_list<T,
114  FirstItems...>, static_list<T>, static_list<T, Head,
115  Tail...>, false> {
116 
117  typedef split_static_list_helper<Index, ListIndex + 1, static_list<T,
118  FirstItems..., Head>, static_list<T>, static_list<T, Tail...>,
119  ListIndex + 1 >= Index> next_type;
120 
121  typedef typename next_type::first first;
122  typedef typename next_type::second second;
123  };
124 
125  template<size_t Index, size_t ListIndex, typename T, T... FirstItems,
126  T... SecondItems, T Head, T... Tail>
127  struct split_static_list_helper<Index, ListIndex, static_list<T,
128  FirstItems...>, static_list<T, SecondItems...>, static_list<T, Head,
129  Tail...>, true> {
130 
131  typedef split_static_list_helper<Index, ListIndex + 1, static_list<T,
132  FirstItems...>, static_list<T, SecondItems..., Head>, static_list<T,
133  Tail...>, ListIndex + 1 >= Index> next_type;
134 
135  typedef typename next_type::first first;
136  typedef typename next_type::second second;
137  };
138 
139  template<size_t Index, size_t ListIndex, typename T, T... FirstItems,
140  T... SecondItems, bool Split>
141  struct split_static_list_helper<Index, ListIndex, static_list<T,
142  FirstItems...>, static_list<T, SecondItems...>,
143  static_list<T>, Split> {
144 
145  typedef static_list<T, FirstItems...> first;
146  typedef static_list<T, SecondItems...> second;
147  };
148 
149  } // namespace detail
150 
153  template<typename T, T... ListItems>
156  ListItems...>::type type;
157  };
158 
161  template<typename List, size_t Index>
163 
164  template<typename T, T... ListItems, size_t Index>
165  struct get_static_list_item<static_list<T, ListItems...>, Index> {
166  static_assert(Index < sizeof...(ListItems), "Index out of range!");
167 
168  static const T value = detail::get_static_list_item_helper<Index, 0,
169  static_list<T, ListItems...>>::value;
170  };
171 
174  template<typename List>
176 
177  template<typename T, T... ListItems>
178  struct reverse_static_list<static_list<T, ListItems...>> {
180  static_list<T, ListItems...>>::type type;
181  };
182 
186  template<typename T, typename List, size_t Index, T Value>
188 
189  template<typename T, size_t Index, T Value>
190  struct replace_static_list_item<T, static_list<T>, Index, Value> {
192  };
193 
194  template<typename T, T... ListItems, size_t Index, T Value>
195  struct replace_static_list_item<T, static_list<T, ListItems...>, Index,
196  Value> {
197 
198  static_assert(Index < sizeof...(ListItems), "Index out of range!");
199 
200  typedef typename detail::replace_static_list_item_helper<T, Index, 0,
201  static_list<T>, static_list<T, ListItems...>, Value>::type type;
202  };
203 
206  template<typename T, typename List, T Value>
208 
209  template<typename T, T... ListItems, T Value>
210  struct append_static_list_item<T, static_list<T, ListItems...>, Value> {
211  typedef static_list<T, ListItems..., Value> type;
212  };
213 
216  template<typename T, typename List, T Value>
218 
219  template<typename T, T... ListItems, T Value>
220  struct prepend_static_list_item<T, static_list<T, ListItems...>, Value> {
221  typedef static_list<T, Value, ListItems...> type;
222  };
223 
226  template<typename List>
228 
229  template<typename T, T... ListItems>
230  struct static_list_size<static_list<T, ListItems...>> {
231  static const size_t value = sizeof...(ListItems);
232  };
233 
236  template<typename List0, typename List1>
238 
239  template<typename T, T... ListItems0, T... ListItems1>
240  struct merge_static_lists<static_list<T, ListItems0...>, static_list<T,
241  ListItems1...>> {
242 
243  typedef static_list<T, ListItems0..., ListItems1...> type;
244  };
245 
248  template<typename List, size_t Index>
250 
251  template<typename T, size_t Index>
252  struct split_static_list<static_list<T>, Index> {
255  };
256 
257  template<typename T, T... ListItems, size_t Index>
258  struct split_static_list<static_list<T, ListItems...>, Index> {
259  typedef typename detail::split_static_list_helper<Index, 0,
260  static_list<T>, static_list<T>, static_list<T, ListItems...>,
261  Index == 0>::first first;
262 
263  typedef typename detail::split_static_list_helper<Index, 0,
264  static_list<T>, static_list<T>, static_list<T, ListItems...>,
265  Index == 0>::second second;
266  };
267 
268  namespace detail {
269 
270  template<size_t Index, size_t End, typename List>
272 
273  template<size_t Index, size_t End, typename T, T... ListItems>
274  struct static_foreach_helper<Index, End, static_list<T, ListItems...>> {
275  using List = static_list<T, ListItems...>;
276 
277  template<typename F, typename...Args>
278  void operator()(F f, Args&&... args) {
281  }
282  };
283 
284  template<size_t End, typename T, T... ListItems>
285  struct static_foreach_helper<End, End, static_list<T, ListItems...>> {
286 
287  template<typename F, typename...Args>
288  void operator()(F f, Args&&... args) {
289  }
290  };
291 
292  } // namespace detail
293 
296  template<typename List>
298 
299  template<typename T, T... ListItems>
300  struct static_foreach<static_list<T, ListItems...>> {
301  using List = static_list<T, ListItems...>;
302 
303  template<typename F, typename...Args>
304  void operator()(F f, Args&&... args) {
306  List>()(f, args...);
307  }
308  };
309 
310  } // namespace orphan
311 
312 } // namespace stator
detail::static_list_helper< T, static_list< T >, ListItems... >::type type
Split a static list at a certain index.
static_list_helper< T, static_list< T, ListItems..., Head >, Tail... >::type type
Definition: static_list.hpp:45
detail::reverse_static_list_helper< T, static_list< T >, static_list< T, ListItems... > >::type type
Access an item in a static list by index.
reverse_static_list_helper< T, static_list< T, Head, ReverseItems... >, static_list< T, Tail... > >::type type
Definition: static_list.hpp:75
Get the size of a static list.
Prepend an item to a static list.
Append an item to a static list.
detail::split_static_list_helper< Index, 0, static_list< T >, static_list< T >, static_list< T, ListItems... >, Index==0 >::first first
Merge two static lists into one.
detail::split_static_list_helper< Index, 0, static_list< T >, static_list< T >, static_list< T, ListItems... >, Index==0 >::second second
detail::replace_static_list_item_helper< T, Index, 0, static_list< T >, static_list< T, ListItems... >, Value >::type type
Convert a parameter pack into a static list.
A static list of variable type.
Definition: static_list.hpp:32
Replace a value at a certain position of a static list by a different one.
The stator library namespace.
Definition: frontpage.dox:243
replace_static_list_item_helper< T, Index, ListIndex+1, static_list< T, NewItems..., Head >, static_list< T, Tail... >, Value >::type type
Definition: static_list.hpp:96
Call functor for each element in a static list.