[Command 设计模式] ( Modern C++ | 模板元编程 | 编译时&运行时多态 | 任务队列 | 树形结构)

接口调用示例

 

int main( void ){
	Atomic< int > A( [](const int& a,
						const int& b)->int{
					return a + b;
	}, 2, 3 );
	A.SetSignature("Calculate 2+3");

	Atomic< double > B( []( const int& a,
							const int& b)->double{
					return ( double )a/b;
	}, 2, 3);
	B.SetSignature("Calculate 2/3");

	Atomic< int > C( []( const int& a,
						 const int& b)->int{
					return a* b;
	}, 2, 3);
	C.SetSignature("Calculate 2*3");

	Macro D("D");
	D.pushCommand( &A );
	D.pushCommand( &B );
	D.SetSignature("Macro : Agressiate Atomic A & B");

	Macro E("E");
	E.pushCommand( &C );
	E.pushCommand( &D );
	E.SetSignature("Macro : Agressiate Atomic C & D and Macro A");

	E.execute();
	
	::std::cout << "Atomic A result:\t"
				<< A.GetResult();
	::std::endl( ::std::cout );

	::std::cout << "Atomic B result:\t"
				<< B.GetResult();
	::std::endl( ::std::cout );

	::std::cout << "Atomic C result:\t"
				<< C.GetResult();
	::std::endl( ::std::cout );

	return 0;
}

[Command 设计模式] ( Modern C++ | 模板元编程 | 编译时&运行时多态 | 任务队列 | 树形结构)_第1张图片

具体实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

template < typename _Ty, typename...Args >
constexpr inline
void __print_type( void ){
	if constexpr ( not ::std::is_function_v< ::std::remove_pointer< _Ty> > ){
		auto _Msg = typeid( _Ty ).name();
		::std::clog << _Msg << "\t";
		if constexpr( sizeof...(Args) ) __print_type< Args... >();
		else ::std::endl( ::std::clog );
	}else throw ::std::runtime_error("__print_type: met function object");
}

template < typename _Ty, typename...Args >
inline
void print_type( void ){
	try{ __print_type< _Ty, Args... >(); }
	catch( const ::std::runtime_error& e){
		::std::cerr << e.what();
	}catch(...){
		::std::cerr << "print_type: unknown error";
	}
}

class Command{
protected:
	::std::string_view _Signature;
public:
	Command( void ) = default;
	Command( const ::std::string_view& sign )
		:_Signature( sign ) {}
	virtual ~Command( void ) {}
	virtual void execute( void ) = 0;
	inline
	void SetSignature( const ::std::string_view& sign ){
		_Signature = sign;
	}
	inline
	const char * GetSignature( void ) const{
		return _Signature.data();
	}
	void print_log( ::std::ostream& out ) const{
		char buf[ 64 ] { 0 };
		sprintf( buf,
				 "Command %s is executing...\n",
				 _Signature.data() );
		out << buf << ::std::endl;
	}
};

template < class _Ty >
class Atomic : public Command{
private:
class CallableExcept : public ::std::exception{
private: const char *_Msg { nullptr };
public:
	CallableExcept( const char * str )
		:_Msg( str ) {}
	virtual const char* what( void ) const noexcept{
		return _Msg;
	}
};

protected:
	::std::function< _Ty( void ) > _Action;
	_Ty _Result;
public:
	Atomic( void ) = default;
	template < class _Fn, class...Args >
	Atomic( _Fn&& f, Args&&...args ){
		try {SetAction( f, args... );}
		catch( const CallableExcept& e){
			::std::cerr << e.what();
			::std::endl( ::std::cerr );
			::std::clog.flush();
			print_type<_Ty, decltype( f( args... ) )>();
		}
		catch(...){
			::std::cerr << "print_type: unknown error";
		}
 	}
		
 	virtual ~Atomic( void ) {}
 	
	template < class _Fn, class...Args >
	constexpr
	void SetAction( _Fn&& f, Args&&...args ){
		static_assert( ::std::is_invocable_v< _Fn, Args... > );
		if constexpr( not ::std::is_same< _Ty,
				typename ::std::result_of< _Fn&&(Args&&...) >::type >
				::value )
			throw CallableExcept("_Ty and result type of _Fn mismatch");
		_Action = ::std::bind( ::std::forward< _Fn >( f ),
							   ::std::forward< Args >( args )... );
 	}

	virtual void execute( void ) override{
		Command::print_log( ::std::cout );
		auto _FuncWrapper =
		[this]{
			_Result = _Action();
		};
		::std::invoke( _FuncWrapper );
	}

	inline constexpr
	const _Ty& GetResult( void ) const noexcept{
		return _Result;
	}
};

class Macro : public Command{
private:
class HandleCommandExcept : public ::std::exception{
private: const char *_Msg { nullptr };
public:
	HandleCommandExcept( const char * str )
		:_Msg( str ) {}
	virtual const char* what( void ) noexcept{
		return _Msg;
	}
};
	Command *_Cache { nullptr };
	::std::queue< Command * > _Aggressive;
public:
	Macro( void ) = default;
	Macro( const ::std::string_view& sign )
		: Command( sign ) {}
	virtual void execute( void ) override{
		Command::print_log( ::std::cout );
		while( !_Aggressive.empty() ) single();
	}
	inline
	void single( void ) noexcept{
		( _Aggressive.front() )->execute();
		_Aggressive.pop();
	}
	inline
	void pushCommand( Command *command ) noexcept{
		_Aggressive.push( command );
	}
	inline
	void undoCommand( void ){
		if( _Aggressive.empty() )
			throw HandleCommandExcept( "Aggressive commands empty" );
		_Aggressive.pop();
	}
	inline
	void redoCommand( void ){
		if( !_Cache )
			throw HandleCommandExcept( "No cache command buffered" );
		pushCommand( _Cache );
		_Cache = nullptr;
	}
};

你可能感兴趣的:(设计模式,语言特性,Modern,Cpp,c++,设计模式,开发语言,数据结构,链表)