diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 29 | ||||
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | src/main.c | 24 | ||||
-rw-r--r-- | src/shape.c | 32 | ||||
-rw-r--r-- | src/shape.h | 21 | ||||
-rw-r--r-- | src/square.c | 49 | ||||
-rw-r--r-- | src/square.h | 16 | ||||
-rw-r--r-- | v1/main.c | 22 | ||||
-rw-r--r-- | v1/shape.c | 32 | ||||
-rw-r--r-- | v1/shape.h | 19 | ||||
-rw-r--r-- | v1/square.c | 48 | ||||
-rw-r--r-- | v1/square.h | 16 |
13 files changed, 322 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1b36766 --- /dev/null +++ b/Makefile @@ -0,0 +1,29 @@ +NAME=poc +CC = gcc +CFLAGS = -Isrc +# Standard compliance +CFLAGS += -std=c99 -pedantic + +PREFIX = /usr/local +MANPREFIX = $(PREFIX)/man + +all: bin/$(NAME) + +debug: CFLAGS += -Wall -DEBUG -g +debug: bin/$(NAME) + +sources = $(wildcard src/*.c) +objects = $(patsubst src/%.c, bin/%.o, $(sources)) + +bin/$(NAME): $(objects) + mkdir -p $$(dirname $@) + $(CC) $(CFLAGS) $^ -o $@ $(LIBS) + +bin/%.o: src/%.c + mkdir -p $$(dirname $@) + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + rm -rf bin/ + +.PHONY: clean diff --git a/README.md b/README.md new file mode 100644 index 0000000..b088076 --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +**Proof-of-Concept project for OOP in C** + +This is my project where I develop possible C99 implementations for some of the concepts found in OOP. Feel free to look around. Bellow you can read a description of things that's already implemented. + +Interface +--------- + +Currently this is the only thing, that's implemented. The solution was designed for supporting the following requirements: + +- A given object should be able to support multiple interfaces. +- Interoperable between multiple dynamicly linked libraries. + +The last point means, that the code for the interface and implementations could reside in different dynamicly linked libraries, which were compiled with different compilers.
\ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..4386a05 --- /dev/null +++ b/src/main.c @@ -0,0 +1,24 @@ +#include <stdio.h> +#include "square.h" + +void print_square(struct square *square) +{ + double area = square_area(square); + printf("square_area=%f\n", area); +} + +void print_shape(struct shape *shape) +{ + double area = shape_area(shape); + printf("shape_area=%f\n", area); +} + +int main(int argc, char **argv) +{ + struct square *square = square_create(5); + print_square(square); + + print_shape(square_as_shape(square)); + + shape_destroy(square_as_shape(square)); +} diff --git a/src/shape.c b/src/shape.c new file mode 100644 index 0000000..cb72c05 --- /dev/null +++ b/src/shape.c @@ -0,0 +1,32 @@ +#include <stdlib.h> +#include "shape.h" + +struct shape +{ + shape_area_t area; + shape_destroy_t destroy; +}; + +double shape_area(struct shape *shape) +{ + return shape->area(shape); +} + +void shape_destroy(struct shape *shape) +{ + shape->destroy(shape); +} + +void shape_init( + struct shape *shape, + shape_area_t area, + shape_destroy_t destroy) +{ + shape->area = area; + shape->destroy = destroy; +} + +int shape_sizeof() +{ + return sizeof(struct shape); +}
\ No newline at end of file diff --git a/src/shape.h b/src/shape.h new file mode 100644 index 0000000..641b440 --- /dev/null +++ b/src/shape.h @@ -0,0 +1,21 @@ +#ifndef POC__SHAPE_H +#define POC__SHAPE_H + +struct shape; + +/* Calculates the area of the shape and returns the value. */ +double shape_area(struct shape *shape); +typedef double (*shape_area_t)(struct shape *); + +/* Deallocates the object. */ +void shape_destroy(struct shape *shape); +typedef void (*shape_destroy_t)(struct shape *); + +void shape_init( + struct shape *shape, + shape_area_t area, + shape_destroy_t destroy); + +int shape_sizeof(); + +#endif diff --git a/src/square.c b/src/square.c new file mode 100644 index 0000000..8aef283 --- /dev/null +++ b/src/square.c @@ -0,0 +1,49 @@ +#include <stdlib.h> +#include <stddef.h> +#include "square.h" + +struct square +{ + double width; +}; + +/* Shape interface */ + +double shape_area_impl(struct shape *shape) +{ + struct square *square = ((void *)shape) + shape_sizeof(); + return square_area(square); +} + +void shape_destroy_impl(struct shape *shape) +{ + struct square *square = ((void *)shape) + shape_sizeof(); + square_destroy(square); +} + +struct shape *square_as_shape(struct square *square) +{ + return ((void *)square) - shape_sizeof(); +} + +/* End of shape interface */ + +struct square *square_create(double width) +{ + struct shape *shape = malloc(shape_sizeof() + sizeof(struct square)); + struct square *square = ((void *)shape) + shape_sizeof(); + square->width = width; + + shape_init(shape, shape_area_impl, shape_destroy_impl); + return square; +} + +double square_area(struct square *square) +{ + return square->width * square->width; +} + +void square_destroy(struct square *square) +{ + free(((void *)square) - shape_sizeof()); +}
\ No newline at end of file diff --git a/src/square.h b/src/square.h new file mode 100644 index 0000000..177c9c7 --- /dev/null +++ b/src/square.h @@ -0,0 +1,16 @@ +#ifndef POC__SQUARE_H +#define POC__SQUARE_H + +#include "shape.h" + +struct square; + +struct square *square_create(double width); + +double square_area(struct square *square); + +void square_destroy(struct square *square); + +struct shape *square_as_shape(struct square *square); + +#endif diff --git a/v1/main.c b/v1/main.c new file mode 100644 index 0000000..d149c87 --- /dev/null +++ b/v1/main.c @@ -0,0 +1,22 @@ +#include <stdio.h> +#include "square.h" + +void print_square(struct square *square) +{ + double area = square_area(square); + printf("square_area=%f\n", area); +} + +void print_shape(struct shape *shape) +{ + double area = shape_area(shape); + printf("shape_area=%f\n", area); +} + +int main(int argc, char **argv) +{ + struct square *square = square_create(5); + print_square(square); + print_shape(square_as_shape(square)); + shape_destroy(square_as_shape(square)); +} diff --git a/v1/shape.c b/v1/shape.c new file mode 100644 index 0000000..eb5e399 --- /dev/null +++ b/v1/shape.c @@ -0,0 +1,32 @@ +#include <stdlib.h> +#include "shape.h" + +struct shape +{ + void *obj; + shape_area_t area; + shape_destroy_t destroy; +}; + +double shape_area(struct shape *shape) +{ + return shape->area(shape->obj); +} + +void shape_destroy(struct shape *shape) +{ + shape->destroy(shape->obj); + free(shape); +} + +struct shape *shape_create( + void *obj, + shape_area_t area, + shape_destroy_t destroy) +{ + struct shape *shape = malloc(sizeof(shape)); + shape->obj = obj; + shape->area = area; + shape->destroy = destroy; + return shape; +}
\ No newline at end of file diff --git a/v1/shape.h b/v1/shape.h new file mode 100644 index 0000000..adc6ec8 --- /dev/null +++ b/v1/shape.h @@ -0,0 +1,19 @@ +#ifndef POC__SHAPE_H +#define POC__SHAPE_H + +struct shape; + +/* Calculates the area of the shape and returns the value. */ +double shape_area(struct shape *shape); +typedef double (*shape_area_t)(struct shape *); + +/* Deallocates the object. */ +void shape_destroy(struct shape *shape); +typedef void (*shape_destroy_t)(struct shape *); + +struct shape *shape_create( + void *obj, + shape_area_t area, + shape_destroy_t destroy); + +#endif diff --git a/v1/square.c b/v1/square.c new file mode 100644 index 0000000..cbf451a --- /dev/null +++ b/v1/square.c @@ -0,0 +1,48 @@ +#include <stdlib.h> +#include "square.h" + +struct square +{ + struct shape *shape; + double width; +}; + +/* Shape interface */ + +double shape_area_impl(struct shape *shape) +{ + struct square *square = (struct square *)shape; + return square_area(square); +} + +void shape_destroy_impl(struct shape *shape) +{ + struct square *square = (struct square *)shape; + square_destroy(square); +} + +struct shape *square_as_shape(struct square *square) +{ + return square->shape; +} + +/* End of shape interface */ + +struct square *square_create(double width) +{ + struct square *square = malloc(sizeof(struct square)); + square->width = width; + + square->shape = shape_create(square, shape_area_impl, shape_destroy_impl); + return square; +} + +double square_area(struct square *square) +{ + return square->width * square->width; +} + +void square_destroy(struct square *square) +{ + free(square); +}
\ No newline at end of file diff --git a/v1/square.h b/v1/square.h new file mode 100644 index 0000000..177c9c7 --- /dev/null +++ b/v1/square.h @@ -0,0 +1,16 @@ +#ifndef POC__SQUARE_H +#define POC__SQUARE_H + +#include "shape.h" + +struct square; + +struct square *square_create(double width); + +double square_area(struct square *square); + +void square_destroy(struct square *square); + +struct shape *square_as_shape(struct square *square); + +#endif |