stl_pair.h (piecewise_construct_t, [...]): Add.

2010-04-30  Paolo Carlini  <paolo.carlini@oracle.com>

	* 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 <utility>.
	* 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
This commit is contained in:
Paolo Carlini 2010-04-30 09:52:41 +00:00 committed by Paolo Carlini
parent 41700fc33b
commit 5e108459ec
12 changed files with 326 additions and 65 deletions

View file

@ -1,3 +1,24 @@
2010-04-30 Paolo Carlini <paolo.carlini@oracle.com>
* 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 <utility>.
* 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 <jwakely.gcc@gmail.com>
PR libstdc++/43865

View file

@ -57,15 +57,25 @@
#ifndef _STL_PAIR_H
#define _STL_PAIR_H 1
#include <bits/move.h> // for std::move / std::forward, std::decay, and
// std::swap
#include <bits/move.h> // for std::move / std::forward, and std::swap
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <type_traits>
#include <type_traits> // for std::__decay_and_strip too
#endif
_GLIBCXX_BEGIN_NAMESPACE(std)
#ifdef __GXX_EXPERIMENTAL_CXX0X__
struct piecewise_construct_t { };
// forward declarations
template<typename...>
class tuple;
template<int...>
struct _Index_tuple;
#endif
/// pair holds two objects of arbitrary type.
template<class _T1, class _T2>
struct pair
@ -111,6 +121,13 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
pair(pair&& __p)
: first(std::move(__p.first)),
second(std::move(__p.second)) { }
template<class... _Args1, class... _Args2>
pair(piecewise_construct_t,
tuple<_Args1...> __first_args,
tuple<_Args2...> __second_args)
: first(__cons<first_type>(std::move(__first_args))),
second(__cons<second_type>(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<typename _Tp, typename... _Args>
static _Tp
__cons(tuple<_Args...>&&);
template<typename _Tp, typename... _Args, int... _Indexes>
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<typename _Tp>
class reference_wrapper;
// Helper which adds a reference to a type when given a reference_wrapper
template<typename _Tp>
struct __strip_reference_wrapper
{
typedef _Tp __type;
};
template<typename _Tp>
struct __strip_reference_wrapper<reference_wrapper<_Tp> >
{
typedef _Tp& __type;
};
template<typename _Tp>
struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
{
typedef _Tp& __type;
};
template<typename _Tp>
struct __decay_and_strip
{
typedef typename __strip_reference_wrapper<
typename decay<_Tp>::type>::__type __type;
};
// NB: DR 706.
template<class _T1, class _T2>
inline pair<typename __decay_and_strip<_T1>::__type,

View file

@ -857,29 +857,6 @@ namespace std
: public integral_constant<int, _Num>
{ };
/**
* Stores a tuple of indices. Used by bind() to extract the elements
* in a tuple.
*/
template<int... _Indexes>
struct _Index_tuple
{
typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
};
/// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
template<std::size_t _Num>
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.

View file

@ -550,6 +550,28 @@ namespace std
return __result_type(std::forward<_Elements>(__args)...);
}
template<typename _Tp, bool = is_array<_Tp>::value>
struct __pa_add_rvalue_reference_helper
{ typedef typename std::add_rvalue_reference<_Tp>::type __type; };
template<typename _Tp>
struct __pa_add_rvalue_reference_helper<_Tp, true>
{ typedef _Tp& __type; };
template<typename _Tp>
struct __pa_add_rvalue_reference
: public __pa_add_rvalue_reference_helper<_Tp>
{ };
template<typename... _Elements>
inline tuple<typename __pa_add_rvalue_reference<_Elements>::__type...>
pack_arguments(_Elements&&... __args)
{
typedef tuple<typename __pa_add_rvalue_reference<_Elements>::__type...>
__result_type;
return __result_type(std::forward<_Elements>(__args)...);
}
template<std::size_t...> struct __index_holder { };
template<std::size_t __i, typename _IdxHolder, typename... _Elements>
@ -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<int... _Indexes>
struct _Index_tuple
{
typedef _Index_tuple<_Indexes..., sizeof...(_Indexes)> __next;
};
/// Builds an _Index_tuple<0, 1, 2, ..., _Num-1>.
template<std::size_t _Num>
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<class _T1, class _T2>
template<typename _Tp, typename... _Args>
inline _Tp
pair<_T1, _T2>::
__cons(tuple<_Args...>&& __tuple)
{
typedef typename _Build_index_tuple<sizeof...(_Args)>::__type
_Indexes;
return __do_cons<_Tp>(std::move(__tuple), _Indexes());
}
template<class _T1, class _T2>
template<typename _Tp, typename... _Args, int... _Indexes>
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__

View file

@ -405,6 +405,35 @@ namespace std
typedef typename __decay_selector<__remove_type>::__type type;
};
template<typename _Tp>
class reference_wrapper;
// Helper which adds a reference to a type when given a reference_wrapper
template<typename _Tp>
struct __strip_reference_wrapper
{
typedef _Tp __type;
};
template<typename _Tp>
struct __strip_reference_wrapper<reference_wrapper<_Tp> >
{
typedef _Tp& __type;
};
template<typename _Tp>
struct __strip_reference_wrapper<const reference_wrapper<_Tp> >
{
typedef _Tp& __type;
};
template<typename _Tp>
struct __decay_and_strip
{
typedef typename __strip_reference_wrapper<
typename decay<_Tp>::type>::__type __type;
};
// Utility for constructing identically cv-qualified types.
template<typename _Unqualified, bool _IsConst, bool _IsVol>

View file

@ -2,7 +2,7 @@
// { dg-do compile }
// 2009-11-12 Paolo Carlini <paolo.carlini@oracle.com>
//
// 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
// <http://www.gnu.org/licenses/>.
// { 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" }

View file

@ -3,7 +3,7 @@
// 2007-05-03 Benjamin Kosnik <bkoz@redhat.com>
//
// 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" }

View file

@ -3,7 +3,7 @@
// 2007-05-03 Benjamin Kosnik <bkoz@redhat.com>
//
// 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" }

View file

@ -0,0 +1,98 @@
// { dg-options "-std=gnu++0x" }
// 2010-04-30 Paolo Carlini <paolo.carlini@oracle.com>
//
// 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
// <http://www.gnu.org/licenses/>.
// Tuple
#include <utility>
#include <tuple>
#include <testsuite_hooks.h>
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<type_one, type_zero> pp0(std::piecewise_construct_t(),
std::pack_arguments(-3),
std::pack_arguments());
VERIFY( pp0.first.get() == -3 );
VERIFY( pp0.second.get() == 757 );
std::pair<type_one, type_two> 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<type_two, type_two> 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;
}

View file

@ -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 <tuple>
#include <utility> // for pair
#include <testsuite_hooks.h>
using namespace std;

View file

@ -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 <tuple>
#include <utility> // for pair
#include <testsuite_hooks.h>
using namespace std;

View file

@ -0,0 +1,72 @@
// { dg-options "-std=gnu++0x" }
// 2010-04-30 Paolo Carlini <paolo.carlini@oracle.com>
//
// 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
// <http://www.gnu.org/licenses/>.
// Tuple
#include <tuple>
#include <type_traits>
#include <testsuite_hooks.h>
void
test01()
{
bool test __attribute__((unused)) = true;
std::pack_arguments();
VERIFY( std::get<0>(std::pack_arguments(-1)) == -1 );
VERIFY( (std::is_same<decltype(std::pack_arguments(-1)),
std::tuple<int&&>>::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<decltype(t1), std::tuple<const int&,
const int&, const double&>>::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<decltype(t2), std::tuple<a_type1&>>::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<decltype(t3), std::tuple<a_type2&,
volatile int&>>::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;
}