Opinionated C11 library for low-level functionality
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
Jaakko Keränen efaf13fa8e Merge pull request 'Haiku: Use proper ai_flags for getaddrinfo' (#5) from sikmir/the_Foundation:haiku into master 4 days ago
conf lldb: Use Python 3 syntax 1 year ago
include/the_Foundation String: Comparing against a NULL character range 6 days ago
src Haiku: Use proper ai_flags for getaddrinfo 4 days ago
tests XmlDocument: Check that the header says version 1.0 and UTF-8 2 months ago
.clang-format Updated Clang-Format configuration 8 months ago
.gitignore Git: Ignore Emacs backup files 3 months ago
CMakeLists.txt Porting to Haiku 2 weeks ago
CheckSSE.cmake Fixed build issues on Raspberry Pi (GCC 4.9) 4 months ago
Depends.cmake Linking dependencies 2 weeks ago
LICENSE Added license file 2 years ago
README.md Updated readme 2 years ago
config.h.in Porting to Haiku 2 weeks ago
ssecheck.c Attempt to detect CPU support for SSE 4.1 4 months ago
the_Foundation.doxygen Renamed to "the_Foundation" 3 years ago

README.md

the_Foundation: a C11 library

Simplicity of C11 combined with the power of object-orientation! API usability is priority #1.

Introduction

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.

Wait, what about GLib?

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.

Conventions

General

  • Global symbols like type names and macros use the i prefix (e.g., iMin).

  • Method names and variables use camelCase.

  • Type names and classes start with a capital letter (following the i prefix).

  • 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.

Types and classes

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., element_Array_.

Type names are declared with the iDeclareType(Name) macro. The implementation struct is always called struct Impl_Name that has a typedef alias called iName. The 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.

Construction and destruction

For a given type Type:

  • new_Type allocates 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_Type deletes the object after deinitializing with deinit_Type.
  • init_Type initializes 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_Type releases 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.

Iterators

  • The member value is a pointer to the current element. If NULL, the iteration will stop.
  • The value pointer 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.
  • Iterators may have additional members depending on the type of the data and the requirements for internal state.
  • Non-const iterators have a method called remove if 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.

License

BSD-2-Clause

Author

the_Foundation has been written by Jaakko Keränen jaakko.keranen@iki.fi.