<commit_before>#pragma once

#include <utility>  // std::forward

namespace Utility
{
    /**
     * Bounce.
     * Convert callback-style free functions into method calls
     * on an object (class) provided in the argument list. 
     * This saves on boilerplate code and avoids name clutter.
     */
    template<typename To, typename From, typename... Args>
    struct Bounce
    {
        static To* to_ptr( From* from )
        {
            return reinterpret_cast<To*>(from);
        }

        template<typename Retval, Retval (To::* Method)(Args...)>
        static Retval rv_fn( From* from, Args... args )
        {
            return (to_ptr( from )->*Method)( std::forward<Args>(args)... );
        }

        template<void (To::* Method)(Args...)>
        static void vd_fn( From* from, Args... args )
        {
            (to_ptr( from )->*Method)( std::forward<Args>(args)... );
        }
    };

} // namespace Utility<commit_msg>improved version<commit_after>#pragma once

#include <utility>  // std::forward

namespace Utility
{
    /**
     * Bounce.
     * Convert callback-style free functions into method calls
     * on an object (class) provided in the argument list. 
     * This saves on boilerplate code and avoids name clutter.
     * For simple pointer recasting cases, the usage will be
     * like this:
     * 
     *     using MyCaster = Caster<MyTo, MyFrom>;
     *
     *     template<typename... Args>
     *     using MyBounce = Bounce<MyCaster, Args...>;
     *
     * In more complex conversion cases, the Converter::cast
     * function will have to be defined explicitly, with 
     * internal typedefs of to_type and from_type.
     */     
    template<typename To, typename From>
    struct Caster
    {
        using to_type   = To;
        using from_type = From;
        
        static to_type* cast( from_type* from )
        {
            return reinterpret_cast<to_type*>(from);
        }
    };
    
    template<typename Converter, typename... Args>
    struct Bounce
    {
        using To   = typename Converter::to_type;
        using From = typename Converter::from_type;
        
        template<typename Retval, Retval (To::* Method)(Args...)>
        static Retval rv_fn( From* from, Args... args )
        {
            return (Converter::cast( from )->*Method)( std::forward<Args>(args)... );
        }

        template<void (To::* Method)(Args...)>
        static void vd_fn( From* from, Args... args )
        {
            (Converter::cast( from )->*Method)( std::forward<Args>(args)... );
        }
    };

} // namespace Utility
{'fraction_non_alphanumeric': 0.12427856868026164, 'fraction_numerical': 0.0, 'mean_word_length': 2.0232558139534884, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 25, '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': '4237764', 'n_tokens_mistral': 764, 'n_tokens_neox': 743, 'n_words': 222}