Skip to content

Instantly share code, notes, and snippets.

@theoknock
Last active September 2, 2020 02:49
Show Gist options
  • Save theoknock/c54cd19c8c923f5da1f0781904834e6a to your computer and use it in GitHub Desktop.
Save theoknock/c54cd19c8c923f5da1f0781904834e6a to your computer and use it in GitHub Desktop.
A factory for blocks that all perform different math operations—either addition or subtraction—using a common interface. The abstract block defines the interface for the blocks that implement the specified functionality (the math operation).
#include "Math.h"
// Assigned to the math_operation_block member of the Math struct
// if its math_operation member is set to math_operation_addition
// (it is never called directly)
double (^math_operation_addition_block)(double, double) = ^double(double first, double second)
{
double sum = first + second;
return sum;
};
// Assigned to the math_operation_block member of the Math struct
// if its math_operation member is set to math_operation_subtraction
// (it is never called directly)
double (^math_operation_subtraction_block)(double, double) = ^double(double first, double second)
{
double difference = first - second;
return difference;
};
// Returns either math_operation_addition_block or math_operation_subtraction_block depending on the specified MathOperation
// (the block is assigned to the math_operation_block member of a newly allocated Math struct)
double(^_Nonnull(^ _Nonnull math_operation_block)(enum MathOperation))(double, double) = ^(enum MathOperation math_operation) {
switch (math_operation) {
case math_operation_addition:
return math_operation_addition_block;
break;
case math_operation_subtraction:
return math_operation_subtraction_block;
break;
default:
return math_operation_addition_block;
break;
}
};
// Returns a pointer to a newly allocated Math struct and...
// ...assigns a math_operation_block to its corresponding member...
// ...based on the specified MathOperation...
// ...by calling an abstract factory block of the same name (math_operation_block)
struct Math * new (enum MathOperation math_operation)
{
struct Math * math = malloc(sizeof(struct Math));
math->math_operation = math_operation;
math->math_operation_block = math_operation_block(math_operation);
assert(math);
return math;
}
#include "Math.h"
// Create two Math structs, one for addition...
struct Math * mplus = new(math_operation_addition);
// ...the other, subtraction
struct Math * mminus = new(math_operation_subtraction);
// Regardless of the specific math operation...
// ...doing the math is always the same
double addition = mplus->math_operation_block(1.0, 1.0);
double subtraction = mminus->math_operation_block(4.0, 2.0);
printf("Sum: %f\t\tDifference: %f\n", addition, subtraction);
#ifndef Math_h
#define Math_h
#include <stdarg.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
// A block that performs a given mathematical operation, encapsulated in a struct
extern const void * Math;
// The specific operation the block performs
enum MathOperation
{
math_operation_addition,
math_operation_subtraction
};
typedef struct Math
{
enum MathOperation math_operation;
double (^math_operation_block)(double, double);
} math;
// Allocates a new Math struct and returns a pointer to its address on the heap
struct Math * new (enum MathOperation math_operation);
#endif /* Math_h */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment