/* * Copyright (C) 2006-2021 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #pragma once #include #include namespace WTF { class AbstractLocker; class AtomString; class AtomStringImpl; class BinarySemaphore; class CString; class CrashOnOverflow; class FunctionDispatcher; class Hasher; class Lock; class Logger; class MonotonicTime; class OrdinalNumber; class PrintStream; class SHA1; class Seconds; class String; class StringBuilder; class StringImpl; class StringView; class SuspendableWorkQueue; class TextPosition; class TextStream; class UniquedStringImpl; class URL; class WallTime; struct AnyThreadsAccessTraits; struct EmptyCounter; struct FastMalloc; struct MainThreadAccessTraits; #if ENABLE(MALLOC_HEAP_BREAKDOWN) struct VectorMalloc; #else using VectorMalloc = FastMalloc; #endif template struct DefaultRefDerefTraits; template class CompletionHandler; template class FixedVector; template class Function; template class LazyNeverDestroyed; template class NeverDestroyed; template class OptionSet; template class Packed; template class PackedAlignedPtr; template struct RawPtrTraits; template> class CheckedRef; template> class CheckedPtr; template> class Ref; template, typename = DefaultRefDerefTraits> class RefPtr; template class RetainPtr; template class ScopedLambda; template class StringBuffer; template class StringParsingBuffer; template class StringTypeAdapter; template class UniqueRef; template class Variant; template class Vector; template class WeakPtr; template struct DefaultHash; template<> struct DefaultHash; template struct DefaultHash>; template<> struct DefaultHash; template<> struct DefaultHash; template<> struct DefaultHash; template struct DefaultHash>; template struct RawValueTraits; template struct EnumTraits; template struct EnumValues; template struct HashTraits; struct HashTableTraits; struct IdentityExtractor; template struct KeyValuePairKeyExtractor; template struct KeyValuePairTraits; template struct KeyValuePair; template class HashTable; template, typename = HashTraits> class HashCountedSet; template, typename = HashTraits, typename = HashTraits, typename = HashTableTraits> class HashMap; template, typename = HashTraits, typename = HashTableTraits> class HashSet; } namespace std { namespace experimental { inline namespace fundamentals_v3 { template class expected; template class unexpected; }}} // namespace std::experimental::fundamentals_v3 using WTF::AbstractLocker; using WTF::AtomString; using WTF::AtomStringImpl; using WTF::BinarySemaphore; using WTF::CString; using WTF::CompletionHandler; using WTF::FixedVector; using WTF::Function; using WTF::FunctionDispatcher; using WTF::HashCountedSet; using WTF::HashMap; using WTF::HashSet; using WTF::Hasher; using WTF::LazyNeverDestroyed; using WTF::Lock; using WTF::Logger; using WTF::NeverDestroyed; using WTF::OptionSet; using WTF::OrdinalNumber; using WTF::PrintStream; using WTF::RawPtrTraits; using WTF::RawValueTraits; using WTF::Ref; using WTF::RefPtr; using WTF::RetainPtr; using WTF::SHA1; using WTF::ScopedLambda; using WTF::String; using WTF::StringBuffer; using WTF::StringBuilder; using WTF::StringImpl; using WTF::StringParsingBuffer; using WTF::StringView; using WTF::SuspendableWorkQueue; using WTF::TextPosition; using WTF::TextStream; using WTF::URL; using WTF::UniqueRef; using WTF::Variant; using WTF::Vector; template using Expected = std::experimental::expected; template using Unexpected = std::experimental::unexpected; // Sometimes an inline method simply forwards to another one and does nothing else. If it were // just a forward declaration of that method then you would only need a forward declaration of // its return types and parameter types too, but because it's inline and it actually needs to // return / pass these types (even though it's just passing through whatever it called) you // now find yourself having to actually have a full declaration of these types. That might be // an include you'd rather avoid. // // No more. Enter template magic to lazily instantiate that method! // // This macro makes the method work as if you'd declared the return / parameter types as normal, // but forces lazy instantiation of the method at the call site, at which point the caller (not // the declaration) had better have a full declaration of the return / parameter types. // // Simply pass the forward-declared types to the macro, with an alias for each, and then define // your function as you otherwise would have but using the aliased name. Why the alias? So you // can be lazy on templated types! Sample usage: // // struct Foo; // No need to define Foo! // template // struct A { // Foo declared(Bar); // Forward declarations of Foo and Bar are sufficient here. // // The below code would normally require a definition of Foo and Bar. // WTF_LAZY_INSTANTIATE(Foo=Foo, Bar=Bar) Foo forwarder(Bar b) { return declared(b); } // }; #define WTF_LAZY_JOIN_UNLAZE(A, B) A##B #define WTF_LAZY_JOIN(A, B) WTF_LAZY_JOIN_UNLAZE(A, B) #define WTF_LAZY_ARGUMENT_NUMBER(_1, _2, _3, _4, _5, _6, _7, _8, N, ...) N #define WTF_LAZY_AUGMENT(...) unused, __VA_ARGS__ #define WTF_LAZY_EXPAND(x) x #define WTF_LAZY_NUM_ARGS_(...) WTF_LAZY_EXPAND(WTF_LAZY_ARGUMENT_NUMBER(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0)) #define WTF_LAZY_NUM_ARGS(...) WTF_LAZY_NUM_ARGS_(WTF_LAZY_AUGMENT(__VA_ARGS__)) #define WTF_LAZY_FOR_EACH_TERM(F, ...) \ WTF_LAZY_JOIN(WTF_LAZY_FOR_EACH_TERM_, WTF_LAZY_NUM_ARGS(__VA_ARGS__))(F, (__VA_ARGS__)) #define WTF_LAZY_FIRST(_1, ...) _1 #define WTF_LAZY_REST(_1, ...) (__VA_ARGS__) #define WTF_LAZY_REST_(_1, ...) __VA_ARGS__ #define WTF_LAZY_CALL(F, ARG) F(ARG) #define WTF_LAZY_FOR_EACH_TERM_0(...) #define WTF_LAZY_FOR_EACH_TERM_1(F, ARGS) WTF_LAZY_CALL(F, WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_0(F, WTF_LAZY_REST ARGS) #define WTF_LAZY_FOR_EACH_TERM_2(F, ARGS) WTF_LAZY_CALL(F, WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_1(F, WTF_LAZY_REST ARGS) #define WTF_LAZY_FOR_EACH_TERM_3(F, ARGS) WTF_LAZY_CALL(F, WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_2(F, WTF_LAZY_REST ARGS) #define WTF_LAZY_FOR_EACH_TERM_4(F, ARGS) WTF_LAZY_CALL(F, WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_3(F, WTF_LAZY_REST ARGS) #define WTF_LAZY_FOR_EACH_TERM_5(F, ARGS) WTF_LAZY_CALL(F, WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_4(F, WTF_LAZY_REST ARGS) #define WTF_LAZY_FOR_EACH_TERM_6(F, ARGS) WTF_LAZY_CALL(F, WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_5(F, WTF_LAZY_REST ARGS) #define WTF_LAZY_FOR_EACH_TERM_7(F, ARGS) WTF_LAZY_CALL(F, WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_6(F, WTF_LAZY_REST ARGS) #define WTF_LAZY_DECLARE_ALIAS_AND_TYPE(ALIAS_AND_TYPE) typename ALIAS_AND_TYPE, #define WTF_LAZY_INSTANTIATE(...) \ template< \ WTF_LAZY_FOR_EACH_TERM(WTF_LAZY_DECLARE_ALIAS_AND_TYPE, __VA_ARGS__) \ typename = void> #define WTF_LAZY_HAS_REST_0(...) #define WTF_LAZY_HAS_REST_1(...) #define WTF_LAZY_HAS_REST_2 WTF_LAZY_EXPAND #define WTF_LAZY_HAS_REST_3 WTF_LAZY_EXPAND #define WTF_LAZY_HAS_REST_4 WTF_LAZY_EXPAND #define WTF_LAZY_HAS_REST_5 WTF_LAZY_EXPAND #define WTF_LAZY_HAS_REST_6 WTF_LAZY_EXPAND #define WTF_LAZY_HAS_REST_7 WTF_LAZY_EXPAND #define WTF_LAZY_HAS_REST_8 WTF_LAZY_EXPAND #define WTF_LAZY_HAS_REST(...) \ WTF_LAZY_JOIN(WTF_LAZY_HAS_REST_, WTF_LAZY_NUM_ARGS(__VA_ARGS__))