1 // Copyright (C) 2012-2013 Vicente J. Botet Escriba
2 //
3 //  Distributed under the Boost Software License, Version 1.0. (See accompanying
4 //  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 // 2013/04 Vicente J. Botet Escriba
7 //   Provide implementation up to 10 parameters when BOOST_NO_CXX11_VARIADIC_TEMPLATES is defined.
8 // 2012/11 Vicente J. Botet Escriba
9 //   Adapt to boost libc++ implementation
10 
11 //===----------------------------------------------------------------------===//
12 //
13 //                     The LLVM Compiler Infrastructure
14 //
15 // This file is dual licensed under the MIT and the University of Illinois Open
16 // Source Licenses. See LICENSE.TXT for details.
17 //
18 // The make_tuple_indices C++11 code is based on the one from libcxx.
19 //===----------------------------------------------------------------------===//
20 
21 #ifndef BOOST_THREAD_DETAIL_MAKE_TUPLE_INDICES_HPP
22 #define BOOST_THREAD_DETAIL_MAKE_TUPLE_INDICES_HPP
23 
24 #include <boost/config.hpp>
25 #include <boost/static_assert.hpp>
26 
27 namespace boost
28 {
29   namespace detail
30   {
31 
32 #if ! defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
33     // make_tuple_indices
34 
35     template <std::size_t...> struct tuple_indices
36     {};
37 
38     template <std::size_t Sp, class IntTuple, std::size_t Ep>
39     struct make_indices_imp;
40 
41     template <std::size_t Sp, std::size_t ...Indices, std::size_t Ep>
42     struct make_indices_imp<Sp, tuple_indices<Indices...>, Ep>
43     {
44       typedef typename make_indices_imp<Sp+1, tuple_indices<Indices..., Sp>, Ep>::type type;
45     };
46 
47     template <std::size_t Ep, std::size_t ...Indices>
48     struct make_indices_imp<Ep, tuple_indices<Indices...>, Ep>
49     {
50       typedef tuple_indices<Indices...> type;
51     };
52 
53     template <std::size_t Ep, std::size_t Sp = 0>
54     struct make_tuple_indices
55     {
56       BOOST_STATIC_ASSERT_MSG(Sp <= Ep, "make_tuple_indices input error");
57       typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
58     };
59 #else
60 
61     // - tuple forward declaration -----------------------------------------------
62     template <
63       std::size_t T0 = 0, std::size_t T1 = 0, std::size_t T2 = 0,
64       std::size_t T3 = 0, std::size_t T4 = 0, std::size_t T5 = 0,
65       std::size_t T6 = 0, std::size_t T7 = 0, std::size_t T8 = 0,
66       std::size_t T9 = 0>
67     class tuple_indices {};
68 
69     template <std::size_t Sp, class IntTuple, std::size_t Ep>
70     struct make_indices_imp;
71 
72     template <std::size_t Sp, std::size_t Ep>
73     struct make_indices_imp<Sp, tuple_indices<>, Ep>
74     {
75       typedef typename make_indices_imp<Sp+1, tuple_indices<Sp>, Ep>::type type;
76     };
77     template <std::size_t Sp, std::size_t I0, std::size_t Ep>
78     struct make_indices_imp<Sp, tuple_indices<I0>, Ep>
79     {
80       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, Sp>, Ep>::type type;
81     };
82     template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t Ep>
83     struct make_indices_imp<Sp, tuple_indices<I0, I1>, Ep>
84     {
85       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, Sp>, Ep>::type type;
86     };
87     template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t Ep>
88     struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2>, Ep>
89     {
90       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, Sp>, Ep>::type type;
91     };
92     template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t Ep>
93     struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3>, Ep>
94     {
95       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, Sp>, Ep>::type type;
96     };
97     template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t Ep>
98     struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4>, Ep>
99     {
100       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, Sp>, Ep>::type type;
101     };
102     template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5, std::size_t Ep>
103     struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5>, Ep>
104     {
105       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, Sp>, Ep>::type type;
106     };
107     template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
108     , std::size_t I6
109     , std::size_t Ep>
110     struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6>, Ep>
111     {
112       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, Sp>, Ep>::type type;
113     };
114     template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
115     , std::size_t I6
116     , std::size_t I7
117     , std::size_t Ep>
118     struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7>, Ep>
119     {
120       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, Sp>, Ep>::type type;
121     };
122     template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
123     , std::size_t I6
124     , std::size_t I7
125     , std::size_t I8
126     , std::size_t Ep>
127     struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7, I8>, Ep>
128     {
129       typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, Sp>, Ep>::type type;
130     };
131 //    template <std::size_t Sp, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
132 //    , std::size_t I6
133 //    , std::size_t I7
134 //    , std::size_t I8
135 //    , std::size_t I9
136 //    , std::size_t Ep>
137 //    struct make_indices_imp<Sp, tuple_indices<I0, I1 , I2, I3, I4, I5, I6, I7, I8, I9>, Ep>
138 //    {
139 //      typedef typename make_indices_imp<Sp+1, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, Sp>, Ep>::type type;
140 //    };
141 
142     template <std::size_t Ep>
143     struct make_indices_imp<Ep, tuple_indices<>, Ep>
144     {
145       typedef tuple_indices<> type;
146     };
147     template <std::size_t Ep, std::size_t I0>
148     struct make_indices_imp<Ep, tuple_indices<I0>, Ep>
149     {
150       typedef tuple_indices<I0> type;
151     };
152     template <std::size_t Ep, std::size_t I0, std::size_t I1>
153     struct make_indices_imp<Ep, tuple_indices<I0, I1>, Ep>
154     {
155       typedef tuple_indices<I0, I1> type;
156     };
157     template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2>
158     struct make_indices_imp<Ep, tuple_indices<I0, I1, I2>, Ep>
159     {
160       typedef tuple_indices<I0, I1, I2> type;
161     };
162     template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3>
163     struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3>, Ep>
164     {
165       typedef tuple_indices<I0, I1, I2, I3> type;
166     };
167     template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4>
168     struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4>, Ep>
169     {
170       typedef tuple_indices<I0, I1, I2, I3, I4> type;
171     };
172     template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5>
173     struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5>, Ep>
174     {
175       typedef tuple_indices<I0, I1, I2, I3, I4, I5> type;
176     };
177     template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
178     , std::size_t I6
179     >
180     struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6>, Ep>
181     {
182       typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6> type;
183     };
184     template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
185     , std::size_t I6
186     , std::size_t I7
187     >
188     struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7>, Ep>
189     {
190       typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7> type;
191     };
192     template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
193     , std::size_t I6
194     , std::size_t I7
195     , std::size_t I8
196     >
197     struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8>, Ep>
198     {
199       typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8> type;
200     };
201 
202     template <std::size_t Ep, std::size_t I0, std::size_t I1, std::size_t I2, std::size_t I3, std::size_t I4, std::size_t I5
203     , std::size_t I6
204     , std::size_t I7
205     , std::size_t I8
206     , std::size_t I9
207     >
208     struct make_indices_imp<Ep, tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9>, Ep>
209     {
210       typedef tuple_indices<I0, I1, I2, I3, I4, I5, I6, I7, I8, I9> type;
211     };
212 
213     template <std::size_t Ep, std::size_t Sp = 0>
214     struct make_tuple_indices
215     {
216       BOOST_STATIC_ASSERT_MSG(Sp <= Ep, "make_tuple_indices input error");
217       typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
218     };
219 
220 #endif
221   }
222 }
223 
224 #endif // header
225