All Classes Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
invoke.hpp
1 // The MIT License (MIT)
2 
3 // Copyright (c) 2012-2014 Danny Y., Rapptz
4 
5 // Permission is hereby granted, free of charge, to any person obtaining a copy of
6 // this software and associated documentation files (the "Software"), to deal in
7 // the Software without restriction, including without limitation the rights to
8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 // the Software, and to permit persons to whom the Software is furnished to do so,
10 // subject to the following conditions:
11 
12 // The above copyright notice and this permission notice shall be included in all
13 // copies or substantial portions of the Software.
14 
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 
22 #ifndef GEARS_FUNCTIONAL_INVOKE_HPP
23 #define GEARS_FUNCTIONAL_INVOKE_HPP
24 
25 #include "../meta/alias.hpp"
26 
27 namespace gears {
28 namespace functional {
29 namespace detail {
30 using namespace gears::meta;
31 template <typename Fun, typename Obj, typename... Args,
32  typename Result = decltype((std::declval<Obj>().*std::declval<Fun>())(std::declval<Args>()...)),
33  bool NoExcept = noexcept((std::declval<Obj>().*std::declval<Fun>())(std::declval<Args>()...)),
35  std::is_base_of<ClassOf<Unqualified<Fun>>, Unqualified<Obj>>> = _>
36 constexpr Result invoke(Fun&& fun, Obj&& obj, Args&&... args) noexcept(NoExcept) {
37  return (std::forward<Obj>(obj).*std::forward<Fun>(fun))(std::forward<Args>(args)...);
38 }
39 
40 template <typename Fun, typename Obj, typename... Args,
41  typename Result = decltype(((*std::declval<Obj>()).*std::declval<Fun>())(std::declval<Args>()...)),
42  bool NoExcept = noexcept(((*std::declval<Obj>()).*std::declval<Fun>())(std::declval<Args>()...)),
45 constexpr Result invoke(Fun&& fun, Obj&& obj, Args&&... args) noexcept(NoExcept) {
46  return ((*std::forward<Obj>(obj)).*std::forward<Fun>(fun))(std::forward<Args>(args)...);
47 }
48 
49 template <typename Fun, typename Obj,
50  typename Result = decltype(std::declval<Obj>().*std::declval<Fun>()),
51  bool NoExcept = noexcept(std::declval<Obj>().*std::declval<Fun>()),
53  std::is_base_of<ClassOf<Unqualified<Fun>>, Unqualified<Obj>>> = _>
54 constexpr Result invoke(Fun&& fun, Obj&& obj) noexcept(NoExcept) {
55  return std::forward<Obj>(obj).*std::forward<Fun>(fun);
56 }
57 
58 template <typename Fun, typename Obj,
59  typename Result = decltype((*std::declval<Obj>()).*std::declval<Fun>()),
60  bool NoExcept = noexcept((*std::declval<Obj>()).*std::declval<Fun>()),
63 constexpr Result invoke(Fun&& fun, Obj&& obj) noexcept(NoExcept) {
64  return (*std::forward<Obj>(obj)).*std::forward<Fun>(fun);
65 }
66 
67 template <typename Fun, typename... Args,
68  typename Result = decltype(std::declval<Fun>()(std::declval<Args>()...)),
69  bool NoExcept = noexcept(std::declval<Fun>()(std::declval<Args>()...)),
71 constexpr Result invoke(Fun&& fun, Args&&... args) noexcept(NoExcept) {
72  return std::forward<Fun>(fun)(std::forward<Args>(args)...);
73 }
74 } // namespace detail
75 
76 #ifndef GEARS_FOR_DOXYGEN_ONLY
77 template <typename Deduced = meta::deduced, typename... Args,
78  typename Expected = decltype(detail::invoke(std::declval<Args>()...)),
79  typename Result = meta::If<meta::is_deduced<Deduced>, Expected, Deduced>,
80  bool NoExcept = noexcept(detail::invoke(std::declval<Args>()...)),
81  meta::EnableIf<meta::Any<std::is_convertible<Expected, Result>, std::is_void<Result>>> = meta::_>
82 #else
83 template<typename... Args>
84 #endif
85 constexpr Result invoke(Args&&... args) noexcept(NoExcept) {
86  return detail::invoke(std::forward<Args>(args)...);
87 }
88 } // functional
89 } // gears
90 
117 #endif // GEARS_FUNCTIONAL_INVOKE_HPP