From 5e108459ec3e6edc88534786f970b57b7714f80a Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 30 Apr 2010 09:52:41 +0000 Subject: [PATCH] stl_pair.h (piecewise_construct_t, [...]): Add. 2010-04-30 Paolo Carlini * include/bits/stl_pair.h (piecewise_construct_t, pair<>::pair(piecewise_construct_t, tuple, tuple)): Add. (pair<>::__cons, pair<>::__do_cons): Declare. (__decay_and_strip, __strip_reference_wrapper): Move... * include/std/type_traits: ... here. * include/std/functional (_Index_tuple, _Build_index_tuple): Move... * include/std/tuple: ... here. (pack_arguments): Add. (pair<>::__cons, pair<>::__do_cons): Define. * testsuite/20_util/tuple/creation_functions/pack_arguments.cc: New. * testsuite/20_util/pair/piecewise.cc: Likewise. * testsuite/20_util/tuple/cons/big_tuples.cc: Include . * testsuite/20_util/tuple/cons/constructor.cc: Likewise. * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust dg-error line numbers. * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: Likewise. * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. From-SVN: r158928 --- libstdc++-v3/ChangeLog | 21 ++++ libstdc++-v3/include/bits/stl_pair.h | 61 ++++++------ libstdc++-v3/include/std/functional | 23 ----- libstdc++-v3/include/std/tuple | 65 ++++++++++++ libstdc++-v3/include/std/type_traits | 29 ++++++ .../20_util/declval/requirements/1_neg.cc | 4 +- .../make_signed/requirements/typedefs_neg.cc | 6 +- .../requirements/typedefs_neg.cc | 6 +- .../testsuite/20_util/pair/piecewise.cc | 98 +++++++++++++++++++ .../20_util/tuple/cons/big_tuples.cc | 3 +- .../20_util/tuple/cons/constructor.cc | 3 +- .../creation_functions/pack_arguments.cc | 72 ++++++++++++++ 12 files changed, 326 insertions(+), 65 deletions(-) create mode 100644 libstdc++-v3/testsuite/20_util/pair/piecewise.cc create mode 100644 libstdc++-v3/testsuite/20_util/tuple/creation_functions/pack_arguments.cc diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 3c4b8db4b62..14287ab3189 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,24 @@ +2010-04-30 Paolo Carlini + + * include/bits/stl_pair.h (piecewise_construct_t, + pair<>::pair(piecewise_construct_t, tuple, tuple)): Add. + (pair<>::__cons, pair<>::__do_cons): Declare. + (__decay_and_strip, __strip_reference_wrapper): Move... + * include/std/type_traits: ... here. + * include/std/functional (_Index_tuple, _Build_index_tuple): Move... + * include/std/tuple: ... here. + (pack_arguments): Add. + (pair<>::__cons, pair<>::__do_cons): Define. + * testsuite/20_util/tuple/creation_functions/pack_arguments.cc: New. + * testsuite/20_util/pair/piecewise.cc: Likewise. + * testsuite/20_util/tuple/cons/big_tuples.cc: Include . + * testsuite/20_util/tuple/cons/constructor.cc: Likewise. + * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Adjust + dg-error line numbers. + * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc: + Likewise. + * testsuite/20_util/declval/requirements/1_neg.cc: Likewise. + 2010-04-27 Jonathan Wakely PR libstdc++/43865 diff --git a/libstdc++-v3/include/bits/stl_pair.h b/libstdc++-v3/include/bits/stl_pair.h index 11d0d107f25..0618026f4d6 100644 --- a/libstdc++-v3/include/bits/stl_pair.h +++ b/libstdc++-v3/include/bits/stl_pair.h @@ -57,15 +57,25 @@ #ifndef _STL_PAIR_H #define _STL_PAIR_H 1 -#include // for std::move / std::forward, std::decay, and - // std::swap +#include // for std::move / std::forward, and std::swap #ifdef __GXX_EXPERIMENTAL_CXX0X__ -#include +#include // for std::__decay_and_strip too #endif _GLIBCXX_BEGIN_NAMESPACE(std) +#ifdef __GXX_EXPERIMENTAL_CXX0X__ + struct piecewise_construct_t { }; + + // forward declarations + template + class tuple; + + template + struct _Index_tuple; +#endif + /// pair holds two objects of arbitrary type. template struct pair @@ -111,6 +121,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std) pair(pair&& __p) : first(std::move(__p.first)), second(std::move(__p.second)) { } + + template + pair(piecewise_construct_t, + tuple<_Args1...> __first_args, + tuple<_Args2...> __second_args) + : first(__cons(std::move(__first_args))), + second(__cons(std::move(__second_args))) { } #endif /** There is also a templated copy ctor for the @c pair class itself. */ @@ -149,6 +166,15 @@ _GLIBCXX_BEGIN_NAMESPACE(std) swap(first, __p.first); swap(second, __p.second); } + + private: + template + static _Tp + __cons(tuple<_Args...>&&); + + template + static _Tp + __do_cons(tuple<_Args...>&&, const _Index_tuple<_Indexes...>&); #endif }; @@ -217,35 +243,6 @@ _GLIBCXX_BEGIN_NAMESPACE(std) make_pair(_T1 __x, _T2 __y) { return pair<_T1, _T2>(__x, __y); } #else - template - class reference_wrapper; - - // Helper which adds a reference to a type when given a reference_wrapper - template - struct __strip_reference_wrapper - { - typedef _Tp __type; - }; - - template - struct __strip_reference_wrapper > - { - typedef _Tp& __type; - }; - - template - struct __strip_reference_wrapper > - { - typedef _Tp& __type; - }; - - template - struct __decay_and_strip - { - typedef typename __strip_reference_wrapper< - typename decay<_Tp>::type>::__type __type; - }; - // NB: DR 706. template inline pair::__type, diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 2ba7243837a..00b94940f24 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -857,29 +857,6 @@ namespace std : public integral_constant { }; - /** - * Stores a tuple of indices. Used by bind() to extract the elements - * in a tuple. - */ - template - struct _Index_tuple - { - typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; - }; - - /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. - template - struct _Build_index_tuple - { - typedef typename _Build_index_tuple<_Num-1>::__type::__next __type; - }; - - template<> - struct _Build_index_tuple<0> - { - typedef _Index_tuple<> __type; - }; - /** * Used by _Safe_tuple_element to indicate that there is no tuple * element at this position. diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple index bba7ba7bd08..f9aa14f2057 100644 --- a/libstdc++-v3/include/std/tuple +++ b/libstdc++-v3/include/std/tuple @@ -550,6 +550,28 @@ namespace std return __result_type(std::forward<_Elements>(__args)...); } + template::value> + struct __pa_add_rvalue_reference_helper + { typedef typename std::add_rvalue_reference<_Tp>::type __type; }; + + template + struct __pa_add_rvalue_reference_helper<_Tp, true> + { typedef _Tp& __type; }; + + template + struct __pa_add_rvalue_reference + : public __pa_add_rvalue_reference_helper<_Tp> + { }; + + template + inline tuple::__type...> + pack_arguments(_Elements&&... __args) + { + typedef tuple::__type...> + __result_type; + return __result_type(std::forward<_Elements>(__args)...); + } + template struct __index_holder { }; template @@ -678,6 +700,49 @@ namespace std { _Swallow_assign ignore; }; // anonymous namespace + + /** + * Stores a tuple of indices. Used by bind() to extract the elements + * in a tuple. + */ + template + struct _Index_tuple + { + typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next; + }; + + /// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>. + template + struct _Build_index_tuple + { + typedef typename _Build_index_tuple<_Num-1>::__type::__next __type; + }; + + template<> + struct _Build_index_tuple<0> + { + typedef _Index_tuple<> __type; + }; + + // See stl_pair.h... + template + template + inline _Tp + pair<_T1, _T2>:: + __cons(tuple<_Args...>&& __tuple) + { + typedef typename _Build_index_tuple::__type + _Indexes; + return __do_cons<_Tp>(std::move(__tuple), _Indexes()); + } + + template + template + inline _Tp + pair<_T1, _T2>:: + __do_cons(tuple<_Args...>&& __tuple, + const _Index_tuple<_Indexes...>&) + { return _Tp(std::forward<_Args>(get<_Indexes>(__tuple))...); } } #endif // __GXX_EXPERIMENTAL_CXX0X__ diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits index c8166198805..a2748c565b1 100644 --- a/libstdc++-v3/include/std/type_traits +++ b/libstdc++-v3/include/std/type_traits @@ -405,6 +405,35 @@ namespace std typedef typename __decay_selector<__remove_type>::__type type; }; + template + class reference_wrapper; + + // Helper which adds a reference to a type when given a reference_wrapper + template + struct __strip_reference_wrapper + { + typedef _Tp __type; + }; + + template + struct __strip_reference_wrapper > + { + typedef _Tp& __type; + }; + + template + struct __strip_reference_wrapper > + { + typedef _Tp& __type; + }; + + template + struct __decay_and_strip + { + typedef typename __strip_reference_wrapper< + typename decay<_Tp>::type>::__type __type; + }; + // Utility for constructing identically cv-qualified types. template diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc index 59b90961398..bd424788dfb 100644 --- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc +++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc @@ -2,7 +2,7 @@ // { dg-do compile } // 2009-11-12 Paolo Carlini // -// Copyright (C) 2009 Free Software Foundation, Inc. +// Copyright (C) 2009, 2010 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 @@ -19,7 +19,7 @@ // with this library; see the file COPYING3. If not see // . -// { dg-error "static assertion failed" "" { target *-*-* } 626 } +// { dg-error "static assertion failed" "" { target *-*-* } 655 } // { dg-error "instantiated from here" "" { target *-*-* } 30 } // { dg-excess-errors "In function" } diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc index eec74c71593..7a8ad661d85 100644 --- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc @@ -3,7 +3,7 @@ // 2007-05-03 Benjamin Kosnik // -// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010 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 @@ -48,8 +48,8 @@ void test01() // { dg-error "instantiated from here" "" { target *-*-* } 40 } // { dg-error "instantiated from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 588 } -// { dg-error "declaration of" "" { target *-*-* } 552 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 617 } +// { dg-error "declaration of" "" { target *-*-* } 581 } // { dg-excess-errors "At global scope" } // { dg-excess-errors "In instantiation of" } diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc index 708482ef8a3..23bca2bffa2 100644 --- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc +++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc @@ -3,7 +3,7 @@ // 2007-05-03 Benjamin Kosnik // -// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010 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 @@ -48,8 +48,8 @@ void test01() // { dg-error "instantiated from here" "" { target *-*-* } 40 } // { dg-error "instantiated from here" "" { target *-*-* } 42 } -// { dg-error "invalid use of incomplete type" "" { target *-*-* } 511 } -// { dg-error "declaration of" "" { target *-*-* } 475 } +// { dg-error "invalid use of incomplete type" "" { target *-*-* } 540 } +// { dg-error "declaration of" "" { target *-*-* } 504 } // { dg-excess-errors "At global scope" } // { dg-excess-errors "In instantiation of" } diff --git a/libstdc++-v3/testsuite/20_util/pair/piecewise.cc b/libstdc++-v3/testsuite/20_util/pair/piecewise.cc new file mode 100644 index 00000000000..3844e1bf1e4 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/pair/piecewise.cc @@ -0,0 +1,98 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-04-30 Paolo Carlini +// +// Copyright (C) 2010 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 +// . + +// Tuple + +#include +#include +#include + +struct type_zero +{ + type_zero() : n_(757) { } + + type_zero(const type_zero&) = delete; + type_zero(type_zero&& other) : n_(other.n_) { } + + int get() const { return n_; } + +private: + int n_; +}; + +struct type_one +{ + type_one(int n) : n_(n) { } + + type_one(const type_one&) = delete; + type_one(type_one&& other) : n_(other.n_) { } + + int get() const { return n_; } + +private: + int n_; +}; + +struct type_two +{ + type_two(int n1, int n2) : n1_(n1), n2_(n2) { } + + type_two(const type_two&) = delete; + type_two(type_two&& other) : n1_(other.n1_), n2_(other.n2_) { } + + int get1() const { return n1_; } + int get2() const { return n2_; } + +private: + int n1_, n2_; +}; + +void test01() +{ + bool test __attribute__((unused)) = true; + + std::pair pp0(std::piecewise_construct_t(), + std::pack_arguments(-3), + std::pack_arguments()); + VERIFY( pp0.first.get() == -3 ); + VERIFY( pp0.second.get() == 757 ); + + std::pair pp1(std::piecewise_construct_t(), + std::pack_arguments(6), + std::pack_arguments(5, 4)); + VERIFY( pp1.first.get() == 6 ); + VERIFY( pp1.second.get1() == 5 ); + VERIFY( pp1.second.get2() == 4 ); + + std::pair pp2(std::piecewise_construct_t(), + std::pack_arguments(2, 1), + std::pack_arguments(-1, -3)); + VERIFY( pp2.first.get1() == 2 ); + VERIFY( pp2.first.get2() == 1 ); + VERIFY( pp2.second.get1() == -1 ); + VERIFY( pp2.second.get2() == -3 ); +} + +int main() +{ + test01(); + return 0; +} diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/big_tuples.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/big_tuples.cc index f979623e932..7bcb5177169 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/cons/big_tuples.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/big_tuples.cc @@ -1,6 +1,6 @@ // { dg-options "-std=gnu++0x" } -// Copyright (C) 2007, 2009 Free Software Foundation, Inc. +// Copyright (C) 2007, 2009, 2010 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 @@ -20,6 +20,7 @@ // Tuple #include +#include // for pair #include using namespace std; diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/constructor.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/constructor.cc index 3afb059ce76..9871f4959a6 100644 --- a/libstdc++-v3/testsuite/20_util/tuple/cons/constructor.cc +++ b/libstdc++-v3/testsuite/20_util/tuple/cons/constructor.cc @@ -1,6 +1,6 @@ // { dg-options "-std=gnu++0x" } -// Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. +// Copyright (C) 2007, 2008, 2009, 2010 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 @@ -20,6 +20,7 @@ // Tuple #include +#include // for pair #include using namespace std; diff --git a/libstdc++-v3/testsuite/20_util/tuple/creation_functions/pack_arguments.cc b/libstdc++-v3/testsuite/20_util/tuple/creation_functions/pack_arguments.cc new file mode 100644 index 00000000000..872405e3025 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/tuple/creation_functions/pack_arguments.cc @@ -0,0 +1,72 @@ +// { dg-options "-std=gnu++0x" } + +// 2010-04-30 Paolo Carlini +// +// Copyright (C) 2010 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 +// . + +// Tuple + +#include +#include +#include + +void +test01() +{ + bool test __attribute__((unused)) = true; + + std::pack_arguments(); + + VERIFY( std::get<0>(std::pack_arguments(-1)) == -1 ); + VERIFY( (std::is_same>::value) ); + + const int i1 = 1; + const int i2 = 2; + const double d1 = 4.0; + auto t1 = std::pack_arguments(i1, i2, d1); + VERIFY( (std::is_same>::value) ); + VERIFY( std::get<0>(t1) == i1 ); + VERIFY( std::get<1>(t1) == i2 ); + VERIFY( std::get<2>(t1) == d1 ); + + typedef const int a_type1[3]; + a_type1 a1 = { -1, 1, 2 }; + auto t2 = std::pack_arguments(a1); + VERIFY( (std::is_same>::value) ); + VERIFY( std::get<0>(t2)[0] == a1[0] ); + VERIFY( std::get<0>(t2)[1] == a1[1] ); + VERIFY( std::get<0>(t2)[2] == a1[2] ); + + typedef int a_type2[2]; + a_type2 a2 = { 2, -2 }; + volatile int i4 = 1; + auto t3 = std::pack_arguments(a2, i4); + VERIFY( (std::is_same>::value) ); + VERIFY( std::get<0>(t3)[0] == a2[0] ); + VERIFY( std::get<0>(t3)[1] == a2[1] ); + VERIFY( std::get<1>(t3) == i4 ); +} + +int main() +{ + test01(); + return 0; +}