function 源码分析3--c++11 function源码分析

我分析的是gcc的function源码。

首先看函数指针怎么存储

class _Undefined_class;//永远不会实现的class
union _Nocopy_types{
	void*       _M_object;//function object指针
	const void* _M_const_object;//const function object指针
	void(*_M_function_pointer)();//函数指针
	void (_Undefined_class::*_M_member_pointer)();//成员函数指针
};

union _Any_data{
	void*       _M_access() { return &_M_pod_data[0]; }
	const void* _M_access() const { return &_M_pod_data[0]; }
	template<typename _Tp>
	_Tp& _M_access(){
		return *static_cast<_Tp*>(_M_access());
	}
	template<typename _Tp>
	const _Tp& _M_access() const{
		return *static_cast<const _Tp*>(_M_access());
	}

	_Nocopy_types _M_unused;
	char _M_pod_data[sizeof(_Nocopy_types)];
};
和boost的实现手法有些近似,有意思的是union有点像类,A union can have member functions (including constructors and destructors), but not virtual (10.3) functions。_Any_data的大小在x86下应该是4个字节。

接着是function_base,从类型定义中可以看出是为了存储指针

enum _Manager_operation
{
	__get_type_info,
	__get_functor_ptr,
	__clone_functor,
	__destroy_functor
};

/// Base class of all polymorphic function object wrappers.
class _Function_base
{
public:
	static const std::size_t _M_max_size = sizeof(_Nocopy_types);
	static const std::size_t _M_max_align = __alignof__(_Nocopy_types);
	...
	_Function_base() : _M_manager(nullptr) { }

	~_Function_base()
	{
		if (_M_manager)
			_M_manager(_M_functor, _M_functor, __destroy_functor);
	}
	bool _M_empty() const { return !_M_manager; }

	typedef bool(*_Manager_type)(_Any_data&, const _Any_data&,
		_Manager_operation);
	_Any_data     _M_functor;//function buffer
	_Manager_type _M_manager;//manager
};

下来我们看manager,和boost的实现机制一样,该类型在_Function_base中定义,优点是把东西都放一起了。而不在另外一个命名空间,比boost多了个empty的判断

template<typename _Functor>
class _Base_manager
{
protected:
	static const bool __stored_locally =
		(__is_location_invariant<_Functor>::value
			&& sizeof(_Functor) <= _M_max_size
			&& __alignof__(_Functor) <= _M_max_align
			&& (_M_max_align % __alignof__(_Functor) == 0));

	typedef integral_constant<bool, __stored_locally> _Local_storage;

	// Retrieve a pointer to the function object
	static _Functor* _M_get_pointer(const _Any_data& __source)
	{
		const _Functor* __ptr =
			__stored_locally ? std::__addressof(__source._M_access<_Functor>())
			/* have stored a pointer */ : __source._M_access<_Functor*>();
		return const_cast<_Functor*>(__ptr);
	}

	// Clone a location-invariant function object that fits within
	// an _Any_data structure.
	static void _M_clone(_Any_data& __dest, const _Any_data& __source, true_type)
	{
		new (__dest._M_access()) _Functor(__source._M_access<_Functor>());
	}

	// Clone a function object that is not location-invariant or
	// that cannot fit into an _Any_data structure.
	static void _M_clone(_Any_data& __dest, const _Any_data& __source, false_type)
	{
		__dest._M_access<_Functor*>() = new _Functor(*__source._M_access<_Functor*>());
	}

	// Destroying a location-invariant object may still require
	// destruction.
	static void _M_destroy(_Any_data& __victim, true_type)
	{
		__victim._M_access<_Functor>().~_Functor();
	}

	// Destroying an object located on the heap.
	static void _M_destroy(_Any_data& __victim, false_type)
	{
		delete __victim._M_access<_Functor*>();
	}

public:
	// Manager具体实现
	static bool _M_manager(_Any_data& __dest, const _Any_data& __source,
			_Manager_operation __op)
	{
		switch (__op)
		{
		case __get_type_info:
			__dest._M_access<const type_info*>() = &typeid(_Functor);
			break;
		case __get_functor_ptr:
			__dest._M_access<_Functor*>() = _M_get_pointer(__source);
			break;

		case __clone_functor:
			_M_clone(__dest, __source, _Local_storage());
			break;

		case __destroy_functor:
			_M_destroy(__dest, _Local_storage());
			break;
		}
		return false;
	}

	static void _M_init_functor(_Any_data& __functor, _Functor&& __f)
	{
		_M_init_functor(__functor, std::move(__f), _Local_storage());
	}

	template<typename _Signature>
	static bool _M_not_empty_function(const function<_Signature>& __f)
	{
		return static_cast<bool>(__f);
	}

	template<typename _Tp>
	static bool _M_not_empty_function(_Tp* const& __fp)
	{
		return __fp;
	}

	template<typename _Class, typename _Tp>
	static bool _M_not_empty_function(_Tp _Class::* const& __mp)
	{
		return __mp;
	}

	template<typename _Tp>
	static bool _M_not_empty_function(const _Tp&)
	{
		return true;
	}
private:
	static void _M_init_functor(_Any_data& __functor, _Functor&& __f, true_type)
	{
		new (__functor._M_access()) _Functor(std::move(__f));
	}

	static void _M_init_functor(_Any_data& __functor, _Functor&& __f, false_type)
	{
		__functor._M_access<_Functor*>() = new _Functor(std::move(__f));
	}
};
先说下_Maybe_unary_or_binary_function,这个主要是为了兼容原来标准中的unay_function,binary_function,

/**
* Derives from @c unary_function or @c binary_function, or perhaps
* nothing, depending on the number of arguments provided. The
* primary template is the basis case, which derives nothing.
*/
template<typename _Res, typename... _ArgTypes>
struct _Maybe_unary_or_binary_function { };

/// Derives from @c unary_function, as appropriate.
template<typename _Res, typename _T1>
struct _Maybe_unary_or_binary_function<_Res, _T1>
	: std::unary_function<_T1, _Res> { };

/// Derives from @c binary_function, as appropriate.
template<typename _Res, typename _T1, typename _T2>
struct _Maybe_unary_or_binary_function<_Res, _T1, _T2>
	: std::binary_function<_T1, _T2, _Res> { };
接着是function的本身

template<typename _Cond, typename _Tp>
using _Requires = typename enable_if<_Cond::value, _Tp>::type;


template<typename _Res, typename... _ArgTypes>
class function<_Res(_ArgTypes...)>
	: public _Maybe_unary_or_binary_function<_Res, _ArgTypes...>,
	private _Function_base
{
	typedef _Res _Signature_type(_ArgTypes...);

	template<typename _Func,
		typename _Res2 = typename result_of<_Func(_ArgTypes...)>::type>
		struct _Callable : __check_func_return_type<_Res2, _Res> { };

	// Used so the return type convertibility checks aren't done when
	// performing overload resolution for copy construction/assignment.
	template<typename _Tp>
	struct _Callable<function, _Tp> : false_type { };

	template<typename _Cond, typename _Tp>
	using _Requires = typename enable_if<_Cond::value, _Tp>::type;

public:
	typedef _Res result_type;

	_Res operator()(_ArgTypes... __args) const
	{
		if (_M_empty())
			__throw_bad_function_call();
		return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...);
	}


	bool _M_empty() const { 
		return !_M_manager; 
	}
	//c++11的safe bool惯用法
	explicit operator bool() const noexcept
	{
		return !_M_empty();
	}

	
	template<typename _Functor,
		typename = _Requires<__not_<is_same<_Functor, function>>, void>,
		typename = _Requires<_Callable<_Functor>, void>>
		function(_Functor);

private:
	using _Invoker_type = _Res(*)(const _Any_data&, _ArgTypes&&...);
	_Invoker_type _M_invoker;
};
然后是这个invoke_type了,这个类型比较多,不一一展开,只选一个

template<typename _Signature, typename _Functor>
class _Function_handler;

template<typename _Res, typename _Functor, typename... _ArgTypes>
class _Function_handler<_Res(_ArgTypes...), _Functor>
	: public _Function_base::_Base_manager<_Functor>
{
	typedef _Function_base::_Base_manager<_Functor> _Base;

public:
	static _Res _M_invoke(const _Any_data& __functor, _ArgTypes&&... __args)
	{
		return (*_Base::_M_get_pointer(__functor))(
			std::forward<_ArgTypes>(__args)...);
	}
};
再就是给invoke和mannage赋值了

	template<typename _Res, typename... _ArgTypes>
	template<typename _Functor, typename, typename>
	function<_Res(_ArgTypes...)>::
		function(_Functor __f)
		: _Function_base()
	{
		typedef _Function_handler<_Signature_type, _Functor> _My_handler;

		if (_My_handler::_M_not_empty_function(__f))
		{
			_My_handler::_M_init_functor(_M_functor, std::move(__f));
			_M_invoker = &_My_handler::_M_invoke;
			_M_manager = &_My_handler::_M_manager;
		}
	}
值得注意的就是Variadic Template的语法了










  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值