Bond
 
Loading...
Searching...
No Matches
mpl.h
1// Copyright (c) Microsoft. All rights reserved.
2// Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
4/*
5 * This header provides a faster alternative to some of the facilities provided by boost::mpl.
6 */
7
8
9#pragma once
10
11#include <bond/core/config.h>
12
13#include <boost/static_assert.hpp>
14
15#include <initializer_list>
16#include <type_traits>
17#include <utility>
18
19
20namespace bond { namespace detail { namespace mpl
21{
22
23template <typename...> struct
24make_void
25{
26 using type = void;
27};
28
29template <typename... T>
30using void_t = typename make_void<T...>::type;
31
32
33template <typename T> struct
34identity
35{
36 using type = T;
37};
38
39
42template <typename T>
44 : std::false_type {};
45
47template <typename... T> struct
48list {};
49
50
52template <typename List, typename... T> struct
53append;
54
55template <typename List, typename... T>
56using append_t = typename append<List, T...>::type;
57
58template <typename List, typename... T> struct
60 : append<List, list<T...> > {};
61
62template <typename... T, typename... U> struct
63append<list<T...>, list<U...> >
64 : identity<list<T..., U...> > {};
65
66
68template <typename List, template <typename> class C> struct
69filter;
70
71template <typename List, template <typename> class C>
72using filter_t = typename filter<List, C>::type;
73
74template <template <typename> class C> struct
76 : identity<list<> > {};
77
78template <typename T, typename... U, template <typename> class C> struct
79filter<list<T, U...>, C>
80 : append< typename std::conditional<C<T>::value, list<T>, list<> >::type, filter_t<list<U...>, C> > {};
81
82
83template <typename F, typename... T>
84inline void apply(F&& f, const list<T...>&)
85{
86 std::initializer_list<int>{ (f(identity<T>{}), 0)... };
87}
88
89template <typename F>
90inline void apply(F&& /*f*/, const list<>&)
91{}
92
93template <typename List, typename F>
94inline void apply(F&& f)
95{
96 apply(std::forward<F>(f), List{});
97}
98
99
100template <typename F, typename T>
101inline auto try_apply(F&& f, const list<T>&)
102#ifdef BOND_NO_CXX14_RETURN_TYPE_DEDUCTION
103 -> decltype(std::forward<F>(f)(identity<T>{}))
104#endif
105{
106 return std::forward<F>(f)(identity<T>{});
107}
108
109template <typename F, typename T, typename U, typename... R>
110inline auto try_apply(F&& f, const list<T, U, R...>&)
111#ifdef BOND_NO_CXX14_RETURN_TYPE_DEDUCTION
112 -> decltype(f(identity<T>{}))
113#endif
114{
115 if (auto&& result = f(identity<T>{}))
116 {
117 return std::move(result);
118 }
119
120 return try_apply(std::forward<F>(f), list<U, R...>{});
121}
122
123template <typename List, typename F>
124inline auto try_apply(F&& f)
125#ifdef BOND_NO_CXX14_RETURN_TYPE_DEDUCTION
126 -> decltype(try_apply(std::forward<F>(f), List{}))
127#endif
128{
129 BOOST_STATIC_ASSERT((!std::is_same<List, list<> >::value));
130
131 return try_apply(std::forward<F>(f), List{});
132}
133
134
135} } } // namespace bond::detail::mpl
namespace bond
Definition: apply.h:17
Appends the given list of types or a single pack of list<> to the end.
Definition: mpl.h:60
Filters the given type list with the provided predicate.
Definition: mpl.h:68
Represents a type list.
Definition: mpl.h:48