1//
2// immer: immutable data structures for C++
3// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente
4//
5// This software is distributed under the Boost Software License, Version 1.0.
6// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt
7//
8
9#pragma once
10
11#include <stdexcept>
12#include <cstdint>
13
14struct no_more_input : std::exception {};
15
16struct fuzzer_input
17{
18 const std::uint8_t* data_;
19 std::size_t size_;
20
21 const std::uint8_t* next(std::size_t size)
22 {
23 if (size_ < size) throw no_more_input{};
24 auto r = data_;
25 data_ += size;
26 size_ -= size;
27 return r;
28 }
29
30 const std::uint8_t* next(std::size_t size, std::size_t align)
31 {
32 auto rem = size % align;
33 if (rem) next(align - rem);
34 return next(size);
35 }
36
37 template <typename Fn>
38 int run(Fn step)
39 {
40 try {
41 while (step(*this));
42 } catch (const no_more_input&) {};
43 return 0;
44 }
45};
46
47template <typename T>
48const T& read(fuzzer_input& fz)
49{
50 return *reinterpret_cast<const T*>(fz.next(sizeof(T), alignof(T)));
51}
52
53template <typename T, typename Cond>
54T read(fuzzer_input& fz, Cond cond)
55{
56 auto x = read<T>(fz);
57 return cond(x)
58 ? x
59 : read<T>(fz, cond);
60}
61