Patchwork [v3] Add _GLIBCXX_HAS_NESTED_TYPE

login
register
mail settings
Submitter Paolo Carlini
Date Oct. 5, 2010, 3:55 p.m.
Message ID <4CAB4A5C.7070506@oracle.com>
Download mbox | patch
Permalink /patch/66839/
State New
Headers show

Comments

Paolo Carlini - Oct. 5, 2010, 3:55 p.m.
Hi,

I'm adding this macro which will be also useful for allocator_traits.
Tested x86_64-linux, committed.

Paolo.

//////////////////
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.

Patch

Index: include/std/type_traits
===================================================================
--- include/std/type_traits	(revision 164990)
+++ include/std/type_traits	(working copy)
@@ -696,6 +696,35 @@ 
         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
 }
 
Index: include/std/functional
===================================================================
--- include/std/functional	(revision 164990)
+++ include/std/functional	(working copy)
@@ -63,34 +63,8 @@ 
   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
-	{ };
+_GLIBCXX_HAS_NESTED_TYPE(result_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>
-    { };
-
   /// If we have found a result_type, extract it.
   template<bool _Has_result_type, typename _Functor>
     struct _Maybe_get_result_type
@@ -108,7 +82,7 @@ 
   */
   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.
Index: include/bits/stl_iterator_base_types.h
===================================================================
--- include/bits/stl_iterator_base_types.h	(revision 164991)
+++ include/bits/stl_iterator_base_types.h	(working copy)
@@ -65,7 +65,7 @@ 
 #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)
@@ -137,8 +137,11 @@ 
    *  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>
Index: include/bits/cpp_type_traits.h
===================================================================
--- include/bits/cpp_type_traits.h	(revision 164991)
+++ include/bits/cpp_type_traits.h	(working copy)
@@ -414,34 +414,6 @@ 
     };
 #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
Index: include/bits/allocator.h
===================================================================
--- include/bits/allocator.h	(revision 164991)
+++ include/bits/allocator.h	(working copy)
@@ -48,7 +48,7 @@ 
 #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)
@@ -210,26 +210,10 @@ 
 
   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
-	{ };
+_GLIBCXX_HAS_NESTED_TYPE(allocator_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;
-    };
-
   template<typename _Tp, typename _Alloc,
-	   bool = __has_allocator_type<_Tp>::__value>
+	   bool = __has_allocator_type<_Tp>::value>
     struct __uses_allocator_helper
     : public false_type { };