|4 days ago|
|conf||1 year ago|
|include/the_Foundation||6 days ago|
|src||4 days ago|
|tests||2 months ago|
|.clang-format||8 months ago|
|.gitignore||3 months ago|
|CMakeLists.txt||2 weeks ago|
|CheckSSE.cmake||4 months ago|
|Depends.cmake||2 weeks ago|
|LICENSE||2 years ago|
|README.md||2 years ago|
|config.h.in||2 weeks ago|
|ssecheck.c||4 months ago|
|the_Foundation.doxygen||3 years ago|
Simplicity of C11 combined with the power of object-orientation! API usability is priority #1.
C++ is an awesome language. It is also extremely complex and each of its modern updates adds even more complexity. Like C, it is a thin abstraction layer over machine instructions, but it also reaches toward ever-higher level of concepts and programming styles. This conflict prevents it from being truly high-level while compromising the benefits of low-level C. The complexity — among other things — makes compiling C++ programs much slower than C.
the_Foundation is a C11 library and a coding convention for object-oriented programming that has been designed from the point of view of someone who appreciates the user-friendliness of Qt and some of the thinking behind C++ STL. The preprocessor is used heavily to provide flexibility and convenience for the programmer.
GLib is a solid library that serves an important function in GTK. It also has its own coding style and naming conventions that come with a set of assumptions how things are expected to work. However, the_Foundation aims to be more light-weight and bolder in its conventions to achieve specific design goals.
Global symbols like type names and macros use the
i prefix (e.g.,
Method names and variables use camelCase.
Type names and classes start with a capital letter (following the
Preprocessor macros and constants use naming similar to classes (e.g.,
iDeclareType). They begin with a verb.
The general base class
iObject implements reference counting. The class of an object determines how the object is deinitialized.
In functions where an object is passed as an argument, the reference count must be incremented if the function holds a pointer to the object. Otherwise, the reference count should not be modified.
All class members use the class name as a suffix, e.g.,
length_String. This improves readability and associates the first argument (the
d object, equivalent to
this in C++) with the type of the class.
A static/private member of a class additionally adds an extra underscore to the suffix, e.g.,
Type names are declared with the
iDeclareType(Name) macro. The implementation struct is always called
struct Impl_Name that has a typedef alias called
Impl_Name struct should be kept opaque (only declared in the header) by default to hide the implementation details.
static inline functions (or macros) are used to define member functions with default values for parameters.
For a given type
new_Typeallocates memory for a Type instance from the heap and initializes it by calling the init method
init_Type. The macro
iMalloc(Type)is provided for convenience.
delete_Typedeletes the object after deinitializing with
init_Typeinitializes an object's memory (e.g., zeroing it) inside a memory buffer with uninitialized contents. The memory can be located anywhere (heap or stack).
deinit_Typereleases any memory/resource allocations, but not delete the object itself nor is any of the object's state reset to zero. The memory contents are considered undefined afterwards.
valueis a pointer to the current element. If NULL, the iteration will stop.
valuepointer must be the first member in an iterator struct. Derived iterators should use an anonymous union to alias the value pointer to an appropriate type, while remaining compatible with the base class's iterator implementation.
removeif the currently iterated element can be removed during iteration. Using this ensures that memory owned by the container itself will be released when the element is deleted.
the_Foundation has been written by Jaakko Keränen email@example.com.