* include/std/type_traits (_GLIBCXX_HAS_NESTED_TYPE): Add.
* include/std/functional (_Has_result_type_helper,
_Has_result_type): Remove; use the above to define __has_result_type.
* include/bits/stl_iterator_base_types.h: Use the above to define
__has_iterator_category.
* include/bits/allocator.h (__has_allocator_type): Use the above.
* include/bits/cpp_type_traits.h (__has_iterator_category,
__is_iterator): Remove.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164993
138bc75d-0d04-0410-961f-
82ee72b054a4
+2010-10-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/std/type_traits (_GLIBCXX_HAS_NESTED_TYPE): Add.
+ * include/std/functional (_Has_result_type_helper,
+ _Has_result_type): Remove; use the above to define __has_result_type.
+ * include/bits/stl_iterator_base_types.h: Use the above to define
+ __has_iterator_category.
+ * include/bits/allocator.h (__has_allocator_type): Use the above.
+ * include/bits/cpp_type_traits.h (__has_iterator_category,
+ __is_iterator): Remove.
+
2010-10-05 Sebastian Huber <sebastian.huber@embedded-brains.de>
Jonathan Wakely <jwakely.gcc@gmail.com>
#include <bits/c++allocator.h>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
-#include <type_traits>
+#include <type_traits> // For _GLIBCXX_HAS_NESTED_TYPE
#endif
_GLIBCXX_BEGIN_NAMESPACE(std)
static const allocator_arg_t allocator_arg = allocator_arg_t();
- template<typename _Tp>
- class __has_allocator_type
- : public __sfinae_types
- {
- template<typename _Up>
- struct _Wrap_type
- { };
-
- template<typename _Up>
- static __one __test(_Wrap_type<typename _Up::allocator_type>*);
-
- template<typename _Up>
- static __two __test(...);
-
- public:
- static const bool __value = sizeof(__test<_Tp>(0)) == 1;
- };
+_GLIBCXX_HAS_NESTED_TYPE(allocator_type)
template<typename _Tp, typename _Alloc,
- bool = __has_allocator_type<_Tp>::__value>
+ bool = __has_allocator_type<_Tp>::value>
struct __uses_allocator_helper
: public false_type { };
};
#endif
- template<typename _Tp>
- class __has_iterator_category
- {
- typedef char __one;
- typedef struct { char __arr[2]; } __two;
-
- template<typename _Up>
- struct _Wrap_type
- { };
-
- template<typename _Up>
- static __one __test(_Wrap_type<typename _Up::iterator_category>*);
-
- template<typename _Up>
- static __two __test(...);
-
- public:
- static const bool __value = sizeof(__test<_Tp>(0)) == 1;
- };
-
- template<typename _Tp>
- struct __is_iterator
- {
- enum { __value = (__has_iterator_category<_Tp>::__value
- || __is_pointer<_Tp>::__value) };
- typedef typename __truth_type<__value>::__type __type;
- };
-
_GLIBCXX_END_NAMESPACE
#endif //_CPP_TYPE_TRAITS_H
#include <bits/c++config.h>
#ifdef __GXX_EXPERIMENTAL_CXX0X__
-# include <bits/cpp_type_traits.h> // For __has_iterator_category
+# include <type_traits> // For _GLIBCXX_HAS_NESTED_TYPE
#endif
_GLIBCXX_BEGIN_NAMESPACE(std)
* provide tighter, more correct semantics.
*/
#ifdef __GXX_EXPERIMENTAL_CXX0X__
+
+_GLIBCXX_HAS_NESTED_TYPE(iterator_category)
+
template<typename _Iterator,
- bool = __has_iterator_category<_Iterator>::__value>
+ bool = __has_iterator_category<_Iterator>::value>
struct __iterator_traits { };
template<typename _Iterator>
template<typename _MemberPointer>
class _Mem_fn;
- /**
- * Actual implementation of _Has_result_type, which uses SFINAE to
- * determine if the type _Tp has a publicly-accessible member type
- * result_type.
- */
- template<typename _Tp>
- class _Has_result_type_helper : __sfinae_types
- {
- template<typename _Up>
- struct _Wrap_type
- { };
-
- template<typename _Up>
- static __one __test(_Wrap_type<typename _Up::result_type>*);
-
- template<typename _Up>
- static __two __test(...);
-
- public:
- static const bool value = sizeof(__test<_Tp>(0)) == 1;
- };
-
- template<typename _Tp>
- struct _Has_result_type
- : integral_constant<bool,
- _Has_result_type_helper<typename remove_cv<_Tp>::type>::value>
- { };
+_GLIBCXX_HAS_NESTED_TYPE(result_type)
/// If we have found a result_type, extract it.
template<bool _Has_result_type, typename _Functor>
*/
template<typename _Functor>
struct _Weak_result_type_impl
- : _Maybe_get_result_type<_Has_result_type<_Functor>::value, _Functor>
+ : _Maybe_get_result_type<__has_result_type<_Functor>::value, _Functor>
{ };
/// Retrieve the result type for a function type.
type;
};
+ /**
+ * Use SFINAE to determine if the type _Tp has a publicly-accessible
+ * member type _NTYPE.
+ */
+#define _GLIBCXX_HAS_NESTED_TYPE(_NTYPE) \
+ template<typename _Tp> \
+ class __has_##_NTYPE##_helper \
+ : __sfinae_types \
+ { \
+ template<typename _Up> \
+ struct _Wrap_type \
+ { }; \
+ \
+ template<typename _Up> \
+ static __one __test(_Wrap_type<typename _Up::_NTYPE>*); \
+ \
+ template<typename _Up> \
+ static __two __test(...); \
+ \
+ public: \
+ static const bool value = sizeof(__test<_Tp>(0)) == 1; \
+ }; \
+ \
+ template<typename _Tp> \
+ struct __has_##_NTYPE \
+ : integral_constant<bool, __has_##_NTYPE##_helper \
+ <typename remove_cv<_Tp>::type>::value> \
+ { };
+
// @} group metaprogramming
}