From: Jonathan Wakely Date: Fri, 1 Sep 2017 12:15:44 +0000 (+0100) Subject: Make std::scoped_allocator_adaptor's OUTERMOST recursive X-Git-Tag: releases/gcc-5.5.0~92 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8656885d533a8542d83f3f49b84bc966d179b76b;p=thirdparty%2Fgcc.git Make std::scoped_allocator_adaptor's OUTERMOST recursive Backport from mainline 2016-10-06 Jonathan Wakely * doc/xml/manual/status_cxx2011.xml: Update status. * doc/html/manual/status.html: Regenerate. * include/std/scoped_allocator (__outer_allocator_t, __outermost_type): New helpers for recursive OUTERMOST. (__outermost): Use __outermost_type::_S_outermost. (__do_outermost, scoped_allocator_adaptor::__outermost_type): Remove. (scoped_allocator_adaptor::__outermost_alloc_traits): Use new __outermost_type helper. (scoped_allocator_adaptor::_Constructible): New alias template. (scoped_allocator_adaptor::scoped_allocator_adaptor<_Outer2>): Constrain template constructors. * testsuite/20_util/scoped_allocator/3.cc: New test. * testsuite/20_util/scoped_allocator/outermost.cc: New test. From-SVN: r251590 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 8ab39d7eb531..7f4febaade6f 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,22 @@ +2017-09-01 Jonathan Wakely + + Backport from mainline + 2016-10-06 Jonathan Wakely + + * doc/xml/manual/status_cxx2011.xml: Update status. + * doc/html/manual/status.html: Regenerate. + * include/std/scoped_allocator (__outer_allocator_t, __outermost_type): + New helpers for recursive OUTERMOST. + (__outermost): Use __outermost_type::_S_outermost. + (__do_outermost, scoped_allocator_adaptor::__outermost_type): Remove. + (scoped_allocator_adaptor::__outermost_alloc_traits): Use new + __outermost_type helper. + (scoped_allocator_adaptor::_Constructible): New alias template. + (scoped_allocator_adaptor::scoped_allocator_adaptor<_Outer2>): + Constrain template constructors. + * testsuite/20_util/scoped_allocator/3.cc: New test. + * testsuite/20_util/scoped_allocator/outermost.cc: New test. + 2017-06-16 Jonathan Wakely * include/bits/locale_conv.h (wbuffer_convert::sync): Fix condition. diff --git a/libstdc++-v3/doc/html/manual/status.html b/libstdc++-v3/doc/html/manual/status.html index f82a3c5c2063..46eb193f619b 100644 --- a/libstdc++-v3/doc/html/manual/status.html +++ b/libstdc++-v3/doc/html/manual/status.html @@ -172,7 +172,7 @@ This page describes the C++11 support in the GCC 5 series. 20.1General  20.2Utility components  20.2.1OperatorsY 20.2.2SwapY 20.2.3forward and move helpersY 20.2.4Function template declvalY 20.3Pairs  20.3.1In general  20.3.2Class template pairY 20.3.3Specialized algorithmsY 20.3.4Tuple-like access to pairY 20.3.5Piecewise constructionY 20.4Tuples  20.4.1In general  20.4.2Class template tuple  20.4.2.1ConstructionY 20.4.2.2AssignmentY 20.4.2.3SwapY 20.4.2.4Tuple creation functionsY 20.4.2.5Tuple helper classesY 20.4.2.6Element accessY 20.4.2.7Relational operatorsY 20.4.2.8Tuple traitsY 20.4.2.9Tuple specialized algorithmsY 20.5Class template bitsetY 20.5.1bitset constructorsY 20.5.2bitset membersY 20.5.3bitset hash supportY 20.5.4bitset operatorsY 20.6Memory  20.6.1In general  20.6.2Header <memory> synopsis  20.6.3Pointer traitsY 20.6.4Pointer safetyPartial 20.6.5AlignY 20.6.6Allocator argument tagY 20.6.7uses_allocatorY 20.6.8Allocator traitsY 20.6.9The default allocatorY 20.6.10Raw storage iteratorY 20.6.11Temporary buffersY 20.6.12Specialized algorithms  20.6.12.1addressofY 20.6.12.2uninitialized_copyY 20.6.12.3uninitialized_fillY 20.6.12.4uninitialized_fill_nY 20.6.13C libraryY 20.7Smart pointers  20.7.1Class template unique_ptrY 20.7.2Shared-ownership pointersY 20.7.2.1Class bad_weak_ptrY 20.7.2.2Class template shared_ptrY Uses code from boost::shared_ptr. - 20.7.2.3Class template weak_ptrY 20.7.2.4Class template emable_shared_from_thisY 20.7.2.5shared_ptr atomic accessY 20.7.2.6Smart pointer hash supportY 20.8Function objects  20.8.1Definitions  20.8.2Requirements  20.8.3Class template reference_wrapperY 20.8.4Arithmetic operationY 20.8.5ComparisonsY 20.8.6Logical operationsY 20.8.7Bitwise operationsY 20.8.8NegatorsY 20.8.9Function template bindY 20.8.10Function template mem_fnY 20.8.11Polymorphic function wrappers  20.8.11.1Class bad_function_callY 20.8.11.2Class template functionPartialMissing allocator support20.8.12Class template hashY 20.9Metaprogramming and type traits  20.9.1RequirementsY 20.9.2Header <type_traits> synopsis  20.9.3Helper classesY 20.9.4Unary Type TraitsY 20.9.4.1Primary type categoriesY 20.9.4.2Composite type traitsY 20.9.4.3Type propertiesY 20.9.5Type property queriesY 20.9.6Relationships between typesY 20.9.7Transformations between types  20.9.7.1Const-volatile modificationsY 20.9.7.2Reference modificationsY 20.9.7.3Sign modificationsY 20.9.7.4Array modificationsY 20.9.7.5Pointer modificationsY 20.9.7.6Other transformationsY 20.10Compile-time rational arithmetic  20.10.1In general  20.10.2Header <ratio> synopsis  20.10.3Class template ratioY 20.10.4Arithmetic on ratiosY 20.10.5Comparison of ratiosY 20.10.6SI types for ratioY 20.11Time utilities  20.11.3Clock requirementsY 20.11.4Time-related traits  20.11.4.1treat_as_floating_pointY 20.11.4.2duration_valuesY 20.11.4.3Specializations of common_typeY 20.11.5Class template durationY 20.11.6Class template time_pointY 20.11.7Clocks  20.11.7.1Class system_clockY 20.11.7.2Class steady_clockY 20.11.7.3Class high_resolution_clockY 20.11.8Date and time functionsY 20.12Scoped allocator adaptorY 20.12.1Header <scoped_allocator> synopsis  20.12.2Scoped allocator adaptor member typesY 20.12.3Scoped allocator adaptor constructorsY 20.12.4Scoped allocator adaptor membersPartialOUTERMOST is not recursive.20.12.5Scoped allocator operatorsY 20.13Class type_indexY  + 20.7.2.3Class template weak_ptrY 20.7.2.4Class template emable_shared_from_thisY 20.7.2.5shared_ptr atomic accessY 20.7.2.6Smart pointer hash supportY 20.8Function objects  20.8.1Definitions  20.8.2Requirements  20.8.3Class template reference_wrapperY 20.8.4Arithmetic operationY 20.8.5ComparisonsY 20.8.6Logical operationsY 20.8.7Bitwise operationsY 20.8.8NegatorsY 20.8.9Function template bindY 20.8.10Function template mem_fnY 20.8.11Polymorphic function wrappers  20.8.11.1Class bad_function_callY 20.8.11.2Class template functionPartialMissing allocator support20.8.12Class template hashY 20.9Metaprogramming and type traits  20.9.1RequirementsY 20.9.2Header <type_traits> synopsis  20.9.3Helper classesY 20.9.4Unary Type TraitsY 20.9.4.1Primary type categoriesY 20.9.4.2Composite type traitsY 20.9.4.3Type propertiesY 20.9.5Type property queriesY 20.9.6Relationships between typesY 20.9.7Transformations between types  20.9.7.1Const-volatile modificationsY 20.9.7.2Reference modificationsY 20.9.7.3Sign modificationsY 20.9.7.4Array modificationsY 20.9.7.5Pointer modificationsY 20.9.7.6Other transformationsY 20.10Compile-time rational arithmetic  20.10.1In general  20.10.2Header <ratio> synopsis  20.10.3Class template ratioY 20.10.4Arithmetic on ratiosY 20.10.5Comparison of ratiosY 20.10.6SI types for ratioY 20.11Time utilities  20.11.3Clock requirementsY 20.11.4Time-related traits  20.11.4.1treat_as_floating_pointY 20.11.4.2duration_valuesY 20.11.4.3Specializations of common_typeY 20.11.5Class template durationY 20.11.6Class template time_pointY 20.11.7Clocks  20.11.7.1Class system_clockY 20.11.7.2Class steady_clockY 20.11.7.3Class high_resolution_clockY 20.11.8Date and time functionsY 20.12Scoped allocator adaptorY 20.12.1Header <scoped_allocator> synopsis  20.12.2Scoped allocator adaptor member typesY 20.12.3Scoped allocator adaptor constructorsY 20.12.4Scoped allocator adaptor membersY20.12.5Scoped allocator operatorsY 20.13Class type_indexY  21 Strings diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml index 7769f52b2baa..5188ab347c0c 100644 --- a/libstdc++-v3/doc/xml/manual/status_cxx2011.xml +++ b/libstdc++-v3/doc/xml/manual/status_cxx2011.xml @@ -1007,11 +1007,10 @@ This page describes the C++11 support in the GCC 5 series. - 20.12.4 Scoped allocator adaptor members - Partial - OUTERMOST is not recursive. + Y + 20.12.5 diff --git a/libstdc++-v3/include/std/scoped_allocator b/libstdc++-v3/include/std/scoped_allocator index d163edd109a9..5beb3a9295d7 100644 --- a/libstdc++-v3/include/std/scoped_allocator +++ b/libstdc++-v3/include/std/scoped_allocator @@ -74,22 +74,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : allocator_traits<_Alloc>::propagate_on_container_swap { }; - template - inline auto - __do_outermost(_Alloc& __a, _Alloc*) -> decltype(__a.outer_allocator()) - { return __a.outer_allocator(); } + using __outer_allocator_t + = decltype(std::declval<_Alloc>().outer_allocator()); + + template + struct __outermost_type + { + using type = _Alloc; + static type& _S_outermost(_Alloc& __a) { return __a; } + }; template - inline _Alloc& - __do_outermost(_Alloc& __a, ...) - { return __a; } + struct __outermost_type<_Alloc, __void_t<__outer_allocator_t<_Alloc>>> + : __outermost_type< + typename remove_reference<__outer_allocator_t<_Alloc>>::type + > + { + using __base = __outermost_type< + typename remove_reference<__outer_allocator_t<_Alloc>>::type + >; + + static typename __base::type& + _S_outermost(_Alloc& __a) + { return __base::_S_outermost(__a.outer_allocator()); } + }; - // TODO: make recursive (see note in 20.12.4/1) template - inline auto - __outermost(_Alloc& __a) -> decltype(__do_outermost(__a, &__a)) - { return __do_outermost(__a, &__a); } + inline typename __outermost_type<_Alloc>::type& + __outermost(_Alloc& __a) + { return __outermost_type<_Alloc>::_S_outermost(__a); } template class scoped_allocator_adaptor; @@ -195,14 +209,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_tie() const noexcept { return std::tuple_cat(std::tie(outer_allocator()), _M_inner._M_tie()); } - template - using __outermost_type = typename - std::decay()))>::type; - template using __outermost_alloc_traits - = allocator_traits<__outermost_type<_Alloc>>; - + = allocator_traits::type>; + template void _M_construct(__uses_alloc0, _Tp* __p, _Args&&... __args) @@ -251,6 +261,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_inner(_S_select_on_copy(std::get<_Indices+1>(__refs))...) { } + // Used to constrain constructors to disallow invalid conversions. + template + using _Constructible = typename enable_if< + is_constructible<_OuterAlloc, _Alloc>::value + >::type; + public: typedef _OuterAlloc outer_allocator_type; typedef typename __inner_type::__type inner_allocator_type; @@ -283,7 +299,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION scoped_allocator_adaptor() : _OuterAlloc(), _M_inner() { } - template + template> scoped_allocator_adaptor(_Outer2&& __outer, const _InnerAllocs&... __inner) : _OuterAlloc(std::forward<_Outer2>(__outer)), @@ -300,14 +316,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_inner(std::move(__other._M_inner)) { } - template + template> scoped_allocator_adaptor( const scoped_allocator_adaptor<_Outer2, _InnerAllocs...>& __other) : _OuterAlloc(__other.outer_allocator()), _M_inner(__other._M_inner) { } - template + template> scoped_allocator_adaptor( scoped_allocator_adaptor<_Outer2, _InnerAllocs...>&& __other) : _OuterAlloc(std::move(__other.outer_allocator())), diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/3.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/3.cc new file mode 100644 index 000000000000..c96c9aa099e2 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/3.cc @@ -0,0 +1,67 @@ +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +#include +#include + +template +struct alloc +{ + using value_type = T; + alloc() = default; + template + alloc(alloc) { } + T* allocate(std::size_t); + void deallocate(T*, std::size_t); +}; + +template + bool operator==(alloc, alloc) { return true; } + +template + bool operator!=(alloc, alloc) { return false; } + +using scoped = std::scoped_allocator_adaptor>; +using other_alloc = __gnu_test::SimpleAllocator; +using other_scoped = std::scoped_allocator_adaptor; + +using std::is_constructible; + +static_assert( is_constructible::value, + "is_constructible"); +static_assert( is_constructible::value, + "is_constructible"); +static_assert( is_constructible&>::value, + "is_constructible"); +static_assert( is_constructible>::value, + "is_constructible"); +static_assert( is_constructible&>::value, + "is_constructible::type&>"); +static_assert( is_constructible>::value, + "is_constructible::type>"); + +static_assert( !is_constructible::value, + "!is_constructible"); +static_assert( !is_constructible::value, + "!is_constructible"); +static_assert( !is_constructible::value, + "!is_constructible"); +static_assert( !is_constructible::value, + "!is_constructible"); diff --git a/libstdc++-v3/testsuite/20_util/scoped_allocator/outermost.cc b/libstdc++-v3/testsuite/20_util/scoped_allocator/outermost.cc new file mode 100644 index 000000000000..5973adcec3a6 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/scoped_allocator/outermost.cc @@ -0,0 +1,92 @@ +// Copyright (C) 2016 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-do compile } +// { dg-options "-std=gnu++11" } + +#include + +template +struct alloc +{ + using value_type = T; + alloc() = default; + template + alloc(alloc) { } + T* allocate(std::size_t); + void deallocate(T*, std::size_t); +}; + +template + bool operator==(alloc, alloc) { return true; } + +template + bool operator!=(alloc, alloc) { return false; } + +struct X +{ + using allocator_type = alloc; + X(const allocator_type&); +}; + +template +struct nested_alloc : A +{ + nested_alloc() = default; + template + nested_alloc(nested_alloc) { } + + A& outer_allocator() { return *this; } + + template + void construct(U*, Args&&...) + { + static_assert(!std::is_same::value, + "OUTERMOST should recurse and use alloc to construct X"); + } +}; + +template + bool operator==(nested_alloc l, nested_alloc r) + { return l.outer_allocator() == r.outer_allocator(); } + +template + bool operator!=(nested_alloc l, nested_alloc r) + { return !(l == r); } + +template + using scoped_alloc = std::scoped_allocator_adaptor; + +void +test01() +{ + scoped_alloc>> a; + alignas(X) char buf[sizeof(X)]; + X* p = (X*)buf; + // Test that OUTERMOST is recursive and doesn't just unwrap one level: + a.construct(p); +} + +void +test02() +{ + scoped_alloc>>> a; + alignas(X) char buf[sizeof(X)]; + X* p = (X*)buf; + // Test that OUTERMOST is recursive and doesn't just unwrap one level: + a.construct(p); +}