Compare commits
2 commits
eda341026b
...
37c11c32cf
| Author | SHA1 | Date | |
|---|---|---|---|
| 37c11c32cf | |||
| 0017c36e2f |
4 changed files with 81 additions and 55 deletions
1
.clangd
1
.clangd
|
|
@ -1,5 +1,6 @@
|
|||
CompileFlags:
|
||||
Add:
|
||||
- -std=c++26
|
||||
- -Xclang
|
||||
- -fno-validate-pch
|
||||
- -fretain-comments-from-system-headers
|
||||
|
|
|
|||
31
Makefile
31
Makefile
|
|
@ -1,24 +1,39 @@
|
|||
.RECIPEPREFIX = >
|
||||
.DEFAULT_GOAL = build/main.out
|
||||
CXX = clang++
|
||||
CXXFLAGS += -std=c++26 -Wno-experimental-header-units
|
||||
CXXFLAGS += -std=c++26 -Wno-experimental-header-units -Wno-unused-command-line-argument
|
||||
LDFLAGS += -std=c++26
|
||||
SYSTEMHEADER_FLAGS = -Wno-deprecated-builtins -Wno-pragma-system-header-outside-header -Wno-keyword-compat
|
||||
build_module_path = $(let first rest,$1,$(if $(rest),-fmodule-file=$(first) $(call build_module_path,$(rest)),-fmodule-file=$(first)))
|
||||
module_pair = $(if $(findstring user,$1),$(patsubst build/user/%.pcm,%=,$1))$1
|
||||
build_module_path = $(if $1,$(let first rest,$1,$(if $(rest),-fmodule-file=$(call module_pair,$(first)) $(call build_module_path,$(rest)),-fmodule-file=$(call module_pair,$(first)))))
|
||||
object_build = $(filter-out %.pcm,$^) $(call build_module_path,$(filter %.pcm,$^))
|
||||
autodir = @mkdir -p $(@D)
|
||||
|
||||
build/main.out: build/main.o
|
||||
build/main.out: build/main.o build/builder.o
|
||||
> $(call autodir)
|
||||
> $(CXX) $(LDFLAGS) $^ -o $@
|
||||
|
||||
build/main.o: main.cxx build/print.pcm build/type_traits.pcm
|
||||
> $(CXX) $(CXXFLAGS) -c $(filter-out %.pcm,$^) $(call build_module_path,$(filter %.pcm,$^))
|
||||
build/main.o:: main.cxx build/system/print.pcm build/user/builder.pcm
|
||||
|
||||
build/builder.o:: builder.cppm build/system/type_traits.pcm
|
||||
build/user/builder.pcm:: build/system/type_traits.pcm
|
||||
|
||||
build/%.o::
|
||||
> $(call autodir)
|
||||
> $(CXX) $(CXXFLAGS) -c $(call object_build)
|
||||
> @mv $(patsubst build/%,%,$@) $@
|
||||
|
||||
build/%.pcm:
|
||||
> $(CXX) $(CXXFLAGS) -xc++-system-header --precompile $(patsubst build/%.pcm,%,$@) -o $@ $(SYSTEMHEADER_FLAGS)
|
||||
build/user/%.pcm:: %.cppm
|
||||
> $(call autodir)
|
||||
> $(CXX) $(CXXFLAGS) --precompile -o $@ $(call object_build)
|
||||
|
||||
build/system/%.pcm:
|
||||
> $(call autodir)
|
||||
> $(CXX) $(CXXFLAGS) -xc++-system-header --precompile $(patsubst build/system/%.pcm,%,$@) -o $@ $(SYSTEMHEADER_FLAGS)
|
||||
|
||||
.PHONY: clean run
|
||||
clean:
|
||||
> @-rm -rf ./build/*
|
||||
> @-rm -rf ./build
|
||||
bear: clean
|
||||
> bear -- $(MAKE)
|
||||
|
||||
|
|
|
|||
56
builder.cppm
Normal file
56
builder.cppm
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
export module builder;
|
||||
import <type_traits>;
|
||||
|
||||
export template <bool param1 = false, bool param2 = false>
|
||||
struct Builder;
|
||||
template <bool enabled>
|
||||
struct BuildMixin {};
|
||||
|
||||
template <>
|
||||
struct BuildMixin<true> {
|
||||
auto build(this auto&& self)
|
||||
requires requires { self.p1 + self.p2; }
|
||||
{
|
||||
return self.p1 + self.p2;
|
||||
}
|
||||
};
|
||||
|
||||
template <bool enabled>
|
||||
struct Param1Mixin {};
|
||||
|
||||
template <>
|
||||
struct Param1Mixin<false> {
|
||||
auto fill_param1(this auto&& self)
|
||||
requires requires { self.p1; }
|
||||
{
|
||||
self.p1 = 1;
|
||||
return Builder<true, std::remove_reference_t<decltype(self)>::param2_v>(
|
||||
self);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool enabled>
|
||||
struct Param2Mixin {};
|
||||
|
||||
template <>
|
||||
struct Param2Mixin<false> {
|
||||
auto fill_param2(this auto&& self)
|
||||
requires requires { self.p2; }
|
||||
{
|
||||
self.p2 = 1;
|
||||
return Builder<std::remove_reference_t<decltype(self)>::param1_v, true>(
|
||||
self);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool param1, bool param2>
|
||||
struct Builder : BuildMixin<param1 && param2>,
|
||||
Param1Mixin<param1>,
|
||||
Param2Mixin<param2> {
|
||||
const constinit static auto param1_v = param1;
|
||||
const constinit static auto param2_v = param2;
|
||||
int p1;
|
||||
int p2;
|
||||
Builder() : p1(0), p2(0) {}
|
||||
Builder(auto&& other) : p1(other.p1), p2(other.p2) {}
|
||||
};
|
||||
48
main.cxx
48
main.cxx
|
|
@ -1,51 +1,5 @@
|
|||
import <print>;
|
||||
import <type_traits>;
|
||||
|
||||
template <bool param1 = false, bool param2 = false>
|
||||
struct Builder;
|
||||
template <bool enabled>
|
||||
struct BuildMixin {};
|
||||
|
||||
template <>
|
||||
struct BuildMixin<true> {
|
||||
auto build(this auto&& self) { return self.p1 + self.p2; }
|
||||
};
|
||||
|
||||
template <bool enabled>
|
||||
struct Param1Mixin {};
|
||||
|
||||
template <>
|
||||
struct Param1Mixin<false> {
|
||||
auto fill_param1(this auto&& self) {
|
||||
self.p1 = 1;
|
||||
return Builder<true, std::remove_reference_t<decltype(self)>::param2_v>(
|
||||
self);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool enabled>
|
||||
struct Param2Mixin {};
|
||||
|
||||
template <>
|
||||
struct Param2Mixin<false> {
|
||||
auto fill_param2(this auto&& self) {
|
||||
self.p2 = 1;
|
||||
return Builder<std::remove_reference_t<decltype(self)>::param1_v, true>(
|
||||
self);
|
||||
}
|
||||
};
|
||||
|
||||
template <bool param1, bool param2>
|
||||
struct Builder : BuildMixin<param1 && param2>,
|
||||
Param1Mixin<param1>,
|
||||
Param2Mixin<param2> {
|
||||
const constinit static auto param1_v = param1;
|
||||
const constinit static auto param2_v = param2;
|
||||
int p1;
|
||||
int p2;
|
||||
Builder() : p1(0), p2(0) {}
|
||||
Builder(auto&& other) : p1(other.p1), p2(other.p2) {}
|
||||
};
|
||||
import builder;
|
||||
|
||||
auto main() -> int {
|
||||
Builder builder;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue