/* An implementation of a Counter class written in C. * Author: Mark A. Sheldon * Copyright: March 2008 */ #include #include #include #include #include "OO.h" #include "Counter.h" PRIVATE counter_t new_counter (int initial_value); PRIVATE int value(counter_t this); PRIVATE void increment(counter_t this); PRIVATE void increment_by(counter_t this, int n); PRIVATE void decrement(counter_t this); PRIVATE void decrement_by(counter_t this, int n); PRIVATE void reset(counter_t this); PRIVATE BOOL equals(counter_t this, counter_t c); PRIVATE void destroy(counter_t this); PRIVATE struct counter_class_ops c_class_ops = { new_counter }; PRIVATE struct counter_class CounterClass_struct = { "Counter", &c_class_ops }; PUBLIC counter_class_t CounterClass = &CounterClass_struct; PRIVATE struct counter_instance_ops c_ops = { value, increment, increment_by, decrement, decrement_by, reset, equals, destroy }; /* This would be great, but casting doesn't do the right thing. PRIVATE BOOL isCounter (Object o) { return o->class == (Object) CounterClass; } */ /* constructor */ PRIVATE counter_t new_counter (int initial_value) { counter_t c; assert(sizeof(int) <= sizeof(void *)); if ((c = (counter_t) malloc(sizeof(struct counter_instance))) == NULL) { perror("Counter: cannot allocate instance"); exit(ENOMEM); } c->private = (void *) initial_value; c->class = CounterClass; c->ops = &c_ops; return c; } PRIVATE int value(counter_t this) { return (int) this->private; } PRIVATE void increment(counter_t this) { this->private++; } PRIVATE void increment_by(counter_t this, int n) { this->private += n; } PRIVATE void decrement(counter_t this) { this->private--; } PRIVATE void decrement_by(counter_t this, int n) { this->private = (void *) ((int) this->private - n); } PRIVATE void reset(counter_t this) { this->private = (void *) 0; } /* No need to check that this is a counter, since we wouldn't be here * if it were something else --- assuming we were called with a proper * message send... Hmm, maybe I should check. */ PRIVATE BOOL equals(counter_t this, counter_t c) { /* would like to include this condition: isCounter((Object) c) but the cast won't allow us to get to field. */ return ((int) this->private == (int) c->private); } PRIVATE void destroy(counter_t this) { free(this); }