<commit_before>#pragma once

#include <boost/any.hpp>
#include <boost/mpl/for_each.hpp>

#include "integer.hpp"

namespace blackhole {

namespace aux {

template<typename T>
static void any_to(const boost::any& from, T& to) {
    to = boost::any_cast<T>(from);
}

template<typename T>
struct cast {
    const boost::any& source;
    T& value;
    bool& successful;

    cast(const boost::any& source, T& value, bool& successful) :
        source(source),
        value(value),
        successful(successful)
    {}

    template<typename Integer>
    void operator ()(Integer) {
        if (successful) {
            return;
        }

        const Integer* value_ptr = boost::any_cast<Integer>(&source);
        if (value_ptr) {
            value = *value_ptr;
            successful = true;
        }
    }
};

template<typename T, class = void> struct cast_traits;

template<typename T>
struct cast_traits<T, typename std::enable_if<!is_supported_integer<T>::value>::type> {
    static void to(const boost::any& source, T& value) {
        any_to(source, value);
    }
};

// When parsing external configs (like json) there are no information about
// the exact size of integer types.
// But for configs it is very unlikely to keep all integer variables under `int` without size
// specification, for example - port is always keeped as std::uint16_t.
// So, after parsing we have raw `int` type stored in boost::any.
// On the other side final config awaits concrete type. To connect them, I've decided to
// iterate over all supported integers in library (total 8) and try to convert boost::any to
// each of them in sequence until successful.
template<typename T>
struct cast_traits<T, typename std::enable_if<is_supported_integer<T>::value>::type> {
    static void to(const boost::any& source, T& value) {
        bool successful = false;
        boost::mpl::for_each<supported_integers_t>(cast<T>(source, value, successful));
        if (!successful) {
            throw blackhole::error_t("unsupported integer type");
        }
    }
};

} // namespace aux

} // namespace blackhole<commit_msg>Comments styling fix.<commit_after>#pragma once

#include <boost/any.hpp>
#include <boost/mpl/for_each.hpp>

#include "integer.hpp"

namespace blackhole {

namespace aux {

template<typename T>
static void any_to(const boost::any& from, T& to) {
    to = boost::any_cast<T>(from);
}

template<typename T>
struct cast {
    const boost::any& source;
    T& value;
    bool& successful;

    cast(const boost::any& source, T& value, bool& successful) :
        source(source),
        value(value),
        successful(successful)
    {}

    template<typename Integer>
    void operator ()(Integer) {
        if (successful) {
            return;
        }

        const Integer* value_ptr = boost::any_cast<Integer>(&source);
        if (value_ptr) {
            value = *value_ptr;
            successful = true;
        }
    }
};

//! \brief Helper class to ease casting from dynamic objects to the specific types.
/*! When parsing external configs (like json) there are no information about
    the exact size of integer types.
    But for configs it is very unlikely to keep all integer variables under `int` without size
    specification, for example - port is always keeped as std::uint16_t.
    So, after parsing we have raw `int` type stored in boost::any.
    On the other side final config awaits concrete type. To connect them, I've decided to
    iterate over all supported integers in library (total 8) and try to convert boost::any to
    each of them in sequence until successful.
*/
template<typename T, class = void> struct cast_traits;

template<typename T>
struct cast_traits<T, typename std::enable_if<!is_supported_integer<T>::value>::type> {
    static void to(const boost::any& source, T& value) {
        any_to(source, value);
    }
};

template<typename T>
struct cast_traits<T, typename std::enable_if<is_supported_integer<T>::value>::type> {
    static void to(const boost::any& source, T& value) {
        bool successful = false;
        boost::mpl::for_each<supported_integers_t>(cast<T>(source, value, successful));
        if (!successful) {
            throw blackhole::error_t("unsupported integer type");
        }
    }
};

} // namespace aux

} // namespace blackhole
{'fraction_non_alphanumeric': 0.11203897007654837, 'fraction_numerical': 0.0013917884481558804, 'mean_word_length': 3.235756385068762, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, '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': '4765039', 'n_tokens_mistral': 1272, 'n_tokens_neox': 1241, 'n_words': 418}