/home/users/khuck/src/hpx-lsu/hpx/util/invoke.hpp

Line% of fetchesSource
1  
//  Copyright (c) 2013-2015 Agustin Berge
2  
//  Copyright (c) 2016 Antoine Tran Tan
3  
//
4  
//  Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
//  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
7  
// hpxinspect:nodeprecatedinclude:boost/ref.hpp
8  
// hpxinspect:nodeprecatedname:boost::reference_wrapper
9  
10  
#ifndef HPX_UTIL_INVOKE_HPP
11  
#define HPX_UTIL_INVOKE_HPP
12  
13  
#include <hpx/config.hpp>
14  
#include <hpx/util/result_of.hpp>
15  
#include <hpx/util/void_guard.hpp>
16  
17  
#include <boost/ref.hpp>
18  
19  
#include <type_traits>
20  
#include <utility>
21  
22  
namespace hpx { namespace util
23  
{
24  
    ///////////////////////////////////////////////////////////////////////////
25  
    namespace detail
26  
    {
27  
        template <typename R,typename FD>
28  
        struct invoke_impl
29  
        {
30  
            // f(t0, t1, ..., tN)
31  
            template <typename F, typename ...Ts>
32  
            HPX_HOST_DEVICE HPX_FORCEINLINE
33  
            R operator()(F&& f, Ts&&... vs)
34  
            {
35  
                return hpx::util::void_guard<R>(),
36  
                    std::forward<F>(f)(std::forward<Ts>(vs)...);
37  
            }
38  
        };
39  
40  
41  
        template <typename R, typename M, typename C>
42  
        struct invoke_impl<R, M C::*>
43  
        {
44  
            // t0.*f
45  
            template <typename F, typename T0>
46  
            HPX_HOST_DEVICE HPX_FORCEINLINE
47  
            typename std::enable_if<
48  
                std::is_base_of<C, typename std::decay<T0>::type>::value,
49  
                R
50  
            >::type
51  
            operator()(F f, T0& v0)
52  
            {
53  
                return hpx::util::void_guard<R>(), (v0.*f);
54  
            }
55  
56  
            template <typename F, typename T0>
57  
            HPX_HOST_DEVICE HPX_FORCEINLINE
58  
            typename std::enable_if<
59  
                std::is_base_of<C, typename std::decay<T0>::type>::value
60  
             && !std::is_lvalue_reference<T0>::value,
61  
                R
62  
            >::type
63  
            operator()(F f, T0&& v0)
64  
            {
65  
                return hpx::util::void_guard<R>(), std::move(v0.*f);
66  
            }
67  
68  
            // (*t0).*f
69  
            template <typename F, typename T0>
70  
            HPX_HOST_DEVICE HPX_FORCEINLINE
71  
            typename std::enable_if<
72  
                !std::is_base_of<C, typename std::decay<T0>::type>::value,
73  
                R
74  
            >::type
75  
            operator()(F f, T0&& v0)
76  
            {
77  
                return hpx::util::void_guard<R>(), (*this)(f, *std::forward<T0>(v0));
78  
            }
79  
        };
80  
81  
        template <typename R, typename RR, typename C, typename ...Ps>
82  
        struct invoke_impl<R, RR (C::*)(Ps...)>
83  
        {
84  
            // (t0.*f)(t1, ..., tN)
85  
            template <typename F, typename T0, typename ...Ts>
86  
            HPX_HOST_DEVICE HPX_FORCEINLINE
87  
            typename std::enable_if<
88  
                std::is_base_of<C, typename std::decay<T0>::type>::value,
89  
                R
90  
            >::type
91  
            operator()(F f, T0&& v0, Ts&&... vs)
92  
            {
93  
                return hpx::util::void_guard<R>(),
94  
                    (std::forward<T0>(v0).*f)(std::forward<Ts>(vs)...);
95  
            }
96  
97  
            // ((*t0).*f)(t1, ..., tN)
98  
            template <typename F, typename T0, typename ...Ts>
99  
            HPX_HOST_DEVICE HPX_FORCEINLINE
100  
            typename std::enable_if<
101  
                !std::is_base_of<C, typename std::decay<T0>::type>::value,
102  
                R
103  
            >::type
104  
            operator()(F f, T0&& v0, Ts&&... vs)
105  
            {
106  
                return hpx::util::void_guard<R>(),
107  
                    (*this)(f, *std::forward<T0>(v0), std::forward<Ts>(vs)...);
108  
            }
109  
        };
110  
111  
        template <typename R, typename RR, typename C, typename ...Ps>
112  
        struct invoke_impl<R, RR (C::*)(Ps...) const>
113  
          : invoke_impl<R, RR (C::*)(Ps...)>
114  
        {};
115  
116  
        template <typename R,typename X>
117  
        struct invoke_impl<R,::boost::reference_wrapper<X>>
118  
          : invoke_impl<R,X&>
119  
        {
120  
            // support boost::[c]ref, which is not callable as std::[c]ref
121  
            template <typename F, typename ...Ts>
122  
            HPX_HOST_DEVICE HPX_FORCEINLINE
123  
            R operator()(F f, Ts&&... vs)
124  
            {
125  
                return hpx::util::void_guard<R>(), f.get()(std::forward<Ts>(vs)...);
126  
            }
127  
        };
128  
    }
129  
130  
    template <typename F, typename ...Ts>
131  
    HPX_HOST_DEVICE HPX_FORCEINLINE
132  
    typename util::result_of<F&&(Ts&&...)>::type
133  
    invoke(F&& f, Ts&&... vs)
134  
    {
135  
        typedef typename util::result_of<F&&(Ts&&...)>::type R;
136  
137  
        return detail::invoke_impl<R,typename std::decay<F>::type>()(
138  
            std::forward<F>(f), std::forward<Ts>(vs)...);
139  
    }
140  
141  
    template <typename R, typename F, typename ...Ts>
142  
    HPX_HOST_DEVICE HPX_FORCEINLINE
143  
    R invoke_r(F&& f, Ts&&... vs)
144  
    {
145  
        return detail::invoke_impl<R,typename std::decay<F>::type>()(
146  
            std::forward<F>(f), std::forward<Ts>(vs)...);
147  
    }
148  
149  
    ///////////////////////////////////////////////////////////////////////////
150  
    namespace functional
151  
    {
152  
        struct invoke
153  
        {
154  
            template <typename F, typename... Ts>
155  
            HPX_HOST_DEVICE HPX_FORCEINLINE
156  
            typename util::result_of<F&&(Ts &&...)>::type
157  
            operator()(F && f, Ts &&... vs)
158  
            {
159  
                typedef typename util::result_of<F&&(Ts&&...)>::type R;
160  
161  
                return hpx::util::void_guard<R>(), util::invoke(std::forward<F>(f),
162  
                    std::forward<Ts>(vs)...);
163  
            }
164  
        };
165  
166  
        template <typename R>
167  
        struct invoke_r
168  
        {
169  
            template <typename F, typename... Ts>
170  
            HPX_HOST_DEVICE HPX_FORCEINLINE
171  
            R operator()(F && f, Ts &&... vs)
172  
            {
173  
                return hpx::util::void_guard<R>(), util::invoke_r<R>(std::forward<F>(f),
174  
                    std::forward<Ts>(vs)...);
175  
            }
176  
        };
177  
    }
178  
}}
179  
180  
#endif
181  

Copyright (c) 2006-2012 Rogue Wave Software, Inc. All Rights Reserved.
Patents pending.