From patchwork Mon Jan 11 16:48:11 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 566036 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 761661402D9 for ; Tue, 12 Jan 2016 03:48:35 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=LJXRNb5t; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=vi1snhfmxqIXtOs2AQkt6/JVOJG7bSV4pEbesp6EriUvWmGTnoyEz Dqt5WdgJ8bo4gKpxGK/rp+tEIuDy6y+arOmD4DC9OtWjGadkNzlnEbjZtb+n/Iv5 AduS7kxVNjWlcAlYmAFxEb8jWY35qAhKTfxGATArbEhHFW5HLRSP0M= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=Yq83lp5OUrFgW8xiDGec/aVyW7k=; b=LJXRNb5thSKXrYaI2zEM HlK76gjI9kj2iosmzAmrzqtfV5boysoG5ThUVBZpGB/P6OlFByF6U2Mc9p+UUAvX bXW86OmkBOKmj+dezqc/PUapHGzQz0l/UcZPrqahy3rjnwnjqcL00Vh+mtUu+2yo gODTSYG7SZp43vhTy51faGY= Received: (qmail 44251 invoked by alias); 11 Jan 2016 16:48:28 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 44233 invoked by uid 89); 11 Jan 2016 16:48:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=@return, @param, __a, __p X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Mon, 11 Jan 2016 16:48:16 +0000 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (Postfix) with ESMTPS id 7F72FA37FC; Mon, 11 Jan 2016 16:48:12 +0000 (UTC) Received: from localhost (ovpn-116-38.ams2.redhat.com [10.36.116.38]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u0BGmB5a011069; Mon, 11 Jan 2016 11:48:12 -0500 Date: Mon, 11 Jan 2016 16:48:11 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [patch] libstdc++/60976 allocator_traits> partial specialization Message-ID: <20160111164811.GT30323@redhat.com> MIME-Version: 1.0 Content-Disposition: inline X-Clacks-Overhead: GNU Terry Pratchett User-Agent: Mutt/1.5.24 (2015-08-30) This adds a specialization of std::allocator_traits> 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 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 Date: Mon Jan 11 14:29:07 2016 +0000 allocator_traits> partial specialization PR libstdc++/60976 * include/bits/alloc_traits.h (allocator_traits>): 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 + template 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 + struct allocator_traits> + { + /// 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 + using rebind_alloc = allocator<_Up>; + + template + using rebind_traits = allocator_traits>; + + /** + * @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 a.allocate(n, hint) + */ + 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 a.deallocate(p, n) + */ + 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 __a.construct(__p, std::forward(__args)...) + */ + template + 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 + 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 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 + void construct(_Up* __p, _Args&&... __args) + { ::new(__p) _Up(std::forward<_Args>(__args)...); } + + template + void destroy(_Up* __p) + { __p->~_Up(); } + static char storage[sizeof(spcd)]; static bool allocated; };