blob: a7ddc6e1798f93ae251e43ddfe0568867dcbdcfa [file] [log] [blame]
// Copyright 2023 The Pigweed Authors
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy of
// the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations under
// the License.
#pragma once
/// @file fuzztest.h
/// Stubs for the FuzzTest interface
///
/// @rst
/// .. warning::
/// This header depends on portions of the standard library that may not
/// supported on your device!
///
/// This header provides stubs for the full FuzzTest interface, including
/// `macros`_ and `domains`_ that include C++ standard library `headers`_ that
/// are not permitted in Pigweed. It should only be used in downstream projects
/// that support the full standard library on both host and device. It should
/// never be used in core Pigweed.
///
/// If possible, consider including ``pw_fuzzer/fuzztest.h`` instead.
///
/// This header is included when FuzzTest is disabled, e.g. for GN, when
/// ``dir_pw_third_party_fuzztest`` or ``pw_toolchain_FUZZING_ENABLED`` are not
/// set. Otherwise, ``$dir_pw_third_party_fuzztest/fuzztest.h`` is used instead.
///
/// .. _domains:
/// https://github.com/google/fuzztest/blob/main/doc/domains-reference.md
/// .. _headers: https://pigweed.dev/docs/style_guide.html#permitted-headers
/// .. _macros:
/// https://github.com/google/fuzztest/blob/main/doc/fuzz-test-macro.md
/// @endrst
#include <deque>
#include <list>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "pw_fuzzer/internal/fuzztest.h"
namespace fuzztest {
// This namespace is here only as a way to disable ADL (argument-dependent
// lookup). Names should be used from the fuzztest:: namespace.
namespace internal_no_adl {
template <typename T>
auto ElementOf(std::vector<T>) {
return internal::Domain<T>{};
}
inline auto String() { return Arbitrary<std::string>(); }
template <int&... ExplicitArgumentBarrier, typename T>
inline auto StringOf(internal::Domain<T> inner) {
return ContainerOf<std::string>(std::move(inner));
}
inline auto AsciiString() { return StringOf(AsciiChar()); }
inline auto PrintableAsciiString() { return StringOf(PrintableAsciiChar()); }
template <template <typename> class Ptr,
int&... ExplicitArgumentBarrier,
typename T>
auto SmartPointerOf(internal::Domain<T>) {
return internal::Domain<Ptr<T>>{};
}
template <int&... ExplicitArgumentBarrier, typename T>
auto UniquePtrOf(internal::Domain<T>) {
return internal::Domain<std::unique_ptr<T>>{};
}
template <int&... ExplicitArgumentBarrier, typename T>
auto SharedPtrOf(internal::Domain<T>) {
return internal::Domain<std::shared_ptr<T>>{};
}
template <int&... ExplicitArgumentBarrier, typename T>
auto VectorOf(internal::Domain<T> inner) {
return ContainerOf<std::vector<T>>(std::move(inner));
}
template <int&... ExplicitArgumentBarrier, typename T>
auto DequeOf(internal::Domain<T> inner) {
return ContainerOf<std::deque<T>>(std::move(inner));
}
template <int&... ExplicitArgumentBarrier, typename T>
auto ListOf(internal::Domain<T> inner) {
return ContainerOf<std::list<T>>(std::move(inner));
}
template <int&... ExplicitArgumentBarrier, typename T>
auto SetOf(internal::Domain<T> inner) {
return ContainerOf<std::set<T>>(std::move(inner));
}
template <int&... ExplicitArgumentBarrier, typename K, typename V>
auto MapOf(internal::Domain<K> keys, internal::Domain<V> values) {
return ContainerOf<std::map<K, V>>(
PairOf(std::move(keys), std::move(values)));
}
template <int&... ExplicitArgumentBarrier, typename T>
auto UnorderedSetOf(internal::Domain<T> inner) {
return ContainerOf<std::unordered_set<T>>(std::move(inner));
}
template <int&... ExplicitArgumentBarrier, typename K, typename V>
auto UnorderedMapOf(internal::Domain<K> keys, internal::Domain<V> values) {
return ContainerOf<std::unordered_map<K, V>>(
PairOf(std::move(keys), std::move(values)));
}
template <typename T>
auto UniqueElementsVectorOf(internal::Domain<T> inner) {
return VectorOf(std::move(inner));
}
template <typename P,
typename T = std::remove_cv_t<
std::remove_pointer_t<decltype(std::declval<P>()())>>>
auto ProtobufOf(P) {
return internal::Domain<std::unique_ptr<T>>{};
}
} // namespace internal_no_adl
// Inject the names from internal_no_adl into fuzztest, without allowing for
// ADL. Note that an `inline` namespace would not have this effect (ie it would
// still allow ADL to trigger).
using namespace internal_no_adl; // NOLINT
} // namespace fuzztest