Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
end of simplification of dependencies
[simgrid.git] / include / xbt / utility.hpp
1 /* Copyright (c) 2016. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include <tuple>
8
9 namespace simgrid {
10 namespace xbt {
11
12 // integer_sequence and friends from C++14
13 // We need them to implement `apply` from C++17.
14
15 /** A compile-time sequence of integers (from C++14)
16  *
17  * `index_sequence<std::size_t,1,5,7,9>` represents the sequence `(1,5,7,9)`.
18  *
19  * @code{.cpp}
20  * template<class T, std::size_t... I>
21  * auto extract_tuple(T&& t, integer_sequence<std::size_t, I...>)
22  *   -> decltype(std::make_tuple(std::get<I>(std::forward<T>(t))...))
23  * {
24  *  return std::make_tuple(std::get<I>(std::forward<T>(t))...);
25  * }
26  *
27  * int main()
28  * {
29  *   integer_sequence<std::size_t, 1, 3> seq;
30  *   auto a = std::make_tuple(1, 2.0, false, 'a');
31  *   auto b = extract_tuple(a, seq);
32  *   std::cout << std::get<0>(b) << '\n'; // 2
33  *   std::cout << std::get<1>(b) << '\n'; // a
34  *   return 0;
35  * }
36  * @endcode
37  */
38 template<class T, T... N>
39 class integer_sequence {
40   static constexpr std::size_t size()
41   {
42     return std::tuple_size<decltype(std::make_tuple(N...))>::value;
43   }
44 };
45
46 namespace bits {
47   template<class T, long long N, long long... M>
48   struct make_integer_sequence :
49     public make_integer_sequence<T, N-1, N-1, M...>
50   {};
51   template<class T, long long... M>
52   struct make_integer_sequence<T, 0, M...> {
53     typedef integer_sequence<T, (T) M...> type;
54   };
55 }
56
57 /** A compile-time sequence of integers of the form `(0,1,2,3,...,N-1)` (from C++14) */
58 template<class T, T N>
59 using make_integer_sequence = typename simgrid::xbt::bits::make_integer_sequence<T,N>::type;
60
61 /** A compile-time sequence of indices (from C++14) */
62 template<std::size_t... Ints>
63 using index_sequence = integer_sequence<std::size_t, Ints...>;
64
65 /** A compile-time sequence of indices of the form `(0,1,2,3,...,N-1)` (from C++14) */
66 template<std::size_t N>
67 using make_index_sequence = make_integer_sequence<std::size_t, N>;
68
69 /** Convert a type parameter pack into a index_sequence (from C++14) */
70 template<class... T>
71 using index_sequence_for = make_index_sequence<sizeof...(T)>;
72
73 static_assert(std::is_same< make_index_sequence<0>, index_sequence<> >::value, "seq0");
74 static_assert(std::is_same< make_index_sequence<1>, index_sequence<0> >::value, "seq1");
75 static_assert(std::is_same< make_index_sequence<2>, index_sequence<0, 1> >::value, "seq2");
76 static_assert(std::is_same< make_index_sequence<3>, index_sequence<0, 1, 2> >::value, "seq3");
77 static_assert(std::is_same< index_sequence_for<int,double,float>, make_index_sequence<3> >::value, "seq4");
78
79 }
80 }