I've implemented a linked list in C with many functions to help ease its manipulation.
I don't want to port this functionality to C++ so I'm trying to create a simple Wrapper Class that calls the original functions internally, and manipulates the C linked list internally as well.
For most of the functionality, the wrapper code works well. There is one problem, however. The C linked list structure has pointers to the next and the previous C linked list structures, and I want to be able to get the C++ equivalent class pointers instead ..
How can I do that ?
E.x: There is a C function that gets the linked list in the chain at an index. The Original function would do something like this:
struct _linkedlist *LinkedList_get(struct _linkedlist * list, const unsigned long index)
{ /* Gets the index'th linked list in the chain as a pointer */
if ((list) == NULL) return NULL;
if (index >= LinkedList_get_depth(list))
return NULL;
for(unsigned int i = 0; i < index; list = list->next, ++i);
return list;
}
The function clearly returns a pointer to the linked list C struct. What I want to do is get a pointer to the C++ linked list wrapper object.
The whole purpose of this is that I can make an object oriented wrapper (the C++ interface) around a purely functional interface (the C interface) without altering the original source (the C version).
You've mentioned in comments that your C linked list stores an arbitrary value type (as void*
). Therefore, it should be fairly trivial for the C++ wrapper to store extra information in that value type. This extra information could be the pointer to the corresponding C++ wrapper.
You haven't shown your code, so I will just show the idea in a generic fashion:
// This is the original C interface
struct C_Node;
void* c_getValue(struct C_Node *node);
struct C_Node* c_insertAfter(struct C_Node *node, void *value);
// This is the C++ wrapper
template <class T>
class Node
{
C_Node *cNode;
typedef std::pair<T, Node*> ProxyValueType;
explicit Node(C_Node *cNode) : cNode(cNode)
{
static_cast<ProxyValueType*>(c_getValue(cNode))->second = this;
}
public:
T& getValue() const
{ return static_cast<ProxyValueType*>(c_getValue(cNode))->first; }
Node* insertAfter(T value)
{
ProxyValueType *proxy = new ProxyValueType(T, nullptr);
C_Node *newNode = c_insertAfter(cNode, proxy);
return new Node(newNode);
}
};
Of course, the above as written is bad C++, as it uses owning raw pointers etc. Treat it as a demonstration of the idea, not as pastable code.