blob: 6a7c9109ca6d906ff53601799c65b208917200e4 [file] [log] [blame]
kwiberg24c7c122016-09-28 11:57:10 -07001/*
2 * Copyright 2016 The WebRTC Project Authors. All rights reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11#ifndef WEBRTC_BASE_FUNCTION_VIEW_H_
12#define WEBRTC_BASE_FUNCTION_VIEW_H_
13
14#include <type_traits>
15#include <utility>
16
17// Just like std::function, FunctionView will wrap any callable and hide its
18// actual type, exposing only its signature. But unlike std::function,
19// FunctionView doesn't own its callable---it just points to it. Thus, it's a
20// good choice mainly as a function argument when the callable argument will
21// not be called again once the function has returned.
22//
23// TODO(kwiberg): FunctionView doesn't work with function pointers, just with
24// lambdas. It's trivial to work around this by wrapping the function pointer
25// in a stateless lambda, but it's tedious so it'd be nice to not have to do
26// it.
27
28namespace rtc {
29
30template <typename T>
31class FunctionView; // Undefined.
32
33template <typename RetT, typename... ArgT>
34class FunctionView<RetT(ArgT...)> final {
35 public:
36 // This constructor is implicit, so that callers won't have to convert
37 // lambdas and other callables to FunctionView<Blah(Blah, Blah)> explicitly.
38 // This is safe because FunctionView is only a reference to the real
39 // callable.
40 //
41 // We jump through some template metaprogramming hoops to ensure that this
42 // constructor does *not* accept FunctionView arguments. That way, copy
43 // construction, assignment, swap etc. will all do the obvious thing (because
44 // they use the implicitly-declared copy constructor and copy assignment),
45 // and we will never get a FunctionView object that points to another
46 // FunctionView.
47 template <typename F,
48 typename std::enable_if<!std::is_same<
49 FunctionView,
50 typename std::remove_cv<typename std::remove_reference<
51 F>::type>::type>::value>::type* = nullptr>
52 FunctionView(F&& f)
53 : f_(&f), call_(Call<typename std::remove_reference<F>::type>) {}
54
55 RetT operator()(ArgT... args) const {
56 return call_(f_, std::forward<ArgT>(args)...);
57 }
58
59 private:
60 template <typename F>
61 static RetT Call(void* f, ArgT... args) {
62 return (*static_cast<F*>(f))(std::forward<ArgT>(args)...);
63 }
64 void* f_;
65 RetT (*call_)(void* f, ArgT... args);
66};
67
68} // namespace rtc
69
70#endif // WEBRTC_BASE_FUNCTION_VIEW_H_