std::function 学习笔记(4)

#pragma once
namespace MyFunctionNameSpace
{// size in pointers of std::function and std::any (roughly 3 pointers larger than std::string when building debug)
	constexpr int _Small_object_num_ptrs = 6 + 16 / sizeof(void*);

	constexpr size_t _Space_size = (_Small_object_num_ptrs - 1) * sizeof(void*);
	template  // determine whether _Impl must be dynamically allocated
	constexpr bool _Is_large = (_Space_size < sizeof(_Impl)) || !_Impl::_Nothrow_move::value;

	template
	class MyFunction
	{
		using FuncType = RetType(*)(Types...);
		union _Storage { // storage for small objects (basic_string is small)
			double _Dummy1; // for maximum alignment
			char _Dummy2[_Space_size]; // to permit aliasing
			FuncType _Ptrs[_Small_object_num_ptrs]; // 之前这里是接口指针数组,但是我们没必要那么搞,直接用函数指针就行
		};

		_Storage _Mystorage;// 公共的存储空间,如果大小比较小,就用这个部分直接存储数据,否则,就需要动态申请内存了
	public:
		RetType operator()(_Types... _Args) const {// _Func_class 重载了operator(),以进行函数调用
			const auto _Impl = _Getimpl();
			return _Impl(_STD forward<_Types>(_Args)...);
		}

		~MyFunction()
		{
			_Destroy();
		}

	protected:

		void _Destroy() {
			if (!_Empty()) {
				_Getimpl()->_Delete_this(!_Local());// 因为有着不同的析构方式,这里需要用接口的形式提供一系列的动作
				_Set(nullptr);
			}
		}
		bool _Empty() const noexcept
		{
			return !_Getimpl();
		}
		FuncType _Getimpl() const noexcept { // get pointer to object
			return _Mystorage._Ptrs[_Small_object_num_ptrs - 1];// 对应下面的_Set函数,这里有一个读取的动作,那就没法直接使用函数指针的类型来存储这个指针了
																// 就得用_Func_Base 的方法,抽象出来_move,_copy,_Delete,_Contruct _do_call,这样的接口
																// 其中还有一个原因,这个function 对象是支持赋值操作的,当其承载的动作不同的时候,用来做支撑的内存空间必然不同,因此,需要一系列的虚函数,来做支持
		}
		void _Set(FuncType _Ptr) noexcept { // store pointer to object
			_Mystorage._Ptrs[_Small_object_num_ptrs - 1] = _Ptr;// 最后一个位置,需要存储我们的接口指针,因此,在计算是否超过存储空间大小的时候,需要去掉这一块的大小
		}
	};
}

尝试实现的过程,暂时按照失败处理吧,后面需要的时候,再学习其中的东西,上面是做了一半,更好的了解了一些std::function 的设计意图

你可能感兴趣的:(学习笔记)