C++ How to create unique types, from the all stack template. Part two.

Same Template Different Types
Same Template Different Types

Part one is here. And what is going on in here?

A real-life use case. I had the same task in my dbj++sql. An SQLite standard C++ API. A simple template with “nothing” inside that has to be made into separate unique types when defined.

Simple looking, but crucial for the whole framework to offer “simple udf’s” functionality for the customers.  And I wanted to implement this with as little interaction as possible with complex sqlite3 C API.

SQLite API provides one function to register UDF’s. And it is to be used like so:

Where udf is a C/C++ function, that must conform to exact signature required.

To use this in it’s “naked” form is for 99% of SQLite users “not fun”. And hardly leads to reusable code. Thus they resort to C++ wrapper like mine is. Where I am offering “almost naked” UDF’s , described here. And I am offering (what I am calling) “dbj easy udf’s” described here.

What I am sharing here is how I have designed and developed this “easy UDF’s”. Let’s start with the key abstraction.

A template with just one static function inside.  One template argument is not a type, it is a value argument. A function pointer type.

Why is it done this way?

A template is not a type. Types are made from template definitions. Function pointer as a template argument is providing identity to the types made from this template.

udf_holder template, has no data and no functions, only one static method. To be shared among all types made from it.

The template argument is a function pointer. Each udf is a unique function pointer, thus providing a unique identity to the types udf_h_1 and udf_h_2 above.

Ok, but why is this function static?

Because we need to cast it to non-member aka “free standing” function pointer type. And that function is required by C API.  How do we transform it form C++ static template function to free-standing function:

Address of class static function can be assigned to C function pointer. You can not do that with “normal” non-static C++ class function.

The API

Basically, I have a standard callback function, that is always the same. From which, in turn, I call different SQLite user-defined “easy udf” functions. Here is the one method from dbj++sql.h in my SQLite C++ api that does the transformation into C function and registration with the SQLite:

All of the above C++ sorcery is hidden away and happy users make happy standard C++ functions to be used as SQLite “easy udf’s”, each in one simple call:

 

Same as ever, if anybody requires more clarifications, do not be afraid to comment.  Enjoy the standard C++.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.