From patchwork Mon Sep 9 18:34:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Fran=C3=A7ois_Dumont?= X-Patchwork-Id: 1159902 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-508711-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="WduevFkx"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="FeUs2n+a"; dkim-atps=neutral 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 46Rxft19Yyz9s00 for ; Tue, 10 Sep 2019 04:35:15 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=HcRnxqS5YYpeKuK4GbB6gkE0kz6oYSkPxmR3m0ep7/Atadh5gA6bU iAD7XPuu+Z5a27REwqouSk7LsCGu5wHadomhh7h2Bwh2HXp9Crfp15/zsYZaHUNW LIazS5pzkd4wiX62mVA/FWZ/m21oqYQ7Y+XF5K2G6lE78YowWPR3zI= 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:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=b26elEUy/PpMc20LaSFfG7EPx4Q=; b=WduevFkxHGtvBCS5llOk mIb0I6DhKfAIN7YbVvP4SLI2uPUBg+5biXeiFLQUiCACnVjiOvkm2I/rzyPZZLJO 13PE95yyhL59ad61Ot3stoYZ57sCYROgHW4LopEOEGQ1F+Tvi9AQDFelALqa7Uco ZebTJGrQHSpdr4D/za1HQxY= Received: (qmail 85619 invoked by alias); 9 Sep 2019 18:34:51 -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 85580 invoked by uid 89); 9 Sep 2019 18:34:50 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=cd1, patience, 1s, 5777 X-HELO: mail-wr1-f48.google.com Received: from mail-wr1-f48.google.com (HELO mail-wr1-f48.google.com) (209.85.221.48) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 09 Sep 2019 18:34:39 +0000 Received: by mail-wr1-f48.google.com with SMTP id i1so14578143wro.4; Mon, 09 Sep 2019 11:34:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:subject:to:message-id:date:user-agent:mime-version :content-language; bh=qMjncJozacZquklkYiBWLljYQM3l0/CCJ367rYFG3A0=; b=FeUs2n+asVEbNu/EpUBSb9PgXAf8mt+AyOdEP4fPGcThvpbXavlFdszHwrCZj/TzVf jFQx3Gz3hkIALVIgxIAs/c0/htN2eQMtPP5UKidxPOkvQhds9/UZX5SmqptCaHOaRiI/ hqHbqtXXbBZ7CeVZZGLCJmkcpgjivXIv+YtyZGRSVghhiz6OTm1uKenS+elzcQRDFKsg 21mK8ChaReeLy4yiV4VGQRuoU7InWvpkaZIz6OmFEOfUGcqUzO5cyuwp3h5a3xLNrLi9 D3q+n+vFGO7Q8UkeKY1w0xsjQC8TyBm2SHbThxtQflGSLpGsMn5geAB97ovQ7pmpEJLz V/VA== Received: from ?IPv6:2a01:e0a:1dc:b1c0:e9eb:b61f:2855:bdaf? ([2a01:e0a:1dc:b1c0:e9eb:b61f:2855:bdaf]) by smtp.googlemail.com with ESMTPSA id z189sm631110wmc.25.2019.09.09.11.34.34 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 Sep 2019 11:34:35 -0700 (PDT) From: =?utf-8?q?Fran=C3=A7ois_Dumont?= Subject: copy/copy_backward/fill/fill_n/equal rework To: "libstdc++@gcc.gnu.org" , gcc-patches Message-ID: <1aba6050-85ae-8753-eb81-0ec76340e10b@gmail.com> Date: Mon, 9 Sep 2019 20:34:34 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 Hi     This patch improves stl_algobase.h copy/copy_backward/fill/fill_n/equal implementations. The improvements are: - activation of algo specialization for __gnu_debug::_Safe_iterator (w/o _GLIBCXX_DEBUG mode) - activation of algo specialization for _Deque_iterator even if mixed with another kind of iterator. - activation of algo specializations __copy_move_a2 for something else than pointers. For example this code: std::vector v { 'a', 'b', .... }; ostreambuf_iterator out(std::cout); std::copy(v.begin(), v.end(), out); is not calling the specialization __copy_move_a2(const char*, const char*, ostreambuf_iterator<>); It also fix a _GLIBCXX_DEBUG issue where the __niter_base specialization was wrongly removing the _Safe_iterator<> layer. The testsuite/25_algorithms/copy/debug/1_neg.cc test case was failing on a debug assertion because _after_ the copy we were trying to increment the vector iterator after past-the-end. Of course the problem is the _after_, Debug mode should detect this _before_ it takes place which it does now. Note that std::fill_n is now making use of std::fill for some optimizations dealing with random access iterators. Performances are very good: Before: copy_backward_deque_iterators.cc    deque 2 deque 1084r 1084u    0s         0mem    0pf copy_backward_deque_iterators.cc    deque 2 vector 3373r 3372u    0s         0mem    0pf copy_backward_deque_iterators.cc    vector 2 deque 3316r 3316u    0s         0mem    0pf copy_backward_deque_iterators.cc    int deque 2 char vector 3610r 3609u    0s         0mem    0pf copy_backward_deque_iterators.cc    char vector 2 int deque 3552r 3552u    0s         0mem    0pf copy_backward_deque_iterators.cc    deque 2 list 10528r 10528u    0s         0mem    0pf copy_backward_deque_iterators.cc    list 2 deque 2161r 2162u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 deque                 752r 751u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 vector               3300r 3299u    0s         0mem    0pf copy_deque_iterators.cc      vector 2 deque               3144r 3140u    0s         0mem    0pf copy_deque_iterators.cc      int deque 2 char vector      3340r 3338u    1s         0mem    0pf copy_deque_iterators.cc      char vector 2 int deque      3132r 3132u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 list                 10013r 10012u    0s         0mem    0pf copy_deque_iterators.cc      list 2 deque                 2274r 2275u    0s         0mem    0pf equal_deque_iterators.cc     deque vs deque               8676r 8675u    0s         0mem    0pf equal_deque_iterators.cc     deque vs vector              5870r 5870u    0s         0mem    0pf equal_deque_iterators.cc     vector vs deque              3163r 3163u    0s         0mem    0pf equal_deque_iterators.cc     int deque vs char vector     5845r 5845u    0s         0mem    0pf equal_deque_iterators.cc     char vector vs int deque     3307r 3307u    0s         0mem    0pf After: copy_backward_deque_iterators.cc    deque 2 deque  697r  697u    0s         0mem    0pf copy_backward_deque_iterators.cc    deque 2 vector  219r  218u    0s         0mem    0pf copy_backward_deque_iterators.cc    vector 2 deque  453r  453u    0s         0mem    0pf copy_backward_deque_iterators.cc    int deque 2 char vector 1914r 1915u    0s         0mem    0pf copy_backward_deque_iterators.cc    char vector 2 int deque 2112r 2111u    0s         0mem    0pf copy_backward_deque_iterators.cc    deque 2 list 7770r 7771u    0s         0mem    0pf copy_backward_deque_iterators.cc    list 2 deque 2194r 2193u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 deque                 505r 504u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 vector                221r 221u    0s         0mem    0pf copy_deque_iterators.cc      vector 2 deque                398r 397u    0s         0mem    0pf copy_deque_iterators.cc      int deque 2 char vector      1770r 1767u    0s         0mem    0pf copy_deque_iterators.cc      char vector 2 int deque      1995r 1993u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 list                 7650r 7641u    2s         0mem    0pf copy_deque_iterators.cc      list 2 deque                 2270r 2270u    0s         0mem    0pf equal_deque_iterators.cc     deque vs deque                769r 768u    0s         0mem    0pf equal_deque_iterators.cc     deque vs vector               231r 230u    0s         0mem    0pf equal_deque_iterators.cc     vector vs deque               397r 397u    0s         0mem    0pf equal_deque_iterators.cc     int deque vs char vector     1541r 1541u    0s         0mem    0pf equal_deque_iterators.cc     char vector vs int deque     1623r 1623u    0s         0mem    0pf In Debug Mode it is of course even better. I haven't had the patience to run the benches before the patch, it just takes hours to run. So here is just the After part: copy_backward_deque_iterators.cc    deque 2 deque 1128r 1128u    0s         0mem    0pf copy_backward_deque_iterators.cc    deque 2 vector  616r  616u    0s         0mem    0pf copy_backward_deque_iterators.cc    vector 2 deque  856r  855u    0s         0mem    0pf copy_backward_deque_iterators.cc    int deque 2 char vector 2277r 2277u    0s         0mem    0pf copy_backward_deque_iterators.cc    char vector 2 int deque 2518r 2519u    0s         0mem    0pf copy_backward_deque_iterators.cc    deque 2 list 8029r 8028u    0s         0mem    0pf copy_backward_deque_iterators.cc    list 2 deque 10418r 10416u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 deque                 931r 930u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 vector                613r 613u    0s         0mem    0pf copy_deque_iterators.cc      vector 2 deque                794r 795u    0s         0mem    0pf copy_deque_iterators.cc      int deque 2 char vector      2192r 2192u    0s         0mem    0pf copy_deque_iterators.cc      char vector 2 int deque      2365r 2364u    0s         0mem    0pf copy_deque_iterators.cc      deque 2 list                 8009r 8010u    0s         0mem    0pf copy_deque_iterators.cc      list 2 deque                 10979r 10970u    1s         0mem    0pf equal_deque_iterators.cc     deque vs deque               1034r 1032u    0s         0mem    0pf equal_deque_iterators.cc     deque vs vector               481r 482u    0s         0mem    0pf equal_deque_iterators.cc     vector vs deque               646r 646u    0s         0mem    0pf equal_deque_iterators.cc     int deque vs char vector     1802r 1802u    0s         0mem    0pf equal_deque_iterators.cc     char vector vs int deque     1867r 1865u    0s         0mem    0pf Note that copy/copy_backward 'list 2 deque' is still much slower because for the moment we can't remove the debug layer. I plan to do a refinement to also cover this use case. In Debug implementations I have duplicated the Debug checks because those algo specialization will also be used when users are directly using for instance without defining _GLIBCXX_DEBUG. All algos tests passed except the constexpr ones in Debug mode, I've put this on my todo list. Ok to commit once I completed all the other tests ? François * include/bits/stl_algobase.h (__copy_move_a1<>(_II, _II, _OI)): New. (__copy_move_a1<>(_Deque_iterator<>, _Deque_iterator<>, _OI)): New. (__copy_move_a1<>(_Deque_iterator<>, _Deque_iterator<>, _Deque_iterator<>)): New. (__copy_move_a1<>(_II, _II, _Deque_iterator<>)): New. (__copy_move_a<>(_II, _II, _OI)): Adapt, call __copy_move_a1<>. (__copy_move_a<>(const _Safe_iterator<>&, const _Safe_iterator<>&, _OI)): New. (__copy_move_a<>(const _Safe_iterator<>&, const _Safe_iterator<>&, const _Safe_iterator<>&)): New. (__copy_move_a<>(_II, _II, const _Safe_iterator<>&)): New. (copy, move): Adapt, call __copy_move_a. (__copy_move_backward_a1<>(_II, _II, _OI)): New, call __copy_move_backward_a2. (__copy_move_backward_a1<>(_Deque_iterator<>, _Deque_iterator<>, _OI)): New. (__copy_move_backward_a1<>(_Deque_iterator<>, _Deque_iterator<>, _Deque_iterator<>)): New. (__copy_move_backward_a1<>(_II, _II, _Deque_iterator<>)): New. (__copy_move_backward_a<>(_II, _II, _OI)): Adapt, call __copy_move_backward_a1<>. (__copy_move_backward_a<>(const _Safe_iterator<>&, const _Safe_iterator<>&, _OI)): New. (__copy_move_backward_a<>(const _Safe_iterator<>&, const _Safe_iterator<>&, const _Safe_iterator<>&)): New. (__copy_move_backward_a<>(_II, _II, const _Safe_iterator<>&)): New. (copy_backward, move_backward): Adapt, call __copy_move_backward_a<>. (__fill_a): Rename into... (__fill_a1): ... this. (__fill_a1(__normal_iterator<>, __normal_iterator<>, const _Tp&)): New. (__fill_a1(const _Deque_iterator<>&, const _Deque_iterator<>&, _VTp)): New. (__fill_a(_FIte, _FIte, const _Tp&)): New, call __fill_a1. (__fill_a(const _Safe_iterator<>&, const _Safe_iterator<>&, const _Tp&)): New. (fill): Adapt, remove __niter_base usage. (__fill_n_a): Rename into... (__fill_n_a1): ...this. (__fill_n_a(const _Safe_iterator<>&, _Size, const _Tp&, input_iterator_tag)): New. (__fill_n_a(_OI, _Size, const _Tp&, output_iterator_tag)): New, call __fill_n_a1. (__fill_n_a(_OI, _Size, const _Tp&, random_access_iterator_tag)): New, call __fill_a. (__equal_aux): Rename into... (__equal_aux1): ...this. (__equal_aux1(_Deque_iterator<>, _Deque_iterator<>, _OI)): New. (__equal_aux1(_Deque_iterator<>, _Deque_iterator<>, _Deque_iterator<>)): New. (__equal_aux1(_II, _II, _Deque_iterator<>)): New. (__equal_aux(_II1, _II1, _II2)): New, call __equal_aux1. (__equal_aux(const _Safe_iterator<>&, const _Safe_iterator<>&, _OI)): New. (__equal_aux(const _Safe_iterator<>&, const _Safe_iterator<>&, const _Safe_iterator<>&)): New. (__equal_aux(_II, _II, const _Safe_iterator<>&)): New. (equal(_II1, _II1, _II2)): Adapt. * include/bits/stl_deque.h (fill, copy, copy_backward, move, move_backward): Remove. (__fill_a1, __copy_move_a1, __copy_move_backward_a1, __equal_a1): New declarations. * include/bits/deque.tcc (__fill_a1): New. (__copy_move_dit): New. (__copy_move_a1): New, use latter. (__copy_move_a1(_II, _II, _Deque_iterator<>)): New. (__copy_move_backward_dit): New. (__copy_move_backward_a1): New, use latter. (__copy_move_backward_a1(_II, _II, _Deque_iterator<>)): New. (__equal_dit): New. (__equal_aux1): New, use latter. (__equal_aux1(_II, _II, _Deque_iterator<>)): New. * include/std/numeric (__is_random_access_iter): Move... * include/bits/stl_iterator_base_types.h (__is_random_access_iter): ... here. Provide pre-C++11 definition. * include/debug/debug.h (_Safe_iterator<>): New declaration. * include/debug/safe_iterator.h: Include . (_Safe_iterator<>::_M_can_advance): Add __strict parameter. (std::__copy_move_a, std::__copy_move_backward_a, __fill_a): New. (__fill_n_a, __equal_aux): New. * include/debug/safe_iterator.tcc (_Safe_iterator<>::_M_can_advance): Adapt. * include/debug/stl_iterator.h (__niter_base): Remove. * include/debug/vector (__niter_base): Remove. * testsuite/performance/25_algorithms/copy_backward_deque_iterators.cc: Include and . Add benches. * testsuite/performance/25_algorithms/copy_deque_iterators.cc: Likewise. * testsuite/performance/25_algorithms/equal_deque_iterators.cc: Likewise. * testsuite/25_algorithms/copy/debug/1_neg.cc: New. * testsuite/25_algorithms/copy/deque_iterators/2.cc: New. * testsuite/25_algorithms/copy/deque_iterators/31.cc: New. * testsuite/25_algorithms/copy/deque_iterators/32.cc: New. * testsuite/25_algorithms/copy/deque_iterators/33.cc: New. * testsuite/25_algorithms/copy/deque_iterators/41.cc: New. * testsuite/25_algorithms/copy/deque_iterators/42.cc: New. * testsuite/25_algorithms/copy/deque_iterators/43.cc: New. * testsuite/25_algorithms/copy_backward/deque_iterators/2.cc: New. * testsuite/25_algorithms/equal/deque_iterators/1.cc: New. * testsuite/25_algorithms/fill/deque_iterators/1.cc: New. * testsuite/25_algorithms/move/deque_iterators/2.cc: New. * testsuite/25_algorithms/move_backward/deque_iterators/2.cc: New. diff --git a/libstdc++-v3/include/bits/deque.tcc b/libstdc++-v3/include/bits/deque.tcc index 3f77b4f079c..ab996ca52fa 100644 --- a/libstdc++-v3/include/bits/deque.tcc +++ b/libstdc++-v3/include/bits/deque.tcc @@ -967,155 +967,247 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER this->_M_impl._M_finish._M_set_node(__new_nstart + __old_num_nodes - 1); } +_GLIBCXX_END_NAMESPACE_CONTAINER + // Overload for deque::iterators, exploiting the "segmented-iterator // optimization". - template + template void - fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>& __first, - const _Deque_iterator<_Tp, _Tp&, _Tp*>& __last, const _Tp& __value) + __fill_a1(const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __first, + const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>& __last, + const _VTp& __value) { - typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; + typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter; + if (__first._M_node != __last._M_node) + { + std::__fill_a1(__first._M_cur, __first._M_last, __value); - for (typename _Self::_Map_pointer __node = __first._M_node + 1; + for (typename _Iter::_Map_pointer __node = __first._M_node + 1; __node < __last._M_node; ++__node) - std::fill(*__node, *__node + _Self::_S_buffer_size(), __value); + std::__fill_a1(*__node, *__node + _Iter::_S_buffer_size(), __value); + std::__fill_a1(__last._M_first, __last._M_cur, __value); + } + else + std::__fill_a1(__first._M_cur, __last._M_cur, __value); + } + + template + _OI + __copy_move_dit(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last, + _OI __result) + { + typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter; if (__first._M_node != __last._M_node) { - std::fill(__first._M_cur, __first._M_last, __value); - std::fill(__last._M_first, __last._M_cur, __value); + __result + = std::__copy_move_a1<_IsMove>(__first._M_cur, __first._M_last, + __result); + + for (typename _Iter::_Map_pointer __node = __first._M_node + 1; + __node != __last._M_node; ++__node) + __result + = std::__copy_move_a1<_IsMove>(*__node, + *__node + _Iter::_S_buffer_size(), + __result); + + return std::__copy_move_a1<_IsMove>(__last._M_first, __last._M_cur, + __result); } - else - std::fill(__first._M_cur, __last._M_cur, __value); + + return std::__copy_move_a1<_IsMove>(__first._M_cur, __last._M_cur, + __result); } - template - _Deque_iterator<_Tp, _Tp&, _Tp*> - copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, - _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, - _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + template + _OI + __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last, + _OI __result) + { return __copy_move_dit<_IsMove>(__first, __last, __result); } + + template + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> + __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first, + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last, + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result) + { return __copy_move_dit<_IsMove>(__first, __last, __result); } + + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type + __copy_move_a1(_II __first, _II __last, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result) { - typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; - typedef typename _Self::difference_type difference_type; + typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter; + typedef typename _Iter::difference_type difference_type; difference_type __len = __last - __first; while (__len > 0) { const difference_type __clen - = std::min(__len, std::min(__first._M_last - __first._M_cur, - __result._M_last - __result._M_cur)); - std::copy(__first._M_cur, __first._M_cur + __clen, __result._M_cur); + = std::min(__len, __result._M_last - __result._M_cur); + std::__copy_move_a1<_IsMove>(__first, __first + __clen, + __result._M_cur); + __first += __clen; __result += __clen; __len -= __clen; } + return __result; } - template - _Deque_iterator<_Tp, _Tp&, _Tp*> - copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, - _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, - _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + template + _OI + __copy_move_backward_dit( + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last, + _OI __result) + { + typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter; + if (__first._M_node != __last._M_node) + { + __result = std::__copy_move_backward_a1<_IsMove>( + __last._M_first, __last._M_cur, __result); + + for (typename _Iter::_Map_pointer __node = __last._M_node - 1; + __node != __first._M_node; --__node) + __result = std::__copy_move_backward_a1<_IsMove>( + *__node, *__node + _Iter::_S_buffer_size(), __result); + + return std::__copy_move_backward_a1<_IsMove>( + __first._M_cur, __first._M_last, __result); + } + + return std::__copy_move_backward_a1<_IsMove>( + __first._M_cur, __last._M_cur, __result); + } + + template + _OI + __copy_move_backward_a1( + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last, + _OI __result) + { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); } + + template + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> + __copy_move_backward_a1( + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __first, + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr> __last, + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> __result) + { return __copy_move_backward_dit<_IsMove>(__first, __last, __result); } + + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type + __copy_move_backward_a1(_II __first, _II __last, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> __result) { - typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; - typedef typename _Self::difference_type difference_type; + typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> _Iter; + typedef typename _Iter::difference_type difference_type; difference_type __len = __last - __first; while (__len > 0) { - difference_type __llen = __last._M_cur - __last._M_first; - _Tp* __lend = __last._M_cur; - difference_type __rlen = __result._M_cur - __result._M_first; _Tp* __rend = __result._M_cur; - - if (!__llen) - { - __llen = _Self::_S_buffer_size(); - __lend = *(__last._M_node - 1) + __llen; - } if (!__rlen) { - __rlen = _Self::_S_buffer_size(); + __rlen = _Iter::_S_buffer_size(); __rend = *(__result._M_node - 1) + __rlen; } - const difference_type __clen = std::min(__len, - std::min(__llen, __rlen)); - std::copy_backward(__lend - __clen, __lend, __rend); + const difference_type __clen = std::min(__len, __rlen); + std::__copy_move_backward_a1<_IsMove>(__last - __clen, __last, __rend); + __last -= __clen; __result -= __clen; __len -= __clen; } + return __result; } -#if __cplusplus >= 201103L - template - _Deque_iterator<_Tp, _Tp&, _Tp*> - move(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, - _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, - _Deque_iterator<_Tp, _Tp&, _Tp*> __result) + template + bool + __equal_dit( + const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __first1, + const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>& __last1, + _II __first2) { - typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; - typedef typename _Self::difference_type difference_type; - - difference_type __len = __last - __first; - while (__len > 0) + typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter; + if (__first1._M_node != __last1._M_node) { - const difference_type __clen - = std::min(__len, std::min(__first._M_last - __first._M_cur, - __result._M_last - __result._M_cur)); - std::move(__first._M_cur, __first._M_cur + __clen, __result._M_cur); - __first += __clen; - __result += __clen; - __len -= __clen; - } - return __result; + if (!std::__equal_aux1(__first1._M_cur, __first1._M_last, __first2)) + return false; + + __first2 += __first1._M_last - __first1._M_cur; + for (typename _Iter::_Map_pointer __node = __first1._M_node + 1; + __node != __last1._M_node; + __first2 += _Iter::_S_buffer_size(), ++__node) + if (!std::__equal_aux1(*__node, *__node + _Iter::_S_buffer_size(), + __first2)) + return false; + + return std::__equal_aux1(__last1._M_first, __last1._M_cur, __first2); } - template - _Deque_iterator<_Tp, _Tp&, _Tp*> - move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*> __first, - _Deque_iterator<_Tp, const _Tp&, const _Tp*> __last, - _Deque_iterator<_Tp, _Tp&, _Tp*> __result) - { - typedef typename _Deque_iterator<_Tp, _Tp&, _Tp*>::_Self _Self; - typedef typename _Self::difference_type difference_type; + return std::__equal_aux1(__first1._M_cur, __last1._M_cur, __first2); + } - difference_type __len = __last - __first; - while (__len > 0) - { - difference_type __llen = __last._M_cur - __last._M_first; - _Tp* __lend = __last._M_cur; + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, bool>::__type + __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first1, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __last1, + _II __first2) + { return std::__equal_dit(__first1, __last1, __first2); } - difference_type __rlen = __result._M_cur - __result._M_first; - _Tp* __rend = __result._M_cur; + template + bool + __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __first1, + _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1> __last1, + _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2> __first2) + { return std::__equal_dit(__first1, __last1, __first2); } - if (!__llen) + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, bool>::__type + __equal_aux1(_II __first1, _II __last1, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> __first2) { - __llen = _Self::_S_buffer_size(); - __lend = *(__last._M_node - 1) + __llen; - } - if (!__rlen) + typedef _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr> _Iter; + typedef typename _Iter::difference_type difference_type; + + difference_type __len = __last1 - __first1; + while (__len > 0) { - __rlen = _Self::_S_buffer_size(); - __rend = *(__result._M_node - 1) + __rlen; - } + const difference_type __clen + = std::min(__len, __first2._M_last - __first2._M_cur); + if (!std::__equal_aux1(__first1, __first1 + __clen, __first2._M_cur)) + return false; - const difference_type __clen = std::min(__len, - std::min(__llen, __rlen)); - std::move_backward(__lend - __clen, __lend, __rend); - __last -= __clen; - __result -= __clen; + __first1 += __clen; __len -= __clen; + __first2 += __clen; } - return __result; + + return true; } -#endif -_GLIBCXX_END_NAMESPACE_CONTAINER _GLIBCXX_END_NAMESPACE_VERSION } // namespace std diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index 98d324827ed..e2969a1f66b 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -454,7 +454,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _GLIBCXX20_CONSTEXPR inline _OI - __copy_move_a(_II __first, _II __last, _OI __result) + __copy_move_a2(_II __first, _II __last, _OI __result) { typedef typename iterator_traits<_II>::value_type _ValueTypeI; typedef typename iterator_traits<_OI>::value_type _ValueTypeO; @@ -467,6 +467,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _Category>::__copy_m(__first, __last, __result); } + template + _GLIBCXX20_CONSTEXPR + inline _OI + __copy_move_a1(_II __first, _II __last, _OI __result) + { return std::__copy_move_a2<_IsMove>(__first, __last, __result); } + +_GLIBCXX_BEGIN_NAMESPACE_CONTAINER + + template + struct _Deque_iterator; + +_GLIBCXX_END_NAMESPACE_CONTAINER + + template + _OI + __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _OI); + + template + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> + __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr>, + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr>, + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>); + + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type + __copy_move_a1(_II, _II, _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>); + // Helpers for streambuf iterators (either istream or ostream). // NB: avoid including , relatively large. template @@ -499,14 +532,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _GLIBCXX20_CONSTEXPR inline _OI - __copy_move_a2(_II __first, _II __last, _OI __result) + __copy_move_a(_II __first, _II __last, _OI __result) { return std::__niter_wrap(__result, - std::__copy_move_a<_IsMove>(std::__niter_base(__first), + std::__copy_move_a1<_IsMove>(std::__niter_base(__first), std::__niter_base(__last), std::__niter_base(__result))); } + template + _OI + __copy_move_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, + _OI); + + template + __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat> + __copy_move_a(_II, _II, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&); + + template + ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat> + __copy_move_a(const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>&, + const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>&, + const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>&); + /** * @brief Copies the range [first,last) into result. * @ingroup mutating_algorithms @@ -535,7 +589,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_II>::value_type>) __glibcxx_requires_can_increment_range(__first, __last, __result); - return std::__copy_move_a2<__is_move_iterator<_II>::__value> + return std::__copy_move_a<__is_move_iterator<_II>::__value> (std::__miter_base(__first), std::__miter_base(__last), __result); } @@ -568,7 +622,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_II>::value_type>) __glibcxx_requires_can_increment_range(__first, __last, __result); - return std::__copy_move_a2(std::__miter_base(__first), + return std::__copy_move_a(std::__miter_base(__first), std::__miter_base(__last), __result); } @@ -577,7 +631,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #define _GLIBCXX_MOVE3(_Tp, _Up, _Vp) std::copy(_Tp, _Up, _Vp) #endif - template + template struct __copy_move_backward { template @@ -666,7 +720,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _GLIBCXX20_CONSTEXPR inline _BI2 - __copy_move_backward_a(_BI1 __first, _BI1 __last, _BI2 __result) + __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result) { typedef typename iterator_traits<_BI1>::value_type _ValueType1; typedef typename iterator_traits<_BI2>::value_type _ValueType2; @@ -691,14 +745,65 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template _GLIBCXX20_CONSTEXPR inline _BI2 - __copy_move_backward_a2(_BI1 __first, _BI1 __last, _BI2 __result) + __copy_move_backward_a1(_BI1 __first, _BI1 __last, _BI2 __result) + { return std::__copy_move_backward_a2<_IsMove>(__first, __last, __result); } + + template + _OI + __copy_move_backward_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _OI); + + template + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> + __copy_move_backward_a1( + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr>, + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr>, + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>); + + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type + __copy_move_backward_a1(_II, _II, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>); + + template + _GLIBCXX20_CONSTEXPR + inline _OI + __copy_move_backward_a(_II __first, _II __last, _OI __result) { return std::__niter_wrap(__result, - std::__copy_move_backward_a<_IsMove> + std::__copy_move_backward_a1<_IsMove> (std::__niter_base(__first), std::__niter_base(__last), std::__niter_base(__result))); } + template + _OI + __copy_move_backward_a( + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, + _OI); + + template + __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat> + __copy_move_backward_a(_II, _II, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&); + + template + ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat> + __copy_move_backward_a( + const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>&, + const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>&, + const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>&); + /** * @brief Copies the range [first,last) into result. * @ingroup mutating_algorithms @@ -730,7 +835,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_BI2>::value_type>) __glibcxx_requires_can_decrement_range(__first, __last, __result); - return std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value> + return std::__copy_move_backward_a<__is_move_iterator<_BI1>::__value> (std::__miter_base(__first), std::__miter_base(__last), __result); } @@ -766,7 +871,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typename iterator_traits<_BI2>::value_type>) __glibcxx_requires_can_decrement_range(__first, __last, __result); - return std::__copy_move_backward_a2(std::__miter_base(__first), + return std::__copy_move_backward_a(std::__miter_base(__first), std::__miter_base(__last), __result); } @@ -780,7 +885,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__enable_if::__value, void>::__type - __fill_a(_ForwardIterator __first, _ForwardIterator __last, + __fill_a1(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { for (; __first != __last; ++__first) @@ -791,7 +896,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, void>::__type - __fill_a(_ForwardIterator __first, _ForwardIterator __last, + __fill_a1(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { const _Tp __tmp = __value; @@ -803,13 +908,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION template inline typename __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, void>::__type - __fill_a(_Tp* __first, _Tp* __last, const _Tp& __c) + __fill_a1(_Tp* __first, _Tp* __last, const _Tp& __c) { const _Tp __tmp = __c; if (const size_t __len = __last - __first) __builtin_memset(__first, static_cast(__tmp), __len); } + template + _GLIBCXX20_CONSTEXPR + inline void + __fill_a1(::__gnu_cxx::__normal_iterator<_Ite, _Cont> __first, + ::__gnu_cxx::__normal_iterator<_Ite, _Cont> __last, + const _Tp& __value) + { std::__fill_a1(__first.base(), __last.base(), __value); } + + template + void + __fill_a1(const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>&, + const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>&, + const _VTp&); + + template + _GLIBCXX20_CONSTEXPR + inline void + __fill_a(_FIte __first, _FIte __last, const _Tp& __value) + { std::__fill_a1(__first, __last, __value); } + + template + void + __fill_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>&, + const _Tp&); + /** * @brief Fills the range [first,last) with copies of value. * @ingroup mutating_algorithms @@ -832,8 +963,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _ForwardIterator>) __glibcxx_requires_valid_range(__first, __last); - std::__fill_a(std::__niter_base(__first), std::__niter_base(__last), - __value); + std::__fill_a(__first, __last, __value); } // Used by fill_n, generate_n, etc. to convert _Size to an integral type: @@ -890,11 +1020,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__enable_if::__value, _OutputIterator>::__type - __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value) + __fill_n_a1(_OutputIterator __first, _Size __n, const _Tp& __value) { -#if __cplusplus >= 201103L - static_assert(is_integral<_Size>{}, "fill_n must pass integral size"); -#endif for (; __n > 0; --__n, (void) ++__first) *__first = __value; return __first; @@ -904,24 +1031,55 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _GLIBCXX20_CONSTEXPR inline typename __gnu_cxx::__enable_if<__is_scalar<_Tp>::__value, _OutputIterator>::__type - __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value) + __fill_n_a1(_OutputIterator __first, _Size __n, const _Tp& __value) { -#if __cplusplus >= 201103L - static_assert(is_integral<_Size>{}, "fill_n must pass integral size"); -#endif const _Tp __tmp = __value; for (; __n > 0; --__n, (void) ++__first) *__first = __tmp; return __first; } - template + template + ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat> + __fill_n_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first, + _Size __n, const _Tp& __value, + std::input_iterator_tag); + + template _GLIBCXX20_CONSTEXPR - inline typename - __gnu_cxx::__enable_if<__is_byte<_Tp>::__value, _Tp*>::__type - __fill_n_a(_Tp* __first, _Size __n, const _Tp& __c) + inline _OutputIterator + __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value, + std::output_iterator_tag) { - std::__fill_a(__first, __first + __n, __c); +#if __cplusplus >= 201103L + static_assert(is_integral<_Size>{}, "fill_n must pass integral size"); +#endif + return __fill_n_a1(__first, __n, __value); + } + + template + _GLIBCXX20_CONSTEXPR + inline _OutputIterator + __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value, + std::input_iterator_tag) + { +#if __cplusplus >= 201103L + static_assert(is_integral<_Size>{}, "fill_n must pass integral size"); +#endif + return __fill_n_a1(__first, __n, __value); + } + + template + _GLIBCXX20_CONSTEXPR + inline _OutputIterator + __fill_n_a(_OutputIterator __first, _Size __n, const _Tp& __value, + std::random_access_iterator_tag) + { + if (__n <= 0) + return __first; + + std::__fill_a(__first, __first + __n, __value); return __first + __n; } @@ -949,11 +1107,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { // concept requirements __glibcxx_function_requires(_OutputIteratorConcept<_OI, _Tp>) + __glibcxx_requires_can_increment(__first, __n); - return std::__niter_wrap(__first, - std::__fill_n_a(std::__niter_base(__first), - std::__size_to_integer(__n), - __value)); + return std::__fill_n_a(__first, std::__size_to_integer(__n), __value, + std::__iterator_category(__first)); } template @@ -985,10 +1142,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION } }; + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, bool>::__type + __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _II); + + template + bool + __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2>); + + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, bool>::__type + __equal_aux1(_II, _II, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>); + template _GLIBCXX20_CONSTEXPR inline bool - __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2) + __equal_aux1(_II1 __first1, _II1 __last1, _II2 __first2) { typedef typename iterator_traits<_II1>::value_type _ValueType1; typedef typename iterator_traits<_II2>::value_type _ValueType2; @@ -1001,6 +1178,34 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION return std::__equal<__simple>::equal(__first1, __last1, __first2); } + template + _GLIBCXX20_CONSTEXPR + inline bool + __equal_aux(_II1 __first1, _II1 __last1, _II2 __first2) + { + return std::__equal_aux1(std::__niter_base(__first1), + std::__niter_base(__last1), + std::__niter_base(__first2)); + } + + template + bool + __equal_aux(const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>&, + const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>&, + _II2); + + template + bool + __equal_aux(_II1, _II1, + const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>&); + + template + bool + __equal_aux(const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>&, + const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>&, + const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>&); + template struct __lc_rai { @@ -1227,9 +1432,7 @@ _GLIBCXX_BEGIN_NAMESPACE_ALGO typename iterator_traits<_II2>::value_type>) __glibcxx_requires_can_increment_range(__first1, __last1, __first2); - return std::__equal_aux(std::__niter_base(__first1), - std::__niter_base(__last1), - std::__niter_base(__first2)); + return std::__equal_aux(__first1, __last1, __first2); } /** diff --git a/libstdc++-v3/include/bits/stl_deque.h b/libstdc++-v3/include/bits/stl_deque.h index ac76d681ff0..62218b1c058 100644 --- a/libstdc++-v3/include/bits/stl_deque.h +++ b/libstdc++-v3/include/bits/stl_deque.h @@ -370,76 +370,77 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return __x + __n; } }; - template +_GLIBCXX_END_NAMESPACE_CONTAINER + + template void - fill(const _Deque_iterator<_Tp, _Tp&, _Tp*>&, - const _Deque_iterator<_Tp, _Tp&, _Tp*>&, const _Tp&); - - template - _Deque_iterator<_Tp, _Tp&, _Tp*> - copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, - _Deque_iterator<_Tp, const _Tp&, const _Tp*>, - _Deque_iterator<_Tp, _Tp&, _Tp*>); - - template - inline _Deque_iterator<_Tp, _Tp&, _Tp*> - copy(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, - _Deque_iterator<_Tp, _Tp&, _Tp*> __last, - _Deque_iterator<_Tp, _Tp&, _Tp*> __result) - { return std::copy(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first), - _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), - __result); } - - template - _Deque_iterator<_Tp, _Tp&, _Tp*> - copy_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, - _Deque_iterator<_Tp, const _Tp&, const _Tp*>, - _Deque_iterator<_Tp, _Tp&, _Tp*>); - - template - inline _Deque_iterator<_Tp, _Tp&, _Tp*> - copy_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, - _Deque_iterator<_Tp, _Tp&, _Tp*> __last, - _Deque_iterator<_Tp, _Tp&, _Tp*> __result) - { return std::copy_backward(_Deque_iterator<_Tp, - const _Tp&, const _Tp*>(__first), - _Deque_iterator<_Tp, - const _Tp&, const _Tp*>(__last), - __result); } + __fill_a1(const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>&, + const _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>&, + const _VTp&); + + template + _OI + __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _OI); + + template + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> + __copy_move_a1(_GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr>, + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr>, + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>); + + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type + __copy_move_a1(_II, _II, _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>); + + template + _OI + __copy_move_backward_a1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _OI); + + template + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*> + __copy_move_backward_a1( + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr>, + _GLIBCXX_STD_C::_Deque_iterator<_ITp, _IRef, _IPtr>, + _GLIBCXX_STD_C::_Deque_iterator<_OTp, _OTp&, _OTp*>); + + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*> >::__type + __copy_move_backward_a1(_II, _II, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Tp&, _Tp*>); + + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, bool>::__type + __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>, + _II); + + template + bool + __equal_aux1(_GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp1, _Ref1, _Ptr1>, + _GLIBCXX_STD_C::_Deque_iterator<_Tp2, _Ref2, _Ptr2>); -#if __cplusplus >= 201103L - template - _Deque_iterator<_Tp, _Tp&, _Tp*> - move(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, - _Deque_iterator<_Tp, const _Tp&, const _Tp*>, - _Deque_iterator<_Tp, _Tp&, _Tp*>); - - template - inline _Deque_iterator<_Tp, _Tp&, _Tp*> - move(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, - _Deque_iterator<_Tp, _Tp&, _Tp*> __last, - _Deque_iterator<_Tp, _Tp&, _Tp*> __result) - { return std::move(_Deque_iterator<_Tp, const _Tp&, const _Tp*>(__first), - _Deque_iterator<_Tp, const _Tp&, const _Tp*>(__last), - __result); } - - template - _Deque_iterator<_Tp, _Tp&, _Tp*> - move_backward(_Deque_iterator<_Tp, const _Tp&, const _Tp*>, - _Deque_iterator<_Tp, const _Tp&, const _Tp*>, - _Deque_iterator<_Tp, _Tp&, _Tp*>); - - template - inline _Deque_iterator<_Tp, _Tp&, _Tp*> - move_backward(_Deque_iterator<_Tp, _Tp&, _Tp*> __first, - _Deque_iterator<_Tp, _Tp&, _Tp*> __last, - _Deque_iterator<_Tp, _Tp&, _Tp*> __result) - { return std::move_backward(_Deque_iterator<_Tp, - const _Tp&, const _Tp*>(__first), - _Deque_iterator<_Tp, - const _Tp&, const _Tp*>(__last), - __result); } -#endif + template + typename __gnu_cxx::__enable_if< + __is_random_access_iter<_II>::__value, bool>::__type + __equal_aux1(_II, _II, + _GLIBCXX_STD_C::_Deque_iterator<_Tp, _Ref, _Ptr>); + +_GLIBCXX_BEGIN_NAMESPACE_CONTAINER /** * Deque base class. This class provides the unified face for %deque's diff --git a/libstdc++-v3/include/bits/stl_iterator_base_types.h b/libstdc++-v3/include/bits/stl_iterator_base_types.h index af69dbb017a..8135f4857fc 100644 --- a/libstdc++-v3/include/bits/stl_iterator_base_types.h +++ b/libstdc++-v3/include/bits/stl_iterator_base_types.h @@ -213,6 +213,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION enable_if::iterator_category, input_iterator_tag>::value>::type; + + template, + typename _Cat = typename _Traits::iterator_category> + struct __is_random_access_iter + : is_base_of + { + typedef is_base_of _Base; + enum { __value = _Base::value }; + }; +#else + template, + typename _Cat = typename _Traits::iterator_category> + struct __is_random_access_iter + { enum { __value = __is_base_of(random_access_iterator_tag, _Cat) }; }; #endif _GLIBCXX_END_NAMESPACE_VERSION diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h index d851b4ae6dd..8d3a8606ccd 100644 --- a/libstdc++-v3/include/debug/debug.h +++ b/libstdc++-v3/include/debug/debug.h @@ -56,6 +56,9 @@ namespace std namespace __gnu_debug { using namespace std::__debug; + + template + struct _Safe_iterator; } #ifndef _GLIBCXX_DEBUG diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h index 6700eafca0b..c04b5a4a355 100644 --- a/libstdc++-v3/include/debug/safe_iterator.h +++ b/libstdc++-v3/include/debug/safe_iterator.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #define _GLIBCXX_DEBUG_VERIFY_OPERANDS(_Lhs, _Rhs, _BadMsgId, _DiffMsgId) \ @@ -396,7 +397,7 @@ namespace __gnu_debug // Can we advance the iterator @p __n steps (@p __n may be negative) bool - _M_can_advance(difference_type __n) const; + _M_can_advance(difference_type __n, bool __strict = false) const; // Is the iterator range [*this, __rhs) valid? bool @@ -950,6 +951,237 @@ namespace __gnu_debug } // namespace __gnu_debug +namespace std _GLIBCXX_VISIBILITY(default) +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + _OI + __copy_move_a( + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last, + _OI __result) + { + typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist; + __glibcxx_check_valid_range2(__first, __last, __dist); + __glibcxx_check_can_increment(__result, __dist.first); + + if (__dist.second > ::__gnu_debug::__dp_equality) + return std::__copy_move_a<_IsMove>(__first.base(), __last.base(), + __result); + + return std::__copy_move_a1<_IsMove>(__first, __last, __result); + } + + template + __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat> + __copy_move_a(_II __first, _II __last, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result) + { + typename ::__gnu_debug::_Distance_traits<_II>::__type __dist; + __glibcxx_check_valid_range2(__first, __last, __dist); + __glibcxx_check_can_increment(__result, __dist.first); + + if (__dist.second == ::__gnu_debug::__dp_exact + && __result._M_can_advance(__dist.first, true)) + return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>( + std::__copy_move_a<_IsMove>(__first, __last, __result.base()), + __result._M_sequence); + + return std::__copy_move_a1<_IsMove>(__first, __last, __result); + } + + template + ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat> + __copy_move_a( + const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first, + const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last, + const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result) + { + typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist; + __glibcxx_check_valid_range2(__first, __last, __dist); + __glibcxx_check_can_increment(__result, __dist.first); + + if (__dist.second > ::__gnu_debug::__dp_equality) + { + if (__dist.second == ::__gnu_debug::__dp_exact + && __result._M_can_advance(__dist.first, true)) + return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>( + std::__copy_move_a<_IsMove>(__first.base(), __last.base(), + __result.base()), + __result._M_sequence); + + return std::__copy_move_a<_IsMove>(__first.base(), __last.base(), + __result); + } + + return std::__copy_move_a1<_IsMove>(__first, __last, __result); + } + + template + _OI + __copy_move_backward_a( + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last, + _OI __result) + { + typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist; + __glibcxx_check_valid_range2(__first, __last, __dist); + __glibcxx_check_can_increment(__result, -__dist.first); + + if (__dist.second > ::__gnu_debug::__dp_equality) + return std::__copy_move_backward_a<_IsMove>( + __first.base(), __last.base(), __result); + + return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result); + } + + template + __gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat> + __copy_move_backward_a(_II __first, _II __last, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __result) + { + typename ::__gnu_debug::_Distance_traits<_II>::__type __dist; + __glibcxx_check_valid_range2(__first, __last, __dist); + __glibcxx_check_can_increment(__result, -__dist.first); + + if (__dist.second == ::__gnu_debug::__dp_exact + && __result._M_can_advance(-__dist.first, true)) + return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>( + std::__copy_move_backward_a<_IsMove>(__first, __last, + __result.base()), + __result._M_sequence); + + return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result); + } + + template + ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat> + __copy_move_backward_a( + const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __first, + const ::__gnu_debug::_Safe_iterator<_IIte, _ISeq, _ICat>& __last, + const ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>& __result) + { + typename ::__gnu_debug::_Distance_traits<_IIte>::__type __dist; + __glibcxx_check_valid_range2(__first, __last, __dist); + __glibcxx_check_can_increment(__result, -__dist.first); + + if (__dist.second > ::__gnu_debug::__dp_equality) + { + if (__dist.second == ::__gnu_debug::__dp_exact + && __result._M_can_advance(-__dist.first, true)) + return ::__gnu_debug::_Safe_iterator<_OIte, _OSeq, _OCat>( + std::__copy_move_backward_a<_IsMove>(__first.base(), __last.base(), + __result.base()), + __result._M_sequence); + + return std::__copy_move_backward_a<_IsMove>( + __first.base(), __last.base(), __result); + } + + return std::__copy_move_backward_a1<_IsMove>(__first, __last, __result); + } + + template + void + __fill_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first, + const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __last, + const _Tp& __value) + { + typename ::__gnu_debug::_Distance_traits<_Ite>::__type __dist; + __glibcxx_check_valid_range2(__first, __last, __dist); + + if (__dist.second > ::__gnu_debug::__dp_equality) + std::__fill_a(__first.base(), __last.base(), __value); + + std::__fill_a1(__first, __last, __value); + } + + template + ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat> + __fill_n_a(const ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>& __first, + _Size __n, const _Tp& __value, + std::input_iterator_tag) + { + __glibcxx_check_can_increment(__first, __n); + + if (__first._M_can_advance(__n, true)) + return ::__gnu_debug::_Safe_iterator<_Ite, _Seq, _Cat>( + std::__fill_n_a(__first.base(), __n, __value, _Cat()), + __first._M_sequence); + + return std::__fill_n_a1(__first, __n, __value); + } + + template + bool + __equal_aux( + const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1, + const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1, + _II2 __first2) + { + typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist; + __glibcxx_check_valid_range2(__first1, __last1, __dist); + __glibcxx_check_can_increment(__first2, __dist.first); + + if (__dist.second > ::__gnu_debug::__dp_equality) + return std::__equal_aux(__first1.base(), __last1.base(), __first2); + + return std::__equal_aux1(__first1, __last1, __first2); + } + + template + bool + __equal_aux(_II1 __first1, _II1 __last1, + const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2) + { + typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist; + __glibcxx_check_valid_range2(__first1, __last1, __dist); + __glibcxx_check_can_increment(__first2, __dist.first); + + if (__dist.second == ::__gnu_debug::__dp_exact + && __first2._M_can_advance(__dist.first, true)) + return std::__equal_aux(__first1, __last1, __first2.base()); + + return std::__equal_aux1(__first1, __last1, __first2); + } + + template + bool + __equal_aux( + const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __first1, + const ::__gnu_debug::_Safe_iterator<_II1, _Seq1, _Cat1>& __last1, + const ::__gnu_debug::_Safe_iterator<_II2, _Seq2, _Cat2>& __first2) + { + typename ::__gnu_debug::_Distance_traits<_II1>::__type __dist; + __glibcxx_check_valid_range2(__first1, __last1, __dist); + __glibcxx_check_can_increment(__first2, __dist.first); + + if (__dist.second > ::__gnu_debug::__dp_equality) + { + if (__dist.second == ::__gnu_debug::__dp_exact && + __first2._M_can_advance(__dist.first, true)) + return std::__equal_aux(__first1.base(), __last1.base(), + __first2.base()); + return std::__equal_aux(__first1.base(), __last1.base(), __first2); + } + + return __equal_aux1(__first1, __last1, __first2); + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace std + #undef _GLIBCXX_DEBUG_VERIFY_DIST_OPERANDS #undef _GLIBCXX_DEBUG_VERIFY_REL_OPERANDS #undef _GLIBCXX_DEBUG_VERIFY_EQ_OPERANDS diff --git a/libstdc++-v3/include/debug/safe_iterator.tcc b/libstdc++-v3/include/debug/safe_iterator.tcc index 581c51c9607..3d30029dd25 100644 --- a/libstdc++-v3/include/debug/safe_iterator.tcc +++ b/libstdc++-v3/include/debug/safe_iterator.tcc @@ -82,7 +82,7 @@ namespace __gnu_debug template bool _Safe_iterator<_Iterator, _Sequence, _Category>:: - _M_can_advance(difference_type __n) const + _M_can_advance(difference_type __n, bool __strict) const { if (this->_M_singular()) return false; @@ -94,17 +94,17 @@ namespace __gnu_debug { std::pair __dist = _M_get_distance_from_begin(); - bool __ok = ((__dist.second == __dp_exact && __dist.first >= -__n) - || (__dist.second != __dp_exact && __dist.first > 0)); - return __ok; + return __dist.second == __dp_exact + ? __dist.first >= -__n + : !__strict && __dist.first > 0; } else { std::pair __dist = _M_get_distance_to_end(); - bool __ok = ((__dist.second == __dp_exact && __dist.first >= __n) - || (__dist.second != __dp_exact && __dist.first > 0)); - return __ok; + return __dist.second == __dp_exact + ? __dist.first >= __n + : !__strict && __dist.first > 0; } } diff --git a/libstdc++-v3/include/debug/stl_iterator.h b/libstdc++-v3/include/debug/stl_iterator.h index 3b9ee5d9beb..8a7c19428a6 100644 --- a/libstdc++-v3/include/debug/stl_iterator.h +++ b/libstdc++-v3/include/debug/stl_iterator.h @@ -115,17 +115,4 @@ namespace __gnu_debug #endif } -namespace std -{ -_GLIBCXX_BEGIN_NAMESPACE_VERSION - - template - _Iterator - __niter_base(const __gnu_debug::_Safe_iterator< - __gnu_cxx::__normal_iterator<_Iterator, _Container>, - _Sequence, std::random_access_iterator_tag>&); - -_GLIBCXX_END_NAMESPACE_VERSION -} - #endif diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector index 56b5e140fd3..8138600f143 100644 --- a/libstdc++-v3/include/debug/vector +++ b/libstdc++-v3/include/debug/vector @@ -794,13 +794,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION }; #endif - template - _Iterator - __niter_base(const __gnu_debug::_Safe_iterator< - __gnu_cxx::__normal_iterator<_Iterator, _Container>, - _Sequence, std::random_access_iterator_tag>& __it) - { return std::__niter_base(__it.base()); } - #if __cplusplus >= 201703L namespace __detail::__variant { diff --git a/libstdc++-v3/include/std/numeric b/libstdc++-v3/include/std/numeric index 239276946b5..0135db889c6 100644 --- a/libstdc++-v3/include/std/numeric +++ b/libstdc++-v3/include/std/numeric @@ -229,13 +229,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION /// @addtogroup numeric_ops /// @{ - /// @cond undocumented - template, - typename _Cat = typename _Traits::iterator_category> - using __is_random_access_iter - = is_base_of; - /// @endcond - /** * @brief Calculate reduction of values in a range. * diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/debug/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy/debug/1_neg.cc new file mode 100644 index 00000000000..f5a396e811d --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/debug/1_neg.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2019 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 +// . + +// 25.2.1 [lib.alg.copy] Copy. + +// { dg-do run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include +#include + +void +test01() +{ + std::list l(10, 1); + std::vector v(5, 0); + + std::copy(++l.begin(), --l.end(), v.begin()); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/2.cc b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/2.cc new file mode 100644 index 00000000000..7b0dc3d2126 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/2.cc @@ -0,0 +1,109 @@ +// Copyright (C) 2019 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 +#include + +#include + +void test01() +{ + using namespace std; + + deque d; + for (int i = 0; i != _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + deque dest(d.size(), 0); + + copy(d.begin(), d.end(), dest.begin()); + + VERIFY( equal(dest.begin(), dest.end(), d.begin()) ); +} + +void test02() +{ + using namespace std; + + deque d; + for (int i = 0; i != 4 * _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + deque dest(d.size(), 0); + + const deque& cd = d; + copy(cd.begin(), cd.end(), dest.begin()); + + VERIFY( equal(dest.begin(), dest.end(), cd.begin()) ); +} + +void test03() +{ + using namespace std; + + deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + d.pop_front(); + d.pop_back(); + + vector dest(d.size(), 0); + + copy(d.begin(), d.end(), dest.begin()); + VERIFY( equal(dest.begin(), dest.end(), d.begin()) ); +} + +void test04() +{ + using namespace std; + + vector v; + for (int i = 0; i != 1024; ++i) + v.push_back(i); + + deque dest(v.size() - 10, 0); + + std::copy(v.begin() + 5, v.end() - 5, dest.begin()); + VERIFY( std::equal(dest.begin(), dest.end(), v.begin() + 5) ); +} + +void test05() +{ + using namespace std; + + std::list l; + for (int i = 0; i != 1024; ++i) + l.push_back(i); + + std::deque dest(l.size(), 0); + + std::copy(l.begin(), l.end(), dest.begin()); + VERIFY( std::equal(dest.begin(), dest.end(), l.begin()) ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/31.cc b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/31.cc new file mode 100644 index 00000000000..ae2c33b1d10 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/31.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2019 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 run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include +#include + +#include + +void test01() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::vector dest(d.size(), 0); + + const std::deque& cd = d; + std::copy(cd.begin() + 10, cd.begin() + 5, dest.begin()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/32.cc b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/32.cc new file mode 100644 index 00000000000..8028bd6b542 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/32.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2019 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 run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include +#include + +#include + +void test01() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::vector dest(d.size() / 2, 0); + + const std::deque& cd = d; + std::copy(cd.begin(), cd.end(), dest.begin()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/33.cc b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/33.cc new file mode 100644 index 00000000000..1633fafd20c --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/33.cc @@ -0,0 +1,57 @@ +// Copyright (C) 2019 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 run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include +#include + +#include + +void test01() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::list dest(d.size(), 0); + + const std::deque& cd = d; + std::copy(cd.begin(), cd.end(), dest.begin()); +} + +void test02() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::list dest(d.size() / 2, 0); + std::list::iterator lit = dest.begin(); + + const std::deque& cd = d; + std::copy(cd.begin(), cd.end(), ++lit); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/41.cc b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/41.cc new file mode 100644 index 00000000000..0c9d949807a --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/41.cc @@ -0,0 +1,42 @@ +// Copyright (C) 2019 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 run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include +#include + +#include + +void test01() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::vector dest(d.size(), 0); + + std::copy(d.begin() + 10, d.begin() + 5, dest.begin()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/42.cc b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/42.cc new file mode 100644 index 00000000000..c7e0c1f49fd --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/42.cc @@ -0,0 +1,42 @@ +// Copyright (C) 2019 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 run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include +#include + +#include + +void test01() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::vector dest(d.size() / 2, 0); + + std::copy(d.begin(), d.end(), dest.begin()); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/43.cc b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/43.cc new file mode 100644 index 00000000000..2f29afae09f --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy/deque_iterators/43.cc @@ -0,0 +1,55 @@ +// Copyright (C) 2019 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 run { xfail *-*-* } } +// { dg-require-debug-mode "" } + +#include +#include +#include + +#include + +void test01() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::list dest(d.size(), 0); + + std::copy(d.begin(), d.end(), dest.begin()); +} + +void test02() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::list dest(d.size() / 2, 0); + std::list::iterator lit = dest.begin(); + + std::copy(d.begin(), d.end(), ++lit); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/deque_iterators/2.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/deque_iterators/2.cc new file mode 100644 index 00000000000..ccde5279859 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/deque_iterators/2.cc @@ -0,0 +1,109 @@ +// Copyright (C) 2019 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 +#include + +#include + +void test01() +{ + using namespace std; + + deque d; + for (int i = 0; i != _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + deque dest(d.size(), 0); + + copy_backward(d.begin(), d.end(), dest.end()); + + VERIFY( equal(dest.begin(), dest.end(), d.begin()) ); +} + +void test02() +{ + using namespace std; + + deque d; + for (int i = 0; i != 4 * _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + deque dest(d.size(), 0); + + const deque& cd = d; + copy_backward(cd.begin(), cd.end(), dest.end()); + + VERIFY( equal(dest.begin(), dest.end(), cd.begin()) ); +} + +void test03() +{ + using namespace std; + + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + d.pop_front(); + d.pop_back(); + + std::vector dest(d.size(), 0); + + std::copy_backward(d.begin(), d.end(), dest.end()); + VERIFY( std::equal(dest.begin(), dest.end(), d.begin()) ); +} + +void test04() +{ + using namespace std; + + std::vector v; + for (int i = 0; i != 1024; ++i) + v.push_back(i); + + std::deque dest(v.size() - 10, 0); + + std::copy_backward(v.begin() + 5, v.end() - 5, dest.end()); + VERIFY( std::equal(v.begin() + 5, v.end() - 5, dest.begin()) ); +} + +void test05() +{ + using namespace std; + + std::list l; + for (int i = 0; i != 1024; ++i) + l.push_back(i); + + std::deque dest(l.size(), 0); + + std::copy_backward(l.begin(), l.end(), dest.end()); + VERIFY( std::equal(dest.begin(), dest.end(), l.begin()) ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/deque_iterators/1.cc b/libstdc++-v3/testsuite/25_algorithms/equal/deque_iterators/1.cc new file mode 100644 index 00000000000..b99cf1df538 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/equal/deque_iterators/1.cc @@ -0,0 +1,122 @@ +// Copyright (C) 2019 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 + +#include +#include + +#include + +void test01() +{ + using namespace std; + + deque d; + for (int i = 0; i != _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + const deque& cd = d; + + VERIFY( equal(cd.begin(), cd.end(), cd.begin()) ); + VERIFY( equal(cd.begin(), cd.end(), d.begin()) ); + VERIFY( equal(d.begin(), d.end(), d.begin()) ); + VERIFY( equal(d.begin(), d.end(), cd.begin()) ); +} + +void test02() +{ + using namespace std; + + deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i % 10); + + VERIFY( equal(d.begin(), d.begin() + 10, d.begin() + 20) ); + VERIFY( equal(d.begin() + 10, d.end() - 10, d.begin()) ); + + const deque& cd = d; + + VERIFY( equal(cd.begin(), cd.begin() + 10, cd.begin() + 20) ); + VERIFY( equal(cd.begin() + 10, cd.end() - 10, d.begin()) ); + VERIFY( equal(d.begin() + 10, d.end() - 10, cd.begin()) ); +} + +void test03() +{ + using namespace std; + + deque d1; + for (int i = 0; i != 1024; ++i) + d1.push_back(i % 10); + + deque d2(d1); + for (int i = 0; i != 10; ++i) + d2.pop_front(); + + VERIFY( equal(d1.begin(), d1.begin() + 10, d2.begin()) ); + VERIFY( equal(d1.begin() + 10, d1.end() - 10, d2.begin()) ); + + const deque& cd1 = d1; + const deque& cd2 = d2; + + VERIFY( equal(cd1.begin(), cd1.begin() + 10, cd2.begin() + 20) ); + VERIFY( equal(cd1.begin() + 10, cd1.end() - 10, d2.begin()) ); + VERIFY( equal(cd2.begin() + 10, cd2.end() - 10, cd1.begin()) ); +} + +void test04() +{ + using namespace std; + + deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + vector v(d.begin(), d.end()); + + VERIFY( equal(d.begin(), d.end(), v.begin()) ); + VERIFY( equal(v.begin(), v.end(), d.begin()) ); + + const deque& cd = d; + + VERIFY( equal(cd.begin(), cd.end(), v.begin()) ); + VERIFY( equal(v.begin(), v.end(), cd.begin()) ); +} + +void test05() +{ + using namespace std; + + int a[] { 0, 1, 2, 3, 4 }; + deque > d1(a, a + 5); + deque > d2(a, a + 5); + + VERIFY( equal(d1.begin(), d1.end(), d2.begin()) ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/fill/deque_iterators/1.cc b/libstdc++-v3/testsuite/25_algorithms/fill/deque_iterators/1.cc new file mode 100644 index 00000000000..604ccb67fcd --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/fill/deque_iterators/1.cc @@ -0,0 +1,58 @@ +// Copyright (C) 2019 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 + +void test01() +{ + using namespace std; + + deque d1; + for (int i = 0; i != _GLIBCXX_STD_C::__deque_buf_size(sizeof(char)); ++i) + d1.push_back((char)i); + + deque d2(d1.size(), '\0'); + + fill(d1.begin(), d1.end(), '\0'); + + VERIFY( equal(d1.begin(), d1.end(), d2.begin()) ); +} + +void test02() +{ + using namespace std; + + deque d1; + for (int i = 0; i != 4 * _GLIBCXX_STD_C::__deque_buf_size(sizeof(char)); ++i) + d1.push_back(i); + + deque d2(d1.size(), '\0'); + + fill(d1.begin(), d1.end(), '\0'); + + VERIFY( equal(d1.begin(), d1.end(), d2.begin()) ); +} + +int main() +{ + test01(); + test02(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/move/deque_iterators/2.cc b/libstdc++-v3/testsuite/25_algorithms/move/deque_iterators/2.cc new file mode 100644 index 00000000000..1f7930036d1 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/move/deque_iterators/2.cc @@ -0,0 +1,101 @@ +// { dg-do run { target c++11 } } +// Copyright (C) 2019 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 +#include + +#include + +void test01() +{ + using namespace std; + + deque d; + for (int i = 0; i != _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + deque dest(d.size(), 0); + + move(d.begin(), d.end(), dest.begin()); + + VERIFY( equal(dest.begin(), dest.end(), d.begin()) ); +} + +void test02() +{ + using namespace std; + + deque d; + for (int i = 0; i != 4 * _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + deque dest(d.size(), 0); + + const deque& cd = d; + move(cd.begin(), cd.end(), dest.begin()); + + VERIFY( equal(dest.begin(), dest.end(), cd.begin()) ); +} + +void test03() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::vector dest(d.size(), 0); + + std::move(d.begin(), d.end(), dest.begin()); + VERIFY( std::equal(dest.begin(), dest.end(), d.begin()) ); +} + +void test04() +{ + std::vector v; + for (int i = 0; i != 1024; ++i) + v.push_back(i); + + std::deque dest(v.size() - 10, 0); + + std::move(v.begin() + 5, v.end() - 5, dest.begin()); + VERIFY( std::equal(dest.begin(), dest.end(), v.begin() + 5) ); +} + +void test05() +{ + std::list l; + for (int i = 0; i != 1024; ++i) + l.push_back(i); + + std::deque dest(l.size(), 0); + + std::move(l.begin(), l.end(), dest.begin()); + VERIFY( std::equal(dest.begin(), dest.end(), l.begin()) ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/move_backward/deque_iterators/2.cc b/libstdc++-v3/testsuite/25_algorithms/move_backward/deque_iterators/2.cc new file mode 100644 index 00000000000..82fff3e20c8 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/move_backward/deque_iterators/2.cc @@ -0,0 +1,101 @@ +// { dg-do run { target c++11 } } +// Copyright (C) 2019 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 +#include + +#include + +void test01() +{ + using namespace std; + + deque d; + for (int i = 0; i != _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + deque dest(d.size(), 0); + + move_backward(d.begin(), d.end(), dest.end()); + + VERIFY( equal(dest.begin(), dest.end(), d.begin()) ); +} + +void test02() +{ + using namespace std; + + deque d; + for (int i = 0; i != 4 * _GLIBCXX_STD_C::__deque_buf_size(sizeof(int)); ++i) + d.push_back(i); + + deque dest(d.size(), 0); + + const deque& cd = d; + move_backward(cd.begin(), cd.end(), dest.end()); + + VERIFY( equal(dest.begin(), dest.end(), cd.begin()) ); +} + +void test03() +{ + std::deque d; + for (int i = 0; i != 1024; ++i) + d.push_back(i); + + std::vector dest(d.size(), 0); + + std::move_backward(d.begin(), d.end(), dest.end()); + VERIFY( std::equal(dest.begin(), dest.end(), d.begin()) ); +} + +void test04() +{ + std::vector v; + for (int i = 0; i != 1024; ++i) + v.push_back(i); + + std::deque dest(v.size() - 10, 0); + + std::move_backward(v.begin() + 5, v.end() - 5, dest.end()); + VERIFY( std::equal(dest.begin(), dest.end(), v.begin() + 5) ); +} + +void test05() +{ + std::list l; + for (int i = 0; i != 1024; ++i) + l.push_back(i); + + std::deque dest(l.size(), 0); + + std::move_backward(l.begin(), l.end(), dest.end()); + VERIFY( std::equal(dest.begin(), dest.end(), l.begin()) ); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + return 0; +} diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/copy_backward_deque_iterators.cc b/libstdc++-v3/testsuite/performance/25_algorithms/copy_backward_deque_iterators.cc index 461dfc044ad..716907c1a96 100644 --- a/libstdc++-v3/testsuite/performance/25_algorithms/copy_backward_deque_iterators.cc +++ b/libstdc++-v3/testsuite/performance/25_algorithms/copy_backward_deque_iterators.cc @@ -16,6 +16,9 @@ // . #include +#include +#include + #include int main() @@ -34,7 +37,71 @@ int main() for (int j = 0; j < 3000; ++j) std::copy_backward(data.begin(), data.begin() + j, d.end()); stop_counters(time, resource); - report_performance(__FILE__, "", time, resource); + report_performance(__FILE__, "deque 2 deque", time, resource); + clear_counters(time, resource); + + std::vector v(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy_backward(data.begin(), data.begin() + j, v.end()); + stop_counters(time, resource); + report_performance(__FILE__, "deque 2 vector", time, resource); + clear_counters(time, resource); + + d.assign(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy_backward(v.begin(), v.begin() + j, d.end()); + stop_counters(time, resource); + report_performance(__FILE__, "vector 2 deque", time, resource); + clear_counters(time, resource); + + std::vector cv(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy_backward(data.begin(), data.begin() + j, cv.end()); + stop_counters(time, resource); + report_performance(__FILE__, "int deque 2 char vector", time, resource); + clear_counters(time, resource); + + d.assign(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy_backward(cv.begin(), cv.begin() + j, d.end()); + stop_counters(time, resource); + report_performance(__FILE__, "char vector 2 int deque", time, resource); + clear_counters(time, resource); + + std::list l(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy_backward(data.begin(), data.begin() + j, l.end()); + stop_counters(time, resource); + report_performance(__FILE__, "deque 2 list", time, resource); + clear_counters(time, resource); + + d.assign(3000, 1); + + std::list::iterator lit; + start_counters(time, resource); + for (int i = 0; i < 200; ++i) + { + lit = l.begin(); + for (int j = 0; j < 3000; ++j, ++lit) + std::copy_backward(l.begin(), lit, d.end()); + } + stop_counters(time, resource); + report_performance(__FILE__, "list 2 deque", time, resource); return 0; } diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/copy_deque_iterators.cc b/libstdc++-v3/testsuite/performance/25_algorithms/copy_deque_iterators.cc index 35d5d79dec9..0bb2c55a950 100644 --- a/libstdc++-v3/testsuite/performance/25_algorithms/copy_deque_iterators.cc +++ b/libstdc++-v3/testsuite/performance/25_algorithms/copy_deque_iterators.cc @@ -16,6 +16,9 @@ // . #include +#include +#include + #include int main() @@ -34,7 +37,71 @@ int main() for (int j = 0; j < 3000; ++j) std::copy(data.begin(), data.begin() + j, d.begin()); stop_counters(time, resource); - report_performance(__FILE__, "", time, resource); + report_performance(__FILE__, "deque 2 deque", time, resource); + clear_counters(time, resource); + + std::vector v(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy(data.begin(), data.begin() + j, v.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "deque 2 vector", time, resource); + clear_counters(time, resource); + + d.assign(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy(v.begin(), v.begin() + j, d.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "vector 2 deque", time, resource); + clear_counters(time, resource); + + std::vector cv(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy(data.begin(), data.begin() + j, cv.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "int deque 2 char vector", time, resource); + clear_counters(time, resource); + + d.assign(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy(cv.begin(), cv.begin() + j, d.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "char vector 2 int deque", time, resource); + clear_counters(time, resource); + + std::list l(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::copy(data.begin(), data.begin() + j, l.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "deque 2 list", time, resource); + clear_counters(time, resource); + + d.assign(3000, 1); + + std::list::iterator lit; + start_counters(time, resource); + for (int i = 0; i < 200; ++i) + { + lit = l.begin(); + for (int j = 0; j < 3000; ++j, ++lit) + std::copy(l.begin(), lit, d.begin()); + } + stop_counters(time, resource); + report_performance(__FILE__, "list 2 deque", time, resource); return 0; } diff --git a/libstdc++-v3/testsuite/performance/25_algorithms/equal_deque_iterators.cc b/libstdc++-v3/testsuite/performance/25_algorithms/equal_deque_iterators.cc new file mode 100644 index 00000000000..66c4601c5f6 --- /dev/null +++ b/libstdc++-v3/testsuite/performance/25_algorithms/equal_deque_iterators.cc @@ -0,0 +1,82 @@ +// Copyright (C) 2019 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 + +int main() +{ + using namespace __gnu_test; + + time_counter time; + resource_counter resource; + + const std::deque data(3000, 1); + + std::deque d(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::equal(data.begin(), data.begin() + j, d.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "deque vs deque", time, resource); + clear_counters(time, resource); + + std::vector v(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::equal(data.begin(), data.begin() + j, v.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "deque vs vector", time, resource); + clear_counters(time, resource); + + d.assign(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::equal(v.begin(), v.begin() + j, d.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "vector vs deque", time, resource); + clear_counters(time, resource); + + std::vector cv(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::equal(data.begin(), data.begin() + j, cv.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "int deque vs char vector", time, resource); + clear_counters(time, resource); + + d.assign(3000, 1); + + start_counters(time, resource); + for (int i = 0; i < 1000; ++i) + for (int j = 0; j < 3000; ++j) + std::equal(cv.begin(), cv.begin() + j, d.begin()); + stop_counters(time, resource); + report_performance(__FILE__, "char vector vs int deque", time, resource); + + return 0; +}