class Command
{
public:
Command(const std::string&);
std::vector<std::string> getArguments();
std::vector<std::string> getOptions();
virtual void execute(Directory& currentDirectory) = 0;
virtual std::string getCommandName() = 0;
protected:
std::vector<std::string> arguments_;
std::vector<std::string> options_;
void parseStr(std::string);
};
std::string commandLine = console.getSomeCommandLine();
Command command;
std::string error;
if (!command.parse(commandLine, error)) {
console.err().writeln(error);
return;
}
Program* program = system.findProgram(command.programName);
if (!program) {
console.err().writeln("Bad command or file name");
return;
}
Console redirectedConsole = console.redirectStreams(command);
program->exec(redirectedConsole, system, command.getArguments());
const std::vector<std::string>& getArguments() const;
const std::vector<std::string>& getOptions() const;
template< typename TInterface, typename... TArguments >
class AbstractFactory final
{
public:
// Produce the implementation, but return the pointer to interface.
inline std::shared_ptr<TInterface> Produce( const std::string& implementation_name, TArguments... arguments )
{
auto found_function = m_factory_functions.find( implementation_name );
return ( found_function == m_factory_functions.end() )? std::shared_ptr<TInterface>{} : found_function->second( std::forward<TArguments>( arguments )... );
};
// Define the implementation.
template< typename TImplementation >
inline const bool DefineImplementation()
{
return DefineImplementation<TImplementation>( TImplementation::ClassName() );
};
// Define the implementation.
template< typename TImplementation >
inline const bool DefineImplementation( const std::string& implementation_name )
{
// Abort the incorrect registration.
static_assert( std::is_base_of<TInterface, TImplementation>::value, "Implementation may only be derived from interface of Factory." );
auto found_function = m_factory_functions.find( implementation_name );
if( found_function == m_factory_functions.end() )
{
m_factory_functions[ implementation_name ] = &AbstractFactory<TInterface, TArguments...>::template ConstructImplementation<TImplementation>;
return true;
};
return false;
};
// Check the implementation name is already defined.
inline const bool IsImplementationDefined( const std::string& implementation_name ) const
{
return m_factory_functions.find( implementation_name ) != m_factory_functions.end();
};
private:
// The factory function just produce implementation.
template< typename TImplementation >
static std::shared_ptr<TInterface> ConstructImplementation( TArguments... arguments )
{
return std::static_pointer_cast<TInterface>(
std::make_shared<TImplementation>( std::forward<TArguments>( arguments )... )
);
};
private:
// Factory function produces the implementations of TInterface.
using FactoryFunction = std::shared_ptr<TInterface> (*)( TArguments... arguments );
std::unordered_map<std::string, FactoryFunction> m_factory_functions;
};