<commit_before>#ifndef SRC_PORTS_CONNECTION_BUFFER_HPP_
#define SRC_PORTS_CONNECTION_BUFFER_HPP_

#include <functional>
#include <memory>

#include <flexcore/pure/pure_ports.hpp>
#include <flexcore/extended/ports/token_tags.hpp>

namespace fc
{

/**
 * \brief common interface of nodes serving as buffers within connections.
 *
 * Classes implementing this are independent of the way they implement buffering.
 * Classes might even directly forward events.
 *
 * \tparam event_t type of tokens passing through the buffer
 */
template<class token_t, class tag>
struct buffer_interface
{
	typedef typename pure::out_port<token_t, tag>::type out_port_t;
	typedef typename pure::in_port<token_t, tag>::type in_port_t;

	buffer_interface() = default;
	virtual ~buffer_interface() = default;

	///input port for events, expects event_t
	virtual in_port_t& in() = 0;
	///output port for events, sends event_t
	virtual out_port_t& out() = 0;

	buffer_interface(const buffer_interface&) = delete;
	buffer_interface& operator= (const buffer_interface &) = delete;
};

/// Implementation of buffer_interface, which directly forwards events.
template<class token_t, class tag = event_tag>
class event_no_buffer final : public buffer_interface<token_t, tag>
{
public:
	event_no_buffer()	:
		in_event_port( [this](token_t in_event) { out_event_port.fire(in_event);})
	{
	}

	typename pure::in_port<token_t, tag>::type& in() override
	{
		return in_event_port;
	}
	typename pure::out_port<token_t, tag>::type& out() override
	{
		return out_event_port;
	}

private:
	typename pure::in_port<token_t, tag>::type in_event_port;
	typename pure::out_port<token_t, tag>::type out_event_port;
};

/// Partial Specialization for events of type void
template<class tag>
class event_no_buffer<void, tag> final : public buffer_interface<void, tag>
{
public:
	event_no_buffer()	:
		//only difference to template is here
		in_event_port( [this]() { out_event_port.fire();})
	{
	}

	typename pure::in_port<void, tag>::type& in() override
	{
		return in_event_port;
	}
	typename pure::out_port<void, tag>::type& out() override
	{
		return out_event_port;
	}

private:
	typename pure::in_port<void, tag>::type in_event_port;
	typename pure::out_port<void, tag>::type out_event_port;
};

/**
 * \brief buffer for events using double buffering
 *
 * Stores events of event_t in two buffers.
 * Switches Buffers on receiving switch_tick.
 * This moves events from internal to external buffer.
 * New events are added to to the internal buffer.
 * Events from the external buffer are fired on receiving send tick.
 */
template<class event_t>
class event_buffer : public buffer_interface<event_t, event_tag>
{<commit_msg>ports: Remove event_no_buffer<void> spec. by using variadic lambda<commit_after>#ifndef SRC_PORTS_CONNECTION_BUFFER_HPP_
#define SRC_PORTS_CONNECTION_BUFFER_HPP_

#include <functional>
#include <memory>

#include <flexcore/pure/pure_ports.hpp>
#include <flexcore/extended/ports/token_tags.hpp>

namespace fc
{

/**
 * \brief common interface of nodes serving as buffers within connections.
 *
 * Classes implementing this are independent of the way they implement buffering.
 * Classes might even directly forward events.
 *
 * \tparam event_t type of tokens passing through the buffer
 */
template<class token_t, class tag>
struct buffer_interface
{
	typedef typename pure::out_port<token_t, tag>::type out_port_t;
	typedef typename pure::in_port<token_t, tag>::type in_port_t;

	buffer_interface() = default;
	virtual ~buffer_interface() = default;

	///input port for events, expects event_t
	virtual in_port_t& in() = 0;
	///output port for events, sends event_t
	virtual out_port_t& out() = 0;

	buffer_interface(const buffer_interface&) = delete;
	buffer_interface& operator= (const buffer_interface &) = delete;
};

/// Implementation of buffer_interface, which directly forwards events.
template<class token_t, class tag = event_tag>
class event_no_buffer final : public buffer_interface<token_t, tag>
{
public:
	event_no_buffer()
	    : in_event_port([this](auto&&... in_event)
	                    {
		                    out_event_port.fire(std::forward<decltype(in_event)>(in_event)...);
	                    })
	{
	}

	typename pure::in_port<token_t, tag>::type& in() override
	{
		return in_event_port;
	}
	typename pure::out_port<token_t, tag>::type& out() override
	{
		return out_event_port;
	}

private:
	typename pure::in_port<token_t, tag>::type in_event_port;
	typename pure::out_port<token_t, tag>::type out_event_port;
};

/**
 * \brief buffer for events using double buffering
 *
 * Stores events of event_t in two buffers.
 * Switches Buffers on receiving switch_tick.
 * This moves events from internal to external buffer.
 * New events are added to to the internal buffer.
 * Events from the external buffer are fired on receiving send tick.
 */
template<class event_t>
class event_buffer : public buffer_interface<event_t, event_tag>
{
{'fraction_non_alphanumeric': 0.10226354082457559, 'fraction_numerical': 0.0008084074373484236, 'mean_word_length': 4.991525423728813, 'pattern_counts': {'":': 0, '<': 42, '<?xml version=': 0, '>': 42, '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': '4220393', 'n_tokens_mistral': 1615, 'n_tokens_neox': 1548, 'n_words': 456}