poaflocParser Of Arguments For Lines Of Commands |
git clone git://git.dimitrijedobrota.com/poafloc.git |
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | 4d7e51ac5f4f93d0a3c599dbc091c34b100563ca |
parent | 0b0ea66959b7a617db75d272d8e9bed40702705b |
author | Dimitrije Dobrota < mail@dimitrijedobrota.com > |
date | Tue, 27 May 2025 13:50:00 +0200 |
Template madness cleanup
* Further cleanup crashes clang...
M | include/poafloc/poafloc.hpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++ ------------------------------- |
M | source/option.cpp | | | ++ |
2 files changed, 54 insertions(+), 31 deletions(-)
diff --git a/ include/poafloc/poafloc.hpp b/ include/poafloc/poafloc.hpp
@@ -1,7 +1,5 @@
#pragma once
#include <algorithm>
#include <concepts>
#include <cstring>
#include <functional>
#include <initializer_list>
@@ -13,9 +11,12 @@
#include <string_view>
#include <vector>
#include <based/concepts/is/same.hpp>
#include <based/trait/integral_constant.hpp>
#include <based/trait/remove/cvref.hpp>
#include <based/types/types.hpp>
#include <based/utility/forward.hpp>
#include <based/utility/move.hpp>
namespace poafloc
{
@@ -87,10 +88,16 @@
public:
}
};
template<class T>
using rec_type = typename based::remove_cvref_t<T>::rec_type;
template<class T, class... Rest>
concept SameRec = (based::SameAs<rec_type<T>, rec_type<Rest>> && ...);
} // namespace detail
template<class Record, class Type>
requires(!std::same_as<bool, Type>)
requires(!based::SameAs<bool, Type>)
class argument : public detail::option
{
using base = detail::option;
@@ -110,7 +117,7 @@
public:
};
template<class Record, class Type>
requires(!std::same_as<bool, Type>)
requires(!based::SameAs<bool, Type>)
class direct : public detail::option
{
using base = detail::option;
@@ -155,7 +162,7 @@
public:
};
template<class Record, class Type>
requires(!std::same_as<bool, Type>)
requires(!based::SameAs<bool, Type>)
class list : public detail::option
{
using base = detail::option;
@@ -206,9 +213,10 @@
class positional_base : public std::vector<detail::option>
using base = std::vector<option>;
protected:
template<detail::IsArgument... Args>
explicit positional_base(Args&&... args)
template<detail::IsArgument Arg, detail::IsArgument... Args>
explicit positional_base(Arg&& arg, Args&&... args)
: base(std::initializer_list<option> {
based::forward<Arg>(arg),
based::forward<Args>(args)...,
})
{
@@ -237,17 +245,18 @@
public:
template<class Record>
struct positional : detail::positional_base
{
template<detail::IsArgument... Args>
explicit positional(Args&&... args)
requires(std::same_as<Record, typename Args::rec_type> && ...)
: positional_base(based::forward<Args>(args)...)
using rec_type = Record;
template<detail::IsArgument Arg, detail::IsArgument... Args>
explicit positional(Arg&& arg, Args&&... args)
requires detail::SameRec<Arg, Args...>
: positional_base(based::forward<Arg>(arg), based::forward<Args>(args)...)
{
}
template<detail::IsArgument... Args, detail::IsList List>
explicit positional(Args&&... args, List&& list)
requires(std::same_as<Record, typename List::rec_type>)
&& (std::same_as<Record, typename Args::rec_type> && ...)
requires detail::SameRec<List, Args...>
: positional_base(
based::forward<Args>(args)..., based::forward<List>(list)
)
@@ -256,10 +265,10 @@
struct positional : detail::positional_base
};
template<detail::IsArgument Arg, detail::IsArgument... Args>
positional(Arg&& arg, Args&&... args) -> positional<typename Arg::rec_type>;
positional(Arg&& arg, Args&&... args) -> positional<detail::rec_type<Arg>>;
template<detail::IsArgument... Args, detail::IsList List>
positional(Args&&... args, List&& list) -> positional<typename List::rec_type>;
positional(Args&&... args, List&& list) -> positional<detail::rec_type<List>>;
namespace detail
{
@@ -294,9 +303,10 @@
class group_base : public std::vector<detail::option>
std::string m_name;
protected:
template<detail::IsOption... Opts>
explicit group_base(std::string_view name, Opts&&... opts)
template<detail::IsOption Opt, detail::IsOption... Opts>
explicit group_base(std::string_view name, Opt&& opt, Opts&&... opts)
: base(std::initializer_list<option> {
based::forward<Opt>(opt),
based::forward<Opts>(opts)...,
})
, m_name(name)
@@ -314,10 +324,14 @@
public:
template<class Record>
struct group : detail::group_base
{
template<detail::IsOption... Opts>
explicit group(std::string_view name, Opts&&... opts)
requires(std::same_as<Record, typename Opts::rec_type> && ...)
: group_base(name, based::forward<Opts>(opts)...)
using rec_type = Record;
template<detail::IsOption Opt, detail::IsOption... Opts>
explicit group(std::string_view name, Opt&& opt, Opts&&... opts)
requires detail::SameRec<Opt, Opts...>
: group_base(
name, based::forward<Opt>(opt), based::forward<Opts>(opts)...
)
{
}
};
@@ -401,15 +415,15 @@
class parser_base
protected:
template<class... Groups>
explicit parser_base(Groups&&... groups)
requires(std::same_as<group_base, Groups> && ...)
requires(based::SameAs<group_base, Groups> && ...)
: parser_base({}, based::forward<group_base>(groups)...)
{
}
template<class... Groups>
explicit parser_base(positional_base positional, Groups&&... groups)
requires(std::same_as<group_base, Groups> && ...)
: m_pos(std::move(positional))
explicit parser_base(positional_base&& positional, Groups&&... groups)
requires(based::SameAs<group_base, Groups> && ...)
: m_pos(based::forward<decltype(positional)>(positional))
{
m_options.reserve(m_options.size() + (groups.size() + ...));
@@ -431,18 +445,25 @@
protected:
template<class Record>
struct parser : detail::parser_base
{
template<class... Groups>
explicit parser(Groups&&... groups)
requires(std::same_as<group<Record>, Groups> && ...)
: parser_base(based::forward<detail::group_base>(groups)...)
template<class Group, class... Groups>
explicit parser(Group&& grp, Groups&&... groups)
requires(
based::SameAs<group<Record>, Group>
&& (based::SameAs<group<Record>, Groups> && ...)
)
: parser_base(
based::forward<detail::group_base>(grp),
based::forward<detail::group_base>(groups)...
)
{
}
template<class... Groups>
explicit parser(positional<Record>&& positional, Groups&&... groups)
requires(std::same_as<group<Record>, Groups> && ...)
requires(based::SameAs<group<Record>, Groups> && ...)
: parser_base(
std::move(positional), based::forward<detail::group_base>(groups)...
based::move(positional),
based::forward<detail::group_base>(groups)...
)
{
}
diff --git a/ source/option.cpp b/ source/option.cpp
@@ -1,3 +1,5 @@
#include <algorithm>
#include "poafloc/error.hpp"
#include "poafloc/poafloc.hpp"