<commit_before>#pragma once
#include "../CoreThread.h"
#include <boost/thread/barrier.hpp>

/// <summary>
/// A simple "decoration" class which will be added to a variety of sample packets
/// </summary>
template<int N>
class Decoration {
public:
  Decoration(void) :
    i(N)
  {}

  int i;
};

// Some simple filters which use the above decoration:
class FilterRoot {
public:
  FilterRoot(void) :
    m_called(false)
  {}

  bool m_called;
  Decoration<0> m_zero;
  Decoration<1> m_one;
};

class FilterA:
  public FilterRoot,
  public ContextMember
{
public:
  FilterA() {}
  virtual ~FilterA() {}
  void AutoFilter(Decoration<0> zero, Decoration<1> one) {
    m_called = true;
    m_zero = zero;
    m_one = one;
  }
};
static_assert(has_autofilter<FilterA>::value, "Expected the filter to have an AutoFilter method");

class FilterB:
  public CoreThread,
  public FilterRoot
{
public:
  FilterB(void) :
    m_barr(2),
    m_excepted(false)
  {}

  Deferred AutoFilter(Decoration<0> zero, Decoration<1> one) {
    m_called = true;
    m_zero = zero;
    m_one = one;
    return Deferred(this);
  }

  boost::barrier m_barr;
  bool m_excepted;

  void Run(void) override {
    m_barr.wait();
    try {
      CoreThread::Run();
    } catch(dispatch_aborted_exception&) {
      // Expected exception type
      throw;
    } catch(...) {
      m_excepted = true;
    }
  }
};

/// <summary>
/// This is a filter which, in addition to accepting a decoration, also accepts a packet and tries to decorate it
/// </summary>
class FilterC:
  public FilterRoot
{
public:
  void AutoFilter(AutoPacket& pkt, const Decoration<0>& zero) {
    // Copy out:
    m_called = true;
    m_zero = zero;

    // Add a decoration:
    pkt.Decorate(Decoration<1>());
  }
};

/// <summary>
/// A filter which will simply get hit any time a packet is issued in the current context
/// </summary>
class FilterD:
  public FilterRoot
{
public:
  void AutoFilter(AutoPacket& pkt) {
    m_called = true;
  }
};

class FilterF:
  public FilterRoot,
  public ContextMember
{
public:
  void AutoFilter(const Decoration<0>& dec) {
    m_called = true;
  }
};

/// <summary>
/// A generic filter which accepts templated input types
/// </summary>
template<class... Args>
class FilterGen {
public:
  FilterGen(void):
    m_called(false)
  {}

  void AutoFilter(AutoPacket& packet, Args... args) {
    bool detection [] = {
      std::is_reference<Args>::value && packet.Has<Args>()...
    };

    for(bool cur : detection)
      ASSERT_FALSE(cur) << "Packet was already decorated with at least one output-only type";

    m_called = true;
    m_args = std::tie(args...);
  }

  bool m_called;
  std::tuple<typename std::remove_reference<Args>::type...> m_args;
};<commit_msg>Generalizing the behavior of the FilterGen type<commit_after>#pragma once
#include "../CoreThread.h"
#include <boost/thread/barrier.hpp>

/// <summary>
/// A simple "decoration" class which will be added to a variety of sample packets
/// </summary>
template<int N>
class Decoration {
public:
  Decoration(int val = N) :
    i(val)
  {}

  int i;
};

// Some simple filters which use the above decoration:
class FilterRoot {
public:
  FilterRoot(void) :
    m_called(false)
  {}

  bool m_called;
  Decoration<0> m_zero;
  Decoration<1> m_one;
};

class FilterA:
  public FilterRoot,
  public ContextMember
{
public:
  FilterA() {}
  virtual ~FilterA() {}
  void AutoFilter(Decoration<0> zero, Decoration<1> one) {
    m_called = true;
    m_zero = zero;
    m_one = one;
  }
};
static_assert(has_autofilter<FilterA>::value, "Expected the filter to have an AutoFilter method");

class FilterB:
  public CoreThread,
  public FilterRoot
{
public:
  FilterB(void) :
    m_barr(2),
    m_excepted(false)
  {}

  Deferred AutoFilter(Decoration<0> zero, Decoration<1> one) {
    m_called = true;
    m_zero = zero;
    m_one = one;
    return Deferred(this);
  }

  boost::barrier m_barr;
  bool m_excepted;

  void Run(void) override {
    m_barr.wait();
    try {
      CoreThread::Run();
    } catch(dispatch_aborted_exception&) {
      // Expected exception type
      throw;
    } catch(...) {
      m_excepted = true;
    }
  }
};

/// <summary>
/// This is a filter which, in addition to accepting a decoration, also accepts a packet and tries to decorate it
/// </summary>
class FilterC:
  public FilterRoot
{
public:
  void AutoFilter(AutoPacket& pkt, const Decoration<0>& zero) {
    // Copy out:
    m_called = true;
    m_zero = zero;

    // Add a decoration:
    pkt.Decorate(Decoration<1>());
  }
};

/// <summary>
/// A filter which will simply get hit any time a packet is issued in the current context
/// </summary>
class FilterD:
  public FilterRoot
{
public:
  void AutoFilter(AutoPacket& pkt) {
    m_called = true;
  }
};

class FilterF:
  public FilterRoot,
  public ContextMember
{
public:
  void AutoFilter(const Decoration<0>& dec) {
    m_called = true;
  }
};

/// <summary>
/// A generic filter which accepts templated input types
/// </summary>
template<class... Args>
class FilterGen {
public:
  FilterGen(void):
    m_called(false)
  {}

  void AutoFilter(AutoPacket& packet, Args... args) {
    // Detect cases where a non-const reference is already decorated on the input packet
    bool detection [] = {
      !std::is_const<typename std::remove_reference<Args>::type>::value &&
      std::is_reference<Args>::value &&
      packet.Has<Args>()...
    };

    for(bool cur : detection)
      ASSERT_FALSE(cur) << "Packet was already decorated with at least one output-only type";

    m_called = true;
    m_args = std::tie(args...);
  }

  bool m_called;
  std::tuple<typename std::decay<Args>::type...> m_args;
};
{'fraction_non_alphanumeric': 0.13172704889201547, 'fraction_numerical': 0.0035174111853675696, 'mean_word_length': 3.151094890510949, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 55, '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': '5076882', 'n_tokens_mistral': 1913, 'n_tokens_neox': 1894, 'n_words': 533}