Create a public C++ API
This is the head issue related to the proposition of a new C++ API.
The main idea is as follow.
PDI::Data_Store
:
- the core of PDI should be a
PDI::Data_Store
class, - an instance of
Data_Store
is accessible fromPDI::Context
by adata()
member function, - the
Data_Store
class is very similar to astd::unordered_map<std::string, PDI::Weak_Ref>
, - in addition, it is "observable", i.e. one can register to be notified when references are added/removed in it.
PDI::Weak_Ref
/PDI::Shared_Ref
/PDI::Shared_R_Ref
/PDI::Shared_RW_Ref
- the
PDI::Shared_Ref
/PDI::Weak_Ref
classes can be used outside of PDI, they behave similarly tostd::shared_ptr
/std::weak_ptr
,-
PDI::Weak_Ref
/PDI::Shared_Ref
can not be directly dereferenced, - when dereferenced,
PDI::Shared_R_Ref
returns a const pointer, - when dereferenced,
PDI::Shared_R_Ref
returns a normal pointer,
-
- these references implement locking:
-
PDI::Shared_R_Ref
behaves like astd::shared_lock
, -
PDI::Shared_W_Ref
behaves like astd::unique_lock
,
-
- the memory ownership of
shared_ref
is weaker than that ofshared_ptr
(see JavaSoftReference
):- all reference types offer a
release()
member function similarly tostd::unique_ptr
, - the
reclaim()
variant release all reference to the exception of the current one, - all reference types offer a callback mechanism to be notified before the referenced data is released,
- all reference types offer a
- unlike their C++ counterpart, these references offer dynamic typing
- a
type()
member function is offered that returns aDatatype
to retrieve the type information, - templated versions are offered so that the user doesn't have to cast the
void*
pointer on every use,
- a
- TODO: add a word about metadata & type template system
g_user_ref
:
- the
unordered_map<string, std::unique_ptr<Ref_holder>> g_user_ref
global variable stores the user-side references of the C API users, -
Ref_holder
is a base class that is specialized with versions holding any ofPDI::Weak_Ref
/PDI::Shared_Ref
/PDI::Shared_R_Ref
/PDI::Shared_RW_Ref
, -
Ref_holder
can always be converted to aPDI::Weak_Ref
.
The C API behaviour is as follow:
-
share
creates a new reference and stores it both in the globalContext
and ing_user_ref
, -
access
gets a reference from the globalContext
and store it ing_user_ref
, -
release
removes the reference fromg_user_ref
, -
reclaim
callsrelease()
on the reference fromg_user_ref
and removes it.
In other words
void* my_data = //...
// this
PDI_share("name", ptr, PDI_INOUT);
// is equivalent to this
Shared_RW_Ref my_ref(ptr);
pdi.data["name"] = my_ref;
// and this
PDI_release("name");
// is equivalent to this
my_ref.~Shared_RW_Ref(); //< usually done automatically
and
// this
PDI_access("name", *ptr, PDI_INOUT);
// is equivalent to this
Shared_RW_Ref my_ref = pdi.data["name"];
// and this
PDI_reclaim("name");
// is equivalent to this
my_ref.reclaim();
// or this
ptr = my_ref.release();
Edited by Julien Bigot