From patchwork Mon Jun 11 19:26:23 2018 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: 927870 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-479489-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="M9KVoX5/"; 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 414NLH5nDCz9rvt for ; Tue, 12 Jun 2018 05:26:47 +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=k9/XHvfOq5d97KsSJ47geCrhMFd2zGN31ez3vONqIyaUa0SYpEtgJ 0DjlFjPive449gM9eNko+FE28WN0L5fXCo5I/uptWkrxun8lLHlBhU8AnXbx8HKE 6QLFvW8l2+cFgQFo0s7jGfOGszEuwYnD8eBrA4oY5hSkt6nm6lBujc= 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=mB9zJFQD72epK477QLaBaySSeL4=; b=M9KVoX5/X6zdf0xAPphf 7YaGeOpWbK6acrm3gbHXlznjqy5eH6OJbSS/t3Tgo7cQzxUVw2ycdk01t21CKqXY g7KOBdvbsn09P/plQ0TJ+fvfRIFBSh9Ig7XVNftFqZQNMRH8D6b9nXzyBUVE9H0F 26C293Uf5cKcSvhAdasogfc= Received: (qmail 103981 invoked by alias); 11 Jun 2018 19:26:31 -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 103957 invoked by uid 89); 11 Jun 2018 19:26:31 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.1 required=5.0 tests=AWL, 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.2 spammy=told, evening, HX-Received:sk:n6-v6mr, 2nd X-Spam-User: qpsmtpd, 2 recipients X-HELO: mail-wr0-f169.google.com Received: from mail-wr0-f169.google.com (HELO mail-wr0-f169.google.com) (209.85.128.169) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 11 Jun 2018 19:26:27 +0000 Received: by mail-wr0-f169.google.com with SMTP id x4-v6so13436619wro.11; Mon, 11 Jun 2018 12:26:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-language; bh=3VpsVJXS04U3a9dcV7RJL75WsQAQSP/Y/SiMnJkt4Ls=; b=VRdFzNPbGQ3guLIZLazICkdfBDAPf1VgfAAGiQNXxXyvouC1zdmbGmULOcRzJrK62E AT4Lz4ldvP0VSHq7C3GNtN7yEiZGCMoIdtZM5JlYgRtcFTLG5PiJqVu3DT6BVPy64FE6 IKt+aXTl/4BDyMH7vXosg1kjaozMxy3LDILCXryS0Pm8qz5w7sEQj7qQH/QUcN2IDHng cwVk3Yj/6kaMYptH75hLO3jeQf1nT+m/gPj7ljk9Qb7DH5ufn2QSbU8XFq7MDjnhuH5/ ZnL2mY9iIEKAGMugQHnvF5adDjYDbrYlzIifcRBd3rOjG/WmcPH9ZA2xD0Ddj651mWrX UyVA== X-Gm-Message-State: APt69E0d8NmJuuv+mAWOOHjfIf8oiz2Biqb6paIHjaPhUx8PUzpA84q5 Lp/cx8TljLE7GtfdTCjw3gS21g== X-Google-Smtp-Source: ADUXVKIwpttpfmpElYMn06KqYqFEQkRdbP0US9zMFJZJGA+VZLfRVlfxupjQKMyxoZduPhla2IO4jQ== X-Received: by 2002:a5d:4206:: with SMTP id n6-v6mr333734wrq.13.1528745185521; Mon, 11 Jun 2018 12:26:25 -0700 (PDT) Received: from [192.168.0.22] (arf62-1-82-237-250-248.fbx.proxad.net. [82.237.250.248]) by smtp.googlemail.com with ESMTPSA id n7-v6sm47472560wri.27.2018.06.11.12.26.24 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Jun 2018 12:26:24 -0700 (PDT) From: =?utf-8?q?Fran=C3=A7ois_Dumont?= Subject: New can_[in,de]crement_range debug checks To: "libstdc++@gcc.gnu.org" , gcc-patches Message-ID: <43e32319-c5a6-90ce-5b28-1e9273992a7e@gmail.com> Date: Mon, 11 Jun 2018 21:26:23 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.8.0 MIME-Version: 1.0 Hi     If not told otherwise I plan to commit attached patch tomorrow evening.     It is adding new Debug checks to find out if an output iterator will always be reachable while looping on an input range. Note that this check was already done previously by checking if the iterator was [in,de]crementable but it will now assert before any operation take place. I also need it in order to remove debug layer on the output iterator in a future patch.     I am also adding some tests on the std::equal algorithm because I plan to apply those macros to this algo too but users can append a special value at the end of the 2nd range to make sure it will never go beyond this position. Some tests are doing this and was triggering the Debug check.     * include/debug/macros.h (__glibcxx_check_can_increment_range): New.     (__glibcxx_check_can_decrement_range): New.     * include/debug/debug.h (__glibcxx_requires_can_increment_range): New.     (__glibcxx_requires_can_decrement_range): New.     * include/bits/stl_algobase.h (std::copy(_II, _II, _OI)): Use     __glibcxx_requires_can_increment_range.     (std::move(_II, _II, _OI)): Likewise.     (std::copy_backward(_BI, _BI, _BI2)): Use     __glibcxx_requires_can_decrement_range.     (std::move_backward(_BI, _BI, _BI2)): Likewise.     * testsuite/25_algorithms/copy_backward/debug/1_neg.cc: New.     * testsuite/25_algorithms/copy_backward/debug/2_neg.cc: New.     * testsuite/25_algorithms/copy_backward/debug/3_neg.cc: New.     * testsuite/25_algorithms/equal/debug/1_neg.cc: New.     * testsuite/25_algorithms/equal/debug/2_neg.cc: New.     * testsuite/25_algorithms/equal/debug/3_neg.cc: New. Tested under Linux x86_64, normal and debug modes. François diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h index bbc5774..d429943 100644 --- a/libstdc++-v3/include/bits/stl_algobase.h +++ b/libstdc++-v3/include/bits/stl_algobase.h @@ -449,11 +449,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_function_requires(_InputIteratorConcept<_II>) __glibcxx_function_requires(_OutputIteratorConcept<_OI, typename iterator_traits<_II>::value_type>) - __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_can_increment_range(__first, __last, __result); - return (std::__copy_move_a2<__is_move_iterator<_II>::__value> - (std::__miter_base(__first), std::__miter_base(__last), - __result)); + return std::__copy_move_a2<__is_move_iterator<_II>::__value> + (std::__miter_base(__first), std::__miter_base(__last), __result); } #if __cplusplus >= 201103L @@ -482,7 +481,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_function_requires(_InputIteratorConcept<_II>) __glibcxx_function_requires(_OutputIteratorConcept<_OI, typename iterator_traits<_II>::value_type>) - __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_can_increment_range(__first, __last, __result); return std::__copy_move_a2(std::__miter_base(__first), std::__miter_base(__last), __result); @@ -627,11 +626,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_function_requires(_ConvertibleConcept< typename iterator_traits<_BI1>::value_type, typename iterator_traits<_BI2>::value_type>) - __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_can_decrement_range(__first, __last, __result); - return (std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value> - (std::__miter_base(__first), std::__miter_base(__last), - __result)); + return std::__copy_move_backward_a2<__is_move_iterator<_BI1>::__value> + (std::__miter_base(__first), std::__miter_base(__last), __result); } #if __cplusplus >= 201103L @@ -663,7 +661,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __glibcxx_function_requires(_ConvertibleConcept< typename iterator_traits<_BI1>::value_type, typename iterator_traits<_BI2>::value_type>) - __glibcxx_requires_valid_range(__first, __last); + __glibcxx_requires_can_decrement_range(__first, __last, __result); return std::__copy_move_backward_a2(std::__miter_base(__first), std::__miter_base(__last), diff --git a/libstdc++-v3/include/debug/debug.h b/libstdc++-v3/include/debug/debug.h index bddaa1c..f157a6d 100644 --- a/libstdc++-v3/include/debug/debug.h +++ b/libstdc++-v3/include/debug/debug.h @@ -63,6 +63,8 @@ namespace __gnu_debug # define __glibcxx_requires_cond(_Cond,_Msg) # define __glibcxx_requires_valid_range(_First,_Last) # define __glibcxx_requires_can_increment(_First,_Size) +# define __glibcxx_requires_can_increment_range(_First1,_Last1,_First2) +# define __glibcxx_requires_can_decrement_range(_First1,_Last1,_First2) # define __glibcxx_requires_sorted(_First,_Last) # define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) # define __glibcxx_requires_sorted_set(_First1,_Last1,_First2) @@ -89,6 +91,10 @@ namespace __gnu_debug __glibcxx_check_valid_range(_First,_Last) # define __glibcxx_requires_can_increment(_First,_Size) \ __glibcxx_check_can_increment(_First,_Size) +# define __glibcxx_requires_can_increment_range(_First1,_Last1,_First2) \ + __glibcxx_check_can_increment_range(_First1,_Last1,_First2) +# define __glibcxx_requires_can_decrement_range(_First1,_Last1,_First2) \ + __glibcxx_check_can_decrement_range(_First1,_Last1,_First2) # define __glibcxx_requires_sorted(_First,_Last) \ __glibcxx_check_sorted(_First,_Last) # define __glibcxx_requires_sorted_pred(_First,_Last,_Pred) \ diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h index 3a8cbe8..44f48b0 100644 --- a/libstdc++-v3/include/debug/macros.h +++ b/libstdc++-v3/include/debug/macros.h @@ -38,12 +38,15 @@ * the user error and where the error is reported. * */ +#define _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func) \ + if (! (_Cond)) \ + __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func) \ + ._ErrMsg._M_error() + #define _GLIBCXX_DEBUG_VERIFY_AT_F(_Cond,_ErrMsg,_File,_Line,_Func) \ do \ { \ - if (! (_Cond)) \ - __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func) \ - ._ErrMsg._M_error(); \ + _GLIBCXX_DEBUG_VERIFY_COND_AT(_Cond,_ErrMsg,_File,_Line,_Func); \ } while (false) #define _GLIBCXX_DEBUG_VERIFY_AT(_Cond,_ErrMsg,_File,_Line) \ @@ -91,6 +94,42 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__can_advance(_First, _Size), \ ._M_iterator(_First, #_First) \ ._M_integer(_Size, #_Size)) +#define __glibcxx_check_can_increment_range(_First1,_Last1,_First2) \ + do \ + { \ + typename __gnu_debug::_Distance_traits<__decltype(_First1)>::__type __dist;\ + _GLIBCXX_DEBUG_VERIFY_COND_AT( \ + __gnu_debug::__valid_range(_First1, _Last1, __dist),\ + _M_message(__gnu_debug::__msg_valid_range) \ + ._M_iterator(_First1, #_First1) \ + ._M_iterator(_Last1, #_Last1), \ + __FILE__,__LINE__,__PRETTY_FUNCTION__); \ + _GLIBCXX_DEBUG_VERIFY_COND_AT( \ + __gnu_debug::__can_advance(_First2, __dist.first),\ + _M_message(__gnu_debug::__msg_iter_subscript_oob)\ + ._M_iterator(_First2, #_First2) \ + ._M_integer(__dist.first), \ + __FILE__,__LINE__,__PRETTY_FUNCTION__); \ + } while(false) + +#define __glibcxx_check_can_decrement_range(_First1,_Last1,_First2) \ + do \ + { \ + typename __gnu_debug::_Distance_traits<__decltype(_First1)>::__type __dist;\ + _GLIBCXX_DEBUG_VERIFY_COND_AT( \ + __gnu_debug::__valid_range(_First1, _Last1, __dist),\ + _M_message(__gnu_debug::__msg_valid_range) \ + ._M_iterator(_First1, #_First1) \ + ._M_iterator(_Last1, #_Last1), \ + __FILE__,__LINE__,__PRETTY_FUNCTION__); \ + _GLIBCXX_DEBUG_VERIFY_COND_AT( \ + __gnu_debug::__can_advance(_First2, -__dist.first),\ + _M_message(__gnu_debug::__msg_iter_subscript_oob)\ + ._M_iterator(_First2, #_First2) \ + ._M_integer(-__dist.first), \ + __FILE__,__LINE__,__PRETTY_FUNCTION__); \ + } while(false) + /** Verify that we can insert into *this with the iterator _Position. * Insertion into a container at a specific position requires that * the iterator be nonsingular, either dereferenceable or past-the-end, @@ -152,7 +191,7 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First,_Last),\ * _Safe_sequence and the _Position iterator is a _Safe_iterator. */ #define __glibcxx_check_insert_range_after(_Position,_First,_Last,_Dist)\ - __glibcxx_check_valid_range2(_First,_Last,_Dist); \ +__glibcxx_check_valid_range2(_First,_Last,_Dist); \ __glibcxx_check_insert_after(_Position); \ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First,_Last),\ _M_message(__gnu_debug::__msg_insert_range_from_self)\ diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/1_neg.cc new file mode 100644 index 0000000..10375b7 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/1_neg.cc @@ -0,0 +1,37 @@ +// Copyright (C) 2018 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 + +void +test01() +{ + std::vector vect; + vect.push_back(1); + std::copy_backward(vect.end(), vect.begin(), vect.end()); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/2_neg.cc new file mode 100644 index 0000000..7f6bcd1 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/2_neg.cc @@ -0,0 +1,37 @@ +// Copyright (C) 2018 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 + +void +test01() +{ + std::vector vect; + vect.push_back(1); + std::copy_backward(vect.begin(), vect.end(), vect.begin()); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/3_neg.cc b/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/3_neg.cc new file mode 100644 index 0000000..89d5d0a --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/copy_backward/debug/3_neg.cc @@ -0,0 +1,41 @@ +// Copyright (C) 2018 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 + +void +test01() +{ + std::list l1, l2; + l1.push_back(1); + l1.push_back(2); + l1.push_back(3); + + l2.push_back(1); + std::copy_backward(++l1.begin(), l1.end(), l2.end()); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/debug/1_neg.cc b/libstdc++-v3/testsuite/25_algorithms/equal/debug/1_neg.cc new file mode 100644 index 0000000..096c785e --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/equal/debug/1_neg.cc @@ -0,0 +1,37 @@ +// Copyright (C) 2018 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 + +void +test01() +{ + std::vector vect; + vect.push_back(1); + std::equal(vect.end(), vect.begin(), vect.begin()); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/debug/2_neg.cc b/libstdc++-v3/testsuite/25_algorithms/equal/debug/2_neg.cc new file mode 100644 index 0000000..97b1e1f --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/equal/debug/2_neg.cc @@ -0,0 +1,37 @@ +// Copyright (C) 2018 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 + +void +test01() +{ + std::vector v1, v2; + v1.push_back(1); + std::equal(v1.begin(), v1.end(), v2.begin()); +} + +int +main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/25_algorithms/equal/debug/3_neg.cc b/libstdc++-v3/testsuite/25_algorithms/equal/debug/3_neg.cc new file mode 100644 index 0000000..48bcea7 --- /dev/null +++ b/libstdc++-v3/testsuite/25_algorithms/equal/debug/3_neg.cc @@ -0,0 +1,43 @@ +// Copyright (C) 2018 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 + +void +test01() +{ + std::list l1, l2; + l1.push_back(1); + l1.push_back(2); + l1.push_back(3); + + l2.push_back(1); + l2.push_back(2); + + std::equal(++l1.begin(), l1.end(), ++l2.begin()); +} + +int +main() +{ + test01(); + return 0; +}