1e4b17023SJohn Marino // Allocator traits -*- C++ -*- 2e4b17023SJohn Marino 3e4b17023SJohn Marino // Copyright (C) 2011, 2012 Free Software Foundation, Inc. 4e4b17023SJohn Marino // 5e4b17023SJohn Marino // This file is part of the GNU ISO C++ Library. This library is free 6e4b17023SJohn Marino // software; you can redistribute it and/or modify it under the 7e4b17023SJohn Marino // terms of the GNU General Public License as published by the 8e4b17023SJohn Marino // Free Software Foundation; either version 3, or (at your option) 9e4b17023SJohn Marino // any later version. 10e4b17023SJohn Marino 11e4b17023SJohn Marino // This library is distributed in the hope that it will be useful, 12e4b17023SJohn Marino // but WITHOUT ANY WARRANTY; without even the implied warranty of 13e4b17023SJohn Marino // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14e4b17023SJohn Marino // GNU General Public License for more details. 15e4b17023SJohn Marino 16e4b17023SJohn Marino // Under Section 7 of GPL version 3, you are granted additional 17e4b17023SJohn Marino // permissions described in the GCC Runtime Library Exception, version 18e4b17023SJohn Marino // 3.1, as published by the Free Software Foundation. 19e4b17023SJohn Marino 20e4b17023SJohn Marino // You should have received a copy of the GNU General Public License and 21e4b17023SJohn Marino // a copy of the GCC Runtime Library Exception along with this program; 22e4b17023SJohn Marino // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 23e4b17023SJohn Marino // <http://www.gnu.org/licenses/>. 24e4b17023SJohn Marino 25e4b17023SJohn Marino /** @file ext/alloc_traits.h 26e4b17023SJohn Marino * This file is a GNU extension to the Standard C++ Library. 27e4b17023SJohn Marino */ 28e4b17023SJohn Marino 29e4b17023SJohn Marino #ifndef _EXT_ALLOC_TRAITS_H 30e4b17023SJohn Marino #define _EXT_ALLOC_TRAITS_H 1 31e4b17023SJohn Marino 32e4b17023SJohn Marino #pragma GCC system_header 33e4b17023SJohn Marino 34e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 35*5ce9237cSJohn Marino # include <bits/move.h> 36e4b17023SJohn Marino # include <bits/alloc_traits.h> 37e4b17023SJohn Marino #else 38e4b17023SJohn Marino # include <bits/allocator.h> // for __alloc_swap 39e4b17023SJohn Marino #endif 40e4b17023SJohn Marino 41e4b17023SJohn Marino namespace std _GLIBCXX_VISIBILITY(default) 42e4b17023SJohn Marino { 43e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 44e4b17023SJohn Marino template<typename> struct allocator; 45e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 46e4b17023SJohn Marino } // namespace 47e4b17023SJohn Marino 48e4b17023SJohn Marino namespace __gnu_cxx _GLIBCXX_VISIBILITY(default) 49e4b17023SJohn Marino { 50e4b17023SJohn Marino _GLIBCXX_BEGIN_NAMESPACE_VERSION 51e4b17023SJohn Marino 52e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 53e4b17023SJohn Marino template<typename _Alloc> 54e4b17023SJohn Marino struct __allocator_always_compares_equal 55e4b17023SJohn Marino { static const bool value = false; }; 56e4b17023SJohn Marino 57e4b17023SJohn Marino template<typename _Alloc> 58e4b17023SJohn Marino const bool __allocator_always_compares_equal<_Alloc>::value; 59e4b17023SJohn Marino 60e4b17023SJohn Marino template<typename _Tp> 61e4b17023SJohn Marino struct __allocator_always_compares_equal<std::allocator<_Tp>> 62e4b17023SJohn Marino { static const bool value = true; }; 63e4b17023SJohn Marino 64e4b17023SJohn Marino template<typename _Tp> 65e4b17023SJohn Marino const bool __allocator_always_compares_equal<std::allocator<_Tp>>::value; 66e4b17023SJohn Marino 67e4b17023SJohn Marino template<typename, typename> struct array_allocator; 68e4b17023SJohn Marino 69e4b17023SJohn Marino template<typename _Tp, typename _Array> 70e4b17023SJohn Marino struct __allocator_always_compares_equal<array_allocator<_Tp, _Array>> 71e4b17023SJohn Marino { static const bool value = true; }; 72e4b17023SJohn Marino 73e4b17023SJohn Marino template<typename _Tp, typename _Array> 74e4b17023SJohn Marino const bool 75e4b17023SJohn Marino __allocator_always_compares_equal<array_allocator<_Tp, _Array>>::value; 76e4b17023SJohn Marino 77e4b17023SJohn Marino template<typename> struct mt_allocator; 78e4b17023SJohn Marino 79e4b17023SJohn Marino template<typename _Tp> 80e4b17023SJohn Marino struct __allocator_always_compares_equal<mt_allocator<_Tp>> 81e4b17023SJohn Marino { static const bool value = true; }; 82e4b17023SJohn Marino 83e4b17023SJohn Marino template<typename _Tp> 84e4b17023SJohn Marino const bool __allocator_always_compares_equal<mt_allocator<_Tp>>::value; 85e4b17023SJohn Marino 86e4b17023SJohn Marino template<typename> struct new_allocator; 87e4b17023SJohn Marino 88e4b17023SJohn Marino template<typename _Tp> 89e4b17023SJohn Marino struct __allocator_always_compares_equal<new_allocator<_Tp>> 90e4b17023SJohn Marino { static const bool value = true; }; 91e4b17023SJohn Marino 92e4b17023SJohn Marino template<typename _Tp> 93e4b17023SJohn Marino const bool __allocator_always_compares_equal<new_allocator<_Tp>>::value; 94e4b17023SJohn Marino 95e4b17023SJohn Marino template<typename> struct pool_allocator; 96e4b17023SJohn Marino 97e4b17023SJohn Marino template<typename _Tp> 98e4b17023SJohn Marino struct __allocator_always_compares_equal<pool_allocator<_Tp>> 99e4b17023SJohn Marino { static const bool value = true; }; 100e4b17023SJohn Marino 101e4b17023SJohn Marino template<typename _Tp> 102e4b17023SJohn Marino const bool __allocator_always_compares_equal<pool_allocator<_Tp>>::value; 103e4b17023SJohn Marino #endif 104e4b17023SJohn Marino 105e4b17023SJohn Marino /** 106e4b17023SJohn Marino * @brief Uniform interface to C++98 and C++0x allocators. 107e4b17023SJohn Marino * @ingroup allocators 108e4b17023SJohn Marino */ 109e4b17023SJohn Marino template<typename _Alloc> 110e4b17023SJohn Marino struct __alloc_traits 111e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 112e4b17023SJohn Marino : std::allocator_traits<_Alloc> 113e4b17023SJohn Marino #endif 114e4b17023SJohn Marino { 115e4b17023SJohn Marino typedef _Alloc allocator_type; 116e4b17023SJohn Marino #ifdef __GXX_EXPERIMENTAL_CXX0X__ 117e4b17023SJohn Marino typedef std::allocator_traits<_Alloc> _Base_type; 118e4b17023SJohn Marino typedef typename _Base_type::value_type value_type; 119e4b17023SJohn Marino typedef typename _Base_type::pointer pointer; 120e4b17023SJohn Marino typedef typename _Base_type::const_pointer const_pointer; 121e4b17023SJohn Marino typedef typename _Base_type::size_type size_type; 122e4b17023SJohn Marino // C++0x allocators do not define reference or const_reference 123e4b17023SJohn Marino typedef value_type& reference; 124e4b17023SJohn Marino typedef const value_type& const_reference; 125e4b17023SJohn Marino using _Base_type::allocate; 126e4b17023SJohn Marino using _Base_type::deallocate; 127e4b17023SJohn Marino using _Base_type::construct; 128e4b17023SJohn Marino using _Base_type::destroy; 129e4b17023SJohn Marino using _Base_type::max_size; 130e4b17023SJohn Marino 131e4b17023SJohn Marino private: 132e4b17023SJohn Marino template<typename _Ptr> 133e4b17023SJohn Marino struct __is_custom_pointer 134e4b17023SJohn Marino : std::integral_constant<bool, std::is_same<pointer, _Ptr>::value 135e4b17023SJohn Marino && !std::is_pointer<_Ptr>::value> 136e4b17023SJohn Marino { }; 137e4b17023SJohn Marino 138e4b17023SJohn Marino public: 139e4b17023SJohn Marino // overload construct for non-standard pointer types 140e4b17023SJohn Marino template<typename _Ptr, typename... _Args> 141e4b17023SJohn Marino static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type 142e4b17023SJohn Marino construct(_Alloc& __a, _Ptr __p, _Args&&... __args) 143e4b17023SJohn Marino { 144e4b17023SJohn Marino _Base_type::construct(__a, std::addressof(*__p), 145e4b17023SJohn Marino std::forward<_Args>(__args)...); 146e4b17023SJohn Marino } 147e4b17023SJohn Marino 148e4b17023SJohn Marino // overload destroy for non-standard pointer types 149e4b17023SJohn Marino template<typename _Ptr> 150e4b17023SJohn Marino static typename std::enable_if<__is_custom_pointer<_Ptr>::value>::type 151e4b17023SJohn Marino destroy(_Alloc& __a, _Ptr __p) 152e4b17023SJohn Marino { _Base_type::destroy(__a, std::addressof(*__p)); } 153e4b17023SJohn Marino 154e4b17023SJohn Marino static _Alloc _S_select_on_copy(const _Alloc& __a) 155e4b17023SJohn Marino { return _Base_type::select_on_container_copy_construction(__a); } 156e4b17023SJohn Marino 157e4b17023SJohn Marino static void _S_on_swap(_Alloc& __a, _Alloc& __b) 158e4b17023SJohn Marino { std::__alloc_on_swap(__a, __b); } 159e4b17023SJohn Marino 160e4b17023SJohn Marino static constexpr bool _S_propagate_on_copy_assign() 161e4b17023SJohn Marino { return _Base_type::propagate_on_container_copy_assignment::value; } 162e4b17023SJohn Marino 163e4b17023SJohn Marino static constexpr bool _S_propagate_on_move_assign() 164e4b17023SJohn Marino { return _Base_type::propagate_on_container_move_assignment::value; } 165e4b17023SJohn Marino 166e4b17023SJohn Marino static constexpr bool _S_propagate_on_swap() 167e4b17023SJohn Marino { return _Base_type::propagate_on_container_swap::value; } 168e4b17023SJohn Marino 169e4b17023SJohn Marino static constexpr bool _S_always_equal() 170e4b17023SJohn Marino { return __allocator_always_compares_equal<_Alloc>::value; } 171e4b17023SJohn Marino 172e4b17023SJohn Marino static constexpr bool _S_nothrow_move() 173e4b17023SJohn Marino { return _S_propagate_on_move_assign() || _S_always_equal(); } 174e4b17023SJohn Marino 175e4b17023SJohn Marino static constexpr bool _S_nothrow_swap() 176e4b17023SJohn Marino { 177e4b17023SJohn Marino using std::swap; 178e4b17023SJohn Marino return !_S_propagate_on_swap() 179e4b17023SJohn Marino || noexcept(swap(std::declval<_Alloc&>(), std::declval<_Alloc&>())); 180e4b17023SJohn Marino } 181e4b17023SJohn Marino 182e4b17023SJohn Marino template<typename _Tp> 183e4b17023SJohn Marino struct rebind 184e4b17023SJohn Marino { typedef typename _Base_type::template rebind_alloc<_Tp> other; }; 185e4b17023SJohn Marino #else 186e4b17023SJohn Marino 187e4b17023SJohn Marino typedef typename _Alloc::pointer pointer; 188e4b17023SJohn Marino typedef typename _Alloc::const_pointer const_pointer; 189e4b17023SJohn Marino typedef typename _Alloc::value_type value_type; 190e4b17023SJohn Marino typedef typename _Alloc::reference reference; 191e4b17023SJohn Marino typedef typename _Alloc::const_reference const_reference; 192e4b17023SJohn Marino typedef typename _Alloc::size_type size_type; 193e4b17023SJohn Marino 194e4b17023SJohn Marino static pointer 195e4b17023SJohn Marino allocate(_Alloc& __a, size_type __n) 196e4b17023SJohn Marino { return __a.allocate(__n); } 197e4b17023SJohn Marino 198e4b17023SJohn Marino static void deallocate(_Alloc& __a, pointer __p, size_type __n) 199e4b17023SJohn Marino { __a.deallocate(__p, __n); } 200e4b17023SJohn Marino 201e4b17023SJohn Marino template<typename _Tp> 202e4b17023SJohn Marino static void construct(_Alloc& __a, pointer __p, const _Tp& __arg) 203e4b17023SJohn Marino { __a.construct(__p, __arg); } 204e4b17023SJohn Marino 205e4b17023SJohn Marino static void destroy(_Alloc& __a, pointer __p) 206e4b17023SJohn Marino { __a.destroy(__p); } 207e4b17023SJohn Marino 208e4b17023SJohn Marino static size_type max_size(const _Alloc& __a) 209e4b17023SJohn Marino { return __a.max_size(); } 210e4b17023SJohn Marino 211e4b17023SJohn Marino static const _Alloc& _S_select_on_copy(const _Alloc& __a) { return __a; } 212e4b17023SJohn Marino 213e4b17023SJohn Marino static void _S_on_swap(_Alloc& __a, _Alloc& __b) 214e4b17023SJohn Marino { 215e4b17023SJohn Marino // _GLIBCXX_RESOLVE_LIB_DEFECTS 216e4b17023SJohn Marino // 431. Swapping containers with unequal allocators. 217e4b17023SJohn Marino std::__alloc_swap<_Alloc>::_S_do_it(__a, __b); 218e4b17023SJohn Marino } 219e4b17023SJohn Marino 220e4b17023SJohn Marino template<typename _Tp> 221e4b17023SJohn Marino struct rebind 222e4b17023SJohn Marino { typedef typename _Alloc::template rebind<_Tp>::other other; }; 223e4b17023SJohn Marino #endif 224e4b17023SJohn Marino }; 225e4b17023SJohn Marino 226e4b17023SJohn Marino _GLIBCXX_END_NAMESPACE_VERSION 227e4b17023SJohn Marino } // namespace 228e4b17023SJohn Marino 229e4b17023SJohn Marino #endif 230