Commit 35b0e105 authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Moved stuff from ConfigDescription.cpp and ParameterContainer.cpp into header files

parent 53601037
Loading
Loading
Loading
Loading
+5 −17
Original line number Diff line number Diff line
@@ -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 )
+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
+118 −17
Original line number Diff line number Diff line
@@ -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>
@@ -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:
@@ -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 );

@@ -270,3 +369,5 @@ protected:

} //namespace Config
} //namespace TNL

#include <TNL/Config/parseCommandLine.h>
+102 −42
Original line number Diff line number Diff line
@@ -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>

@@ -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.
@@ -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.
@@ -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
+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