# Custom type containers

Default containers in `libcdada`:

* Don't require C++ code to be compiled. It's sufficient to link `-lcdada`
* Keys (values for lists) are limited to 1-256 bytes
* Types that are not aligned to a power 2 bytes might be suboptimal both in performance and
  memory

Custom type containers solve these two limitations by specializing backend
`libstc++` containers for your C types. Some tools are provided
so that you don't have to write C++ (if you don't want to).

The only changes to your code from regular `libcdada` will be:

```diff

+ //Fwd decl
+ CDADA_LIST_CUSTOM_TYPE_DECL(foo_t);

  int my_func(){

-       list = cdada_list_create(foo_t);
+       list = cdada_list_create_custom(foo_t);
        TEST_ASSERT(list != NULL);

```

The rest of operations over the containers are done using the same `libcdada` API.

## Step by step guide

In this example we aim to create customer containers for:

* A `list` of objects of C type `foo_t`
* A `map` of objects of C type `bar_t`

The code for this example, in the two variants is in:

* [custom-gen/](../examples/custom-gen/)
* [custom-macro/](../examples/custom-macro/)

### 1. Create `cdada.cc` file

#### 1.1 Code generation `cdada-gen`

Make sure `cdada-gen` is installed (you need `python3`), and:

```bash

~/ cdada-gen -o cdada.cc list:foo_t map:bar_t

```

Now edit the autogenerated file `cada.cc` and add the header includes for
types `foo_t` `bar_t`:

```diff

  /*****************************************************************************/
  /*                      BEGIN libcdada AUTOGENERATED C++ file                */
  /*****************************************************************************/
  // File autogenerated from cmd: ['./cdada-gen', 'list:foo_t', 'map:bar_t', '-o', 'cdada.cc']
  // Add your header includes for types {'foo_t', 'bar_t'} here

+ #include "foo.h"
+ #include "bar.h"

  ///////////////////////////////////////////////////////////////////////////////
  ///                       DO NOT MODIFY AFTER THIS LINE                     ///
  ///////////////////////////////////////////////////////////////////////////////

```

#### 1.2 MACRO option

Alternatively, create a new file `cdada.cc` and add:

```cc
#include <cdada/list_custom_cc.h>
#include <cdada/map_custom_cc.h>

#include "foo.h"
#include "bar.h"

//Autogen C++ comparison operators (once per user type)
CDADA_CUSTOM_GEN_MEMCP_OPERATORS(foo_t);
CDADA_CUSTOM_GEN_MEMCP_OPERATORS(bar_t);

//Autogenerate C++ code for the containers
CDADA_LIST_CUSTOM_GEN(foo_t);
CDADA_MAP_CUSTOM_GEN(bar_t);
```

### 2. Modify the code of your application

Replace `cdada_list_xxx()` by `cdada_xxx_create_custom()`, and add forward
declarations `CDADA_XXX_CUSTOM_TYPE_DECL` in the compilation unit where
`cdada_xxx_create_custom()` are called:

```diff

+ //Fwd decl
+ CDADA_LIST_CUSTOM_TYPE_DECL(foo_t);
+ CDADA_MAP_CUSTOM_TYPE_DECL(bar_t);


  int my_func(){

-       list = cdada_list_create(foo_t);
+       list = cdada_list_create_custom(foo_t);
-       map = cdada_map_create(bar_t);
+       map = cdada_map_create_custom(bar_t);
        TEST_ASSERT(list != NULL);

```

### 3. Compile and link

Make sure `cdada.cc` is compiled with `g++` or `clang++`:

```bash
~/ g++ -c cdada.cc cdada.o
```

And link it:

```bash
~/ gcc <your files> cdada.o -o my_program -lcdada -lstdc++
```
