Last active
August 31, 2020 15:53
-
-
Save boki1/779f6491780e8217c4235f6d2611c9df to your computer and use it in GitHub Desktop.
OOP w/ ANSI C: Chapter 2 - Dynamic Linkage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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_ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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_ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// 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