]>
Commit | Line | Data |
---|---|---|
b32b8144 FG |
1 | #ifndef BOOST_MP11_BIND_HPP_INCLUDED |
2 | #define BOOST_MP11_BIND_HPP_INCLUDED | |
3 | ||
92f5a8d4 | 4 | // Copyright 2017, 2018 Peter Dimov. |
b32b8144 FG |
5 | // |
6 | // Distributed under the Boost Software License, Version 1.0. | |
7 | // | |
8 | // See accompanying file LICENSE_1_0.txt or copy at | |
9 | // http://www.boost.org/LICENSE_1_0.txt | |
10 | ||
11 | #include <boost/mp11/algorithm.hpp> | |
11fdf7f2 | 12 | #include <boost/mp11/utility.hpp> |
b32b8144 FG |
13 | #include <cstddef> |
14 | ||
15 | namespace boost | |
16 | { | |
17 | namespace mp11 | |
18 | { | |
19 | ||
92f5a8d4 TL |
20 | // mp_bind_front |
21 | template<template<class...> class F, class... T> struct mp_bind_front | |
22 | { | |
23 | // the indirection through mp_defer works around the language inability | |
24 | // to expand U... into a fixed parameter list of an alias template | |
25 | ||
26 | template<class... U> using fn = typename mp_defer<F, T..., U...>::type; | |
27 | }; | |
28 | ||
29 | template<class Q, class... T> using mp_bind_front_q = mp_bind_front<Q::template fn, T...>; | |
30 | ||
31 | // mp_bind_back | |
32 | template<template<class...> class F, class... T> struct mp_bind_back | |
33 | { | |
34 | template<class... U> using fn = typename mp_defer<F, U..., T...>::type; | |
35 | }; | |
36 | ||
37 | template<class Q, class... T> using mp_bind_back_q = mp_bind_back<Q::template fn, T...>; | |
38 | ||
b32b8144 FG |
39 | // mp_arg |
40 | template<std::size_t I> struct mp_arg | |
41 | { | |
42 | template<class... T> using fn = mp_at_c<mp_list<T...>, I>; | |
43 | }; | |
44 | ||
45 | using _1 = mp_arg<0>; | |
46 | using _2 = mp_arg<1>; | |
47 | using _3 = mp_arg<2>; | |
48 | using _4 = mp_arg<3>; | |
49 | using _5 = mp_arg<4>; | |
50 | using _6 = mp_arg<5>; | |
51 | using _7 = mp_arg<6>; | |
52 | using _8 = mp_arg<7>; | |
53 | using _9 = mp_arg<8>; | |
54 | ||
55 | // mp_bind | |
56 | template<template<class...> class F, class... T> struct mp_bind; | |
57 | ||
58 | namespace detail | |
59 | { | |
60 | ||
61 | template<class V, class... T> struct eval_bound_arg | |
62 | { | |
63 | using type = V; | |
64 | }; | |
65 | ||
66 | template<std::size_t I, class... T> struct eval_bound_arg<mp_arg<I>, T...> | |
67 | { | |
68 | using type = typename mp_arg<I>::template fn<T...>; | |
69 | }; | |
70 | ||
71 | template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind<F, U...>, T...> | |
72 | { | |
73 | using type = typename mp_bind<F, U...>::template fn<T...>; | |
74 | }; | |
75 | ||
92f5a8d4 TL |
76 | template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind_front<F, U...>, T...> |
77 | { | |
78 | using type = typename mp_bind_front<F, U...>::template fn<T...>; | |
79 | }; | |
b32b8144 | 80 | |
92f5a8d4 | 81 | template<template<class...> class F, class... U, class... T> struct eval_bound_arg<mp_bind_back<F, U...>, T...> |
b32b8144 | 82 | { |
92f5a8d4 | 83 | using type = typename mp_bind_back<F, U...>::template fn<T...>; |
b32b8144 FG |
84 | }; |
85 | ||
92f5a8d4 | 86 | } // namespace detail |
b32b8144 | 87 | |
92f5a8d4 | 88 | template<template<class...> class F, class... T> struct mp_bind |
b32b8144 | 89 | { |
92f5a8d4 TL |
90 | #if BOOST_MP11_WORKAROUND( BOOST_MP11_MSVC, == 1915 ) |
91 | private: | |
b32b8144 | 92 | |
92f5a8d4 | 93 | template<class... U> struct _f { using type = F<typename detail::eval_bound_arg<T, U...>::type...>; }; |
b32b8144 | 94 | |
92f5a8d4 | 95 | public: |
b32b8144 | 96 | |
92f5a8d4 TL |
97 | template<class... U> using fn = typename _f<U...>::type; |
98 | ||
99 | #else | |
100 | ||
101 | template<class... U> using fn = F<typename detail::eval_bound_arg<T, U...>::type...>; | |
102 | ||
103 | #endif | |
b32b8144 FG |
104 | }; |
105 | ||
92f5a8d4 | 106 | template<class Q, class... T> using mp_bind_q = mp_bind<Q::template fn, T...>; |
b32b8144 FG |
107 | |
108 | } // namespace mp11 | |
109 | } // namespace boost | |
110 | ||
111 | #endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED |