From 267d3499232cd538530beac0cb1047ed6cf3eadc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Krzy=C5=BCanowski?= Date: Sun, 23 Feb 2025 22:51:14 +0100 Subject: [PATCH] Initial commit --- .gitignore | 2 ++ Makefile | 35 +++++++++++++++++++++++++++++++++++ pureoption-example.c | 15 +++++++++++++++ pureoption.c | 23 +++++++++++++++++++++++ pureoption.h | 25 +++++++++++++++++++++++++ 5 files changed, 100 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 pureoption-example.c create mode 100644 pureoption.c create mode 100644 pureoption.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44d23bc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/ +pureoption-example diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..69bef38 --- /dev/null +++ b/Makefile @@ -0,0 +1,35 @@ +CC = gcc +CCFLAGS = -Wall +BUILDDIR = build +SRCS = pureoption-example.c pureoption.c +OBJS = $(addprefix $(BUILDDIR)/, $(patsubst %.c,%.o,$(SRCS))) +OUT = pureoption-example + +.PHONY: all format clean +.PRECIOUS: $(BUILDDIR)/. $(BUILDDIR)%/. + +all: $(OUT) + +debug: CCFLAGS += -g +debug: all + +$(BUILDDIR)/.: + mkdir -p $@ + +$(BUILDDIR)%/.: + mkdir -p $@ + +$(OUT): $(OBJS) + $(CC) $^ -o $(OUT) $(LDFLAGS) + +.SECONDEXPANSION: + +$(BUILDDIR)/%.o: %.c | $$(@D)/. + $(CC) $(CCFLAGS) -c $< -o $@ + +format: + clang-format -i *.c *.h + +clean: + rm -rf $(BUILDDIR) + rm -f $(OUT) diff --git a/pureoption-example.c b/pureoption-example.c new file mode 100644 index 0000000..e854cad --- /dev/null +++ b/pureoption-example.c @@ -0,0 +1,15 @@ +#include "pureoption.h" +#include + +int main(void) { + pureoption opt = pureoption_some(3); + + printf("pureoption_some(3)\n"); + printf("\thas value: %s\n", pureoption_has(opt) == 1 ? "yes" : "no"); + printf("\tvalue: %d\n", pureoption_get(int, opt)); + + opt = pureoption_none(); + + printf("pureoption_none\n"); + printf("\thas value: %s\n", pureoption_has(opt) == 1 ? "yes" : "no"); +} diff --git a/pureoption.c b/pureoption.c new file mode 100644 index 0000000..4443ed9 --- /dev/null +++ b/pureoption.c @@ -0,0 +1,23 @@ +#include "pureoption.h" +#include + +inline static pureoption __pureoption_new(bool has_value, void *value) { + pureoption result = { + .has_value = has_value, + .value = value, + }; + + return result; +} + +pureoption _pureoption_some(void *value) { + return __pureoption_new(true, value); +} + +pureoption pureoption_none(void) { return __pureoption_new(false, NULL); } + +bool pureoption_has(pureoption option) { return option.has_value; } + +bool pureoption_lacks(pureoption option) { return !option.has_value; } + +void *_pureoption_get(pureoption option) { return option.value; } diff --git a/pureoption.h b/pureoption.h new file mode 100644 index 0000000..fe474d6 --- /dev/null +++ b/pureoption.h @@ -0,0 +1,25 @@ +#ifndef PUREOPTION_H +#define PUREOPTION_H + +#include + +#define pureoption_some(x) \ + ({ \ + static typeof(x) _temp = (x); \ + _pureoption_some(&_temp); \ + }) + +#define pureoption_get(x_type, x) *(x_type *)_pureoption_get(x) + +typedef struct { + bool has_value; + void *value; +} pureoption; + +pureoption _pureoption_some(void *value); +pureoption pureoption_none(void); +bool pureoption_has(pureoption option); +bool pureoption_lacks(pureoption option); +void *_pureoption_get(pureoption option); + +#endif // PUREOPTION_H