Skip to content

Instantly share code, notes, and snippets.

@boki1
Last active August 31, 2020 15:53
Show Gist options
  • Save boki1/779f6491780e8217c4235f6d2611c9df to your computer and use it in GitHub Desktop.
Save boki1/779f6491780e8217c4235f6d2611c9df to your computer and use it in GitHub Desktop.
OOP w/ ANSI C: Chapter 2 - Dynamic Linkage
//
// Created by boki on 8/31/20.
//
#ifndef _CLASS_H_
#define _CLASS_H_
#include <stdlib.h>
struct Class
{
size_t size;
const void *(*ctor)();
const void *(*dtor)();
const void *(*copy)();
const void *(*mov)();
_Bool (*oper_equals)();
};
#endif //_CLASS_H_
#include <stdio.h>
#include "String.h"
#include "new.h"
int main ()
{
void *a = new(String, "a");
void *b = new(String, "b");
void *aa = clone(a);
printf("a size == %lu\n", (unsigned long) size(a));
if (equals(a, b))
puts("ok");
if (!equals(a, aa))
puts("ok");
if (a != aa)
puts("ok");
delete(a);
delete(aa);
delete(b);
return 0;
}
//
// Created by boki on 8/31/20.
//
#include <assert.h>
#include "new.h"
#include "Class.h"
void *
new (const void *Class, ...)
{
struct Class *const class = (void *) Class;
void *p = malloc (class->size);
assert(p);
*(struct Class **) p = class;
if (class->ctor)
{
va_list ap;
va_start(ap, Class);
p = (void *) class->ctor (p, &ap);
va_end(ap);
}
return p;
}
void
delete (const void *Class)
{
const struct Class **p = (void *) Class;
if (Class && p && (*p)->dtor)
p = (void *) (*p)->dtor (Class);
free (p);
}
void *
clone (const void *Class)
{
const struct Class **p = (void *) Class;
if (Class && p && (*p)->copy)
{
return (void *) (*p)->copy (Class);
}
return 0;
}
int
equals (const void *Self, const void *Other)
{
const struct Class **self = (void *) Self;
const struct Class **other = (void *) Other;
return (*self)->oper_equals (self, other);
}
size_t
size (const void *Self)
{
const struct Class **self = (void *) Self;
return (*self)->size;
}
//
// Created by boki on 8/31/20.
//
#ifndef _NEW_H_
#define _NEW_H_
#include <stdarg.h>
#include <stddef.h>
void *
new(const void *, ...);
void
delete(const void *);
void *
clone(const void *);
int
equals(const void *, const void *);
size_t
size(const void *);
#endif //_NEW_H_
//
// Created by boki on 8/31/20.
//
#include <stdarg.h>
#include <string.h>
#include <assert.h>
#include "String.h"
#include "Class.h"
#include "new.h"
struct String {
const void *class;
char *buffer;
};
const void *String_ctor (const void *_self, va_list ap)
{
struct String *const self = (void *) _self;
const char *str = va_arg(ap, const char *);
self->buffer = (char *) malloc (strlen (str) + sizeof "");
strcpy (self->buffer, str);
return self;
}
const void *String_dtor (const void *_self)
{
struct String *self = (void *) _self;
free (self->buffer), self->buffer = 0;
free (self);
return 0;
}
const void *String_copy (const void *_self)
{
struct String *const self = (void *) _self;
return new(String, self->buffer);
}
const void *String_mov (const void *_self, const void *_other)
{
struct String *const self = (void *) _self;
struct String *other = (void *) _other;
self->buffer = realloc (self->buffer, strlen (other->buffer) + sizeof "");
strcpy (self->buffer, other->buffer);
/* Move, so destroy other */
other = (void *) String_dtor (other);
assert(other == 0);
return self;
}
_Bool String_equals (const void *_self, const void *_other)
{
struct String *const self = (void *) _self;
struct String *other = (void *) _other;
if (other->class != String)
return 1;
return strcmp (self->buffer, other->buffer);
}
static const struct Class StringClass = {
.size = sizeof (struct String),
.dtor = String_dtor,
.ctor = String_ctor,
.copy = String_copy,
.mov = String_mov,
.oper_equals=String_equals
};
const void *String = &StringClass;
//
// Created by boki on 8/31/20.
//
#ifndef _STRING_H_
#define _STRING_H_
extern const void *String;
#endif //_STRING_H_
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment