clang-tools  7.0.0
Function.h
Go to the documentation of this file.
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 template <class Func, class... Args> struct ForwardBinder {
36  using Tuple = std::tuple<typename std::decay<Func>::type,
37  typename std::decay<Args>::type...>;
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  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  return std::get<0>(this->FuncWithArguments)(
55  std::forward<Args>(std::get<Indexes + 1>(this->FuncWithArguments))...,
56  std::forward<RestArgs>(Rest)...);
57  }
58 
59 public:
60  template <class... RestArgs>
61  auto operator()(RestArgs &&... Rest)
62  -> decltype(this->CallImpl(llvm::index_sequence_for<Args...>(),
63  std::forward<RestArgs>(Rest)...)) {
64 
65 #ifndef NDEBUG
66  assert(!WasCalled && "Can only call result of Bind once.");
67  WasCalled = true;
68 #endif
69  return CallImpl(llvm::index_sequence_for<Args...>(),
70  std::forward<RestArgs>(Rest)...);
71  }
72 };
73 
74 /// 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 /// 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 ForwardBinder<Func, Args...> Bind(Func F, Args &&... As) {
82  return ForwardBinder<Func, Args...>(
83  std::make_tuple(std::forward<Func>(F), std::forward<Args>(As)...));
84 }
85 
86 } // namespace clangd
87 } // namespace clang
88 
89 #endif
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
ForwardBinder< Func, Args... > Bind(Func F, Args &&... As)
Creates an object that stores a callable (F) and first arguments to the callable (As) and allows to c...
Definition: Function.h:81
ForwardBinder(Tuple FuncWithArguments)
Definition: Function.h:44
std::tuple< typename std::decay< Func >::type, typename std::decay< Args >::type... > Tuple
Definition: Function.h:37
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Stores a callable object (Func) and arguments (Args) and allows to call the callable with provided ar...
Definition: Function.h:35
auto operator()(RestArgs &&... Rest) -> decltype(this->CallImpl(llvm::index_sequence_for< Args... >(), std::forward< RestArgs >(Rest)...))
Definition: Function.h:61