diff --git a/Subtrees/beast/modules/beast_core/system/beast_Functional.h b/Subtrees/beast/modules/beast_core/system/beast_Functional.h index b16f1915ba..076438ed38 100644 --- a/Subtrees/beast/modules/beast_core/system/beast_Functional.h +++ b/Subtrees/beast/modules/beast_core/system/beast_Functional.h @@ -17,8 +17,252 @@ */ //============================================================================== -#ifndef BEAST_FUNCTIONAL_BEASTHEADER -#define BEAST_FUNCTIONAL_BEASTHEADER +#ifndef BEAST_FUNCTIONAL_H_INCLUDED +#define BEAST_FUNCTIONAL_H_INCLUDED + +//------------------------------------------------------------------------------ + +// inspired by Roman Perepelitsa's presentation from comp.lang.c++.moderated +// based on the implementation here: http://www.rsdn.ru/forum/cpp/2759773.1.aspx +// +namespace is_call_possible_detail +{ + template + struct add_reference + { + typedef T& type; + }; + + template + struct add_reference + { + typedef T& type; + }; + + template class void_exp_result {}; + + template + U const& operator,(U const&, void_exp_result); + + template + U& operator,(U&, void_exp_result); + + template + struct clone_constness + { + typedef dest_type type; + }; + + template + struct clone_constness + { + typedef const dest_type type; + }; +} + +#define BEAST_DEFINE_HAS_MEMBER_FUNCTION(trait_name, member_function_name) \ +template class trait_name; \ + \ +template \ +class trait_name \ +{ \ + class yes { char m; }; \ + class no { yes m[2]; }; \ + struct base_mixin \ + { \ + Result member_function_name(); \ + }; \ + struct base : public T, public base_mixin { private: base(); }; \ + template class helper{}; \ + template \ + static no deduce(U*, helper* = 0); \ + static yes deduce(...); \ +public: \ + static const bool value = sizeof(yes) == sizeof(deduce(static_cast(0))); \ +}; \ + \ +template \ +class trait_name \ +{ \ + class yes { char m; }; \ + class no { yes m[2]; }; \ + struct base_mixin \ + { \ + Result member_function_name(Arg); \ + }; \ + struct base : public T, public base_mixin { private: base(); }; \ + template class helper{}; \ + template \ + static no deduce(U*, helper* = 0); \ + static yes deduce(...); \ +public: \ + static const bool value = sizeof(yes) == sizeof(deduce(static_cast(0))); \ +}; \ + \ +template \ +class trait_name \ +{ \ + class yes { char m; }; \ + class no { yes m[2]; }; \ + struct base_mixin \ + { \ + Result member_function_name(Arg1,Arg2); \ + }; \ + struct base : public T, public base_mixin { private: base(); }; \ + template class helper{}; \ + template \ + static no deduce(U*, helper* = 0); \ + static yes deduce(...); \ +public: \ + static const bool value = sizeof(yes) == sizeof(deduce(static_cast(0))); \ +}; \ + \ +template \ +class trait_name \ +{ \ + class yes { char m; }; \ + class no { yes m[2]; }; \ + struct base_mixin \ + { \ + Result member_function_name(Arg1,Arg2,Arg3); \ + }; \ + struct base : public T, public base_mixin { private: base(); }; \ + template class helper{}; \ + template \ + static no deduce(U*, helper* = 0); \ + static yes deduce(...); \ +public: \ + static const bool value = sizeof(yes) == sizeof(deduce(static_cast(0))); \ +}; \ + \ +template \ +class trait_name \ +{ \ + class yes { char m; }; \ + class no { yes m[2]; }; \ + struct base_mixin \ + { \ + Result member_function_name(Arg1,Arg2,Arg3,Arg4); \ + }; \ + struct base : public T, public base_mixin { private: base(); }; \ + template class helper{}; \ + template \ + static no deduce(U*, helper* = 0); \ + static yes deduce(...); \ +public: \ + static const bool value = sizeof(yes) == sizeof(deduce(static_cast(0))); \ +} + +#define BEAST_DEFINE_IS_CALL_POSSIBLE(trait_name, member_function_name) \ +struct trait_name##_detail \ +{ \ +BEAST_DEFINE_HAS_MEMBER_FUNCTION(has_member, member_function_name); \ +}; \ + \ +template \ +struct trait_name \ +{ \ + private: \ + class yes {}; \ + class no { yes m[2]; }; \ + struct derived : public T \ + { \ + using T::member_function_name; \ + no member_function_name(...) const; \ + private: derived (); \ + }; \ + \ + typedef typename is_call_possible_detail::clone_constness::type derived_type; \ + \ + template \ + struct return_value_check \ + { \ + static yes deduce(Result); \ + static no deduce(...); \ + static no deduce(no); \ + static no deduce(is_call_possible_detail::void_exp_result); \ + }; \ + \ + template \ + struct return_value_check \ + { \ + static yes deduce(...); \ + static no deduce(no); \ + }; \ + \ + template \ + struct impl \ + { \ + static const bool value = false; \ + }; \ + \ + template \ + struct impl \ + { \ + static typename is_call_possible_detail::add_reference::type test_me; \ + static typename is_call_possible_detail::add_reference::type arg; \ + \ + static const bool value = \ + sizeof( \ + return_value_check::deduce( \ + (test_me.member_function_name(arg), is_call_possible_detail::void_exp_result()) \ + ) \ + ) == sizeof(yes); \ + }; \ + \ + template \ + struct impl \ + { \ + static typename is_call_possible_detail::add_reference::type test_me; \ + static typename is_call_possible_detail::add_reference::type arg1; \ + static typename is_call_possible_detail::add_reference::type arg2; \ + \ + static const bool value = \ + sizeof( \ + return_value_check::deduce( \ + (test_me.member_function_name(arg1,arg2), is_call_possible_detail::void_exp_result()) \ + ) \ + ) == sizeof(yes); \ + }; \ + \ + template \ + struct impl \ + { \ + static typename is_call_possible_detail::add_reference::type test_me; \ + static typename is_call_possible_detail::add_reference::type arg1; \ + static typename is_call_possible_detail::add_reference::type arg2; \ + static typename is_call_possible_detail::add_reference::type arg3; \ + \ + static const bool value = \ + sizeof( \ + return_value_check::deduce( \ + (test_me.member_function_name(arg1,arg2,arg3), is_call_possible_detail::void_exp_result()) \ + ) \ + ) == sizeof(yes); \ + }; \ + \ + template \ + struct impl \ + { \ + static typename is_call_possible_detail::add_reference::type test_me; \ + static typename is_call_possible_detail::add_reference::type arg1; \ + static typename is_call_possible_detail::add_reference::type arg2; \ + static typename is_call_possible_detail::add_reference::type arg3; \ + static typename is_call_possible_detail::add_reference::type arg4; \ + \ + static const bool value = \ + sizeof( \ + return_value_check::deduce( \ + (test_me.member_function_name(arg1,arg2,arg3,arg4), is_call_possible_detail::void_exp_result()) \ + ) \ + ) == sizeof(yes); \ + }; \ + \ + public: \ + static const bool value = impl::value, Signature>::value; \ +} + +//------------------------------------------------------------------------------ /* Brings functional support into our namespace, based on environment.