From patchwork Sat Dec 13 20:44:39 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jonathan Wakely X-Patchwork-Id: 420789 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 68D221400B7 for ; Sun, 14 Dec 2014 07:44:55 +1100 (AEDT) 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=t82Vdj1qDnQoIIQsRyKWDsyejBf9R5GbUWz4s+dMJ/Wx/bVTEsqxx BGM3ABpwVpenQ86Z7pC4TxAQhY+qK6+cMZBKeA7Ri0BH9UG4Apevu35It/Wr2CIw 9J858xycCToupiS5/9r/5tbMJsUBDMQnqV5fiem7KCCZYGsasKWFrU= 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=r0Q4Uz4ToGwjNkAyGa/QTQvgsyE=; b=nBq1EC2JVbGPIVa+n4SQ mjQfOUYnzb445Rfw4TZykcfLqLBT7Kuy92ZpN9J//o6wb1KSNJBGrl99CNP9J3ev IeqYFivCAHZgcc0yePkussDDTjIC93jZADp2UATaXObAFBKVPBVCeP2JpU81Y3Wc HB+pftBy3Jvkjk8erZkHYWU= Received: (qmail 10771 invoked by alias); 13 Dec 2014 20:44:47 -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 10751 invoked by uid 89); 13 Dec 2014 20:44:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 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; Sat, 13 Dec 2014 20:44:43 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id sBDKieW2002163 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL); Sat, 13 Dec 2014 15:44:41 -0500 Received: from localhost (ovpn-116-22.ams2.redhat.com [10.36.116.22]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id sBDKide5019323; Sat, 13 Dec 2014 15:44:39 -0500 Date: Sat, 13 Dec 2014 20:44:39 +0000 From: Jonathan Wakely To: libstdc++@gcc.gnu.org, gcc-patches@gcc.gnu.org Subject: [patch] Update std::experimental::{any,optional,string_view} Message-ID: <20141213204439.GT3134@redhat.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) This updates the Library Fundamentals types to reflect the changes approved in Urbana. Tested x86_64-linux, committed to trunk. commit de8bfae1fd96f002edc115ddeb2cb4e28c6164ce Author: Jonathan Wakely Date: Fri Dec 12 22:28:57 2014 +0000 Post-Urbana updates to Library Fundamentals v1. * include/experimental/any (any): Remove allocator support and update feature-testing macro. * include/experimental/functional: Update feature-testing macro. * include/experimental/optional (optional::_M_get()): Add constexpr. (optional::operator*(), optional::value()): Overload and add ref-qualifiers. Update feature-testing macro. * include/experimental/string_view (basic_string_view::clear): Remove and update feature-testing macro. * testsuite/experimental/any/cons/3.cc: Remove. * testsuite/experimental/any/cons/4.cc: Remove. * testsuite/experimental/any/misc/any_cast.cc: Remove allocator tests. * testsuite/experimental/any/misc/any_cast_neg.cc: Adjust dg-error. * testsuite/experimental/string_view/capacity/1.cc: Don't test clear(). diff --git a/libstdc++-v3/include/experimental/any b/libstdc++-v3/include/experimental/any index 87dd7a1..3af925f 100644 --- a/libstdc++-v3/include/experimental/any +++ b/libstdc++-v3/include/experimental/any @@ -36,11 +36,9 @@ #else #include -#include +#include #include #include -#include -#include namespace std _GLIBCXX_VISIBILITY(default) { @@ -60,7 +58,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ -#define __cpp_lib_experimental_any 201402 +#define __cpp_lib_experimental_any 201411 /** * @brief Exception class thrown by a failed @c any_cast @@ -96,7 +94,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION std::aligned_storage::type _M_buffer; }; - template, + template, bool _Fits = (sizeof(_Tp) <= sizeof(_Storage))> using _Internal = std::integral_constant; @@ -111,19 +109,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Manager_internal<_Tp>, _Manager_external<_Tp>>; -#if __cpp_rtti - // When RTTI is disabled __any_caster assumes the manager is either - // _Manager_internal or _Manager_external, so this type must not be used. - template - struct _Manager_alloc; // creates contained object using an allocator - - template> - using _ManagerAlloc = conditional_t<_Internal<_Tp>::value, - _Manager_internal<_Tp>, - _Manager_alloc<_Tp, _TpAlloc>>; -#endif - template> using _Decay = enable_if_t::value, _Decayed>; @@ -165,35 +150,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION "The contained object must be CopyConstructible"); } - /// Allocator-extended default constructor (the allocator is ignored). - template - any(allocator_arg_t, const _Allocator&) noexcept : any() { } - -#if __cpp_rtti - /// Construct with a copy of @p __value as the contained object. - template , - typename _Mgr = _ManagerAlloc<_Tp, _Allocator>> - any(allocator_arg_t, const _Allocator& __a, _ValueType&& __value) - : _M_manager(&_Mgr::_S_manage), - _M_storage(_Mgr::_S_alloc(__a, std::forward<_ValueType>(__value))) - { - static_assert(is_copy_constructible<_Tp>::value, - "The contained object must be CopyConstructible"); - } -#endif - - /* TODO: implement this somehow - /// Allocator-extended copy constructor. - template - any(allocator_arg_t, const _Allocator& __a, const any& __other); - */ - - /// Allocator-extended move constructor (the allocator is ignored). - template - any(allocator_arg_t, const _Allocator&, any&& __other) noexcept - : any(std::move(__other)) { } - /// Destructor, calls @c clear() ~any() { clear(); } @@ -281,13 +237,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template friend void* __any_caster(const any* __any) { -#if __cpp_rtti - if (__any->type() != typeid(_Tp)) - return nullptr; -#else if (__any->_M_manager != &_Manager>::_S_manage) return nullptr; -#endif _Arg __arg; __any->_M_manager(_Op_access, __any, &__arg); return __arg._M_obj; @@ -334,29 +285,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return __storage; } }; - -#if __cpp_rtti - // Manage external contained object using an allocator - template - struct _Manager_alloc - { - static_assert(std::is_same<_Tp, typename _Alloc::value_type>::value, - "Allocator's value_type is correct"); - - // Type that holds contained object and allocator - struct _Data; - - using _Traits = typename std::allocator_traits<_Alloc>::template - rebind_traits<_Data>; - - static void - _S_manage(_Op __which, const any* __anyp, _Arg* __arg); - - template - static _Storage - _S_alloc(const _Alloc& __a, _Up&& __value); - }; -#endif }; /// Exchange the states of two @c any objects. @@ -446,71 +374,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } // @} -#if __cpp_rtti - template - struct any::_Manager_alloc<_Tp, _Alloc>::_Data - { - using _Traits = std::allocator_traits<_Alloc>; - - std::tuple<__gnu_cxx::__aligned_buffer<_Tp>, _Alloc> _M_data; - - _Alloc& _M_alloc() { return std::get<1>(_M_data); } - const _Alloc& _M_alloc() const { return std::get<1>(_M_data); } - - _Tp* _M_obj() { return std::get<0>(_M_data)._M_ptr(); } - const _Tp* _M_obj() const { return std::get<0>(_M_data)._M_ptr(); } - - template - _Data(const _Alloc& __a, _Up&& __val) : _M_data(nullptr, __a) - { - this->_M_construct(std::__use_alloc<_Tp, _Alloc, _Up&&>(_M_alloc()), - std::forward<_Up>(__val)); - } - - ~_Data() { _Traits::destroy(_M_alloc(), _M_obj()); } - - template - void - _M_construct(__uses_alloc0, _Up&& __val) - { - _Traits::construct(_M_alloc(), _M_obj(), - std::forward<_Up>(__val)); - } - - template - void - _M_construct(__uses_alloc1<_Alloc> __a, _Up&& __val) - { - _Traits::construct(_M_alloc(), _M_obj(), - std::allocator_arg, *__a._M_a, - std::forward<_Up>(__val)); - } - - template - void - _M_construct(__uses_alloc2<_Alloc> __a, _Up&& __val) - { - _Traits::construct(_M_alloc(), _M_obj(), - std::forward<_Up>(__val), *__a._M_a); - } - }; - - template - template - any::_Storage - any::_Manager_alloc<_Tp, _Alloc>:: - _S_alloc(const _Alloc& __a, _Up&& __value) - { - typename _Traits::allocator_type __a2(__a); - auto __guard = std::__allocate_guarded(__a2); - any::_Storage __storage; - __storage._M_ptr = __guard.get(); - ::new(__storage._M_ptr) _Data{__a, std::forward<_Up>(__value)}; - __guard = nullptr; - return __storage; - } -#endif - template void any::_Manager_internal<_Tp>:: @@ -563,38 +426,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } } -#if __cpp_rtti - template - void - any::_Manager_alloc<_Tp, _Alloc>:: - _S_manage(_Op __which, const any* __any, _Arg* __arg) - { - // The contained object is at _M_storage._M_ptr->_M_obj() - auto __ptr = static_cast(__any->_M_storage._M_ptr); - switch (__which) - { - case _Op_access: - __arg->_M_obj = const_cast<_Tp*>(__ptr->_M_obj()); - break; - case _Op_get_type_info: - __arg->_M_typeinfo = &typeid(_Tp); - break; - case _Op_clone: - __arg->_M_any->_M_storage - = _S_alloc(__ptr->_M_alloc(), *__ptr->_M_obj()); - break; - case _Op_destroy: - { - using _Alloc2 = typename _Traits::allocator_type; - _Alloc2 __a(__ptr->_M_alloc()); - __allocated_ptr<_Alloc2> __guard{__a, const_cast<_Data*>(__ptr)}; - __ptr->~_Data(); - } - break; - } - } -#endif - // @} group any _GLIBCXX_END_NAMESPACE_VERSION } // namespace fundamentals_v1 diff --git a/libstdc++-v3/include/experimental/functional b/libstdc++-v3/include/experimental/functional index 4ecc6a5..5202e89 100644 --- a/libstdc++-v3/include/experimental/functional +++ b/libstdc++-v3/include/experimental/functional @@ -61,7 +61,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template constexpr int is_placeholder_v = std::is_placeholder<_Tp>::value; -#define __cpp_lib_experimental_boyer_moore_searching 201402 +#define __cpp_lib_experimental_boyer_moore_searching 201411 // Searchers diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional index 2d3127a..e87a1d4 100644 --- a/libstdc++-v3/include/experimental/optional +++ b/libstdc++-v3/include/experimental/optional @@ -67,7 +67,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ -#define __cpp_lib_experimental_optional 201406 +#define __cpp_lib_experimental_optional 201411 // All subsequent [X.Y.n] references are against n3793. @@ -290,7 +290,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return this->_M_engaged; } // The _M_get operations have _M_engaged as a precondition. - _Tp& + constexpr _Tp& _M_get() noexcept { return _M_payload; } @@ -574,18 +574,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { return std::__addressof(this->_M_get()); } constexpr const _Tp& - operator*() const + operator*() const& { return this->_M_get(); } - _Tp& - operator*() + constexpr _Tp& + operator*()& { return this->_M_get(); } + constexpr _Tp&& + operator*()&& + { return std::move(this->_M_get()); } + + constexpr const _Tp&& + operator*() const&& + { return std::move(this->_M_get()); } + constexpr explicit operator bool() const noexcept { return this->_M_is_engaged(); } constexpr const _Tp& - value() const + value() const& { return this->_M_is_engaged() ? this->_M_get() @@ -594,14 +602,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION this->_M_get()); } - _Tp& - value() + constexpr _Tp& + value()& { - if (this->_M_is_engaged()) - return this->_M_get(); + return this->_M_is_engaged() + ? this->_M_get() + : (__throw_bad_optional_access("Attempt to access value of a " + "disengaged optional object"), + this->_M_get()); + } - __throw_bad_optional_access("Attempt to access value of a " - "disengaged optional object"); + constexpr _Tp&& + value()&& + { + return this->_M_is_engaged() + ? std::move(this->_M_get()) + : (__throw_bad_optional_access("Attempt to access value of a " + "disengaged optional object"), + std::move(this->_M_get())); + } + + constexpr const _Tp&& + value() const&& + { + return this->_M_is_engaged() + ? std::move(this->_M_get()) + : (__throw_bad_optional_access("Attempt to access value of a " + "disengaged optional object"), + std::move(this->_M_get())); } template diff --git a/libstdc++-v3/include/experimental/string_view b/libstdc++-v3/include/experimental/string_view index 320d72d..6e1dd5a 100644 --- a/libstdc++-v3/include/experimental/string_view +++ b/libstdc++-v3/include/experimental/string_view @@ -50,7 +50,7 @@ inline namespace fundamentals_v1 { _GLIBCXX_BEGIN_NAMESPACE_VERSION -#define __cpp_lib_experimental_string_view 201402 +#define __cpp_lib_experimental_string_view 201411 /** * @class basic_string_view @@ -219,13 +219,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // [string.view.modifiers], modifiers: void - clear() noexcept - { - this->_M_len = 0; - this->_M_str = nullptr; - } - - void remove_prefix(size_type __n) { _GLIBCXX_DEBUG_ASSERT(this->_M_len >= __n); diff --git a/libstdc++-v3/testsuite/experimental/any/cons/3.cc b/libstdc++-v3/testsuite/experimental/any/cons/3.cc deleted file mode 100644 index 671a178..0000000 --- a/libstdc++-v3/testsuite/experimental/any/cons/3.cc +++ /dev/null @@ -1,83 +0,0 @@ -// { dg-options "-std=gnu++14" } -// { dg-do run } - -// Copyright (C) 2014 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 -// . - -#include -#include - -using std::experimental::any; -using __gnu_test::CustomPointerAlloc; -using __gnu_test::tracker_allocator; -using __gnu_test::tracker_allocator_counter; - -struct NotSmall { char c[64]; }; - -bool test [[gnu::unused]] = true; - -void test01() -{ - CustomPointerAlloc alloc; - - any x(std::allocator_arg, alloc, 1); - VERIFY( !x.empty() ); - - any y(std::allocator_arg, alloc, std::move(x)); - VERIFY( x.empty() ); - VERIFY( !y.empty() ); -} - -void test02() -{ - tracker_allocator alloc; - - any x(std::allocator_arg, alloc, 1); - auto allocated = tracker_allocator_counter::get_allocation_count(); - VERIFY( allocated == 0 ); // no allocation for small object - - any y(std::allocator_arg, alloc, std::move(x)); - VERIFY( tracker_allocator_counter::get_allocation_count() == 0 ); - - y = {}; - VERIFY( tracker_allocator_counter::get_deallocation_count() == 0 ); -} - -void test03() -{ - tracker_allocator alloc; - - - any x(std::allocator_arg, alloc, NotSmall{}); - auto allocated = tracker_allocator_counter::get_allocation_count(); - __builtin_printf("ALLOCATED %lu\n", (unsigned long)allocated); - VERIFY( allocated >= sizeof(NotSmall) ); - - any y(std::allocator_arg, alloc, std::move(x)); - VERIFY( tracker_allocator_counter::get_allocation_count() == allocated ); - - y = {}; - VERIFY( tracker_allocator_counter::get_deallocation_count() == allocated ); -} - - -int main() -{ - test01(); - test02(); - test03(); -} diff --git a/libstdc++-v3/testsuite/experimental/any/cons/4.cc b/libstdc++-v3/testsuite/experimental/any/cons/4.cc deleted file mode 100644 index 6e5e019..0000000 --- a/libstdc++-v3/testsuite/experimental/any/cons/4.cc +++ /dev/null @@ -1,73 +0,0 @@ -// { dg-options "-std=gnu++14" } -// { dg-do run } - -// Copyright (C) 2014 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 -// . - -#include -#include -#include - -using std::experimental::any; - -struct NotSmall -{ - char c[64]; // prevent small-object optimization -}; - -struct T1 -{ - using allocator_type = std::allocator; - - T1() = default; - T1(const T1&) : used_alloc(false) { } - T1(const T1&, const allocator_type&) : used_alloc(true) { } - - bool used_alloc; - - NotSmall x; -}; - -struct T2 -{ - using allocator_type = std::allocator; - - T2() = default; - T2(const T2&) : used_alloc(false) { } - T2(std::allocator_arg_t, const allocator_type&, const T2&) : used_alloc(true) - { } - - bool used_alloc; - - NotSmall x; -}; - -bool test [[gnu::unused]] = true; - -void test01() -{ - any x1(std::allocator_arg, std::allocator{}, T1{}); - VERIFY( std::experimental::any_cast(x1).used_alloc ); - - any x2(std::allocator_arg, std::allocator{}, T2{}); - VERIFY( std::experimental::any_cast(x2).used_alloc ); -} - -int main() -{ - test01(); -} diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc index 98de1bc6..edb67c3 100644 --- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast.cc @@ -77,32 +77,8 @@ void test02() } } -void test03() -{ - using std::experimental::bad_any_cast; - any x(std::allocator_arg, std::allocator{}, 1); - auto p = any_cast(&x); - VERIFY(p == nullptr); - - x = any(std::allocator_arg, std::allocator{}, 1.0); - p = any_cast(&x); - VERIFY(p != nullptr); - - x = any(std::allocator_arg, std::allocator{}); - p = any_cast(&x); - VERIFY(p == nullptr); - - try { - any_cast(x); - VERIFY(false); - } catch (const bad_any_cast&) { - } -} - - int main() { test01(); test02(); - test03(); } diff --git a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc index 9ef7194..026acb0 100644 --- a/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc +++ b/libstdc++-v3/testsuite/experimental/any/misc/any_cast_neg.cc @@ -26,5 +26,5 @@ void test01() using std::experimental::any_cast; const any y(1); - any_cast(y); // { dg-error "qualifiers" "" { target { *-*-* } } 382 } + any_cast(y); // { dg-error "qualifiers" "" { target { *-*-* } } 310 } } diff --git a/libstdc++-v3/testsuite/experimental/string_view/capacity/1.cc b/libstdc++-v3/testsuite/experimental/string_view/capacity/1.cc index 5643311..1aa055e 100644 --- a/libstdc++-v3/testsuite/experimental/string_view/capacity/1.cc +++ b/libstdc++-v3/testsuite/experimental/string_view/capacity/1.cc @@ -133,7 +133,7 @@ test01() size_type_o sz03; size_type_o sz04; - // non-POD types: size, length, max_size, clear(), empty() + // non-POD types: size, length, max_size, empty() bool b01 = str02.empty(); VERIFY( b01 == true ); sz03 = str02.size(); @@ -148,7 +148,7 @@ test01() VERIFY( sz03 >= sz04 ); sz03 = str02.size(); - str02.clear(); + str02 = {}; b01 = str02.empty(); VERIFY( b01 == true ); sz04 = str02.size();