34 #include <ableton/build_system/Warnings.hpp>
36 #include <boost/mpl/push_back.hpp>
47 template <
typename ...Fns>
50 template <
typename Fn,
typename ...Fns>
51 struct visitor_impl<Fn, Fns...>
53 , visitor_impl<Fns...>
55 using next = visitor_impl<Fns...>;
57 using next::operator();
59 template <
typename Fn2,
typename ...Fns2>
60 visitor_impl(Fn2&& fn, Fns2&& ...fns)
61 : Fn(
std::forward<Fn2>(fn))
62 , next(
std::forward<Fns2>(fns)...)
66 template <
typename Fn>
67 struct visitor_impl<Fn> : Fn
71 template <
typename Fn2>
72 visitor_impl(Fn2&& fn)
73 : Fn(
std::forward<Fn2>(fn))
82 template <
typename ReturnType,
typename ...Fns>
85 detail::visitor_impl<Fns...> impl_;
88 using result_type = ReturnType;
91 : impl_(std::forward<Fns>(fns)...)
94 template<
typename T,
typename U=ReturnType>
95 auto operator() (T&& x)
97 !std::is_void<decltype(impl_(std::forward<T>(x)))>{} ||
101 return impl_(std::forward<T>(x));
104 template<
typename T,
typename U=ReturnType>
105 auto operator() (T&& x)
107 std::is_void<decltype(impl_(std::forward<T>(x)))>{} &&
119 template <
typename Fn,
typename ReturnType=
void>
122 using result_type = ReturnType;
125 : impl_(std::forward<Fn>(fn))
128 template <
typename ...Args>
129 result_type operator() (Args&& ...args)
131 return impl_(std::forward<Args>(args)...);
140 template<
typename ReturnT>
141 struct default_construct
143 template <
typename ...Args>
144 ReturnT operator() (Args&& ...)
152 template <
typename ReturnType = void,
153 typename Fn = detail::default_construct<ReturnType>>
154 otherwise_t<Fn, ReturnType>
155 otherwise(Fn&& fn = Fn())
157 return { std::forward<Fn>(fn) };
164 template <
typename Fn,
typename ...Args>
167 using result_type =
typename std::result_of<Fn(Args...)>::type;
170 : impl_(std::forward<Fn>(fn))
173 result_type operator() (Args&& ...args)
175 return impl_(std::forward<Args>(args)...);
187 template <
typename ...Args,
typename Fn>
189 typename boost::mpl::if_<std::is_reference<Args>,
190 Args,
const Args&>::type...>
193 return { std::forward<Fn>(fn) };
198 template <
typename AccT,
typename FnT,
typename T,
199 typename Enable =
void>
200 struct add_result_of_aux
205 template <
typename AccT,
typename FnT,
typename T>
206 struct add_result_of_aux<AccT, FnT, T,
207 estd::
void_t<estd::result_of_t<FnT(T)> > >
208 : boost::mpl::push_back<AccT, estd::result_of_t<FnT(T)> >
211 template <
typename AccT,
typename FnT,
typename Ts>
212 struct add_results_of;
214 template <
typename AccT,
typename FnT,
typename T,
typename... Ts>
215 struct add_results_of<AccT, FnT, meta::pack<T, Ts...> >
216 : add_results_of<meta::eval_t<add_result_of_aux<AccT, FnT, T> >,
221 template <
typename AccT,
typename FnT>
222 struct add_results_of<AccT, FnT, meta::pack<> >
229 template <
typename FnT,
typename... VariantTs>
233 typename detail::add_results_of<meta::pack<>,
235 meta::pack<VariantTs...> >::type >
238 template <
typename FnT,
typename... VariantTs>
243 template <
typename FnT,
typename... VariantTs>
252 template <
typename... FnTs>
256 typename std::result_of<FnTs(meta::bottom)>::type...>,
259 return { std::forward<FnTs>(fns)... };
262 template <
typename FnT>
263 auto visitor(FnT&& fn) -> FnT&&
265 return std::forward<FnT>(fn);
273 template <
typename VariantT,
typename... FnTs>
277 detail::visitor_impl<FnTs...>,
278 variant_types_t<VariantT> >,
281 return { std::forward<FnTs>(fns)... };
284 template <
typename VarianT,
typename FnT>
287 return std::forward<FnT>(fn);
typename detail::make_void< Ts... >::type void_t
Similar to C++17 std::void_t.
typename std::enable_if< X, T >::type enable_if_t
Similar to C++14 std::enable_if_t.
Wraps a functor such that it has a fixed return value.
Wraps a functor such that it has a fixed argument list.
auto visitor_for(FnTs &&...fns) -> visitor_t< visitor_result_of_t< detail::visitor_impl< FnTs... >, variant_types_t< VariantT > >, FnTs... >
Like visitor, but it uses the variant_types in VariantT to deduce what the return type of the visitor...
auto visitor(FnTs &&...fns) -> visitor_t< meta::common_type_t< typename std::result_of< FnTs(meta::bottom)>::type... >, FnTs... >
Returns a visitor object that can be used to deconstruct various variant types, created by composing ...
General visitor based on a set of function objects.
C++ amazing templates and reusable implementations awesomeness.
when_t< Fn, typename boost::mpl::if_< std::is_reference< Args >, Args, const Args & >::type... > when(Fn &&fn)
Factory for when functors.