Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace ep
- {
- namespace details
- {
- namespace detail
- {
- template<unsigned... digits>
- struct to_chars
- {
- static const char value[];
- };
- template<unsigned... digits>
- const char to_chars<digits...>::value[] = { 'a', 'r', 'g', ( '0' + digits )..., 0 };
- template<unsigned rem, unsigned... digits>
- struct explode : explode<rem / 10, rem % 10, digits...>
- { };
- template<unsigned... digits>
- struct explode<0, digits...> : to_chars<digits...>
- { };
- }
- template<unsigned num>
- struct arg_pos_to_string : detail::explode<num>
- { };
- struct _Ref_ptr
- { };
- template<typename T>
- struct callable_traits;
- template<typename Ret, typename...Params>
- struct callable_traits<Ret( Params... )>
- {
- static constexpr auto size = sizeof...( Params );
- using result_type = Ret;
- template<size_t pos>
- struct arg_t
- {
- using type = typename std::tuple_element<pos, std::tuple<Params...>>::type;
- };
- };
- template<typename _Deduce, bool ref = std::is_base_of<_Ref_ptr, _Deduce>::value>
- struct _Var_deducer
- {
- static _Deduce deduce( ep::variable_ptr &ptr )
- {
- return *ptr->get_ref( )->clone( )->get_pointer<_Deduce>( );
- }
- };
- template<typename _Deduce>
- struct _Var_deducer<_Deduce*, false>
- {
- static _Deduce *deduce( ep::variable_ptr &ptr )
- {
- return ptr->get_ref( )->get_pointer<_Deduce>( );
- }
- };
- template<typename _Deduce>
- struct _Var_deducer<_Deduce&, false>
- {
- static _Deduce &deduce( ep::variable_ptr &ptr )
- {
- return *ptr->get_ref( )->get_pointer<_Deduce>( );
- }
- };
- template<typename _Deduce>
- struct _Var_deducer<_Deduce, true>
- {
- static _Deduce deduce( ep::variable_ptr &ptr )
- {
- return _Deduce( ptr );
- }
- };
- template<>
- struct _Var_deducer<variable_ptr, false>
- {
- static variable_ptr deduce( ep::variable_ptr &ptr )
- {
- return ptr;
- }
- };
- template<size_t pos, size_t max, typename Traits, typename Ret = typename Traits::result_type>
- struct _Caller
- {
- template<typename Func, typename...Deduced>
- static auto
- _Process_and_call( ep::variable_list &a,
- Func &&f,
- Deduced&&...deduced )
- {
- using arg_type = typename Traits::template arg_t<pos>::type;
- return _Caller<pos + 1, max, Traits>::_Process_and_call( a,
- std::forward<Func>( f ),
- std::forward<Deduced>( deduced )...,
- _Var_deducer<arg_type>::deduce( a[pos] ) );
- }
- };
- template<size_t max, typename Traits, typename Ret>
- struct _Caller<max, max, Traits, Ret>
- {
- template<typename Func, typename...Deduced>
- static typename Traits::result_type
- _Process_and_call( ep::variable_list &a,
- Func &&f,
- Deduced&&...deduced )
- {
- return std::forward<Func>( f )( std::forward<Deduced>( deduced )... );
- }
- };
- template<size_t max, typename Traits>
- struct _Caller<max, max, Traits, void>
- {
- template<typename Func, typename...Deduced>
- static ep::value_reference_ptr
- _Process_and_call( ep::variable_list &a,
- Func &&f,
- Deduced&&...deduced )
- {
- std::forward<Func>( f )( std::forward<Deduced>( deduced )... );
- return ep::void_return;
- }
- };
- template<size_t pos, size_t max, typename traits>
- struct _Arg_emplacer
- {
- static void emplace( ep::method_argument_list &list )
- {
- using arg_t = typename traits::template arg_t<pos>::type;
- list.emplace_back( new ep::method_argument( arg_pos_to_string<pos>::value,
- std::is_reference<arg_t>::value || std::is_base_of<_Ref_ptr, arg_t>::value ) );
- _Arg_emplacer<pos + 1, max, traits>::emplace( list );
- }
- };
- template<size_t max, typename traits>
- struct _Arg_emplacer<max, max, traits>
- {
- static void emplace( ep::method_argument_list &list )
- { }
- };
- template<typename T>
- struct _Build_method_from_t
- {
- template<typename _Invalid>
- static ep::method_ptr _Build( std::string, _Invalid &&invalid )
- {
- throw;
- }
- };
- template<typename Ret, typename T, typename...Params>
- struct _Build_method_from_t<Ret( T::* )( Params... ) const>
- {
- template<typename _Func>
- static ep::method_ptr _Build( std::string name, _Func &&functor )
- {
- using traits = callable_traits<Ret( Params... )>;
- ep::method_argument_list args;
- auto method = [func = std::function<Ret( Params... )>( std::forward<_Func>( functor ) )]( ep::variable_list fargs,
- ep::dispatch_engine_ptr )
- {
- return _Caller<0, traits::size, traits>::_Process_and_call( fargs,
- func );
- };
- _Arg_emplacer<0, traits::size, traits>::emplace( args );
- return std::make_shared<ep::method>( std::move( name ),
- std::move( args ),
- std::move( method ) );
- }
- };
- template<typename Ret, typename T>
- struct _Build_method_from_t<Ret( T::* )( ) const>
- {
- template<typename _Func>
- static ep::method_ptr _Build( std::string name, _Func &&functor )
- {
- using traits = callable_traits<Ret( )>;
- ep::method_argument_list args;
- auto method = [func = std::function<Ret( )>( std::forward<_Func>( functor ) )]( ep::variable_list fargs,
- ep::dispatch_engine_ptr )
- {
- return func( );
- };
- _Arg_emplacer<0, traits::size, traits>::emplace( args );
- return std::make_shared<ep::method>( std::move( name ),
- std::move( args ),
- std::move( method ) );
- }
- };
- template<typename T>
- struct _Build_member_method_from_t
- {
- template<typename _Invalid>
- static ep::method_ptr _Build( std::string name,
- _Invalid && )
- {
- static_assert( false, "_Build_member_method_from_t expects callable object as T" );
- }
- };
- template<typename Ret, typename T, typename...Params>
- struct _Build_member_method_from_t<Ret( T::* )( Params... ) const>
- {
- template<typename _Func>
- static ep::method_ptr _Build( std::string name,
- _Func &&functor )
- {
- using traits = callable_traits<Ret( Params... )>;
- ep::method_argument_list args;
- auto method = [func = std::function<Ret( Params... )>( std::forward<_Func>( functor ) )]( ep::variable_list fargs,
- ep::dispatch_engine_ptr )
- {
- return _Caller<0, traits::size, traits>::_Process_and_call( fargs,
- func );
- };
- _Arg_emplacer<1, traits::size, traits>::emplace( args );
- return std::make_shared<ep::method>( std::move( name ),
- std::move( args ),
- std::move( method ) );
- }
- };
- template<typename Ret, typename T>
- struct _Build_member_method_from_t<Ret( T::* )( ) const>
- {
- template<typename _Func>
- static ep::method_ptr _Build( std::string name,
- _Func &&functor )
- {
- using traits = callable_traits<Ret( )>;
- ep::method_argument_list args;
- auto method = [func = std::function<Ret( )>( std::forward<_Func>( functor ) )]( ep::variable_list fargs,
- ep::dispatch_engine_ptr )
- {
- return _Caller<0, traits::size, traits>::_Process_and_call( fargs,
- func );
- };
- _Arg_emplacer<1, traits::size, traits>::emplace( args );
- return std::make_shared<ep::method>( std::move( name ),
- std::move( args ),
- std::move( method ) );
- }
- };
- template<typename..._Specialization>
- struct create_type_impl;
- template<>
- struct create_type_impl<>
- {
- static ep::type_info_ptr _Do( ep::type_info_ptr ti )
- {
- return std::move( ti );
- }
- };
- template<typename Str, typename T, typename..._Specialization>
- struct create_type_impl<Str, T, _Specialization...>
- {
- static ep::type_info_ptr _Do( ep::type_info_ptr ti,
- Str &&str,
- T &&t,
- _Specialization&&...spec )
- {
- ti->add_method( std::move( _Build_member_method_from_t<decltype( &T::operator() )>::_Build( std::forward<Str>( str ),
- std::forward<T>( t ) ) ) );
- return create_type_impl<_Specialization...>::_Do( std::move( ti ),
- std::forward<_Specialization>( spec )... );
- }
- };
- template<typename Str, typename T>
- struct create_type_impl<Str, T>
- {
- static ep::type_info_ptr _Do( ep::type_info_ptr ti,
- Str &&str,
- T &&t )
- {
- ti->add_method( std::move( _Build_member_method_from_t<decltype( &T::operator() )>::_Build( std::forward<Str>( str ),
- std::forward<T>( t ) ) ) );
- return std::move( ti );
- }
- };
- template<size_t arity, size_t mod = arity % 2>
- struct _Check_arity_impl;
- template<typename..._Arity>
- struct _Check_arity
- {
- static constexpr bool value = _Check_arity_impl<sizeof...( _Arity )>::value;
- };
- template<>
- struct _Check_arity<>
- {
- static constexpr bool value = true;
- };
- template<size_t arity>
- struct _Check_arity_impl<arity, 0>
- {
- static constexpr bool value = false;
- };
- template<size_t arity, size_t mod>
- struct _Check_arity_impl
- {
- static constexpr bool value = true;
- };
- }
- template<typename _Dtor, typename _Ctor, typename..._Specialization>
- static ep::type_info_ptr create_type( std::string name, _Dtor &&dtor, _Ctor &&ctor, _Specialization&&...spec )
- {
- static_assert( !details::_Check_arity<_Specialization...>::value,
- "uneven arity, expects arity of pattern (StrConvertable, Callable, Continuation...)" );
- return details::create_type_impl<_Specialization...>::_Do( std::make_shared<ep::type_info>( std::move( name ),
- std::forward<_Dtor>( dtor ),
- std::forward<_Ctor>( ctor ) ),
- std::forward<_Specialization>( spec )... );
- }
- template<typename _Ctor, typename _Dtor, typename _Clone, typename..._Specialization>
- static void add_type( ep::module_ptr &module,
- std::string name,
- _Ctor &&ctor,
- _Dtor &&dtor,
- _Clone &&clone,
- _Specialization&&...spec )
- {
- auto engine = module->get_engine( );
- auto type = create_type( name,
- std::forward<_Dtor>( dtor ),
- std::forward<_Clone>( clone ),
- std::forward<_Specialization>( spec )... );
- engine->add_method( details::_Build_method_from_t<decltype( &_Ctor::operator() )>::_Build( std::move( name ),
- std::forward<_Ctor>( ctor ) ) );
- engine->add_type( std::move( type ) );
- }
- template<typename _Ctor, typename _Dtor, typename _Clone, typename..._Specialization>
- static void add_type( ep::dispatch_engine_ptr &engine,
- std::string name,
- _Ctor &&ctor,
- _Dtor &&dtor,
- _Clone &&clone,
- _Specialization&&...spec )
- {
- auto type = create_type( name,
- std::forward<_Dtor>( dtor ),
- std::forward<_Clone>( clone ),
- std::forward<_Specialization>( spec )... );
- engine->add_method( details::_Build_method_from_t<decltype( &_Ctor::operator() )>::_Build( std::move( name ),
- std::forward<_Ctor>( ctor ) ) );
- engine->add_type( std::move( type ) );
- }
- template<typename Str, typename T>
- static auto make_method( Str && str,
- T &&t )
- {
- return details::_Build_method_from_t<decltype( &T::operator() )>::_Build( std::forward<Str>( str ),
- std::forward<T>( t ) );
- }
- template<typename T, typename...Ts>
- static plugin_list load_plugins_impl( plugin_list &output, T &&t, Ts&&...ts )
- {
- output.emplace_back( load_plugin( std::forward<T>( t ) ) );
- return load_plugins_impl( output, std::forward<Ts>( ts )... );
- }
- template<typename T>
- static plugin_list load_plugins_impl( plugin_list &output, T &&t )
- {
- output.emplace_back( load_plugin( std::forward<T>( t ) ) );
- return output;
- }
- template<typename...Ts>
- static plugin_list load_plugins( Ts&&...ts )
- {
- plugin_list list;
- return load_plugins_impl( list, std::forward<Ts>( ts )... );
- }
- // wrapper for passing variable_ptr as reference
- struct argument_ptr_ref
- : public details::_Ref_ptr
- {
- using ref = void;
- variable_ptr variable;
- argument_ptr_ref( ep::variable_ptr &ptr )
- : variable( ptr )
- { }
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement