@@ -128,6 +128,369 @@ class bad_alloc : public exception {
128128 bad_alloc &operator =(const bad_alloc &) noexcept ;
129129 virtual const char *what () const noexcept ;
130130};
131+
132+ template <typename T1>
133+ struct allocator {
134+ using value_type = T1;
135+ using size_type = std::size_t ;
136+ using difference_type = std::ptrdiff_t ;
137+ using propagate_on_container_move_assignment = std::true_type;
138+ using is_always_equal = std::true_type;
139+
140+ using pointer = T1*; // deprecated since C++17
141+ using const_pointer = const T1*; // deprecated since C++17
142+ using reference = T1&; // deprecated since C++17
143+ using const_reference = const T1&; // deprecated since C++17
144+
145+ // deprecated since C++17
146+ template <typename T2>
147+ struct rebind {
148+ using other = allocator<T2>;
149+ };
150+
151+ constexpr allocator () noexcept = default;
152+ constexpr allocator (const allocator&) noexcept = default;
153+
154+ template <typename T2>
155+ constexpr allocator (const allocator<T2>&) noexcept ;
156+
157+ ~allocator () = default ;
158+
159+ allocator& operator =(const allocator&) = default ;
160+
161+ T1* allocate (std::size_t );
162+ void deallocate (T1*, std::size_t );
163+
164+ T1* address (T1&) const noexcept ; // deprecated since C++17
165+ const T1* address (const T1&) const noexcept ; // deprecated since C++17
166+ std::size_t max_size () const noexcept ; // deprecated since C++17
167+
168+ // deprecated since C++17
169+ template <typename T2, typename ... T3>
170+ void construct (T2*, T3&&...);
171+
172+ // deprecated since C++17
173+ template <typename T2>
174+ void destroy (T2*);
175+ };
176+
177+ // deprecated since C++17
178+ template <>
179+ struct allocator <void > {
180+ using value_type = void ;
181+ using size_type = std::size_t ;
182+ using difference_type = std::ptrdiff_t ;
183+ using propagate_on_container_move_assignment = std::true_type;
184+ using is_always_equal = std::true_type;
185+
186+ // deprecated since C++17
187+ template <typename T1>
188+ struct rebind {
189+ using other = allocator<T1>;
190+ };
191+ };
192+
193+ template <typename T1, typename T2>
194+ constexpr bool operator ==(const allocator<T1>&, const allocator<T2>&) noexcept ;
195+
196+ template <typename T1, typename T2>
197+ constexpr bool operator !=(const allocator<T1>&, const allocator<T2>&) noexcept ;
198+
199+ namespace detail {
200+
201+ template <typename T1, typename = void >
202+ struct has_pointer : std::false_type {};
203+
204+ template <typename T1>
205+ struct has_pointer <T1, std::void_t <typename T1::pointer>> : std::true_type {};
206+
207+ template <typename T1, typename = void >
208+ struct has_const_pointer : std::false_type {};
209+
210+ template <typename T1>
211+ struct has_const_pointer <T1, std::void_t <typename T1::const_pointer>> : std::true_type {};
212+
213+ template <typename T1, typename = void >
214+ struct has_void_pointer : std::false_type {};
215+
216+ template <typename T1>
217+ struct has_void_pointer <T1, std::void_t <typename T1::void_pointer>> : std::true_type {};
218+
219+ template <typename T1, typename = void >
220+ struct has_const_void_pointer : std::false_type {};
221+
222+ template <typename T1>
223+ struct has_const_void_pointer <T1, std::void_t <typename T1::const_void_pointer>> : std::true_type {};
224+
225+ template <typename T1, typename = void >
226+ struct has_difference_type : std::false_type {};
227+
228+ template <typename T1>
229+ struct has_difference_type <T1, std::void_t <typename T1::difference_type>> : std::true_type {};
230+
231+ template <typename T1, typename = void >
232+ struct has_size_type : std::false_type {};
233+
234+ template <typename T1>
235+ struct has_size_type <T1, std::void_t <typename T1::size_type>> : std::true_type {};
236+
237+ template <typename T1, typename = void >
238+ struct has_propagate_on_container_copy_assignment : std::false_type {};
239+
240+ template <typename T1>
241+ struct has_propagate_on_container_copy_assignment <T1,
242+ std::void_t <typename T1::propagate_on_container_copy_assignment>> : std::true_type {};
243+
244+ template <typename T1, typename = void >
245+ struct has_propagate_on_container_move_assignment : std::false_type {};
246+
247+ template <typename T1>
248+ struct has_propagate_on_container_move_assignment <T1,
249+ std::void_t <typename T1::propagate_on_container_move_assignment>> : std::true_type {};
250+
251+ template <typename T1, typename = void >
252+ struct has_propagate_on_container_swap : std::false_type {};
253+
254+ template <typename T1>
255+ struct has_propagate_on_container_swap <T1,
256+ std::void_t <typename T1::propagate_on_container_swap>> : std::true_type {};
257+
258+ template <typename T1, typename = void >
259+ struct has_is_always_equal : std::false_type {};
260+
261+ template <typename T1>
262+ struct has_is_always_equal <T1, std::void_t <typename T1::is_always_equal>> : std::true_type {};
263+
264+ template <typename T1, typename T2, typename = void >
265+ struct has_rebind_alloc : std::false_type {};
266+
267+ template <typename T1, typename T2>
268+ struct has_rebind_alloc <T1, T2,
269+ std::void_t <typename T1::template rebind<T2>::other>> : std::true_type {};
270+
271+ template <typename T1, typename T2, bool = has_rebind_alloc<T1, T2>::value>
272+ struct rebind_alloc_helper ;
273+
274+ template <typename T1, typename T2>
275+ struct rebind_alloc_helper <T1, T2, true > {
276+ using type = typename T1::template rebind<T2>::other;
277+ };
278+
279+ template <template <typename , typename ...> class T1 , typename T2, typename T3, typename ... T4>
280+ struct rebind_alloc_helper <T1<T2, T4...>, T3, false > {
281+ using type = T1<T3, T4...>;
282+ };
283+
284+ }
285+
286+ template <typename T1>
287+ struct allocator_traits {
288+ using allocator_type = T1;
289+ using value_type = typename T1::value_type;
290+
291+ using pointer = typename std::conditional<
292+ detail::has_pointer<T1>::value,
293+ typename T1::pointer,
294+ value_type*
295+ >::type;
296+
297+ using const_pointer = typename std::conditional<
298+ detail::has_const_pointer<T1>::value,
299+ typename T1::const_pointer,
300+ typename std::pointer_traits<pointer>::template rebind<const value_type>
301+ >::type;
302+
303+ using void_pointer = typename std::conditional<
304+ detail::has_void_pointer<T1>::value,
305+ typename T1::void_pointer,
306+ typename std::pointer_traits<pointer>::template rebind<void >
307+ >::type;
308+
309+ using const_void_pointer = typename std::conditional<
310+ detail::has_const_void_pointer<T1>::value,
311+ typename T1::const_void_pointer,
312+ typename std::pointer_traits<pointer>::template rebind<const void >
313+ >::type;
314+
315+ using difference_type = typename std::conditional<
316+ detail::has_difference_type<T1>::value,
317+ typename T1::difference_type,
318+ typename std::pointer_traits<pointer>::difference_type
319+ >::type;
320+
321+ using size_type = typename std::conditional<
322+ detail::has_size_type<T1>::value,
323+ typename T1::size_type,
324+ typename std::make_unsigned<difference_type>::type
325+ >::type;
326+
327+ using propagate_on_container_copy_assignment = typename std::conditional<
328+ detail::has_propagate_on_container_copy_assignment<T1>::value,
329+ typename T1::propagate_on_container_copy_assignment,
330+ std::false_type
331+ >::type;
332+
333+ using propagate_on_container_move_assignment = typename std::conditional<
334+ detail::has_propagate_on_container_move_assignment<T1>::value,
335+ typename T1::propagate_on_container_move_assignment,
336+ std::false_type
337+ >::type;
338+
339+ using propagate_on_container_swap = typename std::conditional<
340+ detail::has_propagate_on_container_swap<T1>::value,
341+ typename T1::propagate_on_container_swap,
342+ std::false_type
343+ >::type;
344+
345+ using is_always_equal = typename std::conditional<
346+ detail::has_is_always_equal<T1>::value,
347+ typename T1::is_always_equal,
348+ typename std::is_empty<T1>::type
349+ >::type;
350+
351+ template <typename T2>
352+ using rebind_alloc = typename detail::rebind_alloc_helper<T1, T2>::type;
353+
354+ template <typename T2>
355+ using rebind_traits = allocator_traits<rebind_alloc<T2>>;
356+
357+ static pointer allocate (T1&, size_type);
358+ static pointer allocate (T1&, size_type, const_void_pointer);
359+ static void deallocate (T1&, pointer, size_type);
360+
361+ template <typename T2, typename ... T3>
362+ static void construct (T1&, T2*, T3&&...);
363+
364+ template <typename T2>
365+ static void destroy (T1&, T2*);
366+
367+ static size_type max_size (const T1&) noexcept ;
368+ static T1 select_on_container_copy_construction (const T1&);
369+ };
370+
371+ template <typename T1, typename ... T2>
372+ class scoped_allocator_adaptor : public T1 {
373+ public:
374+ using outer_allocator_type = T1;
375+ using inner_allocator_type = typename std::conditional<
376+ sizeof ...(T2) == 0 ,
377+ scoped_allocator_adaptor<T1>,
378+ scoped_allocator_adaptor<T2...>
379+ >::type;
380+
381+ using value_type = typename allocator_traits<T1>::value_type;
382+ using size_type = typename allocator_traits<T1>::size_type;
383+ using difference_type = typename allocator_traits<T1>::difference_type;
384+ using pointer = typename allocator_traits<T1>::pointer;
385+ using const_pointer = typename allocator_traits<T1>::const_pointer;
386+ using void_pointer = typename allocator_traits<T1>::void_pointer;
387+ using const_void_pointer = typename allocator_traits<T1>::const_void_pointer;
388+
389+ using propagate_on_container_copy_assignment = typename std::conditional<
390+ allocator_traits<T1>::propagate_on_container_copy_assignment::value ||
391+ (allocator_traits<T2>::propagate_on_container_copy_assignment::value || ...),
392+ std::true_type,
393+ std::false_type
394+ >::type;
395+
396+ using propagate_on_container_move_assignment = typename std::conditional<
397+ allocator_traits<T1>::propagate_on_container_move_assignment::value ||
398+ (allocator_traits<T2>::propagate_on_container_move_assignment::value || ...),
399+ std::true_type,
400+ std::false_type
401+ >::type;
402+
403+ using propagate_on_container_swap = typename std::conditional<
404+ allocator_traits<T1>::propagate_on_container_swap::value ||
405+ (allocator_traits<T2>::propagate_on_container_swap::value || ...),
406+ std::true_type,
407+ std::false_type
408+ >::type;
409+
410+ using is_always_equal = typename std::conditional<
411+ allocator_traits<T1>::is_always_equal::value &&
412+ (allocator_traits<T2>::is_always_equal::value && ...),
413+ std::true_type,
414+ std::false_type
415+ >::type;
416+
417+ template <typename T3>
418+ struct rebind {
419+ using other = scoped_allocator_adaptor<
420+ typename allocator_traits<T1>::template rebind_alloc<T3>,
421+ T2...
422+ >;
423+ };
424+
425+ scoped_allocator_adaptor ();
426+
427+ template <typename T3>
428+ scoped_allocator_adaptor (T3&&, const T2&...) noexcept ;
429+
430+ scoped_allocator_adaptor (const scoped_allocator_adaptor&) noexcept ;
431+ scoped_allocator_adaptor (scoped_allocator_adaptor&&) noexcept ;
432+
433+ template <typename T3, typename ... T4>
434+ scoped_allocator_adaptor (const scoped_allocator_adaptor<T3, T4...>&) noexcept ;
435+
436+ template <typename T3, typename ... T4>
437+ scoped_allocator_adaptor (scoped_allocator_adaptor<T3, T4...>&&) noexcept ;
438+
439+ scoped_allocator_adaptor& operator =(const scoped_allocator_adaptor&) = default ;
440+ scoped_allocator_adaptor& operator =(scoped_allocator_adaptor&&) = default ;
441+
442+ ~scoped_allocator_adaptor () = default ;
443+
444+ inner_allocator_type& inner_allocator () noexcept ;
445+ const inner_allocator_type& inner_allocator () const noexcept ;
446+
447+ outer_allocator_type& outer_allocator () noexcept ;
448+ const outer_allocator_type& outer_allocator () const noexcept ;
449+
450+ pointer allocate (size_type);
451+ pointer allocate (size_type, const_void_pointer);
452+ void deallocate (pointer, size_type);
453+
454+ size_type max_size () const ;
455+
456+ template <typename T3, typename ... T4>
457+ void construct (T3*, T4&&...);
458+
459+ template <typename T3, typename T4, typename ... T5, typename ... T6>
460+ void construct (std::pair<T3, T4>*,
461+ std::piecewise_construct_t ,
462+ std::tuple<T5...>,
463+ std::tuple<T6...>);
464+
465+ template <typename T3, typename T4>
466+ void construct (std::pair<T3, T4>*);
467+
468+ template <typename T3, typename T4, typename T5, typename T6>
469+ void construct (std::pair<T3, T4>*, T5&&, T6&&);
470+
471+ template <typename T3, typename T4, typename T5, typename T6>
472+ void construct (std::pair<T3, T4>*, const std::pair<T5, T6>&);
473+
474+ template <typename T3, typename T4, typename T5, typename T6>
475+ void construct (std::pair<T3, T4>*, std::pair<T5, T6>&&);
476+
477+ template <typename T3>
478+ void destroy (T3*);
479+
480+ scoped_allocator_adaptor select_on_container_copy_construction () const ;
481+
482+ private:
483+ inner_allocator_type inner_;
484+ };
485+
486+ template <typename T1, typename ... T2, typename T3, typename ... T4>
487+ bool operator ==(const scoped_allocator_adaptor<T1, T2...>&,
488+ const scoped_allocator_adaptor<T3, T4...>&) noexcept ;
489+
490+ template <typename T1, typename ... T2, typename T3, typename ... T4>
491+ bool operator !=(const scoped_allocator_adaptor<T1, T2...>&,
492+ const scoped_allocator_adaptor<T3, T4...>&) noexcept ;
493+
131494} // namespace std
132495
133- #endif // _GHLIBCPP_MEMORY
496+ #endif // _GHLIBCPP_MEMORY
0 commit comments