LCOV - code coverage report
Current view: top level - clang/tools/extra/clangd - Function.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 0 28 0.0 %
Date: 2018-10-20 13:21:21 Functions: 0 7 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===--- Function.h - Utility callable wrappers  -----------------*- C++-*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // This file provides utilities for callable objects.
      11             : //
      12             : //===----------------------------------------------------------------------===//
      13             : 
      14             : #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_FUNCTION_H
      15             : #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_FUNCTION_H
      16             : 
      17             : #include "llvm/ADT/FunctionExtras.h"
      18             : #include "llvm/Support/Error.h"
      19             : #include <tuple>
      20             : #include <utility>
      21             : 
      22             : namespace clang {
      23             : namespace clangd {
      24             : 
      25             : /// A Callback<T> is a void function that accepts Expected<T>.
      26             : /// This is accepted by ClangdServer functions that logically return T.
      27             : template <typename T>
      28             : using Callback = llvm::unique_function<void(llvm::Expected<T>)>;
      29             : 
      30             : /// Stores a callable object (Func) and arguments (Args) and allows to call the
      31             : /// callable with provided arguments later using `operator ()`. The arguments
      32             : /// are std::forward'ed into the callable in the body of `operator()`. Therefore
      33             : /// `operator()` can only be called once, as some of the arguments could be
      34             : /// std::move'ed into the callable on first call.
      35           0 : template <class Func, class... Args> struct ForwardBinder {
      36             :   using Tuple = std::tuple<typename std::decay<Func>::type,
      37             :                            typename std::decay<Args>::type...>;
      38             :   Tuple FuncWithArguments;
      39             : #ifndef NDEBUG
      40             :   bool WasCalled = false;
      41             : #endif
      42             : 
      43             : public:
      44             :   ForwardBinder(Tuple FuncWithArguments)
      45             :       : FuncWithArguments(std::move(FuncWithArguments)) {}
      46             : 
      47             : private:
      48             :   template <std::size_t... Indexes, class... RestArgs>
      49           0 :   auto CallImpl(llvm::integer_sequence<std::size_t, Indexes...> Seq,
      50             :                 RestArgs &&... Rest)
      51             :       -> decltype(std::get<0>(this->FuncWithArguments)(
      52             :           std::forward<Args>(std::get<Indexes + 1>(this->FuncWithArguments))...,
      53             :           std::forward<RestArgs>(Rest)...)) {
      54           0 :     return std::get<0>(this->FuncWithArguments)(
      55             :         std::forward<Args>(std::get<Indexes + 1>(this->FuncWithArguments))...,
      56           0 :         std::forward<RestArgs>(Rest)...);
      57             :   }
      58           0 : 
      59             : public:
      60             :   template <class... RestArgs>
      61             :   auto operator()(RestArgs &&... Rest)
      62             :       -> decltype(this->CallImpl(llvm::index_sequence_for<Args...>(),
      63           0 :                                  std::forward<RestArgs>(Rest)...)) {
      64             : 
      65           0 : #ifndef NDEBUG
      66             :     assert(!WasCalled && "Can only call result of Bind once.");
      67           0 :     WasCalled = true;
      68             : #endif
      69             :     return CallImpl(llvm::index_sequence_for<Args...>(),
      70             :                     std::forward<RestArgs>(Rest)...);
      71             :   }
      72           0 : };
      73             : 
      74           0 : /// Creates an object that stores a callable (\p F) and first arguments to the
      75             : /// callable (\p As) and allows to call \p F with \Args at a later point.
      76           0 : /// Similar to std::bind, but also works with move-only \p F and \p As.
      77             : ///
      78             : /// The returned object must be called no more than once, as \p As are
      79             : /// std::forwarded'ed (therefore can be moved) into \p F during the call.
      80             : template <class Func, class... Args>
      81           0 : ForwardBinder<Func, Args...> Bind(Func F, Args &&... As) {
      82             :   return ForwardBinder<Func, Args...>(
      83           0 :       std::make_tuple(std::forward<Func>(F), std::forward<Args>(As)...));
      84             : }
      85           0 : 
      86             : } // namespace clangd
      87             : } // namespace clang
      88             : 
      89             : #endif

Generated by: LCOV version 1.13