Changeset 230109 in webkit


Ignore:
Timestamp:
Mar 30, 2018, 10:36:20 AM (7 years ago)
Author:
jfbastien@apple.com
Message:

Introduce WTF_LAZY_INSTANTIATE
https://bugs.webkit.org/show_bug.cgi?id=184169
<rdar://problem/39023385>

Reviewed by Mark Lam.

As part of #184164 I'm adding some forwarding methods to
WTF::String. These need to forward RetainPtr and CString, and
usually that would require #include'ing RetainPtr.h and CString.h
to WTFString.h which isn't really something we should do.

Introduce WTF_LAZY_INSTANTIATE to forward-declare functions which
just pass parameters to another function, and return whatever that
other function returned, without having to include the return's /
parameters' type header.

Try it out here: godbolt.org/g/oV8G5Q

  • wtf/Forward.h:
Location:
trunk/Source/WTF
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r230097 r230109  
     12018-03-30  JF Bastien  <jfbastien@apple.com>
     2
     3        Introduce WTF_LAZY_INSTANTIATE
     4        https://bugs.webkit.org/show_bug.cgi?id=184169
     5        <rdar://problem/39023385>
     6
     7        Reviewed by Mark Lam.
     8
     9        As part of #184164 I'm adding some forwarding methods to
     10        WTF::String. These need to forward RetainPtr and CString, and
     11        usually that would require #include'ing RetainPtr.h and CString.h
     12        to WTFString.h which isn't really something we should do.
     13
     14        Introduce WTF_LAZY_INSTANTIATE to forward-declare functions which
     15        just pass parameters to another function, and return whatever that
     16        other function returned, without having to include the return's /
     17        parameters' type header.
     18
     19        Try it out here: godbolt.org/g/oV8G5Q
     20
     21        * wtf/Forward.h:
     22
    1232018-03-29  JF Bastien  <jfbastien@apple.com>
    224
  • trunk/Source/WTF/wtf/Forward.h

    r230097 r230109  
    115115template<class T, class E> using Expected = std::experimental::expected<T, E>;
    116116template<class E> using Unexpected = std::experimental::unexpected<E>;
     117
     118// Sometimes an inline method simply forwards to another one and does nothing else. If it were
     119// just a forward declaration of that method then you would only need a forward declaration of
     120// its return types and parameter types too, but because it's inline and it actually needs to
     121// return / pass these types (even though it's just passing through whatever it called) you
     122// now find yourself having to actually have a full declaration of these types. That might be
     123// an include you'd rather avoid.
     124//
     125// No more. Enter template magic to lazily instantiate that method!
     126//
     127// This macro makes the method work as if you'd declared the return / parameter types as normal,
     128// but forces lazy instantiation of the method at the call site, at which point the caller (not
     129// the declaration) had better have a full declaration of the return / parameter types.
     130//
     131// Simply pass the forward-declared types to the macro, with an alias for each, and then define
     132// your function as you otherwise would have but using the aliased name. Why the alias? So you
     133// can be lazy on templated types! Sample usage:
     134//
     135// struct Foo; // No need to define Foo!
     136// template<typename T>
     137// struct A {
     138//     Foo declared(Bar); // Forward declarations of Foo and Bar are sufficient here.
     139//     // The below code would normally require a definition of Foo and Bar.
     140//     WTF_LAZY_INSTANTIATE(Foo=Foo, Bar=Bar) Foo forwarder(Bar b) { return declared(b); }
     141// };
     142#define WTF_LAZY_JOIN_UNLAZE(A, B) A##B
     143#define WTF_LAZY_JOIN(A, B) WTF_LAZY_JOIN_UNLAZE(A, B)
     144#define WTF_LAZY_ARGUMENT_NUMBER(_1, _2, _3, _4, _5, _6, _7, N, ...) N
     145#define WTF_LAZY_REVERSE_SEQUENCE() 7, 6, 5, 4, 3, 2, 1, 0
     146#define WTF_LAZY_NUM_ARGS_(...) WTF_LAZY_ARGUMENT_NUMBER(__VA_ARGS__)
     147#define WTF_LAZY_NUM_ARGS(...) WTF_LAZY_NUM_ARGS_(__VA_ARGS__, WTF_LAZY_REVERSE_SEQUENCE())
     148#define WTF_LAZY_FOR_EACH_TERM(F, ...) \
     149    WTF_LAZY_JOIN(WTF_LAZY_FOR_EACH_TERM_, WTF_LAZY_NUM_ARGS(__VA_ARGS__))(F, (__VA_ARGS__))
     150#define WTF_LAZY_FIRST(_1, ...) _1
     151#define WTF_LAZY_REST(_1, ...) (__VA_ARGS__)
     152#define WTF_LAZY_FOR_EACH_TERM_0(...)
     153#define WTF_LAZY_FOR_EACH_TERM_1(F, ARGS) F(WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_0(F, WTF_LAZY_REST ARGS)
     154#define WTF_LAZY_FOR_EACH_TERM_2(F, ARGS) F(WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_1(F, WTF_LAZY_REST ARGS)
     155#define WTF_LAZY_FOR_EACH_TERM_3(F, ARGS) F(WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_2(F, WTF_LAZY_REST ARGS)
     156#define WTF_LAZY_FOR_EACH_TERM_4(F, ARGS) F(WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_3(F, WTF_LAZY_REST ARGS)
     157#define WTF_LAZY_FOR_EACH_TERM_5(F, ARGS) F(WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_4(F, WTF_LAZY_REST ARGS)
     158#define WTF_LAZY_FOR_EACH_TERM_6(F, ARGS) F(WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_5(F, WTF_LAZY_REST ARGS)
     159#define WTF_LAZY_FOR_EACH_TERM_7(F, ARGS) F(WTF_LAZY_FIRST ARGS) WTF_LAZY_FOR_EACH_TERM_6(F, WTF_LAZY_REST ARGS)
     160#define WTF_LAZY_DECLARE_ALIAS_AND_TYPE(ALIAS_AND_TYPE) typename ALIAS_AND_TYPE,
     161#define WTF_LAZY_INSTANTIATE(...)                                        \
     162    template<                                                            \
     163    WTF_LAZY_FOR_EACH_TERM(WTF_LAZY_DECLARE_ALIAS_AND_TYPE, __VA_ARGS__) \
     164    typename = void>
Note: See TracChangeset for help on using the changeset viewer.