Program Listing for File cla_parser.hpp

Return to documentation for file (inexor/vulkan-renderer/tools/cla_parser.hpp)

#pragma once

#include <cstdint>
#include <optional>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

namespace inexor::vulkan_renderer::tools {

class CommandLineArgumentTemplate {
    const std::string m_argument;
    const bool m_takes_values{false};

public:
    CommandLineArgumentTemplate(std::string argument, bool takes_args)
        : m_argument(std::move(argument)), m_takes_values(takes_args) {}

    [[nodiscard]] const std::string &argument() const {
        return m_argument;
    }

    [[nodiscard]] bool takes_values() const {
        return m_takes_values;
    }
};

class CommandLineArgumentValue {
    const std::string m_value;

public:
    explicit CommandLineArgumentValue(std::string value) : m_value(std::move(value)) {}

    template <typename T>
    [[nodiscard]] T as() const;
};

class CommandLineArgumentParser {
    // TODO: Allow runtime addition of argument templates.
    const std::vector<CommandLineArgumentTemplate> m_accepted_args{
        // Specifies which GPU to use (by array index).
        {"--gpu", true},

        // Disables the use of the special data transfer queue (forces use of the graphics queue).
        {"--no-separate-data-queue", false},

        // Disables GPU info printing.
        {"--no-stats", false},

        // Disables the Khronos vulkan validation layer.
        {"--no-validation", false},

        // Disables vulkan debug markers (even if --renderdoc is specified).
        {"--no-vk-debug-markers", false},

        // Enables the RenderDoc debug layer.
        {"--renderdoc", false},

        // Enables vertical synchronisation (limits FPS to monitor refresh rate).
        {"--vsync", false},

        {"--stop-on-validation-message", false}};

    std::unordered_map<std::string, CommandLineArgumentValue> m_parsed_arguments;

    std::optional<CommandLineArgumentTemplate> make_arg_template(const std::string &argument_name) const;

public:
    void parse_args(int argc, char **argv);

    template <typename T>
    std::optional<T> arg(const std::string &name) const {
        auto arg_template = make_arg_template(name);
        auto it = m_parsed_arguments.find(name);
        if (!arg_template || it == m_parsed_arguments.end()) {
            return std::nullopt;
        }
        if (!arg_template->takes_values()) {
            return true;
        }
        return it->second.as<T>();
    }

    [[nodiscard]] std::size_t parsed_arg_count() const {
        return m_parsed_arguments.size();
    }
};

} // namespace inexor::vulkan_renderer::tools