| // 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 |