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的语法了










神书-STL实现原理,对于强化数据结构-算法的程序员必备、必读书籍。The Best-Selling Programmer Resource–Now Updated for C++11 The C++ standard library provides a set of common classes and interfaces that greatly extend the core C++ language. The library, however, is not self-explanatory. To make full use of its components - and to benefit from their power - you need a resource that does far more than list the classes and their functions. The C++ Standard Library - A Tutorial and Reference, 2nd Edition describes this library as now incorporated into the new ANSI/ISO C++ language standard (C++11). The book provides comprehensive documentation of each library component, including an introduction to its purpose and design; clearly written explanations of complex concepts; the practical programming details needed for effective use; traps and pitfalls; the exact signature and definition of the most important classes and functions; and numerous examples of working code. The book focuses on the Standard Template Library (STL), examining containers, iterators, function objects, and STL algorithms. You will also find detailed coverage of strings, concurrency, random numbers and distributions, special containers, numerical classes, internationalization, and the IOStreams library. An insightful introduction to fundamental concepts and an overview of the library will help bring newcomers quickly up to speed. A comprehensive index will support the C++ programmer in his/her day-to-day life.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值