Template
109 lines
2.5 KiB
C++
109 lines
2.5 KiB
C++
#pragma once
|
|
#include "core-library/traits/function-traits.h"
|
|
|
|
#include <ranges>
|
|
#include <span>
|
|
#include <string_view>
|
|
|
|
namespace core {
|
|
|
|
class command_line_argument
|
|
{
|
|
public:
|
|
constexpr command_line_argument(char* arg, std::span<char*> modifiers)
|
|
: m_arg_view{arg}
|
|
, m_modifiers{modifiers}
|
|
{
|
|
}
|
|
|
|
template<typename F>
|
|
requires std::invocable<F>
|
|
void with(std::string_view arg_to_match_view, F&& function) const
|
|
{
|
|
if (arg_to_match_view == m_arg_view)
|
|
std::invoke(std::forward<F>(function));
|
|
}
|
|
|
|
template<typename F>
|
|
requires core::callable_with_argument_converted<F, std::string_view>
|
|
void with(std::string_view arg_to_match_view, F&& function) const
|
|
{
|
|
if (m_arg_view.starts_with(arg_to_match_view))
|
|
{
|
|
const std::string_view value_part = m_arg_view.substr(arg_to_match_view.size());
|
|
std::invoke(std::forward<F>(function), core::first_argument_type_t<F>{value_part});
|
|
}
|
|
}
|
|
|
|
private:
|
|
std::string_view m_arg_view;
|
|
std::span<char*> m_modifiers;
|
|
};
|
|
|
|
class command_line_args_view : public std::ranges::view_interface<command_line_args_view>
|
|
{
|
|
public:
|
|
constexpr command_line_args_view() = default;
|
|
|
|
constexpr command_line_args_view(int argc, char* argv[])
|
|
: m_argc{--argc}
|
|
, m_application_path{argv++[0]}
|
|
, m_argv{argv}
|
|
{
|
|
}
|
|
|
|
class iterator
|
|
{
|
|
public:
|
|
constexpr iterator(int argc, char** argv, int index)
|
|
: m_argv{argv}
|
|
, m_argc{argc}
|
|
, m_index{index}
|
|
{
|
|
}
|
|
|
|
constexpr iterator& operator++()
|
|
{
|
|
++m_index;
|
|
|
|
while (m_index < m_argc)
|
|
{
|
|
const std::string_view arg_view{m_argv[m_index]};
|
|
if (arg_view.starts_with("--"))
|
|
m_modifier_start_index = m_index++;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
constexpr command_line_argument operator*() const
|
|
{
|
|
if (m_modifier_start_index != -1)
|
|
return command_line_argument{m_argv[m_index], std::span<char*>(&m_argv[m_modifier_start_index], &m_argv[m_index])};
|
|
else
|
|
return command_line_argument{m_argv[m_index], {}};
|
|
}
|
|
|
|
constexpr bool operator!=(const iterator& other) const { return m_argv != other.m_argv || m_index != other.m_index; }
|
|
|
|
private:
|
|
char** m_argv;
|
|
int m_argc;
|
|
int m_index;
|
|
int m_modifier_start_index{-1};
|
|
};
|
|
|
|
constexpr auto&& appliation_path() const { return m_application_path; }
|
|
|
|
constexpr iterator begin() const { return iterator{m_argc, m_argv, 0}; }
|
|
constexpr iterator end() const { return iterator{m_argc, m_argv, m_argc}; }
|
|
constexpr std::size_t size() const { return static_cast<std::size_t>(m_argc); }
|
|
|
|
private:
|
|
int m_argc{};
|
|
char* m_application_path{};
|
|
char** m_argv{};
|
|
};
|
|
|
|
}
|