WeakBind.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2018 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #ifndef GAZEBO_COMMON_WEAKBIND_HH_
19 #define GAZEBO_COMMON_WEAKBIND_HH_
20 
21 #include <boost/shared_ptr.hpp>
22 #include <boost/bind.hpp>
23 
24 namespace gazebo
25 {
26  namespace common
27  {
28  namespace details
29  {
32  template <typename Func, typename T>
33  class WeakBinder
34  {
35  public: using WeakPtr = boost::weak_ptr<T>;
36 
38  private: Func func;
39 
42  private: WeakPtr ptr;
43 
48  public: WeakBinder(Func _func, WeakPtr _ptr) :
49  func(_func),
50  ptr(_ptr)
51  {}
52 
54  public: template <typename... Args> auto operator()(Args&&... _args)
55  -> typename std::enable_if<
56  !std::is_void<
57  decltype(this->func(std::forward<Args>(_args)...))
58  >::value,
59  decltype(this->func(std::forward<Args>(_args)...))
60  >::type
61  {
62  auto ptrLock = this->ptr.lock();
63  if (ptrLock)
64  {
65  return this->func(std::forward<Args>(_args)...);
66  }
67  else
68  {
69  return {}; // NOLINT(readability/braces)
70  }
71  }
72 
74  public: template <typename... Args> auto operator()(Args&&... _args)
75  -> typename std::enable_if<
76  std::is_void<
77  decltype(this->func(std::forward<Args>(_args)...))
78  >::value,
79  void
80  >::type
81  {
82  auto ptrLock = this->ptr.lock();
83  if (ptrLock)
84  {
85  this->func(std::forward<Args>(_args)...);
86  }
87  }
88  };
89 
90  template <typename Func, typename T>
91  WeakBinder<Func, T> makeWeakBinder(Func func, boost::weak_ptr<T> ptr)
92  {
93  return WeakBinder<Func, T>(func, ptr);
94  }
95  }
96 
109  template <typename T, typename Func, typename... Args>
110  auto weakBind(Func _func, boost::shared_ptr<T> _ptr, Args... _args)
111  #if __cplusplus < 201402L
112  -> decltype(details::makeWeakBinder(
113  boost::bind(_func, _ptr.get(), _args...),
114  boost::weak_ptr<T>(_ptr)))
115  #endif
116  {
118  boost::bind(_func, _ptr.get(), _args...),
119  boost::weak_ptr<T>(_ptr));
120  }
122  }
123 }
124 
125 #endif
auto weakBind(Func _func, boost::shared_ptr< T > _ptr, Args... _args) -> decltype(details::makeWeakBinder(boost::bind(_func, _ptr.get(), _args...), boost::weak_ptr< T >(_ptr)))
Definition: WeakBind.hh:110
Forward declarations for the common classes.
Definition: Animation.hh:26
WeakBinder< Func, T > makeWeakBinder(Func func, boost::weak_ptr< T > ptr)
Definition: WeakBind.hh:91
Function object wrapper used by common::weakBind.
Definition: WeakBind.hh:33
auto operator()(Args &&... _args) -> typename std::enable_if< std::is_void< decltype(this->func(std::forward< Args >(_args)...)) >::value, void >::type
Return void version.
Definition: WeakBind.hh:74
auto operator()(Args &&... _args) -> typename std::enable_if< !std::is_void< decltype(this->func(std::forward< Args >(_args)...)) >::value, decltype(this->func(std::forward< Args >(_args)...)) >::type
Return non-void version.
Definition: WeakBind.hh:54
boost::weak_ptr< T > WeakPtr
Definition: WeakBind.hh:35
WeakBinder(Func _func, WeakPtr _ptr)
Constructor.
Definition: WeakBind.hh:48