diff options
Diffstat (limited to '')
| -rw-r--r-- | Makefile | 27 | ||||
| -rw-r--r-- | aisa/aisa.h | 5 | ||||
| -rw-r--r-- | aisa/coroutine.h | 39 | ||||
| -rw-r--r-- | aisa/eval.h | 4 | ||||
| -rw-r--r-- | main.cpp | 5 | ||||
| -rwxr-xr-x | tools/iwyu-header | 5 |
6 files changed, 56 insertions, 29 deletions
| @@ -3,10 +3,12 @@ DEBUG ?= -g | |||
| 3 | 3 | ||
| 4 | AR ?= ar | 4 | AR ?= ar |
| 5 | CXX ?= g++ | 5 | CXX ?= g++ |
| 6 | IWYU ?= iwyu | ||
| 7 | CHRONIC ?= chronic | ||
| 6 | 8 | ||
| 7 | CXXFLAGS := -Wall -Werror -std=c++20 -fPIC -iquote . ${OPTIMIZE} ${DEBUG} | 9 | CXXFLAGS := -Wall -Werror -std=c++20 -fPIC -iquote . ${OPTIMIZE} ${DEBUG} |
| 8 | 10 | ||
| 9 | .DEFAULT: issim | 11 | .DEFAULT_GOAL := all |
| 10 | 12 | ||
| 11 | VERSION := $(shell git describe --always --dirty --long --tags 2> /dev/null) | 13 | VERSION := $(shell git describe --always --dirty --long --tags 2> /dev/null) |
| 12 | ifndef VERSION | 14 | ifndef VERSION |
| @@ -21,14 +23,19 @@ std::string GIT_TAG = "$(subst ",\",${VERSION})"; | |||
| 21 | endef | 23 | endef |
| 22 | export GITTAGCPP | 24 | export GITTAGCPP |
| 23 | 25 | ||
| 26 | ifneq ($(shell which ${IWYU}),) | ||
| 27 | iwyu = ${CHRONIC} ${IWYU} -Xiwyu --error ${CXXFLAGS} $(1) | ||
| 28 | else | ||
| 29 | $(warning Not using IWYU) | ||
| 30 | iwyu = | ||
| 31 | endif | ||
| 32 | |||
| 24 | libname = $(shell realpath --canonicalize-missing --relative-to . build/$(dir $(1))/lib$(notdir $(1))) | 33 | libname = $(shell realpath --canonicalize-missing --relative-to . build/$(dir $(1))/lib$(notdir $(1))) |
| 25 | 34 | ||
| 26 | define mklib = | 35 | define mklib = |
| 27 | 36 | ||
| 28 | ifneq ($(wildcard $(1)/*.cpp),) | 37 | ifneq ($(wildcard $(1)/*.cpp),) |
| 29 | 38 | ||
| 30 | $$(info Component $(call libname,$(1))) | ||
| 31 | |||
| 32 | $(call libname,$(1).a): $(patsubst %.cpp,build/%.o,$(wildcard $(1)/*.cpp)) | 39 | $(call libname,$(1).a): $(patsubst %.cpp,build/%.o,$(wildcard $(1)/*.cpp)) |
| 33 | @mkdir -p $$(dir $$@) | 40 | @mkdir -p $$(dir $$@) |
| 34 | $${AR} cr $$@ $$+ | 41 | $${AR} cr $$@ $$+ |
| @@ -42,15 +49,22 @@ PARTSOS += $(call libname,$(1).so) | |||
| 42 | 49 | ||
| 43 | else | 50 | else |
| 44 | 51 | ||
| 45 | $$(info Header-only component $(1)) | 52 | $(call libname,$(1).cpp): |
| 53 | @mkdir -p $$(dir $$@) | ||
| 54 | @tools/iwyu-header $$(wildcard $(1)/*.h) > $$@ | ||
| 55 | @$$(call iwyu,$$@) | ||
| 56 | .PHONY: $(call libname,$(1).cpp) | ||
| 57 | |||
| 58 | EXTRA_TARGETS += $(call libname,$(1).cpp) | ||
| 46 | 59 | ||
| 47 | endif | 60 | endif |
| 48 | 61 | ||
| 49 | endef | 62 | endef |
| 50 | 63 | ||
| 51 | PARTS := $(patsubst ./%,%,$(shell find -mindepth 1 -type d -\( -name .\* -prune -o -name build -prune -o -print -\))) | 64 | PARTS := $(patsubst ./%,%,$(shell find -mindepth 1 -type d -\( -name .\* -prune -o -name build -prune -o -name tools -prune -o -print -\))) |
| 52 | PARTARS := | 65 | PARTARS := |
| 53 | PARTSOS := | 66 | PARTSOS := |
| 67 | EXTRA_TARGETS := | ||
| 54 | 68 | ||
| 55 | $(foreach part,${PARTS},$(eval $(call mklib,${part}))) | 69 | $(foreach part,${PARTS},$(eval $(call mklib,${part}))) |
| 56 | 70 | ||
| @@ -59,6 +73,8 @@ MAINOBJS += build/git-tag.o | |||
| 59 | 73 | ||
| 60 | $(info ) | 74 | $(info ) |
| 61 | 75 | ||
| 76 | all: ${EXTRA_TARGETS} issim issim-static | ||
| 77 | |||
| 62 | issim: build/issim-dynamic | 78 | issim: build/issim-dynamic |
| 63 | @ln -sf $< $@ | 79 | @ln -sf $< $@ |
| 64 | .PHONY: issim | 80 | .PHONY: issim |
| @@ -88,6 +104,7 @@ include $(shell find -type f -name \*.d) | |||
| 88 | 104 | ||
| 89 | build/%.o: %.cpp | 105 | build/%.o: %.cpp |
| 90 | @mkdir -p $(dir $@) | 106 | @mkdir -p $(dir $@) |
| 107 | @$(call iwyu,$<) | ||
| 91 | ${CXX} ${CXXFLAGS} -MMD -c -o $@ $< | 108 | ${CXX} ${CXXFLAGS} -MMD -c -o $@ $< |
| 92 | 109 | ||
| 93 | build/%.o: build/%.cpp | 110 | build/%.o: build/%.cpp |
diff --git a/aisa/aisa.h b/aisa/aisa.h index c9a215c..3c260c1 100644 --- a/aisa/aisa.h +++ b/aisa/aisa.h | |||
| @@ -1,15 +1,10 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include <coroutine> | ||
| 4 | #include <cstdint> | 3 | #include <cstdint> |
| 5 | #include <initializer_list> | ||
| 6 | #include <iostream> | ||
| 7 | #include <optional> | 4 | #include <optional> |
| 8 | #include <utility> | 5 | #include <utility> |
| 9 | #include <vector> | 6 | #include <vector> |
| 10 | 7 | ||
| 11 | #include "aisa/coroutine.h" | ||
| 12 | |||
| 13 | namespace aisa { | 8 | namespace aisa { |
| 14 | 9 | ||
| 15 | using regnum_t = std::uint_fast64_t; | 10 | using regnum_t = std::uint_fast64_t; |
diff --git a/aisa/coroutine.h b/aisa/coroutine.h index a456c89..333cb26 100644 --- a/aisa/coroutine.h +++ b/aisa/coroutine.h | |||
| @@ -1,46 +1,47 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include <coroutine> | 3 | #include <coroutine> |
| 4 | #include <optional> | ||
| 4 | 5 | ||
| 5 | namespace aisa { | 6 | namespace aisa { |
| 6 | 7 | ||
| 7 | template<typename result_t> struct promise; | 8 | template<typename result_t> struct task_promise; |
| 8 | 9 | ||
| 9 | template<typename result_t> struct task : public std::coroutine_handle<promise<result_t>> { | 10 | template<typename result_t> struct task : public std::coroutine_handle<task_promise<result_t>> { |
| 10 | using handle = std::coroutine_handle<struct promise<result_t>>; | 11 | using handle = std::coroutine_handle<task_promise<result_t>>; |
| 11 | using promise_type = struct promise<result_t>; | 12 | using promise_type = task_promise<result_t>; |
| 12 | bool await_ready() const noexcept { return handle::done(); } | 13 | bool await_ready() const noexcept { return handle::done(); } |
| 13 | result_t await_resume() const noexcept; | 14 | result_t await_resume() const noexcept; |
| 14 | template<typename other_t> void await_suspend(std::coroutine_handle<struct promise<other_t>> h) const noexcept; | 15 | template<typename other_t> void await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept; |
| 15 | std::optional<result_t> operator()() noexcept; | 16 | std::optional<result_t> operator()() noexcept; |
| 16 | }; | 17 | }; |
| 17 | 18 | ||
| 18 | template<> struct task<void> : public std::coroutine_handle<promise<void>> { | 19 | template<> struct task<void> : public std::coroutine_handle<task_promise<void>> { |
| 19 | using handle = std::coroutine_handle<struct promise<void>>; | 20 | using handle = std::coroutine_handle<task_promise<void>>; |
| 20 | using promise_type = struct promise<void>; | 21 | using promise_type = task_promise<void>; |
| 21 | bool await_ready() const noexcept { return handle::done(); } | 22 | bool await_ready() const noexcept { return handle::done(); } |
| 22 | void await_resume() const noexcept; | 23 | void await_resume() const noexcept; |
| 23 | template<typename other_t> void await_suspend(std::coroutine_handle<struct promise<other_t>> h) const noexcept; | 24 | template<typename other_t> void await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept; |
| 24 | bool operator()() noexcept; | 25 | bool operator()() noexcept; |
| 25 | }; | 26 | }; |
| 26 | 27 | ||
| 27 | template<typename result_t> struct promise { | 28 | template<typename result_t> struct task_promise { |
| 28 | std::coroutine_handle<> precursor; | 29 | std::coroutine_handle<> precursor; |
| 29 | std::optional<result_t> result; | 30 | std::optional<result_t> result; |
| 30 | promise() = default; | 31 | task_promise() = default; |
| 31 | promise(const promise &) = delete; | 32 | task_promise(const task_promise &) = delete; |
| 32 | task<result_t> get_return_object() noexcept { return task<result_t>{std::coroutine_handle<promise<result_t>>::from_promise(*this)}; } | 33 | task<result_t> get_return_object() noexcept { return task<result_t>{std::coroutine_handle<task_promise<result_t>>::from_promise(*this)}; } |
| 33 | std::suspend_never initial_suspend() const noexcept { return {}; } | 34 | std::suspend_never initial_suspend() const noexcept { return {}; } |
| 34 | std::suspend_always final_suspend() const noexcept { return {}; } | 35 | std::suspend_always final_suspend() const noexcept { return {}; } |
| 35 | void unhandled_exception() { } | 36 | void unhandled_exception() { } |
| 36 | void return_value(result_t x) noexcept { result = std::move(x); } | 37 | void return_value(result_t x) noexcept { result = std::move(x); } |
| 37 | }; | 38 | }; |
| 38 | 39 | ||
| 39 | template<> struct promise<void> { | 40 | template<> struct task_promise<void> { |
| 40 | std::coroutine_handle<> precursor; | 41 | std::coroutine_handle<> precursor; |
| 41 | promise() = default; | 42 | task_promise() = default; |
| 42 | promise(const promise &) = delete; | 43 | task_promise(const task_promise &) = delete; |
| 43 | task<void> get_return_object() noexcept { return task<void>{std::coroutine_handle<promise<void>>::from_promise(*this)}; } | 44 | task<void> get_return_object() noexcept { return task<void>{std::coroutine_handle<task_promise<void>>::from_promise(*this)}; } |
| 44 | std::suspend_never initial_suspend() const noexcept { return {}; } | 45 | std::suspend_never initial_suspend() const noexcept { return {}; } |
| 45 | std::suspend_always final_suspend() const noexcept { return {}; } | 46 | std::suspend_always final_suspend() const noexcept { return {}; } |
| 46 | void unhandled_exception() { } | 47 | void unhandled_exception() { } |
| @@ -54,7 +55,7 @@ namespace aisa { | |||
| 54 | return std::move(x); | 55 | return std::move(x); |
| 55 | } | 56 | } |
| 56 | 57 | ||
| 57 | template<typename result_t> template<typename other_t> void task<result_t>::await_suspend(std::coroutine_handle<struct promise<other_t>> h) const noexcept | 58 | template<typename result_t> template<typename other_t> void task<result_t>::await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept |
| 58 | { | 59 | { |
| 59 | h.promise().precursor = *this; | 60 | h.promise().precursor = *this; |
| 60 | } | 61 | } |
| @@ -87,7 +88,7 @@ namespace aisa { | |||
| 87 | handle::destroy(); | 88 | handle::destroy(); |
| 88 | } | 89 | } |
| 89 | 90 | ||
| 90 | template<typename other_t> void task<void>::await_suspend(std::coroutine_handle<struct promise<other_t>> h) const noexcept | 91 | template<typename other_t> void task<void>::await_suspend(std::coroutine_handle<task_promise<other_t>> h) const noexcept |
| 91 | { | 92 | { |
| 92 | h.promise().precursor = *this; | 93 | h.promise().precursor = *this; |
| 93 | } | 94 | } |
diff --git a/aisa/eval.h b/aisa/eval.h index 6d65520..30dc617 100644 --- a/aisa/eval.h +++ b/aisa/eval.h | |||
| @@ -1,8 +1,12 @@ | |||
| 1 | #pragma once | 1 | #pragma once |
| 2 | 2 | ||
| 3 | #include <coroutine> | 3 | #include <coroutine> |
| 4 | #include <optional> | ||
| 5 | #include <utility> | ||
| 6 | #include <vector> | ||
| 4 | 7 | ||
| 5 | #include "aisa/aisa.h" | 8 | #include "aisa/aisa.h" |
| 9 | #include "aisa/coroutine.h" // IWYU pragma: export | ||
| 6 | 10 | ||
| 7 | namespace aisa { | 11 | namespace aisa { |
| 8 | 12 | ||
| @@ -1,6 +1,11 @@ | |||
| 1 | #include <initializer_list> | ||
| 1 | #include <iostream> | 2 | #include <iostream> |
| 2 | #include <map> | 3 | #include <map> |
| 3 | #include <optional> | 4 | #include <optional> |
| 5 | #include <string> | ||
| 6 | #include <type_traits> | ||
| 7 | #include <utility> | ||
| 8 | #include <vector> | ||
| 4 | 9 | ||
| 5 | #include "aisa/aisa.h" | 10 | #include "aisa/aisa.h" |
| 6 | #include "aisa/eval.h" | 11 | #include "aisa/eval.h" |
diff --git a/tools/iwyu-header b/tools/iwyu-header new file mode 100755 index 0000000..cd71456 --- /dev/null +++ b/tools/iwyu-header | |||
| @@ -0,0 +1,5 @@ | |||
| 1 | #!/bin/bash | ||
| 2 | |||
| 3 | for ARG in "$@"; do | ||
| 4 | echo "#include \"$ARG\" // IWYU pragma: associated" | ||
| 5 | done | ||
