#include "base/AsyncCall.h"
#include "base/InstanceId.h"
+#include "cbdata.h"
template <class Cbc>
class CbcPointer;
/// \ingroup AsyncJobAPI
/// Base class for all asynchronous jobs
-class AsyncJob
+class AsyncJob: public CbdataParent
{
public:
typedef CbcPointer<AsyncJob> Pointer;
AsyncJob(const char *aTypeName);
virtual ~AsyncJob();
- virtual void *toCbdata() = 0;
-
/// starts a freshly created job (i.e., makes the job asynchronous)
static Pointer Start(AsyncJob *job);
*/
cbdata_type cbdataInternalAddType(cbdata_type type, const char *label, int size);
-/**
- * This needs to be defined FIRST in the class definition.
- * It plays with private/public states in C++.
- */
-#define CBDATA_CLASS(type) \
+/// declaration-generator used internally by CBDATA_CLASS() and CBDATA_CHILD()
+#define CBDATA_DECL_(type, methodSpecifiers) \
public: \
void *operator new(size_t size) { \
assert(size == sizeof(type)); \
void operator delete (void *address) { \
if (address) cbdataInternalFree(address,__FILE__,__LINE__); \
} \
- void *toCbdata() { return this; } \
+ void *toCbdata() methodSpecifiers { return this; } \
private: \
static cbdata_type CBDATA_##type;
+/// Starts cbdata-protection in a class hierarchy.
+/// Child classes in the same hierarchy should use CBDATA_CHILD().
+class CbdataParent
+{
+public:
+ virtual ~CbdataParent() = default;
+ virtual void *toCbdata() = 0;
+};
+
+/// cbdata-enables a stand-alone class that is not a CbdataParent child
+/// sets the class declaration section to "private"
+/// use this at the start of your class declaration for consistency sake
+#define CBDATA_CLASS(type) CBDATA_DECL_(type, noexcept)
+
+/// cbdata-enables a CbdataParent child class (including grandchildren)
+/// sets the class declaration section to "private"
+/// use this at the start of your class declaration for consistency sake
+#define CBDATA_CHILD(type) CBDATA_DECL_(type, override final)
+
/**
* Creates a global instance pointer for the CBDATA memory allocator
* to allocate and free objects for the matching CBDATA_CLASS().