From 3f50495eb4f465531000c33072005ab218fdfb11 Mon Sep 17 00:00:00 2001 From: tylov Date: Sat, 5 Aug 2023 12:57:14 +0200 Subject: Docs improvements in README.md --- README.md | 81 +++++++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 66 insertions(+), 15 deletions(-) (limited to 'README.md') diff --git a/README.md b/README.md index c333f5cd..3ff00e52 100644 --- a/README.md +++ b/README.md @@ -521,39 +521,90 @@ Define `i_type` instead of `i_tag`: #define i_key int #include -myvec vec = MyVec_init(); -MyVec_push_back(&vec, 1); +MyVec vec = {0}; +MyVec_push(&vec, 42); ... ``` --- ## Forward declarations -It is possible to forward declare containers. This is useful when a container is part of a struct, -but still not expose or include the full implementation / API of the container. +There are two ways to pre-declare templated containers in header files: + +1. Include the templated container type instance as a header file. This also exposes all container +functions, which can be used by client code. It requires that the element type is complete. +2. Or, pre-declare the container type only. In this case, the container can be a "private" member of a +user struct (the container functions will not be available to the user). + +### 1. Include as a header file + +Create a dedicated header for the container type instance: +```c +#ifndef PointVec_H_ +#define PointVec_H_ +// Do not to include user defined headers here if they use templated containers themselves + +#define i_type PointVec +#define i_val struct Point // NB! Element type must be complete at this point! +#define i_header // Do not implement, only expose API +#include + +#endif +``` +Usage from e.g. other headers is trivial: +```c +#ifndef Dataset_H_ +#define Dataset_H_ +#include "Point.h" // include element type separately +#include "PointVec.h" + +typedef struct Dataset { + PointVec vertices; + PointVec colors; +} Dataset; +... +#endif +``` + +Implement PointVec in a c-file: +```c +#include "Point.h" +#define i_implement // define immediately before PointVec.h +#include "PointVec.h" +... +``` + +### 2. Forward declare only ```c // Dataset.h -#include // only include data structures +#ifndef Dataset_H_ +#define Dataset_H_ +#include // include various container data structure templates -// declare cstack_pnt; struct Point may be an incomplete type. -forward_cstack(cstack_pnt, struct Point); +// declare PointVec. Note: struct Point may be an incomplete/undeclared type. +forward_cvec(PointVec, struct Point); typedef struct Dataset { - cstack_pnt vertices; - cstack_pnt colors; + PointVec vertices; + PointVec colors; } Dataset; +void Dataset_drop(Dataset* self); ... +#endif +``` +Define and use the "private" container in the c-file: +```c // Dataset.c #include "Dataset.h" +#include "Point.h" // Point must be defined here. -struct Point { int x, y, z; }; // Point must be defined here. -#define i_is_forward // flag that the container was forward declared. -#define i_key struct Point -#define i_tag pnt -#include +#define i_is_forward // flag that the container was forward declared. +#define i_type PointVec +#define i_val struct Point +#include // Implements PointVec with static linking by default +... ``` - --- ## Per container-instance customization Sometimes it is useful to extend a container type to store extra data, e.g. a comparison -- cgit v1.2.3