1 //////////////////////////////////////////////////////////////////////////////
2 //
3 // (C) Copyright Ion Gaztanaga 2017-2017. Distributed under the Boost
4 // Software License, Version 1.0. (See accompanying file
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 //////////////////////////////////////////////////////////////////////////////
10 #ifndef BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
11 #define BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
12 
13 #ifndef BOOST_CONFIG_HPP
14 #  include <boost/config.hpp>
15 #endif
16 
17 #if defined(BOOST_HAS_PRAGMA_ONCE)
18 #  pragma once
19 #endif
20 
21 #include <boost/container/allocator_traits.hpp>
22 
23 
24 namespace boost {
25 namespace container {
26 namespace dtl {
27 
28    template <class Cont, class U>
29    struct container_rebind;
30 
31 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
32 
33    template <template <class, class, class...> class Cont, typename V, typename A, class... An, class U>
34    struct container_rebind<Cont<V, A, An...>, U>
35    {
36       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, An...> type;
37    };
38 
39    //Needed for non-conforming compilers like GCC 4.3
40    template <template <class, class> class Cont, typename V, typename A, class U>
41    struct container_rebind<Cont<V, A>, U>
42    {
43       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
44    };
45 
46    template <template <class> class Cont, typename V, class U>
47    struct container_rebind<Cont<V>, U>
48    {
49       typedef Cont<U> type;
50    };
51 
52    //for small_vector,static_vector
53 
54    template <template <class, std::size_t, class, class...> class Cont, typename V, std::size_t N, typename A, class... An, class U>
55    struct container_rebind<Cont<V, N, A, An...>, U>
56    {
57       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, An...> type;
58    };
59 
60    //Needed for non-conforming compilers like GCC 4.3
61    template <template <class, std::size_t, class> class Cont, typename V, std::size_t N, typename A, class U>
62    struct container_rebind<Cont<V, N, A>, U>
63    {
64       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
65    };
66 
67    template <template <class, std::size_t> class Cont, typename V, std::size_t N, class U>
68    struct container_rebind<Cont<V, N>, U>
69    {
70       typedef Cont<U, N> type;
71    };
72 
73 #else //C++03 compilers
74 
75    template <template <class> class Cont  //0arg
76       , typename V
77       , class U>
78       struct container_rebind<Cont<V>, U>
79    {
80       typedef Cont<U> type;
81    };
82 
83    template <template <class, class> class Cont  //0arg
84       , typename V, typename A
85       , class U>
86       struct container_rebind<Cont<V, A>, U>
87    {
88       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
89    };
90 
91    template <template <class, class, class> class Cont  //1arg
92       , typename V, typename A, class P0
93       , class U>
94       struct container_rebind<Cont<V, A, P0>, U>
95    {
96       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0> type;
97    };
98 
99    template <template <class, class, class, class> class Cont  //2arg
100       , typename V, typename A, class P0, class P1
101       , class U>
102       struct container_rebind<Cont<V, A, P0, P1>, U>
103    {
104       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1> type;
105    };
106 
107    template <template <class, class, class, class, class> class Cont  //3arg
108       , typename V, typename A, class P0, class P1, class P2
109       , class U>
110       struct container_rebind<Cont<V, A, P0, P1, P2>, U>
111    {
112       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2> type;
113    };
114 
115    template <template <class, class, class, class, class, class> class Cont  //4arg
116       , typename V, typename A, class P0, class P1, class P2, class P3
117       , class U>
118       struct container_rebind<Cont<V, A, P0, P1, P2, P3>, U>
119    {
120       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type;
121    };
122 
123    template <template <class, class, class, class, class, class, class> class Cont  //5arg
124       , typename V, typename A, class P0, class P1, class P2, class P3, class P4
125       , class U>
126       struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4>, U>
127    {
128       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type;
129    };
130 
131    template <template <class, class, class, class, class, class, class, class> class Cont  //6arg
132       , typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5
133       , class U>
134       struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5>, U>
135    {
136       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type;
137    };
138 
139    template <template <class, class, class, class, class, class, class, class, class> class Cont  //7arg
140       , typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
141       , class U>
142       struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6>, U>
143    {
144       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type;
145    };
146 
147    template <template <class, class, class, class, class, class, class, class, class, class> class Cont  //8arg
148       , typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
149       , class U>
150       struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7>, U>
151    {
152       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type;
153    };
154 
155    template <template <class, class, class, class, class, class, class, class, class, class, class> class Cont  //9arg
156       , typename V, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
157       , class U>
158       struct container_rebind<Cont<V, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U>
159    {
160       typedef Cont<U, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type;
161    };
162 
163    //For small_vector/static_vector
164    template <template <class, std::size_t> class Cont  //0arg
165       , typename V, std::size_t N
166       , class U>
167       struct container_rebind<Cont<V, N>, U>
168    {
169       typedef Cont<U, N> type;
170    };
171 
172    template <template <class, std::size_t, class> class Cont  //0arg
173       , typename V, std::size_t N, typename A
174       , class U>
175       struct container_rebind<Cont<V, N, A>, U>
176    {
177       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type> type;
178    };
179 
180    template <template <class, std::size_t, class, class> class Cont  //1arg
181       , typename V, std::size_t N, typename A, class P0
182       , class U>
183       struct container_rebind<Cont<V, N, A, P0>, U>
184    {
185       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0> type;
186    };
187 
188    template <template <class, std::size_t, class, class, class> class Cont  //2arg
189       , typename V, std::size_t N, typename A, class P0, class P1
190       , class U>
191       struct container_rebind<Cont<V, N, A, P0, P1>, U>
192    {
193       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1> type;
194    };
195 
196    template <template <class, std::size_t, class, class, class, class> class Cont  //3arg
197       , typename V, std::size_t N, typename A, class P0, class P1, class P2
198       , class U>
199       struct container_rebind<Cont<V, N, A, P0, P1, P2>, U>
200    {
201       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2> type;
202    };
203 
204    template <template <class, std::size_t, class, class, class, class, class> class Cont  //4arg
205       , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3
206       , class U>
207       struct container_rebind<Cont<V, N, A, P0, P1, P2, P3>, U>
208    {
209       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3> type;
210    };
211 
212    template <template <class, std::size_t, class, class, class, class, class, class> class Cont  //5arg
213       , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4
214       , class U>
215       struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4>, U>
216    {
217       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4> type;
218    };
219 
220    template <template <class, std::size_t, class, class, class, class, class, class, class> class Cont  //6arg
221       , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5
222       , class U>
223       struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5>, U>
224    {
225       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5> type;
226    };
227 
228    template <template <class, std::size_t, class, class, class, class, class, class, class, class> class Cont  //7arg
229       , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6
230       , class U>
231       struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6>, U>
232    {
233       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6> type;
234    };
235 
236    template <template <class, std::size_t, class, class, class, class, class, class, class, class, class> class Cont  //8arg
237       , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7
238       , class U>
239       struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6, P7>, U>
240    {
241       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7> type;
242    };
243 
244    template <template <class, std::size_t, class, class, class, class, class, class, class, class, class, class> class Cont  //9arg
245       , typename V, std::size_t N, typename A, class P0, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8
246       , class U>
247       struct container_rebind<Cont<V, N, A, P0, P1, P2, P3, P4, P5, P6, P7, P8>, U>
248    {
249       typedef Cont<U, N, typename allocator_traits<A>::template portable_rebind_alloc<U>::type, P0, P1, P2, P3, P4, P5, P6, P7, P8> type;
250    };
251 
252 #endif   //!defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
253 
254 }  //namespace dtl {
255 }  //namespace container {
256 }  //namespace boost {
257 
258 #endif   //#ifndef BOOST_CONTAINER_DETAIL_CONTAINER_REBIND_HPP
259