use divided module

This commit is contained in:
ulic-youthlic 2025-04-28 13:58:27 +08:00
parent 0534572646
commit e0a242e12b
Signed by: youthlic
GPG key ID: 63E86C3C14A0D721
7 changed files with 138 additions and 74 deletions

10
.clangd
View file

@ -1,22 +1,16 @@
CompileFlags:
Add:
- -std=c++26
- -Xclang
- -fno-validate-pch
- -fretain-comments-from-system-headers
Compiler: clang++
Index:
Background: true
Diagnostics:
ClangTidy:
Add:
- modernize-*
- performance-*
- cppcoreguidelines-*
ClangTidyChecks: true
Options:
UseChecks:
- "*"
WarningAsErrors: cppcoreguidelines-*
InlayHints:
Enabled: true
ParameterNames: true
@ -24,5 +18,3 @@ InlayHints:
Designators: true
Completion:
AllScopes: true
SemanticTokens:
Enabled: true

1
.gitignore vendored
View file

@ -1,4 +1,3 @@
/.direnv/
/build/
/.cache/
/compile_commands.json

28
.helix/languages.toml Normal file
View file

@ -0,0 +1,28 @@
[[language]]
name = "cpp"
file-types = [
"cc",
"hh",
"c++",
"cpp",
"hpp",
"h",
"ipp",
"tpp",
"cxx",
"hxx",
"ixx",
"txx",
"ino",
"C",
"H",
"cu",
"cuh",
"cppm",
"cxxm",
"h++",
"ii",
"inl",
{ glob = ".hpp.in" },
{ glob = ".h.in" },
]

View file

@ -1,26 +1,40 @@
.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.cxxm 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:: %.cxxm
> $(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)
> bear --append -- $(MAKE)
run: $(.DEFAULT_GOAL)
> @./$(.DEFAULT_GOAL)

56
builder.cxxm Normal file
View 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) {}
};

29
compile_commands.json Normal file
View file

@ -0,0 +1,29 @@
[
{
"arguments": [
"/nix/store/k50vj1b6vpz84n88vk09gxsgcyqrg00m-clang-wrapper-20.1.3/bin/clang++",
"-std=c++26",
"-Wno-experimental-header-units",
"-Wno-unused-command-line-argument",
"-c",
"-fmodule-file=build/system/print.pcm",
"-fmodule-file=builder=build/user/builder.pcm",
"main.cxx"
],
"directory": "/home/david/code/cxx",
"file": "/home/david/code/cxx/main.cxx"
},
{
"arguments": [
"/nix/store/k50vj1b6vpz84n88vk09gxsgcyqrg00m-clang-wrapper-20.1.3/bin/clang++",
"-std=c++26",
"-Wno-experimental-header-units",
"-Wno-unused-command-line-argument",
"-c",
"-fmodule-file=build/system/type_traits.pcm",
"builder.cxxm"
],
"directory": "/home/david/code/cxx",
"file": "/home/david/code/cxx/builder.cxxm"
}
]

View file

@ -1,59 +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)
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) {}
};
import builder;
auto main() -> int {
Builder builder;