allocator_traits<allocator<T>> partial specialization
authorJonathan Wakely <jwakely@redhat.com>
Mon, 11 Jan 2016 16:47:58 +0000 (16:47 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 11 Jan 2016 16:47:58 +0000 (16:47 +0000)
PR libstdc++/60976
* include/bits/alloc_traits.h (allocator_traits<allocator<_Tp>>):
Define partial specialization.
* testsuite/20_util/shared_ptr/cons/58659.cc: Add construct and
destroy members to std::allocator explicit specialization.

From-SVN: r232232

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/alloc_traits.h
libstdc++-v3/testsuite/20_util/shared_ptr/cons/58659.cc

index e0cc2a6..ad4cdc3 100644 (file)
@@ -1,3 +1,11 @@
+2016-01-11  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/60976
+       * include/bits/alloc_traits.h (allocator_traits<allocator<_Tp>>):
+       Define partial specialization.
+       * testsuite/20_util/shared_ptr/cons/58659.cc: Add construct and
+       destroy members to std::allocator explicit specialization.
+
 2016-01-08  Jonathan Wakely  <jwakely@redhat.com>
 
        * testsuite/26_numerics/headers/cmath/
index 8abd02f..d2d13c6 100644 (file)
@@ -331,7 +331,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        *  Calls @c __a.destroy(__p) if that expression is well-formed,
        *  otherwise calls @c __p->~_Tp()
       */
-      template <class _Tp>
+      template<typename _Tp>
        static void destroy(_Alloc& __a, _Tp* __p)
        { _S_destroy(__a, __p, 0); }
 
@@ -359,6 +359,133 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       { return _S_select(__rhs, 0); }
     };
 
+  /// Partial specialization for std::allocator.
+  template<typename _Tp>
+    struct allocator_traits<allocator<_Tp>>
+    {
+      /// The allocator type
+      using allocator_type = allocator<_Tp>;
+      /// The allocated type
+      using value_type = _Tp;
+
+      /// The allocator's pointer type.
+      using pointer = _Tp*;
+
+      /// The allocator's const pointer type.
+      using const_pointer = const _Tp*;
+
+      /// The allocator's void pointer type.
+      using void_pointer = void*;
+
+      /// The allocator's const void pointer type.
+      using const_void_pointer = const void*;
+
+      /// The allocator's difference type
+      using difference_type = std::ptrdiff_t;
+
+      /// The allocator's size type
+      using size_type = std::size_t;
+
+      /// How the allocator is propagated on copy assignment
+      using propagate_on_container_copy_assignment = false_type;
+
+      /// How the allocator is propagated on move assignment
+      using propagate_on_container_move_assignment = true_type;
+
+      /// How the allocator is propagated on swap
+      using propagate_on_container_swap = false_type;
+
+      /// Whether all instances of the allocator type compare equal.
+      using is_always_equal = true_type;
+
+      template<typename _Up>
+       using rebind_alloc = allocator<_Up>;
+
+      template<typename _Up>
+       using rebind_traits = allocator_traits<allocator<_Up>>;
+
+      /**
+       *  @brief  Allocate memory.
+       *  @param  __a  An allocator.
+       *  @param  __n  The number of objects to allocate space for.
+       *
+       *  Calls @c a.allocate(n)
+      */
+      static pointer
+      allocate(allocator_type& __a, size_type __n)
+      { return __a.allocate(__n); }
+
+      /**
+       *  @brief  Allocate memory.
+       *  @param  __a  An allocator.
+       *  @param  __n  The number of objects to allocate space for.
+       *  @param  __hint Aid to locality.
+       *  @return Memory of suitable size and alignment for @a n objects
+       *          of type @c value_type
+       *
+       *  Returns <tt> a.allocate(n, hint) </tt>
+      */
+      static pointer
+      allocate(allocator_type& __a, size_type __n, const_void_pointer __hint)
+      { return __a.allocate(__n, __hint); }
+
+      /**
+       *  @brief  Deallocate memory.
+       *  @param  __a  An allocator.
+       *  @param  __p  Pointer to the memory to deallocate.
+       *  @param  __n  The number of objects space was allocated for.
+       *
+       *  Calls <tt> a.deallocate(p, n) </tt>
+      */
+      static void
+      deallocate(allocator_type& __a, pointer __p, size_type __n)
+      { __a.deallocate(__p, __n); }
+
+      /**
+       *  @brief  Construct an object of type @a _Up
+       *  @param  __a  An allocator.
+       *  @param  __p  Pointer to memory of suitable size and alignment for Tp
+       *  @param  __args Constructor arguments.
+       *
+       *  Calls <tt> __a.construct(__p, std::forward<Args>(__args)...) </tt>
+      */
+      template<typename _Up, typename... _Args>
+       static void
+       construct(allocator_type& __a, _Up* __p, _Args&&... __args)
+       { __a.construct(__p, std::forward<_Args>(__args)...); }
+
+      /**
+       *  @brief  Destroy an object of type @a _Up
+       *  @param  __a  An allocator.
+       *  @param  __p  Pointer to the object to destroy
+       *
+       *  Calls @c __a.destroy(__p).
+      */
+      template<typename _Up>
+       static void
+       destroy(allocator_type& __a, _Up* __p)
+       { __a.destroy(__p); }
+
+      /**
+       *  @brief  The maximum supported allocation size
+       *  @param  __a  An allocator.
+       *  @return @c __a.max_size()
+      */
+      static size_type
+      max_size(const allocator_type& __a) noexcept
+      { return __a.max_size(); }
+
+      /**
+       *  @brief  Obtain an allocator to use when copying a container.
+       *  @param  __rhs  An allocator.
+       *  @return @c __rhs
+      */
+      static allocator_type
+      select_on_container_copy_construction(const allocator_type& __rhs)
+      { return __rhs; }
+    };
+
+
   template<typename _Alloc>
     inline void
     __do_alloc_on_copy(_Alloc& __one, const _Alloc& __two, true_type)
index 1509fdd..2dc3b0c 100644 (file)
@@ -51,6 +51,14 @@ namespace std
         allocated = false;
       }
 
+      template<typename _Up, typename... _Args>
+        void construct(_Up* __p, _Args&&... __args)
+        { ::new(__p) _Up(std::forward<_Args>(__args)...); }
+
+      template<typename _Up>
+        void destroy(_Up* __p)
+        { __p->~_Up(); }
+
       static char storage[sizeof(spcd)];
       static bool allocated;
     };