Loading src/TNL/Config/CMakeLists.txt +5 −17 Original line number Diff line number Diff line Loading @@ -5,21 +5,9 @@ SET( headers ConfigEntryList.h ConfigDelimiter.h ConfigDescription.h make_unique.h ParameterContainer.h parseCommandLine.h ) SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Config ) set( common_SOURCES ${CURRENT_DIR}/ConfigDescription.cpp ${CURRENT_DIR}/ParameterContainer.cpp ) SET( tnl_config_SOURCES ${common_SOURCES} PARENT_SCOPE ) if( BUILD_CUDA ) SET( tnl_config_CUDA__SOURCES ${common_SOURCES} PARENT_SCOPE ) endif() INSTALL( FILES ${headers} DESTINATION ${TNL_TARGET_INCLUDE_DIRECTORY}/Config ) src/TNL/Config/ConfigDescription.cppdeleted 100644 → 0 +0 −146 Original line number Diff line number Diff line /*************************************************************************** Config::ConfigDescription.cpp - description ------------------- begin : 2007/06/09 copyright : (C) 2007 by Tomas Oberhuber email : tomas.oberhuber@fjfi.cvut.cz ***************************************************************************/ /* See Copyright Notice in tnl/Copyright */ #include <fstream> #include <iomanip> #include <string> #include <TNL/Config/ConfigDescription.h> #include <TNL/Config/ParameterContainer.h> namespace TNL { namespace Config { void ConfigDescription:: printUsage( const char* program_name ) const { std::cout << "Usage of: " << program_name << std::endl << std::endl; const int entries_num = entries.size(); int max_name_length( 0 ); int max_type_length( 0 ); for( int j = 0; j < entries_num; j++ ) if( ! entries[ j ]->isDelimiter() ) { max_name_length = std::max( max_name_length, entries[ j ] -> name. getLength() ); max_type_length = std::max( max_type_length, entries[ j ] -> getUIEntryType().getLength() ); } max_name_length += 2; // this is for '--' for( int j = 0; j < entries_num; j++ ) { if( entries[ j ]->isDelimiter() ) { std::cout << std::endl; std::cout << entries[ j ]->description; std::cout << std::endl << std::endl; } else { std::cout << std::setw( max_name_length + 3 ) << String( "--" ) + entries[ j ]->name << std::setw( max_type_length + 5 ) << entries[ j ] -> getUIEntryType() << " " << entries[ j ]->description; if( entries[ j ] -> required ) std::cout << " *** REQUIRED ***"; if( entries[ j ]->hasEnumValues() ) { std::cout << std::endl << std::setw( max_name_length + 3 ) << "" << std::setw( max_type_length + 5 ) << "" << " "; entries[ j ]->printEnumValues(); } if( entries[ j ]->hasDefaultValue ) { std::cout << std::endl << std::setw( max_name_length + 3 ) << "" << std::setw( max_type_length + 5 ) << "" << " "; std::cout << "- Default value is: " << entries[ j ]->printDefaultValue(); } std::cout << std::endl; } } std::cout << std::endl; } void ConfigDescription:: addMissingEntries( Config::ParameterContainer& parameter_container ) const { const int size = entries.size(); for( int i = 0; i < size; i++ ) { const char* entry_name = entries[ i ]->name.getString(); if( entries[ i ]->hasDefaultValue && ! parameter_container.checkParameter( entry_name ) ) { if( entries[ i ]->getEntryType() == "String" ) { ConfigEntry< String >& entry = dynamic_cast< ConfigEntry< String >& >( *entries[ i ] ); parameter_container.addParameter< String >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "bool" ) { ConfigEntry< bool >& entry = dynamic_cast< ConfigEntry< bool >& >( *entries[ i ] ); parameter_container.addParameter< bool >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "int" ) { ConfigEntry< int >& entry = dynamic_cast< ConfigEntry< int >& >( *entries[ i ] ); parameter_container.addParameter< int >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "double" ) { ConfigEntry< double >& entry = dynamic_cast< ConfigEntry< double >& >( *entries[ i ] ); parameter_container.addParameter< double >( entry_name, entry.defaultValue ); continue; } } } } bool Config::ConfigDescription:: checkMissingEntries( Config::ParameterContainer& parameter_container, bool printUsage, const char* programName ) const { const int size = entries.size(); std::vector< std::string > missingParameters; for( int i = 0; i < size; i++ ) { const char* entry_name = entries[ i ] -> name.getString(); if( entries[ i ] -> required && ! parameter_container.checkParameter( entry_name ) ) missingParameters.push_back( entry_name ); } if( missingParameters.size() > 0 ) { std::cerr << "Some mandatory parameters are misssing. They are listed at the end. " << std::endl; if( printUsage ) this->printUsage( programName ); std::cerr << "Add the following missing parameters to the command line: " << std::endl << " "; for( int i = 0; i < (int) missingParameters.size(); i++ ) std::cerr << "--" << missingParameters[ i ] << " ... "; std::cerr << std::endl; return false; } return true; } } // namespace Config } // namespace TNL src/TNL/Config/ConfigDescription.h +118 −17 Original line number Diff line number Diff line Loading @@ -10,20 +10,11 @@ #pragma once #include <iomanip> #include <string> #include <vector> #include <memory> // std::make_unique does not exist until C++14 // https://stackoverflow.com/a/9657991 #if __cplusplus < 201402L namespace std { template<typename T, typename ...Args> std::unique_ptr<T> make_unique( Args&& ...args ) { return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) ); } } #endif #include "make_unique.h" #include <TNL/Assert.h> #include <TNL/String.h> Loading @@ -32,12 +23,11 @@ namespace std { #include <TNL/Config/ConfigEntry.h> #include <TNL/Config/ConfigEntryList.h> #include <TNL/Config/ConfigDelimiter.h> #include <TNL/Config/ParameterContainer.h> namespace TNL { namespace Config { class ParameterContainer; class ConfigDescription { public: Loading Loading @@ -245,21 +235,130 @@ public: * If there is missing entry with defined default value in the Config::ParameterContainer it is going to be added. * \param parameter_container Name of the ParameterContainer object. */ void addMissingEntries( Config::ParameterContainer& parameter_container ) const; void addMissingEntries( Config::ParameterContainer& parameter_container ) const { const int size = entries.size(); for( int i = 0; i < size; i++ ) { const char* entry_name = entries[ i ]->name.getString(); if( entries[ i ]->hasDefaultValue && ! parameter_container.checkParameter( entry_name ) ) { if( entries[ i ]->getEntryType() == "String" ) { ConfigEntry< String >& entry = dynamic_cast< ConfigEntry< String >& >( *entries[ i ] ); parameter_container.addParameter< String >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "bool" ) { ConfigEntry< bool >& entry = dynamic_cast< ConfigEntry< bool >& >( *entries[ i ] ); parameter_container.addParameter< bool >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "int" ) { ConfigEntry< int >& entry = dynamic_cast< ConfigEntry< int >& >( *entries[ i ] ); parameter_container.addParameter< int >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "double" ) { ConfigEntry< double >& entry = dynamic_cast< ConfigEntry< double >& >( *entries[ i ] ); parameter_container.addParameter< double >( entry_name, entry.defaultValue ); continue; } } } } //! Check for all entries with the flag 'required'. /*! Returns false if any parameter is missing. */ bool checkMissingEntries( Config::ParameterContainer& parameter_container, bool printUsage, const char* programName ) const; const char* programName ) const { const int size = entries.size(); std::vector< std::string > missingParameters; for( int i = 0; i < size; i++ ) { const char* entry_name = entries[ i ] -> name.getString(); if( entries[ i ] -> required && ! parameter_container.checkParameter( entry_name ) ) missingParameters.push_back( entry_name ); } if( missingParameters.size() > 0 ) { std::cerr << "Some mandatory parameters are misssing. They are listed at the end. " << std::endl; if( printUsage ) this->printUsage( programName ); std::cerr << "Add the following missing parameters to the command line: " << std::endl << " "; for( int i = 0; i < (int) missingParameters.size(); i++ ) std::cerr << "--" << missingParameters[ i ] << " ... "; std::cerr << std::endl; return false; } return true; } /** * \brief Prints configuration description with the \e program_name at the top. * * \param program_name Name of the program */ void printUsage( const char* program_name ) const; void printUsage( const char* program_name ) const { std::cout << "Usage of: " << program_name << std::endl << std::endl; const int entries_num = entries.size(); int max_name_length( 0 ); int max_type_length( 0 ); for( int j = 0; j < entries_num; j++ ) if( ! entries[ j ]->isDelimiter() ) { max_name_length = std::max( max_name_length, entries[ j ] -> name. getLength() ); max_type_length = std::max( max_type_length, entries[ j ] -> getUIEntryType().getLength() ); } max_name_length += 2; // this is for '--' for( int j = 0; j < entries_num; j++ ) { if( entries[ j ]->isDelimiter() ) { std::cout << std::endl; std::cout << entries[ j ]->description; std::cout << std::endl << std::endl; } else { std::cout << std::setw( max_name_length + 3 ) << String( "--" ) + entries[ j ]->name << std::setw( max_type_length + 5 ) << entries[ j ] -> getUIEntryType() << " " << entries[ j ]->description; if( entries[ j ] -> required ) std::cout << " *** REQUIRED ***"; if( entries[ j ]->hasEnumValues() ) { std::cout << std::endl << std::setw( max_name_length + 3 ) << "" << std::setw( max_type_length + 5 ) << "" << " "; entries[ j ]->printEnumValues(); } if( entries[ j ]->hasDefaultValue ) { std::cout << std::endl << std::setw( max_name_length + 3 ) << "" << std::setw( max_type_length + 5 ) << "" << " "; std::cout << "- Default value is: " << entries[ j ]->printDefaultValue(); } std::cout << std::endl; } } std::cout << std::endl; } //bool parseConfigDescription( const char* file_name ); Loading @@ -270,3 +369,5 @@ protected: } //namespace Config } //namespace TNL #include <TNL/Config/parseCommandLine.h> src/TNL/Config/ParameterContainer.h +102 −42 Original line number Diff line number Diff line Loading @@ -12,8 +12,8 @@ #include <vector> #include <memory> #include "make_unique.h" #include <TNL/Config/ConfigDescription.h> #include <TNL/param-types.h> //#include <TNL/Debugging/StackBacktrace.h> Loading Loading @@ -58,14 +58,25 @@ public: */ template< class T > bool addParameter( const String& name, const T& value ); const T& value ) { parameters.push_back( std::make_unique< Parameter< T > >( name, TNL::getType< T >(), value ) ); return true; } /** * \brief Checks whether the parameter \e name already exists in ParameterContainer. * * \param name Name of the parameter. */ bool checkParameter( const String& name ) const; bool checkParameter( const String& name ) const { const int size = parameters.size(); for( int i = 0; i < size; i++ ) if( parameters[ i ]->name == name ) return true; return false; } /** * \brief Assigns new \e value to the parameter \e name. Loading @@ -76,7 +87,25 @@ public: */ template< class T > bool setParameter( const String& name, const T& value ); const T& value ) { for( int i = 0; i < (int) parameters.size(); i++ ) { if( parameters[ i ]->name == name ) { if( parameters[ i ]->type == TNL::getType< T >() ) { Parameter< T >& parameter = dynamic_cast< Parameter< T >& >( *parameters[ i ] ); parameter.value = value; return true; } else { std::cerr << "Parameter " << name << " already exists with different type " << parameters[ i ]->type << " not " << TNL::getType< T >() << std::endl; throw 0; } } } return addParameter< T >( name, value ); } /** * \brief Checks whether the parameter \e name is given the \e value. Loading Loading @@ -133,49 +162,80 @@ public: throw 0; } /* //! Broadcast to other nodes in MPI cluster //void MPIBcast( int root, MPI_Comm mpi_comm = MPI_COMM_WORLD ); protected: std::vector< std::unique_ptr< ParameterBase > > parameters; }; bool parseCommandLine( int argc, char* argv[], const ConfigDescription& config_description, ParameterContainer& parameters, bool printUsage = true ); template< class T > bool ParameterContainer:: addParameter( const String& name, const T& value ) void MPIBcast( int root, MPI_Comm mpi_comm = MPI_COMM_WORLD ) { parameters.push_back( std::make_unique< Parameter< T > >( name, TNL::getType< T >(), value ) ); return true; }; template< class T > bool ParameterContainer:: setParameter( const String& name, const T& value ) #ifdef USE_MPI int i; int size = parameters. getSize(); :: MPIBcast( size, 1, root, mpi_comm ); for( i = 0; i < size; i ++ ) { for( int i = 0; i < (int) parameters.size(); i++ ) { if( parameters[ i ]->name == name ) { if( parameters[ i ]->type == TNL::getType< T >() ) { Parameter< T >& parameter = dynamic_cast< Parameter< T >& >( *parameters[ i ] ); parameter.value = value; return true; if( MPIGetRank() == root ) { tnlParameterBase* param = parameters[ i ]; param -> type. MPIBcast( root, MPI_COMM_WORLD ); param -> name. MPIBcast( root, MPI_COMM_WORLD ); if( param -> type == "String" ) { ( ( tnlParameter< String >* ) param ) -> value. MPIBcast( root, mpi_comm ); } else { std::cerr << "Parameter " << name << " already exists with different type " << parameters[ i ]->type << " not " << TNL::getType< T >() << std::endl; throw 0; if( param -> type == "bool" ) { :: MPIBcast( ( ( tnlParameter< bool >* ) param ) -> value, 1, root, mpi_comm ); } if( param -> type == "int" ) { :: MPIBcast( ( ( tnlParameter< int >* ) param ) -> value, 1, root, mpi_comm ); } if( param -> type == "double" ) { :: MPIBcast( ( ( tnlParameter< double >* ) param ) -> value, 1, root, mpi_comm ); } } return addParameter< T >( name, value ); else { String param_type, param_name; param_type. MPIBcast( root, MPI_COMM_WORLD ); param_name. MPIBcast( root, MPI_COMM_WORLD ); if( param_type == "mString" ) { String val; val. MPIBcast( root, mpi_comm ); addParameter< String >( param_name. getString(), val ); } if( param_type == "bool" ) { bool val; :: MPIBcast( val, 1, root, mpi_comm ); addParameter< bool >( param_name. getString(), val ); } if( param_type == "int" ) { int val; :: MPIBcast( val, 1, root, mpi_comm ); addParameter< int >( param_name. getString(), val ); } if( param_type == "double" ) { double val; :: MPIBcast( val, 1, root, mpi_comm ); addParameter< double >( param_name. getString(), val ); } } } #endif } */ protected: std::vector< std::unique_ptr< ParameterBase > > parameters; }; } // namespace Config Loading src/TNL/Config/make_unique.h 0 → 100644 +15 −0 Original line number Diff line number Diff line #pragma once // std::make_unique does not exist until C++14 // https://stackoverflow.com/a/9657991 #if __cplusplus < 201402L #include <memory> namespace std { template<typename T, typename ...Args> std::unique_ptr<T> make_unique( Args&& ...args ) { return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) ); } } #endif Loading
src/TNL/Config/CMakeLists.txt +5 −17 Original line number Diff line number Diff line Loading @@ -5,21 +5,9 @@ SET( headers ConfigEntryList.h ConfigDelimiter.h ConfigDescription.h make_unique.h ParameterContainer.h parseCommandLine.h ) SET( CURRENT_DIR ${CMAKE_SOURCE_DIR}/src/TNL/Config ) set( common_SOURCES ${CURRENT_DIR}/ConfigDescription.cpp ${CURRENT_DIR}/ParameterContainer.cpp ) SET( tnl_config_SOURCES ${common_SOURCES} PARENT_SCOPE ) if( BUILD_CUDA ) SET( tnl_config_CUDA__SOURCES ${common_SOURCES} PARENT_SCOPE ) endif() INSTALL( FILES ${headers} DESTINATION ${TNL_TARGET_INCLUDE_DIRECTORY}/Config )
src/TNL/Config/ConfigDescription.cppdeleted 100644 → 0 +0 −146 Original line number Diff line number Diff line /*************************************************************************** Config::ConfigDescription.cpp - description ------------------- begin : 2007/06/09 copyright : (C) 2007 by Tomas Oberhuber email : tomas.oberhuber@fjfi.cvut.cz ***************************************************************************/ /* See Copyright Notice in tnl/Copyright */ #include <fstream> #include <iomanip> #include <string> #include <TNL/Config/ConfigDescription.h> #include <TNL/Config/ParameterContainer.h> namespace TNL { namespace Config { void ConfigDescription:: printUsage( const char* program_name ) const { std::cout << "Usage of: " << program_name << std::endl << std::endl; const int entries_num = entries.size(); int max_name_length( 0 ); int max_type_length( 0 ); for( int j = 0; j < entries_num; j++ ) if( ! entries[ j ]->isDelimiter() ) { max_name_length = std::max( max_name_length, entries[ j ] -> name. getLength() ); max_type_length = std::max( max_type_length, entries[ j ] -> getUIEntryType().getLength() ); } max_name_length += 2; // this is for '--' for( int j = 0; j < entries_num; j++ ) { if( entries[ j ]->isDelimiter() ) { std::cout << std::endl; std::cout << entries[ j ]->description; std::cout << std::endl << std::endl; } else { std::cout << std::setw( max_name_length + 3 ) << String( "--" ) + entries[ j ]->name << std::setw( max_type_length + 5 ) << entries[ j ] -> getUIEntryType() << " " << entries[ j ]->description; if( entries[ j ] -> required ) std::cout << " *** REQUIRED ***"; if( entries[ j ]->hasEnumValues() ) { std::cout << std::endl << std::setw( max_name_length + 3 ) << "" << std::setw( max_type_length + 5 ) << "" << " "; entries[ j ]->printEnumValues(); } if( entries[ j ]->hasDefaultValue ) { std::cout << std::endl << std::setw( max_name_length + 3 ) << "" << std::setw( max_type_length + 5 ) << "" << " "; std::cout << "- Default value is: " << entries[ j ]->printDefaultValue(); } std::cout << std::endl; } } std::cout << std::endl; } void ConfigDescription:: addMissingEntries( Config::ParameterContainer& parameter_container ) const { const int size = entries.size(); for( int i = 0; i < size; i++ ) { const char* entry_name = entries[ i ]->name.getString(); if( entries[ i ]->hasDefaultValue && ! parameter_container.checkParameter( entry_name ) ) { if( entries[ i ]->getEntryType() == "String" ) { ConfigEntry< String >& entry = dynamic_cast< ConfigEntry< String >& >( *entries[ i ] ); parameter_container.addParameter< String >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "bool" ) { ConfigEntry< bool >& entry = dynamic_cast< ConfigEntry< bool >& >( *entries[ i ] ); parameter_container.addParameter< bool >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "int" ) { ConfigEntry< int >& entry = dynamic_cast< ConfigEntry< int >& >( *entries[ i ] ); parameter_container.addParameter< int >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "double" ) { ConfigEntry< double >& entry = dynamic_cast< ConfigEntry< double >& >( *entries[ i ] ); parameter_container.addParameter< double >( entry_name, entry.defaultValue ); continue; } } } } bool Config::ConfigDescription:: checkMissingEntries( Config::ParameterContainer& parameter_container, bool printUsage, const char* programName ) const { const int size = entries.size(); std::vector< std::string > missingParameters; for( int i = 0; i < size; i++ ) { const char* entry_name = entries[ i ] -> name.getString(); if( entries[ i ] -> required && ! parameter_container.checkParameter( entry_name ) ) missingParameters.push_back( entry_name ); } if( missingParameters.size() > 0 ) { std::cerr << "Some mandatory parameters are misssing. They are listed at the end. " << std::endl; if( printUsage ) this->printUsage( programName ); std::cerr << "Add the following missing parameters to the command line: " << std::endl << " "; for( int i = 0; i < (int) missingParameters.size(); i++ ) std::cerr << "--" << missingParameters[ i ] << " ... "; std::cerr << std::endl; return false; } return true; } } // namespace Config } // namespace TNL
src/TNL/Config/ConfigDescription.h +118 −17 Original line number Diff line number Diff line Loading @@ -10,20 +10,11 @@ #pragma once #include <iomanip> #include <string> #include <vector> #include <memory> // std::make_unique does not exist until C++14 // https://stackoverflow.com/a/9657991 #if __cplusplus < 201402L namespace std { template<typename T, typename ...Args> std::unique_ptr<T> make_unique( Args&& ...args ) { return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) ); } } #endif #include "make_unique.h" #include <TNL/Assert.h> #include <TNL/String.h> Loading @@ -32,12 +23,11 @@ namespace std { #include <TNL/Config/ConfigEntry.h> #include <TNL/Config/ConfigEntryList.h> #include <TNL/Config/ConfigDelimiter.h> #include <TNL/Config/ParameterContainer.h> namespace TNL { namespace Config { class ParameterContainer; class ConfigDescription { public: Loading Loading @@ -245,21 +235,130 @@ public: * If there is missing entry with defined default value in the Config::ParameterContainer it is going to be added. * \param parameter_container Name of the ParameterContainer object. */ void addMissingEntries( Config::ParameterContainer& parameter_container ) const; void addMissingEntries( Config::ParameterContainer& parameter_container ) const { const int size = entries.size(); for( int i = 0; i < size; i++ ) { const char* entry_name = entries[ i ]->name.getString(); if( entries[ i ]->hasDefaultValue && ! parameter_container.checkParameter( entry_name ) ) { if( entries[ i ]->getEntryType() == "String" ) { ConfigEntry< String >& entry = dynamic_cast< ConfigEntry< String >& >( *entries[ i ] ); parameter_container.addParameter< String >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "bool" ) { ConfigEntry< bool >& entry = dynamic_cast< ConfigEntry< bool >& >( *entries[ i ] ); parameter_container.addParameter< bool >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "int" ) { ConfigEntry< int >& entry = dynamic_cast< ConfigEntry< int >& >( *entries[ i ] ); parameter_container.addParameter< int >( entry_name, entry.defaultValue ); continue; } if( entries[ i ]->getEntryType() == "double" ) { ConfigEntry< double >& entry = dynamic_cast< ConfigEntry< double >& >( *entries[ i ] ); parameter_container.addParameter< double >( entry_name, entry.defaultValue ); continue; } } } } //! Check for all entries with the flag 'required'. /*! Returns false if any parameter is missing. */ bool checkMissingEntries( Config::ParameterContainer& parameter_container, bool printUsage, const char* programName ) const; const char* programName ) const { const int size = entries.size(); std::vector< std::string > missingParameters; for( int i = 0; i < size; i++ ) { const char* entry_name = entries[ i ] -> name.getString(); if( entries[ i ] -> required && ! parameter_container.checkParameter( entry_name ) ) missingParameters.push_back( entry_name ); } if( missingParameters.size() > 0 ) { std::cerr << "Some mandatory parameters are misssing. They are listed at the end. " << std::endl; if( printUsage ) this->printUsage( programName ); std::cerr << "Add the following missing parameters to the command line: " << std::endl << " "; for( int i = 0; i < (int) missingParameters.size(); i++ ) std::cerr << "--" << missingParameters[ i ] << " ... "; std::cerr << std::endl; return false; } return true; } /** * \brief Prints configuration description with the \e program_name at the top. * * \param program_name Name of the program */ void printUsage( const char* program_name ) const; void printUsage( const char* program_name ) const { std::cout << "Usage of: " << program_name << std::endl << std::endl; const int entries_num = entries.size(); int max_name_length( 0 ); int max_type_length( 0 ); for( int j = 0; j < entries_num; j++ ) if( ! entries[ j ]->isDelimiter() ) { max_name_length = std::max( max_name_length, entries[ j ] -> name. getLength() ); max_type_length = std::max( max_type_length, entries[ j ] -> getUIEntryType().getLength() ); } max_name_length += 2; // this is for '--' for( int j = 0; j < entries_num; j++ ) { if( entries[ j ]->isDelimiter() ) { std::cout << std::endl; std::cout << entries[ j ]->description; std::cout << std::endl << std::endl; } else { std::cout << std::setw( max_name_length + 3 ) << String( "--" ) + entries[ j ]->name << std::setw( max_type_length + 5 ) << entries[ j ] -> getUIEntryType() << " " << entries[ j ]->description; if( entries[ j ] -> required ) std::cout << " *** REQUIRED ***"; if( entries[ j ]->hasEnumValues() ) { std::cout << std::endl << std::setw( max_name_length + 3 ) << "" << std::setw( max_type_length + 5 ) << "" << " "; entries[ j ]->printEnumValues(); } if( entries[ j ]->hasDefaultValue ) { std::cout << std::endl << std::setw( max_name_length + 3 ) << "" << std::setw( max_type_length + 5 ) << "" << " "; std::cout << "- Default value is: " << entries[ j ]->printDefaultValue(); } std::cout << std::endl; } } std::cout << std::endl; } //bool parseConfigDescription( const char* file_name ); Loading @@ -270,3 +369,5 @@ protected: } //namespace Config } //namespace TNL #include <TNL/Config/parseCommandLine.h>
src/TNL/Config/ParameterContainer.h +102 −42 Original line number Diff line number Diff line Loading @@ -12,8 +12,8 @@ #include <vector> #include <memory> #include "make_unique.h" #include <TNL/Config/ConfigDescription.h> #include <TNL/param-types.h> //#include <TNL/Debugging/StackBacktrace.h> Loading Loading @@ -58,14 +58,25 @@ public: */ template< class T > bool addParameter( const String& name, const T& value ); const T& value ) { parameters.push_back( std::make_unique< Parameter< T > >( name, TNL::getType< T >(), value ) ); return true; } /** * \brief Checks whether the parameter \e name already exists in ParameterContainer. * * \param name Name of the parameter. */ bool checkParameter( const String& name ) const; bool checkParameter( const String& name ) const { const int size = parameters.size(); for( int i = 0; i < size; i++ ) if( parameters[ i ]->name == name ) return true; return false; } /** * \brief Assigns new \e value to the parameter \e name. Loading @@ -76,7 +87,25 @@ public: */ template< class T > bool setParameter( const String& name, const T& value ); const T& value ) { for( int i = 0; i < (int) parameters.size(); i++ ) { if( parameters[ i ]->name == name ) { if( parameters[ i ]->type == TNL::getType< T >() ) { Parameter< T >& parameter = dynamic_cast< Parameter< T >& >( *parameters[ i ] ); parameter.value = value; return true; } else { std::cerr << "Parameter " << name << " already exists with different type " << parameters[ i ]->type << " not " << TNL::getType< T >() << std::endl; throw 0; } } } return addParameter< T >( name, value ); } /** * \brief Checks whether the parameter \e name is given the \e value. Loading Loading @@ -133,49 +162,80 @@ public: throw 0; } /* //! Broadcast to other nodes in MPI cluster //void MPIBcast( int root, MPI_Comm mpi_comm = MPI_COMM_WORLD ); protected: std::vector< std::unique_ptr< ParameterBase > > parameters; }; bool parseCommandLine( int argc, char* argv[], const ConfigDescription& config_description, ParameterContainer& parameters, bool printUsage = true ); template< class T > bool ParameterContainer:: addParameter( const String& name, const T& value ) void MPIBcast( int root, MPI_Comm mpi_comm = MPI_COMM_WORLD ) { parameters.push_back( std::make_unique< Parameter< T > >( name, TNL::getType< T >(), value ) ); return true; }; template< class T > bool ParameterContainer:: setParameter( const String& name, const T& value ) #ifdef USE_MPI int i; int size = parameters. getSize(); :: MPIBcast( size, 1, root, mpi_comm ); for( i = 0; i < size; i ++ ) { for( int i = 0; i < (int) parameters.size(); i++ ) { if( parameters[ i ]->name == name ) { if( parameters[ i ]->type == TNL::getType< T >() ) { Parameter< T >& parameter = dynamic_cast< Parameter< T >& >( *parameters[ i ] ); parameter.value = value; return true; if( MPIGetRank() == root ) { tnlParameterBase* param = parameters[ i ]; param -> type. MPIBcast( root, MPI_COMM_WORLD ); param -> name. MPIBcast( root, MPI_COMM_WORLD ); if( param -> type == "String" ) { ( ( tnlParameter< String >* ) param ) -> value. MPIBcast( root, mpi_comm ); } else { std::cerr << "Parameter " << name << " already exists with different type " << parameters[ i ]->type << " not " << TNL::getType< T >() << std::endl; throw 0; if( param -> type == "bool" ) { :: MPIBcast( ( ( tnlParameter< bool >* ) param ) -> value, 1, root, mpi_comm ); } if( param -> type == "int" ) { :: MPIBcast( ( ( tnlParameter< int >* ) param ) -> value, 1, root, mpi_comm ); } if( param -> type == "double" ) { :: MPIBcast( ( ( tnlParameter< double >* ) param ) -> value, 1, root, mpi_comm ); } } return addParameter< T >( name, value ); else { String param_type, param_name; param_type. MPIBcast( root, MPI_COMM_WORLD ); param_name. MPIBcast( root, MPI_COMM_WORLD ); if( param_type == "mString" ) { String val; val. MPIBcast( root, mpi_comm ); addParameter< String >( param_name. getString(), val ); } if( param_type == "bool" ) { bool val; :: MPIBcast( val, 1, root, mpi_comm ); addParameter< bool >( param_name. getString(), val ); } if( param_type == "int" ) { int val; :: MPIBcast( val, 1, root, mpi_comm ); addParameter< int >( param_name. getString(), val ); } if( param_type == "double" ) { double val; :: MPIBcast( val, 1, root, mpi_comm ); addParameter< double >( param_name. getString(), val ); } } } #endif } */ protected: std::vector< std::unique_ptr< ParameterBase > > parameters; }; } // namespace Config Loading
src/TNL/Config/make_unique.h 0 → 100644 +15 −0 Original line number Diff line number Diff line #pragma once // std::make_unique does not exist until C++14 // https://stackoverflow.com/a/9657991 #if __cplusplus < 201402L #include <memory> namespace std { template<typename T, typename ...Args> std::unique_ptr<T> make_unique( Args&& ...args ) { return std::unique_ptr<T>( new T( std::forward<Args>(args)... ) ); } } #endif