Define __void_t and SFINAE-friendly iterator_traits.
* include/std/type_traits (__void_t): Define new alias template. (_GLIBCXX_HAS_NESTED_TYPE): Redefine using __void_t. * include/std/functional (_Maybe_get_result_type): Likewise. * include/bits/stl_iterator_base_types.h (__iterator_traits): Likewise. * include/bits/uses_allocator.h (__uses_allocator_helper): Likewise. * testsuite/20_util/bind/ref_neg.cc: Adjust dg-error. * testsuite/20_util/reference_wrapper/typedefs-3.cc: Adjust to changes in _GLIBCXX_HAS_NESTED_TYPE. From-SVN: r217395
This commit is contained in:
parent
3c03d39d45
commit
847e9cf81e
@ -1,3 +1,14 @@
|
|||||||
|
2014-11-11 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
|
* include/std/type_traits (__void_t): Define new alias template.
|
||||||
|
(_GLIBCXX_HAS_NESTED_TYPE): Redefine using __void_t.
|
||||||
|
* include/std/functional (_Maybe_get_result_type): Likewise.
|
||||||
|
* include/bits/stl_iterator_base_types.h (__iterator_traits): Likewise.
|
||||||
|
* include/bits/uses_allocator.h (__uses_allocator_helper): Likewise.
|
||||||
|
* testsuite/20_util/bind/ref_neg.cc: Adjust dg-error.
|
||||||
|
* testsuite/20_util/reference_wrapper/typedefs-3.cc: Adjust to changes
|
||||||
|
in _GLIBCXX_HAS_NESTED_TYPE.
|
||||||
|
|
||||||
2014-11-11 Jonathan Wakely <jwakely@redhat.com>
|
2014-11-11 Jonathan Wakely <jwakely@redhat.com>
|
||||||
|
|
||||||
* include/std/functional (_Mem_fn_traits): Add partial specializations
|
* include/std/functional (_Mem_fn_traits): Add partial specializations
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
#include <bits/c++config.h>
|
#include <bits/c++config.h>
|
||||||
|
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
# include <type_traits> // For _GLIBCXX_HAS_NESTED_TYPE, is_convertible
|
# include <type_traits> // For __void_t, is_convertible
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace std _GLIBCXX_VISIBILITY(default)
|
namespace std _GLIBCXX_VISIBILITY(default)
|
||||||
@ -138,15 +138,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
* provide tighter, more correct semantics.
|
* provide tighter, more correct semantics.
|
||||||
*/
|
*/
|
||||||
#if __cplusplus >= 201103L
|
#if __cplusplus >= 201103L
|
||||||
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||||
_GLIBCXX_HAS_NESTED_TYPE(iterator_category)
|
// 2408. SFINAE-friendly common_type/iterator_traits is missing in C++14
|
||||||
|
template<typename _Iterator, typename = __void_t<>>
|
||||||
template<typename _Iterator,
|
|
||||||
bool = __has_iterator_category<_Iterator>::value>
|
|
||||||
struct __iterator_traits { };
|
struct __iterator_traits { };
|
||||||
|
|
||||||
template<typename _Iterator>
|
template<typename _Iterator>
|
||||||
struct __iterator_traits<_Iterator, true>
|
struct __iterator_traits<_Iterator,
|
||||||
|
__void_t<typename _Iterator::iterator_category,
|
||||||
|
typename _Iterator::value_type,
|
||||||
|
typename _Iterator::difference_type,
|
||||||
|
typename _Iterator::pointer,
|
||||||
|
typename _Iterator::reference>>
|
||||||
{
|
{
|
||||||
typedef typename _Iterator::iterator_category iterator_category;
|
typedef typename _Iterator::iterator_category iterator_category;
|
||||||
typedef typename _Iterator::value_type value_type;
|
typedef typename _Iterator::value_type value_type;
|
||||||
|
@ -40,15 +40,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
|
|
||||||
constexpr allocator_arg_t allocator_arg = allocator_arg_t();
|
constexpr allocator_arg_t allocator_arg = allocator_arg_t();
|
||||||
|
|
||||||
_GLIBCXX_HAS_NESTED_TYPE(allocator_type)
|
template<typename _Tp, typename _Alloc, typename = __void_t<>>
|
||||||
|
|
||||||
template<typename _Tp, typename _Alloc,
|
|
||||||
bool = __has_allocator_type<_Tp>::value>
|
|
||||||
struct __uses_allocator_helper
|
struct __uses_allocator_helper
|
||||||
: false_type { };
|
: false_type { };
|
||||||
|
|
||||||
template<typename _Tp, typename _Alloc>
|
template<typename _Tp, typename _Alloc>
|
||||||
struct __uses_allocator_helper<_Tp, _Alloc, true>
|
struct __uses_allocator_helper<_Tp, _Alloc,
|
||||||
|
__void_t<typename _Tp::allocator_type>>
|
||||||
: is_convertible<_Alloc, typename _Tp::allocator_type>::type
|
: is_convertible<_Alloc, typename _Tp::allocator_type>::type
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
|
@ -67,24 +67,23 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
_Mem_fn<_Tp _Class::*>
|
_Mem_fn<_Tp _Class::*>
|
||||||
mem_fn(_Tp _Class::*) noexcept;
|
mem_fn(_Tp _Class::*) noexcept;
|
||||||
|
|
||||||
_GLIBCXX_HAS_NESTED_TYPE(result_type)
|
|
||||||
|
|
||||||
/// If we have found a result_type, extract it.
|
/// If we have found a result_type, extract it.
|
||||||
template<bool _Has_result_type, typename _Functor>
|
template<typename _Functor, typename = __void_t<>>
|
||||||
struct _Maybe_get_result_type
|
struct _Maybe_get_result_type
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
template<typename _Functor>
|
template<typename _Functor>
|
||||||
struct _Maybe_get_result_type<true, _Functor>
|
struct _Maybe_get_result_type<_Functor,
|
||||||
|
__void_t<typename _Functor::result_type>>
|
||||||
{ typedef typename _Functor::result_type result_type; };
|
{ typedef typename _Functor::result_type result_type; };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for any function object that has a weak result type, as
|
* Base class for any function object that has a weak result type, as
|
||||||
* defined in 3.3/3 of TR1.
|
* defined in 20.8.2 [func.require] of C++11.
|
||||||
*/
|
*/
|
||||||
template<typename _Functor>
|
template<typename _Functor>
|
||||||
struct _Weak_result_type_impl
|
struct _Weak_result_type_impl
|
||||||
: _Maybe_get_result_type<__has_result_type<_Functor>::value, _Functor>
|
: _Maybe_get_result_type<_Functor>
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
/// Retrieve the result type for a function type.
|
/// Retrieve the result type for a function type.
|
||||||
|
@ -2404,6 +2404,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
using result_of_t = typename result_of<_Tp>::type;
|
using result_of_t = typename result_of<_Tp>::type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
template<typename...> using __void_t = void;
|
||||||
|
|
||||||
/// @} group metaprogramming
|
/// @} group metaprogramming
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -2411,27 +2413,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
* member type _NTYPE.
|
* member type _NTYPE.
|
||||||
*/
|
*/
|
||||||
#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
|
#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
|
||||||
template<typename _Tp> \
|
template<typename _Tp, typename = __void_t<>> \
|
||||||
class __has_##_NTYPE##_helper \
|
|
||||||
{ \
|
|
||||||
template<typename _Up> \
|
|
||||||
struct _Wrap_type \
|
|
||||||
{ }; \
|
|
||||||
\
|
|
||||||
template<typename _Up> \
|
|
||||||
static true_type __test(_Wrap_type<typename _Up::_NTYPE>*); \
|
|
||||||
\
|
|
||||||
template<typename _Up> \
|
|
||||||
static false_type __test(...); \
|
|
||||||
\
|
|
||||||
public: \
|
|
||||||
typedef decltype(__test<_Tp>(0)) type; \
|
|
||||||
}; \
|
|
||||||
\
|
|
||||||
template<typename _Tp> \
|
|
||||||
struct __has_##_NTYPE \
|
struct __has_##_NTYPE \
|
||||||
: public __has_##_NTYPE##_helper \
|
: false_type \
|
||||||
<typename remove_cv<_Tp>::type>::type \
|
{ }; \
|
||||||
|
template<typename _Tp> \
|
||||||
|
struct __has_##_NTYPE<_Tp, __void_t<typename _Tp::_NTYPE>> \
|
||||||
|
: true_type \
|
||||||
{ };
|
{ };
|
||||||
|
|
||||||
_GLIBCXX_END_NAMESPACE_VERSION
|
_GLIBCXX_END_NAMESPACE_VERSION
|
||||||
|
@ -30,10 +30,10 @@ void test01()
|
|||||||
{
|
{
|
||||||
const int dummy = 0;
|
const int dummy = 0;
|
||||||
std::bind(&inc, _1)(0); // { dg-error "no match" }
|
std::bind(&inc, _1)(0); // { dg-error "no match" }
|
||||||
// { dg-error "rvalue|const" "" { target *-*-* } 1126 }
|
// { dg-error "rvalue|const" "" { target *-*-* } 1125 }
|
||||||
// { dg-error "rvalue|const" "" { target *-*-* } 1140 }
|
// { dg-error "rvalue|const" "" { target *-*-* } 1139 }
|
||||||
// { dg-error "rvalue|const" "" { target *-*-* } 1154 }
|
// { dg-error "rvalue|const" "" { target *-*-* } 1153 }
|
||||||
// { dg-error "rvalue|const" "" { target *-*-* } 1168 }
|
// { dg-error "rvalue|const" "" { target *-*-* } 1167 }
|
||||||
std::bind(&inc, std::ref(dummy))(); // { dg-error "no match" }
|
std::bind(&inc, std::ref(dummy))(); // { dg-error "no match" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,7 @@ struct S012 : S0, S1, S2 { };
|
|||||||
|
|
||||||
using std::true_type;
|
using std::true_type;
|
||||||
using std::false_type;
|
using std::false_type;
|
||||||
using std::integral_constant;
|
using std::__void_t;
|
||||||
using std::remove_cv;
|
|
||||||
|
|
||||||
_GLIBCXX_HAS_NESTED_TYPE(argument_type)
|
_GLIBCXX_HAS_NESTED_TYPE(argument_type)
|
||||||
_GLIBCXX_HAS_NESTED_TYPE(first_argument_type)
|
_GLIBCXX_HAS_NESTED_TYPE(first_argument_type)
|
||||||
|
Loading…
Reference in New Issue
Block a user