| 1 | // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors | 
|---|
| 2 | // Licensed under the MIT License: | 
|---|
| 3 | // | 
|---|
| 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy | 
|---|
| 5 | // of this software and associated documentation files (the "Software"), to deal | 
|---|
| 6 | // in the Software without restriction, including without limitation the rights | 
|---|
| 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | 
|---|
| 8 | // copies of the Software, and to permit persons to whom the Software is | 
|---|
| 9 | // furnished to do so, subject to the following conditions: | 
|---|
| 10 | // | 
|---|
| 11 | // The above copyright notice and this permission notice shall be included in | 
|---|
| 12 | // all copies or substantial portions of the Software. | 
|---|
| 13 | // | 
|---|
| 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | 
|---|
| 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | 
|---|
| 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | 
|---|
| 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | 
|---|
| 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | 
|---|
| 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | 
|---|
| 20 | // THE SOFTWARE. | 
|---|
| 21 |  | 
|---|
| 22 | #pragma once | 
|---|
| 23 |  | 
|---|
| 24 | #if defined(__GNUC__) && !KJ_HEADER_WARNINGS | 
|---|
| 25 | #pragma GCC system_header | 
|---|
| 26 | #endif | 
|---|
| 27 |  | 
|---|
| 28 | #include "memory.h" | 
|---|
| 29 |  | 
|---|
| 30 | namespace kj { | 
|---|
| 31 |  | 
|---|
| 32 | template <typename Signature> | 
|---|
| 33 | class Function; | 
|---|
| 34 | // Function wrapper using virtual-based polymorphism.  Use this when template polymorphism is | 
|---|
| 35 | // not possible.  You can, for example, accept a Function as a parameter: | 
|---|
| 36 | // | 
|---|
| 37 | //     void setFilter(Function<bool(const Widget&)> filter); | 
|---|
| 38 | // | 
|---|
| 39 | // The caller of `setFilter()` may then pass any callable object as the parameter.  The callable | 
|---|
| 40 | // object does not have to have the exact signature specified, just one that is "compatible" -- | 
|---|
| 41 | // i.e. the return type is covariant and the parameters are contravariant. | 
|---|
| 42 | // | 
|---|
| 43 | // Unlike `std::function`, `kj::Function`s are movable but not copyable, just like `kj::Own`.  This | 
|---|
| 44 | // is to avoid unexpected heap allocation or slow atomic reference counting. | 
|---|
| 45 | // | 
|---|
| 46 | // When a `Function` is constructed from an lvalue, it captures only a reference to the value. | 
|---|
| 47 | // When constructed from an rvalue, it invokes the value's move constructor.  So, for example: | 
|---|
| 48 | // | 
|---|
| 49 | //     struct AddN { | 
|---|
| 50 | //       int n; | 
|---|
| 51 | //       int operator(int i) { return i + n; } | 
|---|
| 52 | //     } | 
|---|
| 53 | // | 
|---|
| 54 | //     Function<int(int, int)> f1 = AddN{2}; | 
|---|
| 55 | //     // f1 owns an instance of AddN.  It may safely be moved out | 
|---|
| 56 | //     // of the local scope. | 
|---|
| 57 | // | 
|---|
| 58 | //     AddN adder(2); | 
|---|
| 59 | //     Function<int(int, int)> f2 = adder; | 
|---|
| 60 | //     // f2 contains a reference to `adder`.  Thus, it becomes invalid | 
|---|
| 61 | //     // when `adder` goes out-of-scope. | 
|---|
| 62 | // | 
|---|
| 63 | //     AddN adder2(2); | 
|---|
| 64 | //     Function<int(int, int)> f3 = kj::mv(adder2); | 
|---|
| 65 | //     // f3 owns an insatnce of AddN moved from `adder2`.  f3 may safely | 
|---|
| 66 | //     // be moved out of the local scope. | 
|---|
| 67 | // | 
|---|
| 68 | // Additionally, a Function may be bound to a class method using KJ_BIND_METHOD(object, methodName). | 
|---|
| 69 | // For example: | 
|---|
| 70 | // | 
|---|
| 71 | //     class Printer { | 
|---|
| 72 | //     public: | 
|---|
| 73 | //       void print(int i); | 
|---|
| 74 | //       void print(kj::StringPtr s); | 
|---|
| 75 | //     }; | 
|---|
| 76 | // | 
|---|
| 77 | //     Printer p; | 
|---|
| 78 | // | 
|---|
| 79 | //     Function<void(uint)> intPrinter = KJ_BIND_METHOD(p, print); | 
|---|
| 80 | //     // Will call Printer::print(int). | 
|---|
| 81 | // | 
|---|
| 82 | //     Function<void(const char*)> strPrinter = KJ_BIND_METHOD(p, print); | 
|---|
| 83 | //     // Will call Printer::print(kj::StringPtr). | 
|---|
| 84 | // | 
|---|
| 85 | // Notice how KJ_BIND_METHOD is able to figure out which overload to use depending on the kind of | 
|---|
| 86 | // Function it is binding to. | 
|---|
| 87 |  | 
|---|
| 88 | template <typename Signature> | 
|---|
| 89 | class ConstFunction; | 
|---|
| 90 | // Like Function, but wraps a "const" (i.e. thread-safe) call. | 
|---|
| 91 |  | 
|---|
| 92 | template <typename Signature> | 
|---|
| 93 | class FunctionParam; | 
|---|
| 94 | // Like Function, but used specifically as a call parameter type. Does not do any heap allocation. | 
|---|
| 95 | // | 
|---|
| 96 | // This type MUST NOT be used for anything other than a parameter type to a function or method. | 
|---|
| 97 | // This is because if FunctionParam binds to a temporary, it assumes that the temporary will | 
|---|
| 98 | // outlive the FunctionParam instance. This is true when FunctionParam is used as a parameter type, | 
|---|
| 99 | // but not if it is used as a local variable nor a class member variable. | 
|---|
| 100 |  | 
|---|
| 101 | template <typename Return, typename... Params> | 
|---|
| 102 | class Function<Return(Params...)> { | 
|---|
| 103 | public: | 
|---|
| 104 | template <typename F> | 
|---|
| 105 | inline Function(F&& f): impl(heap<Impl<F>>(kj::fwd<F>(f))) {} | 
|---|
| 106 | Function() = default; | 
|---|
| 107 |  | 
|---|
| 108 | // Make sure people don't accidentally end up wrapping a reference when they meant to return | 
|---|
| 109 | // a function. | 
|---|
| 110 | KJ_DISALLOW_COPY(Function); | 
|---|
| 111 | Function(Function&) = delete; | 
|---|
| 112 | Function& operator=(Function&) = delete; | 
|---|
| 113 | template <typename T> Function(const Function<T>&) = delete; | 
|---|
| 114 | template <typename T> Function& operator=(const Function<T>&) = delete; | 
|---|
| 115 | template <typename T> Function(const ConstFunction<T>&) = delete; | 
|---|
| 116 | template <typename T> Function& operator=(const ConstFunction<T>&) = delete; | 
|---|
| 117 | Function(Function&&) = default; | 
|---|
| 118 | Function& operator=(Function&&) = default; | 
|---|
| 119 |  | 
|---|
| 120 | inline Return operator()(Params... params) { | 
|---|
| 121 | return (*impl)(kj::fwd<Params>(params)...); | 
|---|
| 122 | } | 
|---|
| 123 |  | 
|---|
| 124 | Function reference() { | 
|---|
| 125 | // Forms a new Function of the same type that delegates to this Function by reference. | 
|---|
| 126 | // Therefore, this Function must outlive the returned Function, but otherwise they behave | 
|---|
| 127 | // exactly the same. | 
|---|
| 128 |  | 
|---|
| 129 | return *impl; | 
|---|
| 130 | } | 
|---|
| 131 |  | 
|---|
| 132 | private: | 
|---|
| 133 | class Iface { | 
|---|
| 134 | public: | 
|---|
| 135 | virtual Return operator()(Params... params) = 0; | 
|---|
| 136 | }; | 
|---|
| 137 |  | 
|---|
| 138 | template <typename F> | 
|---|
| 139 | class Impl final: public Iface { | 
|---|
| 140 | public: | 
|---|
| 141 | explicit Impl(F&& f): f(kj::fwd<F>(f)) {} | 
|---|
| 142 |  | 
|---|
| 143 | Return operator()(Params... params) override { | 
|---|
| 144 | return f(kj::fwd<Params>(params)...); | 
|---|
| 145 | } | 
|---|
| 146 |  | 
|---|
| 147 | private: | 
|---|
| 148 | F f; | 
|---|
| 149 | }; | 
|---|
| 150 |  | 
|---|
| 151 | Own<Iface> impl; | 
|---|
| 152 | }; | 
|---|
| 153 |  | 
|---|
| 154 | template <typename Return, typename... Params> | 
|---|
| 155 | class ConstFunction<Return(Params...)> { | 
|---|
| 156 | public: | 
|---|
| 157 | template <typename F> | 
|---|
| 158 | inline ConstFunction(F&& f): impl(heap<Impl<F>>(kj::fwd<F>(f))) {} | 
|---|
| 159 | ConstFunction() = default; | 
|---|
| 160 |  | 
|---|
| 161 | // Make sure people don't accidentally end up wrapping a reference when they meant to return | 
|---|
| 162 | // a function. | 
|---|
| 163 | KJ_DISALLOW_COPY(ConstFunction); | 
|---|
| 164 | ConstFunction(ConstFunction&) = delete; | 
|---|
| 165 | ConstFunction& operator=(ConstFunction&) = delete; | 
|---|
| 166 | template <typename T> ConstFunction(const ConstFunction<T>&) = delete; | 
|---|
| 167 | template <typename T> ConstFunction& operator=(const ConstFunction<T>&) = delete; | 
|---|
| 168 | template <typename T> ConstFunction(const Function<T>&) = delete; | 
|---|
| 169 | template <typename T> ConstFunction& operator=(const Function<T>&) = delete; | 
|---|
| 170 | ConstFunction(ConstFunction&&) = default; | 
|---|
| 171 | ConstFunction& operator=(ConstFunction&&) = default; | 
|---|
| 172 |  | 
|---|
| 173 | inline Return operator()(Params... params) const { | 
|---|
| 174 | return (*impl)(kj::fwd<Params>(params)...); | 
|---|
| 175 | } | 
|---|
| 176 |  | 
|---|
| 177 | ConstFunction reference() const { | 
|---|
| 178 | // Forms a new ConstFunction of the same type that delegates to this ConstFunction by reference. | 
|---|
| 179 | // Therefore, this ConstFunction must outlive the returned ConstFunction, but otherwise they | 
|---|
| 180 | // behave exactly the same. | 
|---|
| 181 |  | 
|---|
| 182 | return *impl; | 
|---|
| 183 | } | 
|---|
| 184 |  | 
|---|
| 185 | private: | 
|---|
| 186 | class Iface { | 
|---|
| 187 | public: | 
|---|
| 188 | virtual Return operator()(Params... params) const = 0; | 
|---|
| 189 | }; | 
|---|
| 190 |  | 
|---|
| 191 | template <typename F> | 
|---|
| 192 | class Impl final: public Iface { | 
|---|
| 193 | public: | 
|---|
| 194 | explicit Impl(F&& f): f(kj::fwd<F>(f)) {} | 
|---|
| 195 |  | 
|---|
| 196 | Return operator()(Params... params) const override { | 
|---|
| 197 | return f(kj::fwd<Params>(params)...); | 
|---|
| 198 | } | 
|---|
| 199 |  | 
|---|
| 200 | private: | 
|---|
| 201 | F f; | 
|---|
| 202 | }; | 
|---|
| 203 |  | 
|---|
| 204 | Own<Iface> impl; | 
|---|
| 205 | }; | 
|---|
| 206 |  | 
|---|
| 207 | template <typename Return, typename... Params> | 
|---|
| 208 | class FunctionParam<Return(Params...)> { | 
|---|
| 209 | public: | 
|---|
| 210 | template <typename Func> | 
|---|
| 211 | FunctionParam(Func&& func) { | 
|---|
| 212 | typedef Wrapper<Decay<Func>> WrapperType; | 
|---|
| 213 |  | 
|---|
| 214 | // All instances of Wrapper<Func> are two pointers in size: a vtable, and a Func&. So if we | 
|---|
| 215 | // allocate space for two pointers, we can construct a Wrapper<Func> in it! | 
|---|
| 216 | static_assert(sizeof(WrapperType) == sizeof(space), | 
|---|
| 217 | "expected WrapperType to be two pointers"); | 
|---|
| 218 |  | 
|---|
| 219 | // Even if `func` is an rvalue reference, it's OK to use it as an lvalue here, because | 
|---|
| 220 | // FunctionParam is used strictly for parameters. If we captured a temporary, we know that | 
|---|
| 221 | // temporary will not be destroyed until after the function call completes. | 
|---|
| 222 | ctor(*reinterpret_cast<WrapperType*>(space), func); | 
|---|
| 223 | } | 
|---|
| 224 |  | 
|---|
| 225 | FunctionParam(const FunctionParam& other) = default; | 
|---|
| 226 | FunctionParam(FunctionParam&& other) = default; | 
|---|
| 227 | // Magically, a plain copy works. | 
|---|
| 228 |  | 
|---|
| 229 | inline Return operator()(Params... params) { | 
|---|
| 230 | return (*reinterpret_cast<WrapperBase*>(space))(kj::fwd<Params>(params)...); | 
|---|
| 231 | } | 
|---|
| 232 |  | 
|---|
| 233 | private: | 
|---|
| 234 | void* space[2]; | 
|---|
| 235 |  | 
|---|
| 236 | class WrapperBase { | 
|---|
| 237 | public: | 
|---|
| 238 | virtual Return operator()(Params... params) = 0; | 
|---|
| 239 | }; | 
|---|
| 240 |  | 
|---|
| 241 | template <typename Func> | 
|---|
| 242 | class Wrapper: public WrapperBase { | 
|---|
| 243 | public: | 
|---|
| 244 | Wrapper(Func& func): func(func) {} | 
|---|
| 245 |  | 
|---|
| 246 | inline Return operator()(Params... params) override { | 
|---|
| 247 | return func(kj::fwd<Params>(params)...); | 
|---|
| 248 | } | 
|---|
| 249 |  | 
|---|
| 250 | private: | 
|---|
| 251 | Func& func; | 
|---|
| 252 | }; | 
|---|
| 253 | }; | 
|---|
| 254 |  | 
|---|
| 255 | namespace _ {  // private | 
|---|
| 256 |  | 
|---|
| 257 | template <typename T, typename Func, typename ConstFunc> | 
|---|
| 258 | class BoundMethod { | 
|---|
| 259 | public: | 
|---|
| 260 | BoundMethod(T&& t, Func&& func, ConstFunc&& constFunc) | 
|---|
| 261 | : t(kj::fwd<T>(t)), func(kj::mv(func)), constFunc(kj::mv(constFunc)) {} | 
|---|
| 262 |  | 
|---|
| 263 | template <typename... Params> | 
|---|
| 264 | auto operator()(Params&&... params) { | 
|---|
| 265 | return func(t, kj::fwd<Params>(params)...); | 
|---|
| 266 | } | 
|---|
| 267 | template <typename... Params> | 
|---|
| 268 | auto operator()(Params&&... params) const { | 
|---|
| 269 | return constFunc(t, kj::fwd<Params>(params)...); | 
|---|
| 270 | } | 
|---|
| 271 |  | 
|---|
| 272 | private: | 
|---|
| 273 | T t; | 
|---|
| 274 | Func func; | 
|---|
| 275 | ConstFunc constFunc; | 
|---|
| 276 | }; | 
|---|
| 277 |  | 
|---|
| 278 | template <typename T, typename Func, typename ConstFunc> | 
|---|
| 279 | BoundMethod<T, Func, ConstFunc> boundMethod(T&& t, Func&& func, ConstFunc&& constFunc) { | 
|---|
| 280 | return { kj::fwd<T>(t), kj::fwd<Func>(func), kj::fwd<ConstFunc>(constFunc) }; | 
|---|
| 281 | } | 
|---|
| 282 |  | 
|---|
| 283 | }  // namespace _ (private) | 
|---|
| 284 |  | 
|---|
| 285 | #define KJ_BIND_METHOD(obj, method) \ | 
|---|
| 286 | ::kj::_::boundMethod(obj, \ | 
|---|
| 287 | [](auto& s, auto&&... p) mutable { return s.method(kj::fwd<decltype(p)>(p)...); }, \ | 
|---|
| 288 | [](auto& s, auto&&... p) { return s.method(kj::fwd<decltype(p)>(p)...); }) | 
|---|
| 289 | // Macro that produces a functor object which forwards to the method `obj.name`.  If `obj` is an | 
|---|
| 290 | // lvalue, the functor will hold a reference to it.  If `obj` is an rvalue, the functor will | 
|---|
| 291 | // contain a copy (by move) of it. The method is allowed to be overloaded. | 
|---|
| 292 |  | 
|---|
| 293 | }  // namespace kj | 
|---|
| 294 |  | 
|---|