|
@@ -68,7 +68,7 @@ define_vector_type(int)
|
68
|
68
|
|
69
|
69
|
This will then expand into the appropriate vector `struct` (e.g. `vector_int`) with matching functions. All functions are appended with the type, with the general format `vector_`**[TYPE]**`_`**[FUNCTION]**. Therefore, to `push_back` on an `int` vector, one would call `vector_int_push_back`.
|
70
|
70
|
|
71
|
|
-As `vector` relies on dynamically-allocated memory via `malloc`, a convenience function `vector_`**[TYPE]**`_free` has been provided to release a vector after it has finished being used. To supplant a user-defined `malloc`, one can define the `CSTL_MALLOC` macro with the user-supplied function necessary before including the `vector` header file. The same is true for `realloc` and `free`, as `CSTL_REALLOC` and `CSTL_FREE`.
|
|
71
|
+As `vector` relies on dynamically-allocated memory via `malloc`, a set of functions are used to allocate and release a vector after it has finished being used. To supplant a user-defined `malloc`, one can define the `CSTL_CUSTOM_MEMORY` macro and pass it in to the compiler, and implement the following functions: `cstl_malloc`, `cstl_realloc`, and `cstl_free`. To understand why this works, there is essentially a kind of conditional compilation going on. These functions are defined internally within a source file **only if** `CSTL_CUSTOM_MACRO` is not defined. Therefore, defining the macro frees up the implementation, allowing the user to supplant one easily. Through gcc, this might be done as `cc -DCSTL_CUSTOM_MACRO ...`.
|
72
|
72
|
|
73
|
73
|
To sum up, here is some example usage with the declared `vector_int` above:
|
74
|
74
|
```c
|
|
@@ -113,12 +113,45 @@ int main() {
|
113
|
113
|
string_cat_cstr(&s, " And concatenate, too!");
|
114
|
114
|
|
115
|
115
|
//Exporting our string as a C-string
|
116
|
|
- printf(string_cstr(&s));
|
|
116
|
+ printf("%s", string_cstr(&s));
|
117
|
117
|
|
118
|
118
|
string_deinit(&s);
|
119
|
119
|
}
|
120
|
120
|
```
|
121
|
121
|
|
|
122
|
+## Useful C Additions
|
|
123
|
+
|
|
124
|
+Alongside constructs which exist in the C++ STL and standard library, some functions have been written to better interact with "native" C constructs (such as C-strings).
|
|
125
|
+
|
|
126
|
+### \<cstring\>
|
|
127
|
+
|
|
128
|
+This module offers an interface to easily reason through heap-allocated C-strings, which may be struct members. The functions ensure that an initialized C-string is either `NULL` or a `char*` to a valid null-terminated string. In this paradigm, testing if a string is empty/non-existent is as easy as testing the pointer itself, and no unnecessary memory has to be allocated to simply represent an empty C-string. This works particularly well, as `NULL` is a valid argument for `free()`.
|
|
129
|
+
|
|
130
|
+The only minor cost is a branch in C-string assignment (`cstring_asn`), in order to accept a valid, intialized string (which may be `NULL`).
|
|
131
|
+
|
|
132
|
+Example usage:
|
|
133
|
+```c
|
|
134
|
+#include <cstl/cstring.h>
|
|
135
|
+
|
|
136
|
+int main() {
|
|
137
|
+ //Initializing a C-string
|
|
138
|
+ char* s;
|
|
139
|
+ cstring_init(s);
|
|
140
|
+
|
|
141
|
+ //Assigning it a value
|
|
142
|
+ cstring_asn(s, "A new value!");
|
|
143
|
+
|
|
144
|
+ //Printing it as we usually would
|
|
145
|
+ printf("%s", s);
|
|
146
|
+
|
|
147
|
+ cstring_destroy(s);
|
|
148
|
+}
|
|
149
|
+```
|
|
150
|
+
|
|
151
|
+There
|
|
152
|
+
|
|
153
|
+More can be found in [cstring.h](./include/cstl/cstring.h).
|
|
154
|
+
|
122
|
155
|
**NOTE:** This module is constantly changing and improving, this document attempts to work as a good starting point with as much as correct as possible, but the source of truth should rest in the library's comments themselves. This README is not guaranteed to contain up-to-date information with the latest `master` build.
|
123
|
156
|
|
124
|
157
|
## Testing
|