summaryrefslogtreecommitdiff
path: root/src/ctor.h
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <deva@aasimon.org>2025-12-23 18:18:33 +0100
committerBent Bisballe Nyeng <deva@aasimon.org>2025-12-23 18:18:33 +0100
commita43e4eeb6a8c1b0906f5af0b964a301d2ec0321b (patch)
tree871f1ac2b10edcc6f5779b81bbefd07318c0bcdb /src/ctor.h
parent293ccba26f5cd17521df7b4641989dd771865415 (diff)
Experimental new, more flexible, way to construct sources and flagsvariadic_source_decl
Diffstat (limited to 'src/ctor.h')
-rw-r--r--src/ctor.h111
1 files changed, 84 insertions, 27 deletions
diff --git a/src/ctor.h b/src/ctor.h
index 2ecef0e..8dd2ddd 100644
--- a/src/ctor.h
+++ b/src/ctor.h
@@ -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>;