File indexing completed on 2025-01-30 09:43:52
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_HOF_GUARD_FUNCTION_REVEAL_H
0009 #define BOOST_HOF_GUARD_FUNCTION_REVEAL_H
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159
0160
0161
0162
0163
0164
0165
0166 #include <boost/hof/always.hpp>
0167 #include <boost/hof/returns.hpp>
0168 #include <boost/hof/is_invocable.hpp>
0169 #include <boost/hof/identity.hpp>
0170 #include <boost/hof/detail/move.hpp>
0171 #include <boost/hof/detail/callable_base.hpp>
0172 #include <boost/hof/detail/delegate.hpp>
0173 #include <boost/hof/detail/holder.hpp>
0174 #include <boost/hof/detail/join.hpp>
0175 #include <boost/hof/detail/make.hpp>
0176 #include <boost/hof/detail/static_const_var.hpp>
0177 #include <boost/hof/detail/using.hpp>
0178
0179 #ifndef BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
0180 #ifdef __clang__
0181 #define BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS 1
0182 #else
0183 #define BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS 0
0184 #endif
0185 #endif
0186
0187 namespace boost { namespace hof {
0188
0189 namespace detail {
0190
0191
0192 template<class T, class=void>
0193 struct has_failure
0194 : std::false_type
0195 {};
0196
0197 template<class T>
0198 struct has_failure<T, typename holder<
0199 typename T::failure
0200 >::type>
0201 : std::true_type
0202 {};
0203
0204 struct identity_failure
0205 {
0206 template<class T>
0207 T operator()(T&& x);
0208
0209 template<class T>
0210 static T&& val();
0211 #if BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
0212 template<template<class...> class Template, class... Ts>
0213 BOOST_HOF_USING(defer, Template<Ts...>);
0214 #else
0215 template<template<class...> class Template, class... Ts>
0216 static auto defer(Ts&&...) -> Template<Ts...>;
0217 #endif
0218
0219 };
0220
0221 }
0222
0223 template<class F, class=void>
0224 struct get_failure
0225 {
0226 template<class... Ts>
0227 struct of
0228 {
0229 #if BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
0230 template<class Id>
0231 using apply = decltype(Id()(std::declval<F>())(std::declval<Ts>()...));
0232 #else
0233 template<class Id>
0234 static auto apply(Id id) -> decltype(id(std::declval<F>())(std::declval<Ts>()...));
0235 #endif
0236 };
0237 };
0238
0239 template<class F>
0240 struct get_failure<F, typename std::enable_if<detail::has_failure<F>::value>::type>
0241 : F::failure
0242 {};
0243
0244 template<template<class...> class Template>
0245 struct as_failure
0246 {
0247 template<class... Ts>
0248 struct of
0249 {
0250 #if BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
0251 template<class Id>
0252 using apply = typename Id::template defer<Template, Ts...>;
0253 #else
0254 template<class Id>
0255 static auto apply(Id) -> decltype(Id::template defer<Template, Ts...>());
0256 #endif
0257 };
0258 };
0259
0260 namespace detail {
0261 template<class Failure, class... Ts>
0262 BOOST_HOF_USING_TYPENAME(apply_failure, Failure::template of<Ts...>);
0263
0264 template<class F, class Failure>
0265 struct reveal_failure
0266 {
0267
0268 constexpr reveal_failure()
0269 {}
0270
0271
0272 template<
0273 class... Ts,
0274 class=typename std::enable_if<(!is_invocable<F, Ts...>::value)>::type
0275 >
0276 constexpr auto operator()(Ts&&... xs) const
0277 #if BOOST_HOF_REVEAL_USE_TEMPLATE_ALIAS
0278 -> typename apply_failure<Failure, Ts...>::template apply<boost::hof::detail::identity_failure>;
0279 #else
0280 -> decltype(apply_failure<Failure, Ts...>::apply(boost::hof::detail::identity_failure()));
0281 #endif
0282 };
0283
0284 template<class F, class Failure=get_failure<F>, class=void>
0285 struct traverse_failure
0286 : reveal_failure<F, Failure>
0287 {
0288 constexpr traverse_failure()
0289 {}
0290 };
0291
0292 template<class F, class Failure>
0293 struct traverse_failure<F, Failure, typename holder<
0294 typename Failure::children
0295 >::type>
0296 : Failure::children::template overloads<F>
0297 {
0298 constexpr traverse_failure()
0299 {}
0300 };
0301
0302 template<class Failure, class Transform, class=void>
0303 struct transform_failures
0304 : Transform::template apply<Failure>
0305 {};
0306
0307 template<class Failure, class Transform>
0308 struct transform_failures<Failure, Transform, typename holder<
0309 typename Failure::children
0310 >::type>
0311 : Failure::children::template transform<Transform>
0312 {};
0313
0314 }
0315
0316 template<class Failure, class... Failures>
0317 struct failures;
0318
0319 template<class... Fs>
0320 struct with_failures
0321 {
0322 typedef BOOST_HOF_JOIN(failures, Fs...) children;
0323 };
0324
0325 template<class Failure, class... Failures>
0326 struct failures
0327 {
0328 template<class Transform>
0329 BOOST_HOF_USING(transform, with_failures<detail::transform_failures<Failure, Transform>, detail::transform_failures<Failures, Transform>...>);
0330
0331 template<class F, class FailureBase=BOOST_HOF_JOIN(failures, Failures...)>
0332 struct overloads
0333 : detail::traverse_failure<F, Failure>, FailureBase::template overloads<F>
0334 {
0335 constexpr overloads()
0336 {}
0337 using detail::traverse_failure<F, Failure>::operator();
0338 using FailureBase::template overloads<F>::operator();
0339 };
0340 };
0341
0342 template<class Failure>
0343 struct failures<Failure>
0344 {
0345 template<class Transform>
0346 BOOST_HOF_USING(transform, with_failures<detail::transform_failures<Failure, Transform>>);
0347
0348 template<class F>
0349 BOOST_HOF_USING(overloads, detail::traverse_failure<F, Failure>);
0350 };
0351
0352 template<class Transform, class... Fs>
0353 struct failure_map
0354 : with_failures<detail::transform_failures<get_failure<Fs>, Transform>...>
0355 {};
0356
0357 template<class... Fs>
0358 struct failure_for
0359 : with_failures<get_failure<Fs>...>
0360 {};
0361
0362 template<class F, class Base=detail::callable_base<F>>
0363 struct reveal_adaptor
0364 : detail::traverse_failure<Base>, Base
0365 {
0366 typedef reveal_adaptor fit_rewritable1_tag;
0367 using detail::traverse_failure<Base>::operator();
0368 using Base::operator();
0369
0370 BOOST_HOF_INHERIT_CONSTRUCTOR(reveal_adaptor, Base);
0371 };
0372
0373 template<class F>
0374 struct reveal_adaptor<reveal_adaptor<F>>
0375 : reveal_adaptor<F>
0376 {
0377 typedef reveal_adaptor fit_rewritable1_tag;
0378 BOOST_HOF_INHERIT_CONSTRUCTOR(reveal_adaptor, reveal_adaptor<F>);
0379 };
0380
0381 BOOST_HOF_DECLARE_STATIC_VAR(reveal, detail::make<reveal_adaptor>);
0382
0383 }}
0384
0385 #endif