From patchwork Tue Oct 5 15:55:08 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 66839 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id F0EC4B70D9 for ; Wed, 6 Oct 2010 02:55:20 +1100 (EST) Received: (qmail 14453 invoked by alias); 5 Oct 2010 15:55:18 -0000 Received: (qmail 14434 invoked by uid 22791); 5 Oct 2010 15:55:17 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from vsmtp3.tin.it (HELO vsmtp3.tin.it) (212.216.176.223) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 05 Oct 2010 15:55:11 +0000 Received: from [192.168.0.4] (79.33.216.204) by vsmtp3.tin.it (8.5.113) id 4BCE36060C5C2186; Tue, 5 Oct 2010 17:55:08 +0200 Message-ID: <4CAB4A5C.7070506@oracle.com> Date: Tue, 05 Oct 2010 17:55:08 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.11) Gecko/20100714 SUSE/3.0.6 Thunderbird/3.0.6 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: libstdc++ Subject: [v3] Add _GLIBCXX_HAS_NESTED_TYPE X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 * 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. 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 \ + class __has_##_NTYPE##_helper \ + : __sfinae_types \ + { \ + template \ + struct _Wrap_type \ + { }; \ + \ + template \ + static __one __test(_Wrap_type*); \ + \ + template \ + static __two __test(...); \ + \ + public: \ + static const bool value = sizeof(__test<_Tp>(0)) == 1; \ + }; \ + \ + template \ + struct __has_##_NTYPE \ + : integral_constant::type>::value> \ + { }; + // @} group metaprogramming } Index: include/std/functional =================================================================== --- include/std/functional (revision 164990) +++ include/std/functional (working copy) @@ -63,34 +63,8 @@ template 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 - class _Has_result_type_helper : __sfinae_types - { - template - struct _Wrap_type - { }; +_GLIBCXX_HAS_NESTED_TYPE(result_type) - template - static __one __test(_Wrap_type*); - - template - static __two __test(...); - - public: - static const bool value = sizeof(__test<_Tp>(0)) == 1; - }; - - template - struct _Has_result_type - : integral_constant::type>::value> - { }; - /// If we have found a result_type, extract it. template struct _Maybe_get_result_type @@ -108,7 +82,7 @@ */ template 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 #ifdef __GXX_EXPERIMENTAL_CXX0X__ -# include // For __has_iterator_category +# include // 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::__value> + bool = __has_iterator_category<_Iterator>::value> struct __iterator_traits { }; template 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 - class __has_iterator_category - { - typedef char __one; - typedef struct { char __arr[2]; } __two; - - template - struct _Wrap_type - { }; - - template - static __one __test(_Wrap_type*); - - template - static __two __test(...); - - public: - static const bool __value = sizeof(__test<_Tp>(0)) == 1; - }; - - template - 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 #ifdef __GXX_EXPERIMENTAL_CXX0X__ -#include +#include // 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 - class __has_allocator_type - : public __sfinae_types - { - template - struct _Wrap_type - { }; +_GLIBCXX_HAS_NESTED_TYPE(allocator_type) - template - static __one __test(_Wrap_type*); - - template - static __two __test(...); - - public: - static const bool __value = sizeof(__test<_Tp>(0)) == 1; - }; - template::__value> + bool = __has_allocator_type<_Tp>::value> struct __uses_allocator_helper : public false_type { };