LCOV - code coverage report
Current view: top level - media/webrtc/trunk/webrtc/base - function_view.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 9 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       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             : #include "webrtc/base/checks.h"
      18             : 
      19             : // Just like std::function, FunctionView will wrap any callable and hide its
      20             : // actual type, exposing only its signature. But unlike std::function,
      21             : // FunctionView doesn't own its callable---it just points to it. Thus, it's a
      22             : // good choice mainly as a function argument when the callable argument will
      23             : // not be called again once the function has returned.
      24             : //
      25             : // Its constructors are implicit, so that callers won't have to convert lambdas
      26             : // and other callables to FunctionView<Blah(Blah, Blah)> explicitly. This is
      27             : // safe because FunctionView is only a reference to the real callable.
      28             : //
      29             : // Example use:
      30             : //
      31             : //   void SomeFunction(rtc::FunctionView<int(int)> index_transform);
      32             : //   ...
      33             : //   SomeFunction([](int i) { return 2 * i + 1; });
      34             : //
      35             : // Note: FunctionView is tiny (essentially just two pointers) and trivially
      36             : // copyable, so it's probably cheaper to pass it by value than by const
      37             : // reference.
      38             : 
      39             : namespace rtc {
      40             : 
      41             : template <typename T>
      42             : class FunctionView;  // Undefined.
      43             : 
      44             : template <typename RetT, typename... ArgT>
      45             : class FunctionView<RetT(ArgT...)> final {
      46             :  public:
      47             :   // Constructor for lambdas and other callables; it accepts every type of
      48             :   // argument except those noted in its enable_if call.
      49             :   template <
      50             :       typename F,
      51             :       typename std::enable_if<
      52             :           // Not for function pointers; we have another constructor for that
      53             :           // below.
      54             :           !std::is_function<typename std::remove_pointer<
      55             :               typename std::remove_reference<F>::type>::type>::value &&
      56             : 
      57             :           // Not for nullptr; we have another constructor for that below.
      58             :           !std::is_same<std::nullptr_t,
      59             :                         typename std::remove_cv<F>::type>::value &&
      60             : 
      61             :           // Not for FunctionView objects; we have another constructor for that
      62             :           // (the implicitly declared copy constructor).
      63             :           !std::is_same<FunctionView,
      64             :                         typename std::remove_cv<typename std::remove_reference<
      65             :                             F>::type>::type>::value>::type* = nullptr>
      66           0 :   FunctionView(F&& f)
      67           0 :       : call_(CallVoidPtr<typename std::remove_reference<F>::type>) {
      68           0 :     f_.void_ptr = &f;
      69           0 :   }
      70             : 
      71             :   // Constructor that accepts function pointers. If the argument is null, the
      72             :   // result is an empty FunctionView.
      73             :   template <
      74             :       typename F,
      75             :       typename std::enable_if<std::is_function<typename std::remove_pointer<
      76             :           typename std::remove_reference<F>::type>::type>::value>::type* =
      77             :           nullptr>
      78             :   FunctionView(F&& f)
      79             :       : call_(f ? CallFunPtr<typename std::remove_pointer<F>::type> : nullptr) {
      80             :     f_.fun_ptr = reinterpret_cast<void (*)()>(f);
      81             :   }
      82             : 
      83             :   // Constructor that accepts nullptr. It creates an empty FunctionView.
      84             :   template <typename F,
      85             :             typename std::enable_if<std::is_same<
      86             :                 std::nullptr_t,
      87             :                 typename std::remove_cv<F>::type>::value>::type* = nullptr>
      88             :   FunctionView(F&& f) : call_(nullptr) {}
      89             : 
      90             :   // Default constructor. Creates an empty FunctionView.
      91             :   FunctionView() : call_(nullptr) {}
      92             : 
      93           0 :   RetT operator()(ArgT... args) const {
      94           0 :     RTC_DCHECK(call_);
      95           0 :     return call_(f_, std::forward<ArgT>(args)...);
      96             :   }
      97             : 
      98             :   // Returns true if we have a function, false if we don't (i.e., we're null).
      99             :   explicit operator bool() const { return !!call_; }
     100             : 
     101             :  private:
     102             :   union VoidUnion {
     103             :     void* void_ptr;
     104             :     void (*fun_ptr)();
     105             :   };
     106             : 
     107             :   template <typename F>
     108           0 :   static RetT CallVoidPtr(VoidUnion vu, ArgT... args) {
     109           0 :     return (*static_cast<F*>(vu.void_ptr))(std::forward<ArgT>(args)...);
     110             :   }
     111             :   template <typename F>
     112             :   static RetT CallFunPtr(VoidUnion vu, ArgT... args) {
     113             :     return (reinterpret_cast<typename std::add_pointer<F>::type>(vu.fun_ptr))(
     114             :         std::forward<ArgT>(args)...);
     115             :   }
     116             : 
     117             :   // A pointer to the callable thing, with type information erased. It's a
     118             :   // union because we have to use separate types depending on if the callable
     119             :   // thing is a function pointer or something else.
     120             :   VoidUnion f_;
     121             : 
     122             :   // Pointer to a dispatch function that knows the type of the callable thing
     123             :   // that's stored in f_, and how to call it. A FunctionView object is empty
     124             :   // (null) iff call_ is null.
     125             :   RetT (*call_)(VoidUnion, ArgT...);
     126             : };
     127             : 
     128             : }  // namespace rtc
     129             : 
     130             : #endif  // WEBRTC_BASE_FUNCTION_VIEW_H_

Generated by: LCOV version 1.13