Warning, file /include/boost/poly_collection/detail/callable_wrapper.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_POLY_COLLECTION_DETAIL_CALLABLE_WRAPPER_HPP
0010 #define BOOST_POLY_COLLECTION_DETAIL_CALLABLE_WRAPPER_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/poly_collection/detail/is_invocable.hpp>
0017 #include <functional>
0018 #include <type_traits>
0019 #include <typeinfo>
0020
0021 namespace boost{
0022
0023 namespace poly_collection{
0024
0025 namespace detail{
0026
0027
0028
0029 template<typename Signature>
0030 class callable_wrapper;
0031
0032 template<typename R,typename... Args>
0033 class callable_wrapper<R(Args...)>
0034 {
0035 public:
0036
0037 template<
0038 typename Callable,
0039 typename std::enable_if<
0040 !std::is_same<Callable,callable_wrapper>::value&&
0041 is_invocable_r<R,Callable,Args...>::value
0042 >::type* =nullptr
0043 >
0044 explicit callable_wrapper(Callable& x)noexcept:pt{info(x)},px{&x}{}
0045 callable_wrapper(const callable_wrapper&)=default;
0046 callable_wrapper& operator=(const callable_wrapper&)=default;
0047
0048 explicit operator bool()const noexcept{return true;}
0049
0050 R operator()(Args... args)const
0051 {return pt->call(px,std::forward<Args>(args)...);}
0052
0053 const std::type_info& target_type()const noexcept{return pt->info;}
0054
0055 template<typename T>
0056 T* target()noexcept
0057 {return typeid(T)==pt->info?static_cast<T*>(px):nullptr;}
0058 template<typename T>
0059 const T* target()const noexcept
0060 {return typeid(T)==pt->info?static_cast<const T*>(px):nullptr;}
0061
0062
0063
0064 operator std::function<R(Args...)>()const noexcept{return pt->convert(px);}
0065
0066 void* data()noexcept{return px;}
0067 const void* data()const noexcept{return px;}
0068
0069 private:
0070 struct table
0071 {
0072 R(*call)(void*,Args...);
0073 const std::type_info& info;
0074 std::function<R(Args...)> (*convert)(void*);
0075 };
0076
0077 template<typename Callable>
0078 static table* info(Callable&)noexcept
0079 {
0080 static table t={
0081 [](void* p,Args... args){
0082 auto r=std::ref(*static_cast<Callable*>(p));
0083 return static_cast<R>(r(std::forward<Args>(args)...));
0084 },
0085 typeid(Callable),
0086 [](void* p){
0087 auto r=std::ref(*static_cast<Callable*>(p));
0088 return std::function<R(Args...)>{r};
0089 }
0090 };
0091 return &t;
0092 }
0093
0094 table* pt;
0095 void* px;
0096 };
0097
0098 }
0099
0100 }
0101
0102 }
0103
0104 #endif