#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 <class _Impl> // determine whether _Impl must be dynamically allocated
constexpr bool _Is_large = (_Space_size < sizeof(_Impl)) || !_Impl::_Nothrow_move::value;
template<class RetType, class... Types>
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 的设计意图