Template
Initial commit
This commit is contained in:
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{};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -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{};
|
||||
|
||||
}
|
||||
@@ -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{};
|
||||
|
||||
}
|
||||
@@ -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)};
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user