Silicium
function.hpp
Go to the documentation of this file.
1 #ifndef SILICIUM_FUNCTION_HPP
2 #define SILICIUM_FUNCTION_HPP
3 
4 #include <silicium/is_handle.hpp>
6 #include <boost/utility/enable_if.hpp>
7 #include <memory>
8 #include <cassert>
9 
10 namespace Si
11 {
12  template <class Signature>
13  struct function;
14 
15  template <class Result, class ...Args>
16  struct function<Result (Args...)>
17  {
18  function() BOOST_NOEXCEPT
19  {
20  }
21 
22  function(function &&other) BOOST_NOEXCEPT
23  : m_content(std::move(other.m_content))
24  {
25  }
26 
27  function(function const &other) BOOST_NOEXCEPT
28  : m_content(other.m_content)
29  {
30  }
31 
32  function &operator = (function &&other) BOOST_NOEXCEPT
33  {
34  m_content = std::move(other.m_content);
35  return *this;
36  }
37 
38  function &operator = (function const &other) BOOST_NOEXCEPT
39  {
40  m_content = other.m_content;
41  return *this;
42  }
43 
44  template <class F>
45  function(F &&content, typename boost::enable_if_c<!std::is_same<function, typename std::decay<F>::type>::value, void>::type * = nullptr)
46  : m_content(std::make_shared<holder<typename std::decay<F>::type>>(std::forward<F>(content)))
47  {
48  }
49 
50  bool operator !() const BOOST_NOEXCEPT
51  {
52  return !m_content;
53  }
54 
56 
57  Result operator()(Args ...arguments) const
58  {
59  assert(m_content);
60  return m_content->operator ()(std::forward<Args>(arguments)...);
61  }
62 
63  private:
64 
65  struct holder_base
66  {
67  virtual ~holder_base()
68  {
69  }
70  virtual Result operator()(Args ...arguments) = 0;
71  };
72 
73  template <class F>
74  struct holder : holder_base
75  {
76  template <class G>
77  explicit holder(G &&function)
78  : m_function(std::forward<G>(function))
79  {
80  }
81 
82  virtual Result operator()(Args ...arguments) SILICIUM_OVERRIDE
83  {
84  return m_function(std::forward<Args>(arguments)...);
85  }
86 
87  private:
88 
89  F m_function;
90  };
91 
92  std::shared_ptr<holder_base> m_content;
93  };
94 
95  BOOST_STATIC_ASSERT(is_handle<function<void ()>>::value);
96 }
97 
98 #endif
std::remove_reference< T >::type && move(T &&ref)
Definition: move.hpp:10
BOOST_STATIC_ASSERT(Si::is_handle< absolute_path >::value)
Definition: absolute_path.hpp:352
#define SILICIUM_EXPLICIT_OPERATOR_BOOL()
Definition: explicit_operator_bool.hpp:17
Definition: absolute_path.hpp:19
#define SILICIUM_OVERRIDE
Definition: config.hpp:140
Definition: function.hpp:13