support (type safe) user object on id in bindings
An isl_id can have both a name and a user pointer.
The user pointer is specified during construction and
can be retrieved using isl_id_get_user.
In the C API, it is the responsibility of the user
to take care of properly interpreting the pointer
returned by isl_id_get_user.
In the bindings, a safer mechanism should be provided.
In the Python bindings, only Python objects can be specified
during isl.id construction and Python takes care
of the correct interpretation of the object returned by the user method.
The bindings do need to take care of incrementing the reference count
of the Python object embedded in the isl_id.
The reference count of the Python object is decremented again
when the reference count of the isl_id drops to zero.
Furthermore, the user method checks that the isl.id was constructed
by the Python bindings to ensure that the user pointer
does indeed refer to a Python object.
The method returns None when this check fails.
In the C++ bindings, an object of any copy constructible type
can be specified during isl::id construction, but the user
needs to specify the type of the user object returned
by the user method using a template argument.
The user object is copied into a dynamically allocated std::any object and
a pointer to this std::any object is embedded in the isl_id.
The pointer is freed again when the reference count of the isl_id
drops to zero.
The user method checks that the isl::id was constructed
by the C++ bindings and uses std::any_cast to check
that the associated object is of the expected type.
Two variants of the user method are provided,
one that returns std::nullopt when any of the checks fail and
one that throws an exception on failure (or uses the C mechanism
for reporting an error in case of the checked C++ bindings).
Since std::any and std::optional are only available in C++17,
these methods are only made available when the bindings
are used in C++17 mode.
Since the methods for handling user objects are very specific
to isl_id, they are inserted directly, instead of trying
to generate them from the corresponding C functions.
Reviewed-by: Matthew Fernandez <matt.fernandez@cerebras.net>
Reviewed-by: Tianjiao Sun <tianjiao.sun@cerebras.net>
Signed-off-by: Sven Verdoolaege <sven@cerebras.net>
13 files changed: