This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] libstdc++/60976 allocator_traits<allocator<T>> partial specialization


This adds a specialization of std::allocator_traits<std::allocator<T>>
in order to avoid doing all the heavy SFINAE work to detect which
members are present in the allocator. We don't need to check for them
because we know the exact properties of std::allocator<T> so can just
hard-code them.

This helps reduce some of the increased compilation time due to the
C++11 allocator support, but we're still slower than 4.8 (which might
be unavoidable).

Tested x86_64-linux, committed to trunk.
commit e2405ae375e28ca1c73c2f3fd138e63ffabf610d
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Mon Jan 11 14:29:07 2016 +0000

    allocator_traits<allocator<T>> partial specialization
    
    	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.

diff --git a/libstdc++-v3/include/bits/alloc_traits.h b/libstdc++-v3/include/bits/alloc_traits.h
index 8abd02f..d2d13c6 100644
--- a/libstdc++-v3/include/bits/alloc_traits.h
+++ b/libstdc++-v3/include/bits/alloc_traits.h
@@ -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)
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58659.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58659.cc
index 1509fdd..2dc3b0c 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58659.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/58659.cc
@@ -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;
     };

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]