mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-26 20:56:16 +08:00
Refactor SFINAE constraints on std::tuple constructors
Replace the _TC class template with the better-named _TupleConstraints one, which provides a different set of member functions. The new members do not distinguish construction from lvalues and rvalues, but expects the caller to do that by providing different template arguments. Within the std::tuple primary template and std::tuple<T1, T2> partial specialization the _TupleConstraints members are used via new alias templates like _ImplicitCtor and _ExplicitCtor which makes the constructor constraints less verbose and repetitive. For example, where we previously had: template<typename... _UElements, typename enable_if< _TMC<_UElements...>::template _MoveConstructibleTuple<_UElements...>() && _TMC<_UElements...>::template _ImplicitlyMoveConvertibleTuple<_UElements...>() && (sizeof...(_Elements) >= 1), bool>::type=true> constexpr tuple(_UElements&&... __elements) We now have: template<typename... _UElements, bool _Valid = __valid_args<_UElements...>(), _ImplicitCtor<_Valid, _UElements...> = true> constexpr tuple(_UElements&&... __elements) There are two semantic changes as a result of the refactoring: - The allocator-extended default constructor is now constrained. - The rewritten constraints fix PR 90700. * include/std/tuple (_TC): Replace with _TupleConstraints. (_TupleConstraints): New helper for SFINAE constraints, with more expressive member functions to reduce duplication when used. (tuple::_TC2, tuple::_TMC, tuple::_TNTC): Remove. (tuple::_TCC): Replace dummy type parameter with bool non-type parameter that can be used to check the pack size. (tuple::_ImplicitDefaultCtor, tuple::_ExplicitDefaultCtor) (tuple::_ImplicitCtor, tuple::_ExplicitCtor): New alias templates for checking constraints in constructors. (tuple::__valid_args, tuple::_UseOtherCtor, tuple::__use_other_ctor): New SFINAE helpers. (tuple::tuple): Use new helpers to reduce repitition in constraints. (tuple::tuple(allocator_arg_t, const Alloc&)): Constrain. (tuple<T1, T2>::_TCC, tuple<T1, T2>::_ImplicitDefaultCtor) (tuple<T1, T2>::_ExplicitDefaultCtor, tuple<T1, T2>::_ImplicitCtor) (tuple<T1, T2>::_ExplicitCtor): New alias templates for checking constraints in constructors. (tuple::__is_alloc_arg()): New SFINAE helpers. (tuple<T1, T2>::tuple): Use new helpers to reduce repitition in constraints. (tuple<T1, T2>::tuple(allocator_arg_t, const Alloc&)): Constrain. * testsuite/20_util/tuple/cons/90700.cc: New test. * testsuite/20_util/tuple/cons/allocators.cc: Add default constructor to meet new constraint on allocator-extended default constructor. From-SVN: r271998
This commit is contained in:
parent
ec573765e5
commit
d355635e6b
@ -1,3 +1,30 @@
|
||||
2019-06-06 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/std/tuple (_TC): Replace with _TupleConstraints.
|
||||
(_TupleConstraints): New helper for SFINAE constraints, with more
|
||||
expressive member functions to reduce duplication when used.
|
||||
(tuple::_TC2, tuple::_TMC, tuple::_TNTC): Remove.
|
||||
(tuple::_TCC): Replace dummy type parameter with bool non-type
|
||||
parameter that can be used to check the pack size.
|
||||
(tuple::_ImplicitDefaultCtor, tuple::_ExplicitDefaultCtor)
|
||||
(tuple::_ImplicitCtor, tuple::_ExplicitCtor): New alias templates for
|
||||
checking constraints in constructors.
|
||||
(tuple::__valid_args, tuple::_UseOtherCtor, tuple::__use_other_ctor):
|
||||
New SFINAE helpers.
|
||||
(tuple::tuple): Use new helpers to reduce repitition in constraints.
|
||||
(tuple::tuple(allocator_arg_t, const Alloc&)): Constrain.
|
||||
(tuple<T1, T2>::_TCC, tuple<T1, T2>::_ImplicitDefaultCtor)
|
||||
(tuple<T1, T2>::_ExplicitDefaultCtor, tuple<T1, T2>::_ImplicitCtor)
|
||||
(tuple<T1, T2>::_ExplicitCtor): New alias templates for checking
|
||||
constraints in constructors.
|
||||
(tuple::__is_alloc_arg()): New SFINAE helpers.
|
||||
(tuple<T1, T2>::tuple): Use new helpers to reduce repitition in
|
||||
constraints.
|
||||
(tuple<T1, T2>::tuple(allocator_arg_t, const Alloc&)): Constrain.
|
||||
* testsuite/20_util/tuple/cons/90700.cc: New test.
|
||||
* testsuite/20_util/tuple/cons/allocators.cc: Add default constructor
|
||||
to meet new constraint on allocator-extended default constructor.
|
||||
|
||||
2019-06-03 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/bits/stl_map.h (map): Disable static assert for C++98 mode.
|
||||
|
File diff suppressed because it is too large
Load Diff
66
libstdc++-v3/testsuite/20_util/tuple/cons/90700.cc
Normal file
66
libstdc++-v3/testsuite/20_util/tuple/cons/90700.cc
Normal file
@ -0,0 +1,66 @@
|
||||
// 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
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-do compile { target c++11 } }
|
||||
|
||||
#include <tuple>
|
||||
#include <memory>
|
||||
|
||||
struct X { };
|
||||
|
||||
struct Y
|
||||
{
|
||||
Y(const std::tuple<X>&) = delete;
|
||||
Y(std::tuple<X>&&) { throw 1; }
|
||||
Y(const X&) { }
|
||||
};
|
||||
|
||||
struct Z
|
||||
{
|
||||
Z(X&&) { }
|
||||
Z(const std::tuple<X>&) { throw 1; }
|
||||
Z(std::tuple<X>&&) = delete;
|
||||
};
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
// PR libstdc++/90700 wrong constraints on constructor
|
||||
const std::allocator<int> a;
|
||||
const std::tuple<X> x;
|
||||
|
||||
static_assert(!std::is_convertible<const std::tuple<X>&, Y>::value, "");
|
||||
static_assert(!std::is_constructible<Y, const std::tuple<X>&>::value, "");
|
||||
static_assert(!std::is_same<Y, X>::value, "");
|
||||
// should use tuple<Y>::tuple<X>(allocator_arg_t, const A&, const tuple<X>&)
|
||||
// and construct Y from X:
|
||||
std::tuple<Y> y(std::allocator_arg, a, x);
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
const std::allocator<int> a;
|
||||
std::tuple<X> x;
|
||||
|
||||
static_assert(!std::is_convertible<std::tuple<X>, Z>::value, "");
|
||||
static_assert(!std::is_constructible<Z, std::tuple<X>>::value, "");
|
||||
static_assert(!std::is_same<Z, X>::value, "");
|
||||
// should use tuple<Z>::tuple<X>(allocator_arg_t, const A&, tuple<X>&&)
|
||||
// and construct Z from X:
|
||||
std::tuple<Z> z(std::allocator_arg, a, std::move(x));
|
||||
}
|
@ -186,12 +186,26 @@ void test03()
|
||||
struct dr2586
|
||||
{
|
||||
using allocator_type = std::allocator<int>;
|
||||
dr2586() { }
|
||||
dr2586(std::allocator_arg_t, allocator_type&&) { }
|
||||
dr2586(const allocator_type&) { }
|
||||
dr2586(const allocator_type&) : expected(true) { }
|
||||
bool expected = false;
|
||||
};
|
||||
|
||||
const dr2586::allocator_type a;
|
||||
std::tuple<dr2586> t{std::allocator_arg, a};
|
||||
VERIFY( std::get<0>(t).expected );
|
||||
}
|
||||
|
||||
void test04()
|
||||
{
|
||||
struct X {
|
||||
X(std::allocator_arg_t) { }
|
||||
};
|
||||
|
||||
// The element types are not default constructible, so the allocator-extended
|
||||
// default constructor should not participate in overload resolution.
|
||||
std::tuple<X, void(&)()> t(std::allocator_arg, *+[]{});
|
||||
}
|
||||
|
||||
int main()
|
||||
@ -199,5 +213,6 @@ int main()
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
test04();
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user