<commit_before>#ifndef SILICIUM_DELEGATOR_GENERATE_HPP
#define SILICIUM_DELEGATOR_GENERATE_HPP

// enclosing namespace struct:

#define DELEGATOR_TEMPLATE(...) template <__VA_ARGS__>
#define DELEGATOR_NAME(name)                                                                                           \
	struct name                                                                                                        \
	{
#define DELEGATOR_TYPEDEF(...) __VA_ARGS__
#define DELEGATOR_BASIC_METHOD(name, constness, result, ...)

#include DELEGATOR_INCLUDE

#undef DELEGATOR_TEMPLATE
#undef DELEGATOR_NAME
#undef DELEGATOR_TYPEDEF
#undef DELEGATOR_BASIC_METHOD

// abstract base class:

#define DELEGATOR_TEMPLATE(...)
#define DELEGATOR_NAME(name)                                                                                           \
	struct abstract_base                                                                                               \
	{                                                                                                                  \
		virtual ~abstract_base()                                                                                       \
		{                                                                                                              \
		}
#define DELEGATOR_TYPEDEF(...) __VA_ARGS__
#define DELEGATOR_BASIC_METHOD(name, constness, result, ...) virtual auto name(__VA_ARGS__) constness->result = 0;

#include DELEGATOR_INCLUDE
}
;

#undef DELEGATOR_TEMPLATE
#undef DELEGATOR_NAME
#undef DELEGATOR_TYPEDEF
#undef DELEGATOR_BASIC_METHOD

// eraser:

#define DELEGATOR_TEMPLATE(...)
#define DELEGATOR_NAME(name)                                                                                           \
	template <class Impl>                                                                                              \
	struct eraser : abstract_base                                                                                      \
	{                                                                                                                  \
		explicit eraser(Impl impl)                                                                                     \
		    : m_impl(std::move(impl))                                                                                  \
		{                                                                                                              \
		}                                                                                                              \
                                                                                                                       \
	private:                                                                                                           \
		Impl m_impl;                                                                                                   \
                                                                                                                       \
	public:
#define DELEGATOR_TYPEDEF(...)
#define DELEGATOR_BASIC_METHOD_DETAIL_PARAMETER(r, data, i, elem) elem BOOST_PP_CAT(arg, i)
#define DELEGATOR_BASIC_METHOD_DETAIL_FORWARD(r, data, i, elem) std::forward<elem>(BOOST_PP_CAT(arg, i))
#define DELEGATOR_BASIC_METHOD(name, constness, result, ...)                                                           \
	virtual auto name(                                                                                                 \
	    BOOST_PP_LIST_FOR_EACH_I(DELEGATOR_BASIC_METHOD_DETAIL_PARAMETER, _, BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)))  \
	    constness->result SILICIUM_OVERRIDE                                                                            \
	{                                                                                                                  \
		return m_impl.name(BOOST_PP_LIST_FOR_EACH_I(DELEGATOR_BASIC_METHOD_DETAIL_FORWARD, _,                          \
		                                            BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)));                          \
	}

#include DELEGATOR_INCLUDE
}
;

template <class Impl>
static eraser<typename std::decay<Impl>::type> erase(Impl &&impl)
{
	return eraser<typename std::decay<Impl>::type>(std::forward<Impl>(impl));
}

#undef DELEGATOR_TEMPLATE
#undef DELEGATOR_NAME
#undef DELEGATOR_TYPEDEF
#undef DELEGATOR_BASIC_METHOD_DETAIL_PARAMETER
#undef DELEGATOR_BASIC_METHOD_DETAIL_FORWARD
#undef DELEGATOR_BASIC_METHOD

struct fat_ref
{
	template <class Impl>
	explicit fat_ref(Impl &impl)
	    : m_impl(&impl)
	{
		// initialize the vtable<commit_msg>avoid trailing return type for GCC 4.7<commit_after>#ifndef SILICIUM_DELEGATOR_GENERATE_HPP
#define SILICIUM_DELEGATOR_GENERATE_HPP

// enclosing namespace struct:

#define DELEGATOR_TEMPLATE(...) template <__VA_ARGS__>
#define DELEGATOR_NAME(name)                                                                                           \
	struct name                                                                                                        \
	{
#define DELEGATOR_TYPEDEF(...) __VA_ARGS__
#define DELEGATOR_BASIC_METHOD(name, constness, result, ...)

#include DELEGATOR_INCLUDE

#undef DELEGATOR_TEMPLATE
#undef DELEGATOR_NAME
#undef DELEGATOR_TYPEDEF
#undef DELEGATOR_BASIC_METHOD

// abstract base class:

#define DELEGATOR_TEMPLATE(...)
#define DELEGATOR_NAME(name)                                                                                           \
	struct abstract_base                                                                                               \
	{                                                                                                                  \
		virtual ~abstract_base()                                                                                       \
		{                                                                                                              \
		}
#define DELEGATOR_TYPEDEF(...) __VA_ARGS__
#define DELEGATOR_BASIC_METHOD(name, constness, result, ...) virtual auto name(__VA_ARGS__) constness->result = 0;

#include DELEGATOR_INCLUDE
}
;

#undef DELEGATOR_TEMPLATE
#undef DELEGATOR_NAME
#undef DELEGATOR_TYPEDEF
#undef DELEGATOR_BASIC_METHOD

// eraser:

#define DELEGATOR_TEMPLATE(...)
#define DELEGATOR_NAME(name)                                                                                           \
	template <class Impl>                                                                                              \
	struct eraser : abstract_base                                                                                      \
	{                                                                                                                  \
		explicit eraser(Impl impl)                                                                                     \
		    : m_impl(std::move(impl))                                                                                  \
		{                                                                                                              \
		}                                                                                                              \
                                                                                                                       \
	private:                                                                                                           \
		Impl m_impl;                                                                                                   \
                                                                                                                       \
	public:
#define DELEGATOR_TYPEDEF(...)
#define DELEGATOR_BASIC_METHOD_DETAIL_PARAMETER(r, data, i, elem) elem BOOST_PP_CAT(arg, i)
#define DELEGATOR_BASIC_METHOD_DETAIL_FORWARD(r, data, i, elem) std::forward<elem>(BOOST_PP_CAT(arg, i))
#define DELEGATOR_BASIC_METHOD(name, constness, result, ...)                                                           \
	virtual result name(BOOST_PP_LIST_FOR_EACH_I(DELEGATOR_BASIC_METHOD_DETAIL_PARAMETER, _,                           \
	                                             BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__))) constness SILICIUM_OVERRIDE  \
	{                                                                                                                  \
		return m_impl.name(BOOST_PP_LIST_FOR_EACH_I(DELEGATOR_BASIC_METHOD_DETAIL_FORWARD, _,                          \
		                                            BOOST_PP_VARIADIC_TO_LIST(__VA_ARGS__)));                          \
	}

#include DELEGATOR_INCLUDE
}
;

template <class Impl>
static eraser<typename std::decay<Impl>::type> erase(Impl &&impl)
{
	return eraser<typename std::decay<Impl>::type>(std::forward<Impl>(impl));
}

#undef DELEGATOR_TEMPLATE
#undef DELEGATOR_NAME
#undef DELEGATOR_TYPEDEF
#undef DELEGATOR_BASIC_METHOD_DETAIL_PARAMETER
#undef DELEGATOR_BASIC_METHOD_DETAIL_FORWARD
#undef DELEGATOR_BASIC_METHOD

struct fat_ref
{
	template <class Impl>
	explicit fat_ref(Impl &impl)
	    : m_impl(&impl)
	{
		// initialize the vtable
{'fraction_non_alphanumeric': 0.055814963622543165, 'fraction_numerical': 0.0004343576935606472, 'mean_word_length': 0.7593123209169055, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 187, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6251746', 'n_tokens_mistral': 1969, 'n_tokens_neox': 1880, 'n_words': 308}