Just some cosmetics.
This commit is contained in:
parent
32e7d0b337
commit
db7ea91463
1 changed files with 28 additions and 20 deletions
48
README.md
48
README.md
|
|
@ -1,6 +1,9 @@
|
||||||
# libooc
|
# libooc
|
||||||
|
|
||||||
A tiny C library for object-oriented programming using ordinary C structs and function-pointer vtables. It provides object allocation, virtual destructors, intrusive reference counting, runtime class metadata, name-based field access, and a small interface header.
|
A tiny C library for object-oriented programming using ordinary C structs and
|
||||||
|
function-pointer vtables. It provides object allocation, virtual destructors,
|
||||||
|
intrusive reference counting, runtime class metadata, name-based field access,
|
||||||
|
and a small interface header.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
|
|
@ -25,7 +28,8 @@ For packaging, `pkg` stages the same tree under `./pkg` without needing root:
|
||||||
make pkg
|
make pkg
|
||||||
make clean-pkg
|
make clean-pkg
|
||||||
|
|
||||||
That is shorthand for `make DESTDIR="$PWD/pkg" PREFIX=/$(PREFIX) install`, and it honours an overridden prefix:
|
That is shorthand for `make DESTDIR="$PWD/pkg" PREFIX=/$(PREFIX) install`, and
|
||||||
|
it honours an overridden prefix:
|
||||||
|
|
||||||
make pkg PREFIX=/usr
|
make pkg PREFIX=/usr
|
||||||
|
|
||||||
|
|
@ -59,8 +63,8 @@ one through the same calls before putting all four objects through a single
|
||||||
`Animal *`. The output makes the point that is invisible in the source: one call
|
`Animal *`. The output makes the point that is invisible in the source: one call
|
||||||
site reaches four implementations, and the vtable decides which.
|
site reaches four implementations, and the vtable decides which.
|
||||||
|
|
||||||
make test # runs example/main.c
|
make example-test # runs example/main.c
|
||||||
make safety-test # runs the assertion suite in tests/
|
make safety-test # runs the assertion suite in tests/
|
||||||
|
|
||||||
Objects are reference-counted with `ooc_retain()` and `ooc_release()`.
|
Objects are reference-counted with `ooc_retain()` and `ooc_release()`.
|
||||||
|
|
||||||
|
|
@ -68,7 +72,8 @@ The public installed header is:
|
||||||
|
|
||||||
#include <ooc/ooc.h>
|
#include <ooc/ooc.h>
|
||||||
|
|
||||||
Application-specific classes such as `Animal`, `Dog` and `Cat` are not installed by the library.
|
Application-specific classes such as `Animal`, `Dog` and `Cat` are not installed
|
||||||
|
by the library.
|
||||||
|
|
||||||
### Constructors down a chain
|
### Constructors down a chain
|
||||||
|
|
||||||
|
|
@ -168,7 +173,7 @@ field is assigned through a pointer to the pointer:
|
||||||
```c
|
```c
|
||||||
char *name = copy_of("Bella");
|
char *name = copy_of("Bella");
|
||||||
|
|
||||||
ooc_set(dog, "name", &name); /* "Rex" is freed here */
|
ooc_set(dog, "name", &name); /* "Rex" is freed here */
|
||||||
printf("%s\n", *(char **)ooc_get(dog, "name"));
|
printf("%s\n", *(char **)ooc_get(dog, "name"));
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -188,9 +193,9 @@ own `favourite_food` does.
|
||||||
answers for a base class as well as for the type itself:
|
answers for a base class as well as for the type itself:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
ooc_is_a(cat, &Cat_class); /* 1 */
|
ooc_is_a(cat, &Cat_class); /* 1 */
|
||||||
ooc_is_a(cat, &Animal_class); /* 1 -- a Cat is an Animal */
|
ooc_is_a(cat, &Animal_class); /* 1 -- a Cat is an Animal */
|
||||||
ooc_is_a(cat, &Dog_class); /* 0 -- siblings are unrelated */
|
ooc_is_a(cat, &Dog_class); /* 0 -- siblings are unrelated */
|
||||||
```
|
```
|
||||||
|
|
||||||
The walk covers the whole chain, so depth costs nothing to the caller:
|
The walk covers the whole chain, so depth costs nothing to the caller:
|
||||||
|
|
@ -209,7 +214,7 @@ Asking whether an object is *exactly* one type is a different question, and need
|
||||||
no chain walk. The class record is a public member of `ooc_object`:
|
no chain walk. The class record is a public member of `ooc_object`:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
cat->animal.object.class == &Animal_class; /* 0 -- exactly a Cat */
|
cat->animal.object.class == &Animal_class; /* 0 -- exactly a Cat */
|
||||||
```
|
```
|
||||||
|
|
||||||
## Private fields
|
## Private fields
|
||||||
|
|
@ -234,7 +239,7 @@ static const ooc_field Animal_fields[] = {
|
||||||
{ "name", offsetof(Animal, name), sizeof(((Animal *)0)->name), 1 },
|
{ "name", offsetof(Animal, name), sizeof(((Animal *)0)->name), 1 },
|
||||||
{ "_id", offsetof(Animal, _id), sizeof(((Animal *)0)->_id), 0 },
|
{ "_id", offsetof(Animal, _id), sizeof(((Animal *)0)->_id), 0 },
|
||||||
{ "__legs", offsetof(Animal, __legs), sizeof(((Animal *)0)->__legs), 0 },
|
{ "__legs", offsetof(Animal, __legs), sizeof(((Animal *)0)->__legs), 0 },
|
||||||
{ NULL, 0, 0, 0 },
|
{ NULL, 0, 0, 0 },
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -242,8 +247,8 @@ One underscore leaves a field readable but not writable, which is enough for a
|
||||||
class to show its own state without handing out a way to change it:
|
class to show its own state without handing out a way to change it:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
ooc_set(dog, "_id", &id); /* refused with -1, the field is unchanged */
|
ooc_set(dog, "_id", &id); /* refused with -1, the field is unchanged */
|
||||||
*(int *)ooc_get(dog, "_id"); /* still readable */
|
*(int *)ooc_get(dog, "_id"); /* still readable */
|
||||||
```
|
```
|
||||||
|
|
||||||
Two underscores make the field unreachable in both directions. `ooc_get()`
|
Two underscores make the field unreachable in both directions. `ooc_get()`
|
||||||
|
|
@ -251,8 +256,8 @@ still finds it in the table and then withholds the pointer, so there is no way
|
||||||
in by name, and only the object can change the value:
|
in by name, and only the object can change the value:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
ooc_get(dog, "__legs"); /* NULL, whether or not the field exists */
|
ooc_get(dog, "__legs"); /* NULL, whether or not the field exists */
|
||||||
ooc_set(dog, "__legs", &legs); /* refused with -1 */
|
ooc_set(dog, "__legs", &legs); /* refused with -1 */
|
||||||
```
|
```
|
||||||
|
|
||||||
What a class keeps under such a name it hands out itself, through an accessor
|
What a class keeps under such a name it hands out itself, through an accessor
|
||||||
|
|
@ -275,10 +280,10 @@ inheriting Cat's `_lives`, and a caller can read both by name but write neither
|
||||||
the rule belongs to the declaration, not to the object:
|
the rule belongs to the declaration, not to the object:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
ooc_get(garfield, "_meals"); /* readable -- Garfield's */
|
ooc_get(garfield, "_meals"); /* readable -- Garfield's */
|
||||||
ooc_get(garfield, "_lives"); /* readable -- Cat's, two levels up */
|
ooc_get(garfield, "_lives"); /* readable -- Cat's, two levels up */
|
||||||
ooc_set(garfield, "_meals", &n); /* refused */
|
ooc_set(garfield, "_meals", &n); /* refused */
|
||||||
ooc_set(garfield, "_lives", &n); /* also refused */
|
ooc_set(garfield, "_lives", &n); /* also refused */
|
||||||
```
|
```
|
||||||
|
|
||||||
Private means private to the declaring class, which is why a subclass adds a
|
Private means private to the declaring class, which is why a subclass adds a
|
||||||
|
|
@ -308,7 +313,10 @@ threads. `ooc_retain()` returns NULL if the reference count cannot be incremente
|
||||||
|
|
||||||
## Portability
|
## Portability
|
||||||
|
|
||||||
The library API is standard C and has no third-party dependencies. The supplied Makefile uses conventional POSIX/Unix build tools and produces both shared and static libraries. Other platforms can use the same source/API with their native build system if their shared-library conventions differ.
|
The library API is standard C and has no third-party dependencies. The supplied
|
||||||
|
Makefile uses conventional POSIX/Unix build tools and produces both shared and
|
||||||
|
static libraries. Other platforms can use the same source/API with their native
|
||||||
|
build system if their shared-library conventions differ.
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue