diff options
author | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-03 00:03:38 +0000 |
---|---|---|
committer | redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-05-03 00:03:38 +0000 |
commit | 4b220170640e7b7cbd190620cee3d1390b6de059 (patch) | |
tree | 39770ca44c592c150d9d3cf96053a78b5f84a7a3 /libstdc++-v3/include | |
parent | caf89c14f23aca1d0ecbea44b1e07df560429817 (diff) | |
download | gcc-4b220170640e7b7cbd190620cee3d1390b6de059.tar.gz |
2011-05-03 Jonathan Wakely <jwakely.gcc@gmail.com>
* include/std/functional (bind): Remove from overload set when first
argument type might be a socket file descriptor.
* testsuite/20_util/bind/socket.cc: New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@173279 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r-- | libstdc++-v3/include/std/functional | 59 |
1 files changed, 39 insertions, 20 deletions
diff --git a/libstdc++-v3/include/std/functional b/libstdc++-v3/include/std/functional index 57ec5062133..f8ea41cc3ee 100644 --- a/libstdc++-v3/include/std/functional +++ b/libstdc++-v3/include/std/functional @@ -1422,39 +1422,58 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) struct is_bind_expression<_Bind_result<_Result, _Signature> > : public true_type { }; - template<typename _Functor, typename... _ArgTypes> + // Trait type used to remove std::bind() from overload set via SFINAE + // when first argument has integer type, so that std::bind() will + // not be a better match than ::bind() from the BSD Sockets API. + template<typename _Tp> + class __is_socketlike + { + typedef typename decay<_Tp>::type _Tp2; + public: + static const bool value = + is_integral<_Tp2>::value || is_enum<_Tp2>::value; + }; + + template<bool _SocketLike, typename _Func, typename... _BoundArgs> struct _Bind_helper { - typedef _Maybe_wrap_member_pointer<typename decay<_Functor>::type> + typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type> __maybe_type; - typedef typename __maybe_type::type __functor_type; - typedef _Bind<__functor_type(typename decay<_ArgTypes>::type...)> type; + typedef typename __maybe_type::type __func_type; + typedef _Bind<__func_type(typename decay<_BoundArgs>::type...)> type; }; + // Partial specialization for is_socketlike == true, does not define + // nested type so std::bind() will not participate in overload resolution + // when the first argument might be a socket file descriptor. + template<typename _Func, typename... _BoundArgs> + struct _Bind_helper<true, _Func, _BoundArgs...> + { }; + /** * @brief Function template for std::bind. * @ingroup binders */ - template<typename _Functor, typename... _ArgTypes> - inline - typename _Bind_helper<_Functor, _ArgTypes...>::type - bind(_Functor&& __f, _ArgTypes&&... __args) + template<typename _Func, typename... _BoundArgs> + inline typename + _Bind_helper<__is_socketlike<_Func>::value, _Func, _BoundArgs...>::type + bind(_Func&& __f, _BoundArgs&&... __args) { - typedef _Bind_helper<_Functor, _ArgTypes...> __helper_type; + typedef _Bind_helper<false, _Func, _BoundArgs...> __helper_type; typedef typename __helper_type::__maybe_type __maybe_type; typedef typename __helper_type::type __result_type; - return __result_type(__maybe_type::__do_wrap(std::forward<_Functor>(__f)), - std::forward<_ArgTypes>(__args)...); + return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)), + std::forward<_BoundArgs>(__args)...); } - template<typename _Result, typename _Functor, typename... _ArgTypes> + template<typename _Result, typename _Func, typename... _BoundArgs> struct _Bindres_helper { - typedef _Maybe_wrap_member_pointer<typename decay<_Functor>::type> + typedef _Maybe_wrap_member_pointer<typename decay<_Func>::type> __maybe_type; typedef typename __maybe_type::type __functor_type; typedef _Bind_result<_Result, - __functor_type(typename decay<_ArgTypes>::type...)> + __functor_type(typename decay<_BoundArgs>::type...)> type; }; @@ -1462,16 +1481,16 @@ _GLIBCXX_HAS_NESTED_TYPE(result_type) * @brief Function template for std::bind<R>. * @ingroup binders */ - template<typename _Result, typename _Functor, typename... _ArgTypes> + template<typename _Result, typename _Func, typename... _BoundArgs> inline - typename _Bindres_helper<_Result, _Functor, _ArgTypes...>::type - bind(_Functor&& __f, _ArgTypes&&... __args) + typename _Bindres_helper<_Result, _Func, _BoundArgs...>::type + bind(_Func&& __f, _BoundArgs&&... __args) { - typedef _Bindres_helper<_Result, _Functor, _ArgTypes...> __helper_type; + typedef _Bindres_helper<_Result, _Func, _BoundArgs...> __helper_type; typedef typename __helper_type::__maybe_type __maybe_type; typedef typename __helper_type::type __result_type; - return __result_type(__maybe_type::__do_wrap(std::forward<_Functor>(__f)), - std::forward<_ArgTypes>(__args)...); + return __result_type(__maybe_type::__do_wrap(std::forward<_Func>(__f)), + std::forward<_BoundArgs>(__args)...); } /** |