Initial commit

This commit is contained in:
gaztin committed 2026-07-11 19:53:00 +02:00
commit d1890b6e18
16 files changed
+702

No files matched your search

@@ -0,0 +1,95 @@
#pragma once
#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));
}
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{};
};
}
+55
View File
@@ -0,0 +1,55 @@
#pragma once
#include "core-library/views/trim-view.h"
namespace core {
template<std::ranges::forward_range Range>
requires requires(Range&& range) {
(void)range.empty();
(void)trim_view{(*std::begin(range))};
}
class trim_elements_view : public std::ranges::view_interface<trim_elements_view<Range>>
{
public:
constexpr trim_elements_view(Range range)
: m_range(std::move(range))
{
}
class iterator
{
public:
using base_t = std::ranges::iterator_t<Range>;
constexpr iterator(base_t base, base_t end)
: m_base{base}
, m_end{end}
{
}
constexpr bool operator!=(iterator other) const { return m_base != other.m_base; }
constexpr auto operator*() const { return trim_view{*m_base}; }
constexpr iterator& operator++()
{
// Skip empty elements
while (++m_base != m_end && std::ranges::empty(**this)) {}
return *this;
}
private:
base_t m_base;
base_t m_end;
};
constexpr auto begin() { return iterator{std::begin(m_range), std::end(m_range)}; }
constexpr auto end() { return iterator{std::end(m_range), std::end(m_range)}; }
private:
Range m_range{};
};
constexpr view_closure<trim_elements_view> trim_elements{};
}
+53
View File
@@ -0,0 +1,53 @@
#pragma once
#include "core-library/views/view-closure.h"
#include <ranges>
namespace core {
template<std::ranges::forward_range Range>
requires requires(Range&& range) {
*std::begin(range) == ' '; // Comparable with char literals.
}
class trim_view : public std::ranges::view_interface<trim_view<Range>>
{
public:
constexpr explicit trim_view(Range range)
: m_range(std::move(range))
{
}
static constexpr bool is_space(auto&& c)
{
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\0';
}
constexpr auto begin()
{
auto it = std::begin(m_range);
while (it != std::end(m_range) && is_space(*it))
++it;
return it;
}
constexpr auto end()
{
auto nonspace_end = std::end(m_range);
for (auto it = std::begin(m_range); it != std::end(m_range);)
{
if (!is_space(*it++))
nonspace_end = it;
}
return nonspace_end;
}
private:
Range m_range{};
};
constexpr view_closure<trim_view> trim{};
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <ranges>
namespace core {
template<template<typename> typename ViewTemplate>
class view_closure : public std::ranges::range_adaptor_closure<view_closure<ViewTemplate>>
{
public:
template<std::ranges::viewable_range Range>
constexpr auto operator()(Range&& range) const
requires requires { ViewTemplate<std::views::all_t<Range>>{std::forward<Range>(range)}; }
{
return ViewTemplate<std::views::all_t<Range>>{std::forward<Range>(range)};
}
};
}