Skip to content

Commit

Permalink
Add test.yml
Browse files Browse the repository at this point in the history
  • Loading branch information
gen740 committed Dec 6, 2023
1 parent 442db71 commit e846c24
Show file tree
Hide file tree
Showing 19 changed files with 268 additions and 204 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Tests

on:
push:
branches:
- master
pull_request: {}
schedule:
- cron: '0 23 * * SUN-THU'
workflow_dispatch:

jobs:
tests:
runs-on: macos-latest
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install llvm
run: |
brew isntall llvm
- name: Install cmake HEAD
run: |
brew isntall cmake --HEAD
- name: Cmake and Compile
run: |
cmake -B build -S . -DARGO_TEST_ENABLE=true
cmake --build build
File renamed without changes.
54 changes: 38 additions & 16 deletions module/ArgoArg.cc → Argo/ArgoArg.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,18 +136,6 @@ struct ArgName : ArgNameTag {
template <std::size_t N>
ArgName(const char (&)[N]) -> ArgName<N - 1>;

template <class T>
concept ArgType = requires(T& x) {
std::derived_from<decltype(T::name), ArgNameTag>;
std::is_same_v<decltype(T::isVariadic), char>;
std::is_same_v<decltype(T::nargs), NArgs>;
typename T::baseType;
typename T::type;
not std::is_same_v<decltype(T::value), void>;
std::is_same_v<decltype(T::assigned), bool>;
std::is_same_v<decltype(T::description), std::string_view>;
};

template <typename BaseType, ArgName Name, bool Required, ParserID ID>
struct ArgBase {
static constexpr auto name = Name;
Expand All @@ -158,20 +146,36 @@ struct ArgBase {
using baseType = BaseType;
};

template <class T>
concept ArgType = requires(T& x) {
typename T::baseType;
typename T::type;

not std::is_same_v<decltype(T::value), void>;

std::derived_from<decltype(T::name), ArgNameTag>;
std::is_same_v<decltype(T::isVariadic), char>;
std::is_same_v<decltype(T::nargs), NArgs>;
std::is_same_v<decltype(T::assigned), bool>;
std::is_same_v<decltype(T::description), std::string_view>;
std::is_same_v<decltype(T::typeName), std::string>;
std::is_same_v<decltype(T::required), bool>;
};

struct ArgTag {};

template <class T>
consteval std::string get_type_name_base_type() {
if constexpr (std::is_integral_v<T>) {
if constexpr (std::is_same_v<T, bool>) {
return "BOOL";
} else if constexpr (std::is_integral_v<T>) {
return "NUMBER";
} else if constexpr (std::is_floating_point_v<T>) {
return "FLOAT";
} else if constexpr (std::is_same_v<T, const char*> or
std::is_same_v<T, std::string> or
std::is_same_v<T, std::string_view>) {
return "STRING";
} else if constexpr (std::is_same_v<T, bool>) {
return "BOOL";
} else {
return "UNKNOWN";
}
Expand Down Expand Up @@ -283,7 +287,7 @@ struct Arg : ArgTag,
struct FlagArgTag {};

template <ArgName Name, ParserID ID>
struct FlagArg : FlagArgTag, ArgBase<bool, Name, true, ID> {
struct FlagArg : FlagArgTag, ArgBase<bool, Name, false, ID> {
static constexpr bool isVariadic = false;
using type = bool;

Expand All @@ -295,4 +299,22 @@ struct FlagArg : FlagArgTag, ArgBase<bool, Name, true, ID> {
inline static std::string typeName = "";
};

struct HelpArgTag {};

template <ArgName Name, ParserID ID>
struct HelpArg : HelpArgTag, FlagArgTag, ArgBase<bool, Name, true, ID> {
static constexpr bool isVariadic = false;
using type = bool;
inline static type value = {};
inline static type defaultValue = {};

inline static bool assigned = false;
inline static std::string_view description = "Print help information";
inline static bool required = false;

inline static constexpr NArgs nargs = NArgs(-1);
inline static std::function<void()> callback = nullptr;
inline static std::string typeName = "";
};

} // namespace Argo
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion module/ArgoNArgs.cc → Argo/ArgoNArgs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ constexpr char NULLCHAR = '\0';

/*!
* (default)? : If value specified use it else use default -> ValueType
* int: Exactly (n > 1) -> vector<ValueType>
* int: Exactly (n > 1) -> std::array<ValueType, N>
* * : Any number of argument if zero use default -> vector<ValueType>
* + : Any number of argument except zero -> vector<ValueType>
*/
Expand Down
140 changes: 57 additions & 83 deletions module/ArgoParser.cc → Argo/ArgoParser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ struct ParserInfo {
std::optional<std::string_view> usage = std::nullopt;
std::optional<std::string_view> subcommand_help = std::nullopt;
std::optional<std::string_view> options_help = std::nullopt;
std::optional<std::string_view> positional_argument_help = std::nullopt;
};

export template <ParserID ID = 0, class Args = std::tuple<>,
class PositionalArg = void,
class SubParserTuple = std::tuple<>, bool HelpEnabled = false>
export template <ParserID ID = 0, class Args = std::tuple<>, class PArg = void,
class HArg = void, class SubParserTuple = std::tuple<>>
class Parser {
private:
bool parsed_ = false;
Expand Down Expand Up @@ -78,8 +78,6 @@ class Parser {
Parser(const Parser&) = delete;
Parser(Parser&&) = delete;

using Arguments = Args;
using PositionalArgument = PositionalArg;
SubParserTuple subParsers;

constexpr explicit Parser(SubParserTuple tuple) : subParsers(tuple) {}
Expand Down Expand Up @@ -156,17 +154,16 @@ class Parser {
return false;
}
}();
if constexpr (!std::is_same_v<PositionalArgument, void>) {
static_assert(!(std::string_view(Name) ==
std::string_view(PositionalArgument::name)),
if constexpr (!std::is_same_v<PArg, void>) {
static_assert(!(std::string_view(Name) == std::string_view(PArg::name)),
"Duplicated name");
}
static_assert(
(Name.shortName == NULLCHAR) ||
(SearchIndexFromShortName<Arguments, Name.shortName>::value == -1),
(SearchIndexFromShortName<Args, Name.shortName>::value == -1),
"Duplicated short name");
static_assert( //
Argo::SearchIndex<Arguments, Name>::value == -1, //
static_assert( //
Argo::SearchIndex<Args, Name>::value == -1, //
"Duplicated name");
static_assert( //
(nargs.nargs > 0 //
Expand All @@ -190,109 +187,86 @@ class Parser {
auto arg2 = Unspecified(), class... T>
auto addArg(T... args) {
auto arg = createArg<Type, Name, arg1, arg2>(std::forward<T>(args)...);
return Parser<
ID,
decltype(std::tuple_cat(
std::declval<Arguments>(),
std::declval<std::tuple<typename decltype(arg)::type>>())),
PositionalArgument,
SubParserTuple,
HelpEnabled>(std::move(this->info_), subParsers);
return Parser<ID,
tuple_append_t<Args, typename decltype(arg)::type>,
PArg,
HArg,
SubParserTuple>(std::move(this->info_), subParsers);
}

template <ArgName Name, class Type, auto arg1 = Unspecified(),
auto arg2 = Unspecified(), class... T>
auto addPositionalArg(T... args) {
static_assert(std::is_same_v<PositionalArg, void>,
static_assert(std::is_same_v<PArg, void>,
"Positional argument cannot set more than one");
static_assert(Name.shortName == NULLCHAR,
"Positional argment cannot have short name");
auto arg = createArg<Type, Name, arg1, arg2>(std::forward<T>(args)...);
return Parser<ID,
Arguments,
typename decltype(arg)::type,
SubParserTuple,
HelpEnabled>(std::move(this->info_), subParsers);
return Parser<ID, Args, typename decltype(arg)::type, HArg, SubParserTuple>(
std::move(this->info_), subParsers);
}

template <ArgName Name, class... T>
auto addFlag(T... args) {
if constexpr (!std::is_same_v<PositionalArgument, void>) {
static_assert(!(std::string_view(Name) ==
std::string_view(PositionalArgument::name)),
if constexpr (!std::is_same_v<PArg, void>) {
static_assert(!(std::string_view(Name) == std::string_view(PArg::name)),
"Duplicated name");
}
static_assert(
(Name.shortName == NULLCHAR) ||
(SearchIndexFromShortName<Arguments, Name.shortName>::value == -1),
(SearchIndexFromShortName<Args, Name.shortName>::value == -1),
"Duplicated short name");
static_assert(Argo::SearchIndex<Arguments, Name>::value == -1,
static_assert(Argo::SearchIndex<Args, Name>::value == -1,
"Duplicated name");
FlagArgInitializer<Name, ID>::init(std::forward<T>(args)...);
return Parser<ID,
decltype(std::tuple_cat(
std::declval<Arguments>(),
std::declval<std::tuple<FlagArg<Name, ID>>>())),
PositionalArgument,
SubParserTuple,
HelpEnabled>(std::move(this->info_), subParsers);
tuple_append_t<Args, FlagArg<Name, ID>>,
PArg,
HArg,
SubParserTuple>(std::move(this->info_), subParsers);
}

template <ArgName Name = "help,h">
auto addHelp() {
static_assert(
(SearchIndexFromShortName<Arguments, Name.shortName>::value == -1),
"Duplicated short name");
static_assert(Argo::SearchIndex<Arguments, Name>::value == -1,
static_assert((SearchIndexFromShortName<Args, Name.shortName>::value == -1),
"Duplicated short name");
static_assert(Argo::SearchIndex<Args, Name>::value == -1,
"Duplicated name");
FlagArgInitializer<Name, ID>::init(
Argo::description("Print help information"));
return Parser<ID,
decltype(std::tuple_cat(
std::declval<Arguments>(),
std::declval<std::tuple<FlagArg<Name, ID>>>())),
PositionalArgument,
SubParserTuple,
true>(std::move(this->info_), subParsers);
return Parser<ID, Args, PArg, HelpArg<Name, ID>, SubParserTuple>(
std::move(this->info_), subParsers);
}

template <ArgName Name = "help,h">
auto addHelp(std::string_view help) {
static_assert(
(SearchIndexFromShortName<Arguments, Name.shortName>::value == -1),
"Duplicated short name");
static_assert(Argo::SearchIndex<Arguments, Name>::value == -1,
static_assert((SearchIndexFromShortName<Args, Name.shortName>::value == -1),
"Duplicated short name");
static_assert(Argo::SearchIndex<Args, Name>::value == -1,
"Duplicated name");
static_assert(!Name.containsInvalidChar(), "Name has invalid char");
static_assert(Name.hasValidNameLength(),
"Short name can't be more than one charactor");
this->info_->help = help;
FlagArgInitializer<Name, ID>::init(
Argo::description("Print help information"));
return Parser<ID,
decltype(std::tuple_cat(
std::declval<Arguments>(),
std::declval<std::tuple<FlagArg<Name, ID>>>())),
PositionalArgument,
SubParserTuple,
true>(std::move(this->info_), subParsers);
return Parser<ID, Args, PArg, HelpArg<Name, ID>, SubParserTuple>(
std::move(this->info_), subParsers);
}

template <ArgName Name>
auto getArg() {
if (!this->parsed_) {
throw ParseError("Parser did not parse argument, call parse first");
}
if constexpr (!std::is_same_v<PositionalArgument, void>) {
if constexpr (std::string_view(Name) ==
std::string_view(PositionalArgument::name)) {
return PositionalArgument::value;
if constexpr (!std::is_same_v<PArg, void>) {
if constexpr (std::string_view(Name) == std::string_view(PArg::name)) {
return PArg::value;
} else {
return std::remove_cvref_t<
decltype(std::get<SearchIndex<Arguments, Name>::value>(
std::declval<Arguments>()))>::value;
decltype(std::get<SearchIndex<Args, Name>::value>(
std::declval<Args>()))>::value;
}
} else {
return std::remove_cvref_t<
decltype(std::get<SearchIndex<Arguments, Name>::value>(
std::declval<Arguments>()))>::value;
decltype(std::get<SearchIndex<Args, Name>::value>(
std::declval<Args>()))>::value;
}
}

Expand All @@ -312,19 +286,18 @@ class Parser {
if (!this->parsed_) {
throw ParseError("Parser did not parse argument, call parse first");
}
if constexpr (!std::is_same_v<PositionalArgument, void>) {
if constexpr (std::string_view(Name) ==
std::string_view(PositionalArgument::name)) {
return PositionalArgument::assigned;
if constexpr (!std::is_same_v<PArg, void>) {
if constexpr (std::string_view(Name) == std::string_view(PArg::name)) {
return PArg::assigned;
} else {
return std::remove_cvref_t<
decltype(std::get<SearchIndex<Arguments, Name>::value>(
std::declval<Arguments>()))>::assigned;
decltype(std::get<SearchIndex<Args, Name>::value>(
std::declval<Args>()))>::assigned;
}
} else {
return std::remove_cvref_t<
decltype(std::get<SearchIndex<Arguments, Name>::value>(
std::declval<Arguments>()))>::assigned;
decltype(std::get<SearchIndex<Args, Name>::value>(
std::declval<Args>()))>::assigned;
}
}

Expand All @@ -336,11 +309,8 @@ class Parser {
auto s = std::make_tuple(
SubParser<Name, T>{std::ref(sub_parser), description.description});
auto sub_parsers = std::tuple_cat(subParsers, s);
return Parser<ID,
Arguments,
PositionalArgument,
decltype(sub_parsers),
HelpEnabled>(std::move(this->info_), sub_parsers);
return Parser<ID, Args, PArg, HArg, decltype(sub_parsers)>(
std::move(this->info_), sub_parsers);
}

auto resetArgs() -> void;
Expand All @@ -353,6 +323,10 @@ class Parser {
this->info_->subcommand_help = subcommand_help;
}

auto addPositionalArgumentHelp(std::string_view positional_argument_help) {
this->info_->positional_argument_help = positional_argument_help;
}

auto addOptionsHelp(std::string_view options_help) {
this->info_->options_help = options_help;
}
Expand Down
Loading

0 comments on commit e846c24

Please sign in to comment.