use dvided module
This commit is contained in:
		
							parent
							
								
									0017c36e2f
								
							
						
					
					
						commit
						37c11c32cf
					
				
					 4 changed files with 81 additions and 63 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) {}
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										56
									
								
								main.cxx
									
										
									
									
									
								
							
							
						
						
									
										56
									
								
								main.cxx
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue