<commit_before>#ifndef MJOLNIR_UTIL_GET_TOML_VALUE
#define MJOLNIR_UTIL_GET_TOML_VALUE
#include <extlib/toml/toml.hpp>
#include <mjolnir/util/throw_exception.hpp>
#include <string>
#include <stdexcept>

namespace mjolnir
{

inline toml::value const&
toml_value_at(const toml::Table& tab, const std::string& key,
              const std::string& tablename)
{
    try
    {
        return tab.at(key);
    }
    catch(const std::out_of_range& oor)
    {
        throw_exception<std::runtime_error>(
            "mjolnir: while reading toml file: key(", key,
            ") in table(", tablename, ") missing");
    }
}

} // mjolnir
#endif// MJOLNIR_INPUT_GET_TOML_VALUE<commit_msg>add get_toml_value that does both searching and type casting<commit_after>#ifndef MJOLNIR_UTIL_GET_TOML_VALUE
#define MJOLNIR_UTIL_GET_TOML_VALUE
#include <extlib/toml/toml.hpp>
#include <mjolnir/util/type_traits.hpp>
#include <mjolnir/util/throw_exception.hpp>
#include <string>
#include <stdexcept>

namespace mjolnir
{

inline toml::value const&
toml_value_at(const toml::Table& tab, const std::string& key,
              const std::string& tablename)
{
    try
    {
        return tab.at(key);
    }
    catch(const std::out_of_range& oor)
    {
        throw_exception<std::runtime_error>(
            "mjolnir: while reading toml file: key(", key,
            ") in table(", tablename, ") missing");
    }
}

// one of the toml values. needs no conversion. so it can return a reference.
template<typename T, typename std::enable_if<disjunction<
    std::is_same<T, toml::Boolean >,
    std::is_same<T, toml::Integer >,
    std::is_same<T, toml::Float   >,
    std::is_same<T, toml::String  >,
    std::is_same<T, toml::Datetime>,
    std::is_same<T, toml::Array   >,
    std::is_same<T, toml::Table   >
    >::value, std::nullptr_t>::type = nullptr>
T const& get_toml_value(const toml::Table& tab, const std::string& key,
                        const std::string& tablename)
{
    try
    {
        return tab.at(key).cast<toml::value_traits<T>::type_index>();
    }
    catch(const std::out_of_range& oor)
    {
        throw_exception<std::runtime_error>(
            "mjolnir: while reading toml file: key(", key,
            ") in table(", tablename, ") missing");
    }
    catch(const toml::type_error& tte)
    {
        throw_exception<std::runtime_error>(
            "mjolnir: while reading toml file: key(", key,
            ") in table(", tablename, ") has type `",
            tab.at(key).type(), "`, expected `",
            toml::value_traits<T>::type_index, "`.");
    }
}

// none of the toml values. needs conversion.
template<typename T, typename std::enable_if<conjunction<
    negation<std::is_same<T, toml::Boolean >>,
    negation<std::is_same<T, toml::Integer >>,
    negation<std::is_same<T, toml::Float   >>,
    negation<std::is_same<T, toml::String  >>,
    negation<std::is_same<T, toml::Datetime>>,
    negation<std::is_same<T, toml::Array   >>,
    negation<std::is_same<T, toml::Table   >>
    >::value, std::nullptr_t>::type = nullptr>
T get_toml_value(const toml::Table& tab, const std::string& key,
                 const std::string& tablename)
{
    try
    {
        return toml::get<T>(tab.at(key));
    }
    catch(const std::out_of_range& oor)
    {
        throw_exception<std::runtime_error>(
            "mjolnir: while reading toml file: key(", key,
            ") in table(", tablename, ") missing");
    }
    catch(const toml::type_error& tte)
    {
        throw_exception<std::runtime_error>(
            "mjolnir: while reading toml file: key(", key,
            ") in table(", tablename, ") has type `",
            tab.at(key).type(), "`, expected `",
            toml::value_traits<T>::type_index, "`.");
    }
}

} // mjolnir
#endif// MJOLNIR_INPUT_GET_TOML_VALUE
{'fraction_non_alphanumeric': 0.15059132720105126, 'fraction_numerical': 0.0, 'mean_word_length': 3.1324647122692726, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 50, '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': '4602844', 'n_tokens_mistral': 1377, 'n_tokens_neox': 1358, 'n_words': 261}