diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2025-12-23 18:18:33 +0100 |
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2025-12-23 18:18:33 +0100 |
| commit | a43e4eeb6a8c1b0906f5af0b964a301d2ec0321b (patch) | |
| tree | 871f1ac2b10edcc6f5779b81bbefd07318c0bcdb /src | |
| parent | 293ccba26f5cd17521df7b4641989dd771865415 (diff) | |
Experimental new, more flexible, way to construct sources and flagsvariadic_source_decl
Diffstat (limited to 'src')
| -rw-r--r-- | src/ctor.h | 111 | ||||
| -rw-r--r-- | src/tools.cc | 11 |
2 files changed, 90 insertions, 32 deletions
@@ -11,6 +11,7 @@ #include <cstddef> #include <functional> #include <string_view> +#include <cassert> namespace ctor { @@ -61,22 +62,42 @@ enum class toolchain clang, }; -struct source +struct output_file { - source(const char* file_) : file(file_) {} // convenience ctor - - source(std::string_view file_) : source(file_, ctor::language::automatic) {} - source(std::string_view file_, ctor::language lang_) : file(file_), language(lang_) {} - - source(std::string_view file_, std::string_view output_) : file(file_), output(output_) {} - source(std::string_view file_, ctor::language lang_, std::string_view output_) : file(file_), language(lang_), output(output_) {} - - source(ctor::toolchain toolchain_, std::string_view file_) : file(file_), toolchain(toolchain_) {} - source(ctor::toolchain toolchain_, std::string_view file_, ctor::language lang_) : file(file_), toolchain(toolchain_), language(lang_) {} - - source(ctor::toolchain toolchain_, std::string_view file_, std::string_view output_) : file(file_), toolchain(toolchain_), output(output_) {} + std::string file; +}; - source(ctor::toolchain toolchain_, std::string_view file_, ctor::language lang_, std::string_view output_) : file(file_), toolchain(toolchain_), language(lang_), output(output_) {} +struct source +{ + template <class ... Args> + requires (( + std::is_convertible_v<Args, std::string_view> || + std::is_same_v<Args, ctor::toolchain> || + std::is_same_v<Args, ctor::language> || + std::is_same_v<Args, ctor::output_file> + ) && ...) + constexpr source(Args && ... arg) + { + ([&] + { + if constexpr(std::is_convertible_v<Args, std::string_view>) + { + file = arg; + } + else if constexpr(std::is_same_v<Args, ctor::toolchain>) + { + toolchain = arg; + } + else if constexpr(std::is_same_v<Args, ctor::language>) + { + language = arg; + } + else if constexpr(std::is_same_v<Args, ctor::output_file>) + { + output = arg.file; + } + }(), ...); + } std::string file; ctor::toolchain toolchain{ctor::toolchain::any}; @@ -163,24 +184,60 @@ template<typename T> class flag { public: - flag(std::string_view str); - flag(const char* str) : flag(std::string_view(str)) {} - flag(T opt_) : opt(opt_) {} - flag(T opt_, std::string_view arg_, std::string_view arg2_ = "") - : opt(opt_), arg(arg_), arg2(arg2_) {} - flag(T opt_, const char* arg_, const char* arg2_ = "") - : opt(opt_), arg(arg_), arg2(arg2_) {} - flag(ctor::toolchain toolchain_, T opt_) - : toolchain(toolchain_), opt(opt_) {} - flag(ctor::toolchain toolchain_, T opt_, const char* arg_, const char* arg2_ = "") - : toolchain(toolchain_), opt(opt_), arg(arg_), arg2(arg2_) {} - flag(ctor::toolchain toolchain_, T opt_, std::string_view arg_, std::string_view arg2_ = "") - : toolchain(toolchain_), opt(opt_), arg(arg_), arg2(arg2_) {} + template <class ... Args> + requires (( + std::is_convertible_v<Args, std::string_view> || + std::is_same_v<Args, ctor::toolchain> || + std::is_same_v<Args, T> + ) && ...) + constexpr flag(Args && ... _arg) + { + constexpr std::size_t n = sizeof...(Args); + int state{}; // 0: opt, 1: arg1, 2: arg2, 3: error + ([&] + { + if constexpr(std::is_convertible_v<Args, std::string_view>) + { + if constexpr(n == 1) + { + std::string str(_arg); + to_flag(str); + } + else + { + assert(state > 0); // opt must be before args + if(state == 1) + { + this->arg = _arg; + } + else + { + assert(state == 2); // up to 2 args supported + this->arg2 = _arg; + } + ++state; + } + } + else if constexpr(std::is_same_v<Args, ctor::toolchain>) + { + toolchain = _arg; + } + else if constexpr(std::is_same_v<Args, T>) + { + assert(state == 0); // opt must be before args + opt = _arg; + ++state; + } + }(), ...); + } ctor::toolchain toolchain{ctor::toolchain::any}; T opt{}; std::string arg; std::string arg2; + +private: + void to_flag(std::string_view str); }; using c_flag = ctor::flag<ctor::c_opt>; diff --git a/src/tools.cc b/src/tools.cc index 77c0cc0..9dcaec6 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -916,32 +916,33 @@ ctor::toolchain guess_toolchain(std::string_view opt) } } + template<> -ctor::flag<ctor::c_opt>::flag(std::string_view str) +void ctor::flag<ctor::c_opt>::to_flag(std::string_view str) { *this = c_option(str, guess_toolchain(str)); } template<> -ctor::flag<ctor::cxx_opt>::flag(std::string_view str) +void ctor::flag<ctor::cxx_opt>::to_flag(std::string_view str) { *this = cxx_option(str, guess_toolchain(str)); } template<> -ctor::flag<ctor::ld_opt>::flag(std::string_view str) +void ctor::flag<ctor::ld_opt>::to_flag(std::string_view str) { *this = ld_option(str, guess_toolchain(str)); } template<> -ctor::flag<ctor::ar_opt>::flag(std::string_view str) +void ctor::flag<ctor::ar_opt>::to_flag(std::string_view str) { *this = ar_option(str, guess_toolchain(str)); } template<> -ctor::flag<ctor::asm_opt>::flag(std::string_view str) +void ctor::flag<ctor::asm_opt>::to_flag(std::string_view str) { *this = asm_option(str, guess_toolchain(str)); } |
