]> git.proxmox.com Git - ceph.git/blame - ceph/src/Beast/include/beast/core/detail/integer_sequence.hpp
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / Beast / include / beast / core / detail / integer_sequence.hpp
CommitLineData
7c673cae
FG
1//
2// Copyright (c) 2013-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
3//
4// Distributed under the Boost Software License, Version 1.0. (See accompanying
5// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8#ifndef BEAST_DETAIL_INTEGER_SEQUENCE_H_INCLUDED
9#define BEAST_DETAIL_INTEGER_SEQUENCE_H_INCLUDED
10
11#include <cstddef>
12#include <type_traits>
13#include <utility>
14
15namespace beast {
16namespace detail {
17
18template<class T, T... Ints>
19struct integer_sequence
20{
21 using value_type = T;
22 static_assert (std::is_integral<T>::value,
23 "std::integer_sequence can only be instantiated with an integral type" );
24
25 static std::size_t constexpr static_size = sizeof...(Ints);
26
27 static std::size_t constexpr size()
28 {
29 return sizeof...(Ints);
30 }
31};
32
33template<std::size_t... Ints>
34using index_sequence = integer_sequence<std::size_t, Ints...>;
35
36// This workaround is needed for broken sizeof...
37template<class... Args>
38struct sizeof_workaround
39{
40 static std::size_t constexpr size = sizeof... (Args);
41};
42
43#ifdef _MSC_VER
44
45// This implementation compiles on MSVC and clang but not gcc
46
47template<class T, unsigned long long N, class Seq>
48struct make_integer_sequence_unchecked;
49
50template<class T, unsigned long long N, unsigned long long ...Indices>
51struct make_integer_sequence_unchecked<
52 T, N, integer_sequence<T, Indices...>>
53{
54 using type = typename make_integer_sequence_unchecked<
55 T, N-1, integer_sequence<T, N-1, Indices...>>::type;
56};
57
58template<class T, unsigned long long ...Indices>
59struct make_integer_sequence_unchecked<
60 T, 0, integer_sequence<T, Indices...>>
61{
62 using type = integer_sequence<T, Indices...>;
63};
64
65template<class T, T N>
66struct make_integer_sequence_checked
67{
68 static_assert (std::is_integral<T>::value,
69 "T must be an integral type");
70
71 static_assert (N >= 0,
72 "N must be non-negative");
73
74 using type = typename make_integer_sequence_unchecked<
75 T, N, integer_sequence<T>>::type;
76};
77
78template<class T, T N>
79using make_integer_sequence =
80 typename make_integer_sequence_checked<T, N>::type;
81
82template<std::size_t N>
83using make_index_sequence = make_integer_sequence<std::size_t, N>;
84
85template<class... Args>
86using index_sequence_for =
87 make_index_sequence<sizeof_workaround<Args...>::size>;
88
89#else
90
91// This implementation compiles on gcc but not MSVC
92
93template<std::size_t... Ints>
94struct index_tuple
95{
96 using next = index_tuple<Ints..., sizeof... (Ints)>;
97
98};
99
100template<std::size_t N>
101struct build_index_tuple
102{
103 using type = typename build_index_tuple<N-1>::type::next;
104};
105
106template<>
107struct build_index_tuple<0>
108{
109 using type = index_tuple<>;
110};
111
112template<class T, T N,
113 class Seq = typename build_index_tuple<N>::type
114>
115struct integer_sequence_helper;
116
117template<class T, T N, std::size_t... Ints>
118struct integer_sequence_helper<T, N, index_tuple<Ints...>>
119{
120 static_assert (std::is_integral<T>::value,
121 "T must be an integral type");
122
123 static_assert (N >= 0,
124 "N must be non-negative");
125
126 using type = integer_sequence<T, static_cast<T> (Ints)...>;
127};
128
129template<class T, T N>
130using make_integer_sequence =
131 typename integer_sequence_helper<T, N>::type;
132
133template<std::size_t N>
134using make_index_sequence = make_integer_sequence<std::size_t, N>;
135
136template<class... Args>
137using index_sequence_for =
138 make_index_sequence<sizeof_workaround<Args...>::size>;
139
140#endif
141
142} // detail
143} // beast
144
145#endif