Skip to content
thejohnfreeman edited this page Jan 3, 2013 · 2 revisions

A Generator produces an infinite stream of values. Generators carry a notion of size: they can generate "large" or "small" values.

Whereas an Arbitrary generates a test case but can fail, a Generator generates a single value and never fails. [[arbitrary]] uses Generators to generate each value in a test case.

Generator

concept Generator {
  typedef ... result_type;
  result_type operator() (size_t size);
};
  • typedef ... result_type; The type generated.
  • result_type operator() (size_t size); The generating function. With a default argument for size, types modeling AutoCheck's Generator are very close to modeling standard generators.

AutoCheck provides a standard model for Generator:

template <typename T>
class generator {
  public:
    typedef T result_type;
    result_type operator() (size_t size);
};

generator has a number of specializations for various types, each providing some rich behavior specific to the type:

  • bool -- Generates true and false with equal probability.
  • char, signed char, or unsigned char -- Generates characters. "Small" characters are alphanumeric. Once size exceeds the number of alphanumeric characters, printable characters will be generated. After size outgrows that set, it will generate any character that fits in the type.
  • unsigned short/int/long/long long -- Generates unsigned integers. "Small" integers have an absolute value less than size.
  • signed short/int/long/long long -- Like unsigned integers, but signed.
  • std::vector -- Generates lists. The length of the list and the size of elements within are both determined by size.
  • std::basic_string -- Like std::vector, but with character elements.

Combinators

Although generator is the fixed type for the standard generators, programmers should should always deduce the type of a generator produced by a combinator (through template parameters or auto). All that can be expected is that the resulting type models Generator.

String generator combinators

result_type == std::basic_string<CharType>

enum CharCategory {
  ccAlphaNumeric,
  ccPrintable,
  ccAny
};

template <CharCategory Category = ccPrintable, typename CharType = char>
Generator string();
// Build a string generator from a standard character generator
// for the category and character type.

template <typename CharGen>
Generator string(const CharGen& chargen = CharGen());
// Build a string generator from a custom character generator.

List generator combinators

result_type == std::vector<T>

template <typename T>
Generator list_of();
// Build a list generator from a standard element generator.

template <typename Gen>
Generator list_of(const Gen& gen);
// Build a list generator from a custom element generator.

template <typename T>
Generator ordered_list();
// Build an ordered list generator from a standard element generator.

template <typename Gen>
Generator ordered_list(const Gen& gen);
// Build an ordered list generator from a custom element generator.

Constructed-type generator combinators

These are for building types through a call to a constructor.

result_type == T

template <typename T, typename... Args>
Generator cons();
// Builds a generator for T from standard generators for the types of
// (one of) its constructor's arguments.

template <typename T, typename... Gens>
Generator cons(const Gens&... gens);
// Builds a generator for T from custom generators for the types of
// (one of) its constructor's arguments.
template <typename Func, typename Gen>
Generator map(const Func& func, const Gen& gen);
// Maps a generator's results by passing them through a function.
// Note: the function is passed a non-const reference.
// result_type = std::result_of<Func(Gen::result_type&)>

template <typename Pred, typename Gen>
Generator such_that(const Pred& pred, const Gen& gen);
// Filters a generator's results by testing them with a predicate.

template <typename Resize, typename Gen>
Generator resize(const Resize& resizer, const Gen& gen);
// Transforms a generator's `size` argument. Lets a generator's values
// grow faster or slower than others in the hierarchy.

template <typename Gen>
Generator fix(size_t size, const Gen& gen);
// Fixes a generator's `size` argument to a constant.