// // immer: immutable data structures for C++ // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente // // This software is distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt // #pragma once #include #include #include #if defined(__GNUC__) && (__GNUC__ == 9 || __GNUC__ == 8 || __GNUC__ == 10) #define IMMER_DISABLE_FUZZER_DUE_TO_GCC_BUG 1 #endif struct no_more_input : std::exception {}; constexpr auto fuzzer_input_max_size = 1 << 16; struct fuzzer_input { const std::uint8_t* data_; std::size_t size_; const std::uint8_t* next(std::size_t size) { if (size_ < size) throw no_more_input{}; auto r = data_; data_ += size; size_ -= size; return r; } const std::uint8_t* next(std::size_t size, std::size_t align) { auto& p = const_cast(reinterpret_cast(data_)); auto r = std::align(align, size, p, size_); if (r == nullptr) throw no_more_input{}; return next(size); } template int run(Fn step) { if (size_ > fuzzer_input_max_size) return 0; try { while (step(*this)) continue; } catch (const no_more_input&) {}; return 0; } }; template const T& read(fuzzer_input& fz) { return *reinterpret_cast(fz.next(sizeof(T), alignof(T))); } template T read(fuzzer_input& fz, Cond cond) { auto x = read(fz); while (!cond(x)) x = read(fz); return x; }