mirror of git://gcc.gnu.org/git/gcc.git
PR72792 PR72793 relax requirements on rebind members
PR libstdc++/72792 PR libstdc++/72793 * include/bits/alloc_traits.h (__allocator_traits_base::__rebind): Replace with class template using void_t. (__alloc_rebind): Define in terms of __allocator_traits_base::__rebind. (allocator_traits): Remove unconditional static_assert for rebind_alloc. * include/bits/ptr_traits.h (__replace_first_arg): Remove type member. (pointer_traits::__rebind): Replace with class template using void_t. (pointer_traits::rebind): Define in terms of __rebind. (pointer_traits): Remove unconditional static_assert for rebind. * testsuite/20_util/allocator_traits/members/rebind_alloc.cc: New test. * testsuite/20_util/pointer_traits/rebind.cc: New test. From-SVN: r244680
This commit is contained in:
parent
198766b648
commit
a3a1620bb8
|
|
@ -1,5 +1,20 @@
|
||||||
2017-01-20 Jonathan Wakely <jwakely@redhat.com>
|
2017-01-20 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
PR libstdc++/72792
|
||||||
|
PR libstdc++/72793
|
||||||
|
* include/bits/alloc_traits.h (__allocator_traits_base::__rebind):
|
||||||
|
Replace with class template using void_t.
|
||||||
|
(__alloc_rebind): Define in terms of
|
||||||
|
__allocator_traits_base::__rebind.
|
||||||
|
(allocator_traits): Remove unconditional static_assert for
|
||||||
|
rebind_alloc.
|
||||||
|
* include/bits/ptr_traits.h (__replace_first_arg): Remove type member.
|
||||||
|
(pointer_traits::__rebind): Replace with class template using void_t.
|
||||||
|
(pointer_traits::rebind): Define in terms of __rebind.
|
||||||
|
(pointer_traits): Remove unconditional static_assert for rebind.
|
||||||
|
* testsuite/20_util/allocator_traits/members/rebind_alloc.cc: New test.
|
||||||
|
* testsuite/20_util/pointer_traits/rebind.cc: New test.
|
||||||
|
|
||||||
PR libstdc++/69321
|
PR libstdc++/69321
|
||||||
* include/experimental/any (__any_caster): Avoid instantiating
|
* include/experimental/any (__any_caster): Avoid instantiating
|
||||||
manager function for types that can't be stored in any.
|
manager function for types that can't be stored in any.
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
struct __allocator_traits_base
|
struct __allocator_traits_base
|
||||||
{
|
{
|
||||||
template<typename _Alloc, typename _Up>
|
template<typename _Tp, typename _Up, typename = void>
|
||||||
using __rebind = typename _Alloc::template rebind<_Up>::other;
|
struct __rebind : __replace_first_arg<_Tp, _Up> { };
|
||||||
|
|
||||||
|
template<typename _Tp, typename _Up>
|
||||||
|
struct __rebind<_Tp, _Up,
|
||||||
|
__void_t<typename _Tp::template rebind<_Up>::other>>
|
||||||
|
{ using type = typename _Tp::template rebind<_Up>::other; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
|
|
@ -71,9 +76,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename _Alloc, typename _Up>
|
template<typename _Alloc, typename _Up>
|
||||||
using __alloc_rebind = __detected_or_t_<__replace_first_arg_t,
|
using __alloc_rebind
|
||||||
__allocator_traits_base::__rebind,
|
= typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type;
|
||||||
_Alloc, _Up>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Uniform interface to all allocator types.
|
* @brief Uniform interface to all allocator types.
|
||||||
|
|
@ -184,9 +188,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
|
using rebind_traits = allocator_traits<rebind_alloc<_Tp>>;
|
||||||
|
|
||||||
static_assert(!is_same<rebind_alloc<value_type>, __undefined>::value,
|
|
||||||
"allocator defines rebind or is like Alloc<T, Args>");
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template<typename _Alloc2>
|
template<typename _Alloc2>
|
||||||
static auto
|
static auto
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
// Given Template<T, ...> and U return Template<U, ...>, otherwise invalid.
|
// Given Template<T, ...> and U return Template<U, ...>, otherwise invalid.
|
||||||
template<typename _Tp, typename _Up>
|
template<typename _Tp, typename _Up>
|
||||||
struct __replace_first_arg
|
struct __replace_first_arg
|
||||||
{ using type = __undefined; };
|
{ };
|
||||||
|
|
||||||
template<template<typename, typename...> class _Template, typename _Up,
|
template<template<typename, typename...> class _Template, typename _Up,
|
||||||
typename _Tp, typename... _Types>
|
typename _Tp, typename... _Types>
|
||||||
|
|
@ -84,8 +84,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
template<typename _Tp>
|
template<typename _Tp>
|
||||||
using __difference_type = typename _Tp::difference_type;
|
using __difference_type = typename _Tp::difference_type;
|
||||||
|
|
||||||
|
template<typename _Tp, typename _Up, typename = void>
|
||||||
|
struct __rebind : __replace_first_arg<_Tp, _Up> { };
|
||||||
|
|
||||||
template<typename _Tp, typename _Up>
|
template<typename _Tp, typename _Up>
|
||||||
using __rebind = typename _Tp::template rebind<_Up>;
|
struct __rebind<_Tp, _Up, __void_t<typename _Tp::template rebind<_Up>>>
|
||||||
|
{ using type = typename _Tp::template rebind<_Up>; };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// The pointer type.
|
/// The pointer type.
|
||||||
|
|
@ -101,8 +105,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
/// A pointer to a different type.
|
/// A pointer to a different type.
|
||||||
template<typename _Up>
|
template<typename _Up>
|
||||||
using rebind
|
using rebind = typename __rebind<_Ptr, _Up>::type;
|
||||||
= __detected_or_t_<__replace_first_arg_t, __rebind, _Ptr, _Up>;
|
|
||||||
|
|
||||||
static _Ptr
|
static _Ptr
|
||||||
pointer_to(__make_not_void<element_type>& __e)
|
pointer_to(__make_not_void<element_type>& __e)
|
||||||
|
|
@ -110,8 +113,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
||||||
|
|
||||||
static_assert(!is_same<element_type, __undefined>::value,
|
static_assert(!is_same<element_type, __undefined>::value,
|
||||||
"pointer type defines element_type or is like SomePointer<T, Args>");
|
"pointer type defines element_type or is like SomePointer<T, Args>");
|
||||||
static_assert(!is_same<rebind<element_type>, __undefined>::value,
|
|
||||||
"pointer type defines rebind<U> or is like SomePointer<T, Args>");
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
// Copyright (C) 2017 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 <memory>
|
||||||
|
|
||||||
|
using std::is_same;
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
using Rebind = typename std::allocator_traits<T>::template rebind_alloc<U>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct HasRebind {
|
||||||
|
using value_type = T;
|
||||||
|
template<typename U> struct rebind { using other = std::allocator<U>; };
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<HasRebind<int>, long>,
|
||||||
|
std::allocator<long>>::value,
|
||||||
|
"nested alias template is used");
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct NoRebind0 {
|
||||||
|
using value_type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<NoRebind0<int>, long>,
|
||||||
|
NoRebind0<long>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
|
||||||
|
template<typename T, typename>
|
||||||
|
struct NoRebind1 {
|
||||||
|
using value_type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<NoRebind1<int, void>, long>,
|
||||||
|
NoRebind1<long, void>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
|
||||||
|
template<typename T, typename, typename>
|
||||||
|
struct NoRebind2 {
|
||||||
|
using value_type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<NoRebind2<int, void, void>, long>,
|
||||||
|
NoRebind2<long, void, void>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
|
||||||
|
template<typename T, typename...>
|
||||||
|
struct NoRebindN {
|
||||||
|
using value_type = T;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<NoRebindN<int>, long>,
|
||||||
|
NoRebindN<long>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
static_assert(is_same<Rebind<NoRebindN<int, void>, long>,
|
||||||
|
NoRebindN<long, void>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
|
||||||
|
template<typename T, int = 0>
|
||||||
|
struct CannotRebind {
|
||||||
|
using value_type = T;
|
||||||
|
};
|
||||||
|
// PR libstdc++/72792 specialization of allocator_traits is still well-formed:
|
||||||
|
std::allocator_traits<CannotRebind<int>>::value_type v;
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
// Copyright (C) 2017 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 <memory>
|
||||||
|
|
||||||
|
using std::is_same;
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
using Rebind = typename std::pointer_traits<T>::template rebind<U>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct HasRebind {
|
||||||
|
template<typename U> using rebind = U*;
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<HasRebind<int>, long>,
|
||||||
|
long*>::value,
|
||||||
|
"nested alias template is used");
|
||||||
|
|
||||||
|
template<typename T> struct NoRebind0 { };
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<NoRebind0<int>, long>,
|
||||||
|
NoRebind0<long>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
|
||||||
|
template<typename T, typename> struct NoRebind1 { };
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<NoRebind1<int, void>, long>,
|
||||||
|
NoRebind1<long, void>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
|
||||||
|
template<typename T, typename, typename> struct NoRebind2 { };
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<NoRebind2<int, void, void>, long>,
|
||||||
|
NoRebind2<long, void, void>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
|
||||||
|
template<typename T, typename...> struct NoRebindN { };
|
||||||
|
|
||||||
|
static_assert(is_same<Rebind<NoRebindN<int>, long>,
|
||||||
|
NoRebindN<long>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
static_assert(is_same<Rebind<NoRebindN<int, void>, long>,
|
||||||
|
NoRebindN<long, void>>::value,
|
||||||
|
"first template argument is replaced");
|
||||||
|
|
||||||
|
template<typename T, int = 0>
|
||||||
|
struct CannotRebind {
|
||||||
|
using element_type = T;
|
||||||
|
};
|
||||||
|
// PR libstdc++/72793 specialization of pointer_traits is still well-formed:
|
||||||
|
std::pointer_traits<CannotRebind<int>>::element_type e;
|
||||||
Loading…
Reference in New Issue