aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile29
-rw-r--r--README.md13
-rw-r--r--src/main.c24
-rw-r--r--src/shape.c32
-rw-r--r--src/shape.h21
-rw-r--r--src/square.c49
-rw-r--r--src/square.h16
-rw-r--r--v1/main.c22
-rw-r--r--v1/shape.c32
-rw-r--r--v1/shape.h19
-rw-r--r--v1/square.c48
-rw-r--r--v1/square.h16
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