<commit_before>#ifndef SLIC3RXS

#ifndef CONFIG_HPP
#define CONFIG_HPP


#include <initializer_list>
#include <memory>
#include <regex>

#include "PrintConfig.hpp"
#include "ConfigBase.hpp"

namespace Slic3r {

/// Exception class for invalid (but correct type) option values. 
/// Thrown by validate()
class InvalidOptionValue : public std::runtime_error {
public:
    InvalidOptionValue(const char* v) : runtime_error(v) {}
    InvalidOptionValue(const std::string v) : runtime_error(v.c_str()) {}
};

/// Exception class to handle config options that don't exist.
class InvalidConfigOption : public std::runtime_error {};

/// Exception class for type mismatches
class InvalidOptionType : public std::runtime_error {
public:
    InvalidOptionType(const char* v) : runtime_error(v) {}
    InvalidOptionType(const std::string v) : runtime_error(v.c_str()) {}
};

class Config;
using config_ptr = std::shared_ptr<Config>;

class Config {
public:

    /// Factory method to construct a Config with all default values loaded.
    static std::shared_ptr<Config> new_from_defaults();

    /// Factory method to construct a Config with specific default values loaded.
    static std::shared_ptr<Config> new_from_defaults(std::initializer_list<std::string> init);
    
    /// Factory method to construct a Config with specific default values loaded.
    static std::shared_ptr<Config> new_from_defaults(t_config_option_keys init);

    /// Factory method to construct a Config from CLI options.
    static std::shared_ptr<Config> new_from_cli(const int& argc, const char* argv[]);

    /// Factory method to construct a Config from an ini file.
    static std::shared_ptr<Config> new_from_ini(const std::string& inifile);

    /// Write a windows-style opt=value ini file with categories from the configuration store.
    void write_ini(const std::string& file) const;

    /// Parse a windows-style opt=value ini file with categories and load the configuration store.
    void read_ini(const std::string& file);


    double getFloat(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getFloat();
    }

    int getInt(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getInt();
    }
    bool getBool(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getBool();
    }
    std::string getString(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getString();
    }


    /// Template function to dynamic cast and leave it in pointer form.
    template <class T>
    T* get_ptr(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return dynamic_cast<T*>(this->_config.optptr(opt_key, create));
    }

    /// Template function to retrieve and cast in hopefully a slightly nicer 
    /// format than longwinded dynamic_cast<> 
    template <class T>
    T& get(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return *(dynamic_cast<T*>(this->_config.optptr(opt_key, create)));
    }
    
    /// Function to parse value from a string to whatever opt_key is.
    void set(const t_config_option_key& opt_key, const std::string& value);

    void set(const t_config_option_key& opt_key, const char* value) { this->set(opt_key, std::string(value));} 
    
    /// Function to parse value from an integer to whatever opt_key is, if
    /// opt_key is a numeric type. This will throw an exception and do 
    /// nothing if called with an incorrect type.
    void set(const t_config_option_key& opt_key, const int value);

    /// Function to parse value from an boolean to whatever opt_key is, if
    /// opt_key is a numeric type. This will throw an exception and do 
    /// nothing if called with an incorrect type.
    void set(const t_config_option_key& opt_key, const bool value);
    
    /// Function to parse value from an integer to whatever opt_key is, if
    /// opt_key is a numeric type. This will throw an exception and do 
    /// nothing if called with an incorrect type.
    void set(const t_config_option_key& opt_key, const double value);

    /// Method to validate the different configuration options. 
    /// It will throw InvalidConfigOption exceptions on failure.
    bool validate();

    const DynamicPrintConfig& config() const { return _config; }
    bool empty() const { return _config.empty(); }

    /// Pass-through of apply()
    void apply(const config_ptr& other) { _config.apply(other->config()); }
    void apply(const Slic3r::Config& other) { _config.apply(other.config()); }<commit_msg>Pass-through apply and a version of apply_only for Slic3r::Configs so that it can be used with shared_ptr versions.<commit_after>#ifndef SLIC3RXS

#ifndef CONFIG_HPP
#define CONFIG_HPP


#include <initializer_list>
#include <memory>
#include <regex>

#include "PrintConfig.hpp"
#include "ConfigBase.hpp"

namespace Slic3r {

/// Exception class for invalid (but correct type) option values. 
/// Thrown by validate()
class InvalidOptionValue : public std::runtime_error {
public:
    InvalidOptionValue(const char* v) : runtime_error(v) {}
    InvalidOptionValue(const std::string v) : runtime_error(v.c_str()) {}
};

/// Exception class to handle config options that don't exist.
class InvalidConfigOption : public std::runtime_error {};

/// Exception class for type mismatches
class InvalidOptionType : public std::runtime_error {
public:
    InvalidOptionType(const char* v) : runtime_error(v) {}
    InvalidOptionType(const std::string v) : runtime_error(v.c_str()) {}
};

class Config;
using config_ptr = std::shared_ptr<Config>;

class Config {
public:

    /// Factory method to construct a Config with all default values loaded.
    static std::shared_ptr<Config> new_from_defaults();

    /// Factory method to construct a Config with specific default values loaded.
    static std::shared_ptr<Config> new_from_defaults(std::initializer_list<std::string> init);
    
    /// Factory method to construct a Config with specific default values loaded.
    static std::shared_ptr<Config> new_from_defaults(t_config_option_keys init);

    /// Factory method to construct a Config from CLI options.
    static std::shared_ptr<Config> new_from_cli(const int& argc, const char* argv[]);

    /// Factory method to construct a Config from an ini file.
    static std::shared_ptr<Config> new_from_ini(const std::string& inifile);

    /// Write a windows-style opt=value ini file with categories from the configuration store.
    void write_ini(const std::string& file) const;

    /// Parse a windows-style opt=value ini file with categories and load the configuration store.
    void read_ini(const std::string& file);


    double getFloat(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getFloat();
    }

    int getInt(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getInt();
    }
    bool getBool(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getBool();
    }
    std::string getString(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return (dynamic_cast<ConfigOption*>(this->_config.optptr(opt_key, create)))->getString();
    }


    /// Template function to dynamic cast and leave it in pointer form.
    template <class T>
    T* get_ptr(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return dynamic_cast<T*>(this->_config.optptr(opt_key, create));
    }

    /// Template function to retrieve and cast in hopefully a slightly nicer 
    /// format than longwinded dynamic_cast<> 
    template <class T>
    T& get(const t_config_option_key& opt_key, bool create=true) {
        if (print_config_def.options.count(opt_key) == 0) throw InvalidOptionType(opt_key + std::string(" is an invalid option.")); 
        return *(dynamic_cast<T*>(this->_config.optptr(opt_key, create)));
    }
    
    /// Function to parse value from a string to whatever opt_key is.
    void set(const t_config_option_key& opt_key, const std::string& value);

    void set(const t_config_option_key& opt_key, const char* value) { this->set(opt_key, std::string(value));} 
    
    /// Function to parse value from an integer to whatever opt_key is, if
    /// opt_key is a numeric type. This will throw an exception and do 
    /// nothing if called with an incorrect type.
    void set(const t_config_option_key& opt_key, const int value);

    /// Function to parse value from an boolean to whatever opt_key is, if
    /// opt_key is a numeric type. This will throw an exception and do 
    /// nothing if called with an incorrect type.
    void set(const t_config_option_key& opt_key, const bool value);
    
    /// Function to parse value from an integer to whatever opt_key is, if
    /// opt_key is a numeric type. This will throw an exception and do 
    /// nothing if called with an incorrect type.
    void set(const t_config_option_key& opt_key, const double value);

    /// Method to validate the different configuration options. 
    /// It will throw InvalidConfigOption exceptions on failure.
    bool validate();

    const DynamicPrintConfig& config() const { return _config; }
    bool empty() const { return _config.empty(); }

    /// Pass-through of apply()
    void apply(const config_ptr& other) { _config.apply(other->config()); }
    void apply(const Slic3r::Config& other) { _config.apply(other.config()); }
   
    /// Apply only configuration options in the array.
    void apply_with_defaults(const config_ptr& other, const t_config_option_keys& keys) { _config.apply_only(other->_config, keys, false, true); }
    void apply(const config_ptr& other, const t_config_option_keys& keys) { _config.apply_only(other->_config, keys, false, false); }
{'fraction_non_alphanumeric': 0.1095467032967033, 'fraction_numerical': 0.0016311813186813187, 'mean_word_length': 3.9697098976109215, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 67, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5601550', 'n_tokens_mistral': 3411, 'n_tokens_neox': 3312, 'n_words': 1084}