<commit_before>#ifndef AUTOCHECK_ARBITRARY_HPP
#define AUTOCHECK_ARBITRARY_HPP

#include <cassert>
#include <cstdio>

#include "function.hpp"
#include "generator.hpp"
#include "value.hpp"
#include "apply.hpp"

namespace autocheck {

  /* Arbitrary produces a finite sequence, always in a tuple, ready for
   * application, and counts discards. */

  template <typename... Gens>
  class arbitrary {
    static_assert(sizeof...(Gens) > 0, "cannot create unit arbitrary");
    public:
      typedef std::tuple<typename Gens::result_type...> result_type;

      typedef typename predicate<typename Gens::result_type...>::type
        discard_t;
      typedef std::function<void (typename Gens::result_type&...)>
        prep_t;

    private:
      std::tuple<Gens...> gens;
      size_t              count;
      size_t              num_discards;
      size_t              max_discards;
      discard_t           discard_f;
      resize_t            resize_f;
      prep_t              prep_f;

    public:
      arbitrary() : arbitrary(Gens()...) {}

      arbitrary(const Gens&... gens) :
        gens(gens...),
        count(0), num_discards(0), max_discards(500),
        discard_f(), resize_f(id()), prep_f()
      {}

      bool operator() (value<result_type>& candidate) {<commit_msg>Work around parameter-pack expansion bugs in MSVC.<commit_after>#ifndef AUTOCHECK_ARBITRARY_HPP
#define AUTOCHECK_ARBITRARY_HPP

#include <cassert>
#include <cstdio>

#include "function.hpp"
#include "generator.hpp"
#include "value.hpp"
#include "apply.hpp"

namespace autocheck {

  /* Arbitrary produces a finite sequence, always in a tuple, ready for
   * application, and counts discards. */

  template <typename... Gens>
  class arbitrary {
    static_assert(sizeof...(Gens) > 0, "cannot create unit arbitrary");

    /* MSVC has difficulty with a direct `Gens...` parameter pack expansion
     * in the 3 public typedefs below, but can be convinced to work with a
     * trivial helper struct. */
    template <typename T> struct ExpandArgs : T {};

    public:
      typedef std::tuple<typename ExpandArgs<Gens>::result_type...> result_type;

      typedef typename predicate<typename ExpandArgs<Gens>::result_type...>::type
        discard_t;
      typedef std::function<void (typename ExpandArgs<Gens>::result_type&...)>
        prep_t;

    private:
      std::tuple<Gens...> gens;
      size_t              count = 0;
      size_t              num_discards = 0;
      size_t              max_discards = 500;
      discard_t           discard_f;
      resize_t            resize_f = id();
      prep_t              prep_f;

    public:
      arbitrary() {}
      arbitrary(const Gens&... gens) : gens(gens...) {}

      bool operator() (value<result_type>& candidate) {
{'fraction_non_alphanumeric': 0.11673292374412722, 'fraction_numerical': 0.0046982291290206, 'mean_word_length': 2.5762273901808785, 'pattern_counts': {'":': 0, '<': 23, '<?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': '7565537', 'n_tokens_mistral': 872, 'n_tokens_neox': 831, 'n_words': 220}