- typedef bits::TaskErasure TaskErasure;
- struct TaskErasureVtable {
- // Call (and possibly destroy) the function:
- R (*call)(TaskErasure&, Args...);
- // Destroy the function:
- void (*destroy)(TaskErasure&);
+ // Placeholder for some class type:
+ struct whatever {};
+
+ // Union used for storage:
+#if 0
+ typedef typename std::aligned_union<0,
+ void*,
+ std::pair<void(*)(),void*>,
+ std::pair<void(whatever::*)(), whatever*>
+ >::type TaskUnion;
+#else
+ union TaskUnion {
+ void* ptr;
+ std::pair<void(*)(),void*> funcptr;
+ std::pair<void(whatever::*)(), whatever*> memberptr;
+ char any1[sizeof(std::pair<void(*)(),void*>)];
+ char any2[sizeof(std::pair<void(whatever::*)(), whatever*>)];
+ TaskUnion() { /* Nothing to do */}
+ ~TaskUnion() { /* Nothing to do */}
+ };
+#endif
+
+ // Is F suitable for small buffer optimization?
+ template<class F>
+ static constexpr bool canSBO()
+ {
+ return sizeof(F) <= sizeof(TaskUnion) &&
+ alignof(F) <= alignof(TaskUnion);
+ }
+
+ static_assert(canSBO<std::reference_wrapper<whatever>>(),
+ "SBO not working for reference_wrapper");
+
+ // Call (and possibly destroy) the function:
+ typedef R (*call_function)(TaskUnion&, Args...);
+ // Destroy the function (of needed):
+ typedef void (*destroy_function)(TaskUnion&);
+ // Move the function (otherwise memcpy):
+ typedef void (*move_function)(TaskUnion& dest, TaskUnion& src);
+
+ // Vtable of functions for manipulating whatever is in the TaskUnion:
+ struct TaskVtable {
+ call_function call;
+ destroy_function destroy;
+ move_function move;