#pragma once #include "core-library/traits/function-traits.h" #include #include #include namespace core { class command_line_argument { public: constexpr command_line_argument(char* arg, std::span modifiers) : m_arg_view{arg} , m_modifiers{modifiers} { } template requires std::invocable void with(std::string_view arg_to_match_view, F&& function) const { if (arg_to_match_view == m_arg_view) std::invoke(std::forward(function)); } template requires core::callable_with_argument_converted 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(function), core::first_argument_type_t{value_part}); } } private: std::string_view m_arg_view; std::span m_modifiers; }; class command_line_args_view : public std::ranges::view_interface { 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(&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(m_argc); } private: int m_argc{}; char* m_application_path{}; char** m_argv{}; }; }