Commit 25c05210 authored by Jakub Klinkovský's avatar Jakub Klinkovský
Browse files

Reimplemented Config::ConfigDescription and Config::ParameterContainer using...

Reimplemented Config::ConfigDescription and Config::ParameterContainer using std::vector instead of TNL::List

This is much safer and simpler because it solves many problems due to
cyclic inclusion of TNL headers.
parent c29579e4
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -21,6 +21,8 @@
   #include <mpi-ext.h>
   #include <mpi-ext.h>
#endif
#endif


#include <unistd.h>  // getpid

#ifdef HAVE_CUDA
#ifdef HAVE_CUDA
    #include <TNL/Devices/Cuda.h>
    #include <TNL/Devices/Cuda.h>


+4 −5
Original line number Original line Diff line number Diff line
@@ -10,6 +10,8 @@


#pragma once
#pragma once


#include <TNL/Config/ConfigEntryBase.h>

namespace TNL {
namespace TNL {
namespace Config {
namespace Config {


@@ -17,16 +19,13 @@ struct ConfigDelimiter : public ConfigEntryBase
{
{
   ConfigDelimiter( const String& delimiter )
   ConfigDelimiter( const String& delimiter )
   : ConfigEntryBase( "", delimiter, false )
   : ConfigEntryBase( "", delimiter, false )
   {
   {}
   };


   bool isDelimiter() const { return true; };
   bool isDelimiter() const { return true; };


   String getEntryType() const { return ""; };
   String getEntryType() const { return ""; };


   String getUIEntryType() const { return ""; };
   String getUIEntryType() const { return ""; };
   
   //~ConfigDelimiter(){};
};
};


} //namespace Config
} //namespace Config
+36 −46
Original line number Original line Diff line number Diff line
@@ -10,31 +10,23 @@


#include <fstream>
#include <fstream>
#include <iomanip>
#include <iomanip>
#include <string>

#include <TNL/Config/ConfigDescription.h>
#include <TNL/Config/ConfigDescription.h>
#include <TNL/Config/ParameterContainer.h>
#include <TNL/Config/ParameterContainer.h>


namespace TNL {
namespace TNL {
namespace Config {
namespace Config {


ConfigDescription :: ConfigDescription()
void
: currentEntry( 0 )
ConfigDescription::
{
printUsage( const char* program_name ) const
}

ConfigDescription :: ~ConfigDescription()
{
   entries.DeepEraseAll();
}

void ConfigDescription::printUsage( const char* program_name ) const
{
{
   std::cout << "Usage of: " << program_name << std::endl << std::endl;
   std::cout << "Usage of: " << program_name << std::endl << std::endl;
   int i, j;
   const int entries_num = entries.size();
   //const int group_num = groups. getSize();
   const int entries_num = entries. getSize();
   int max_name_length( 0 );
   int max_name_length( 0 );
   int max_type_length( 0 );
   int max_type_length( 0 );
   for( j = 0; j < entries_num; j ++ )
   for( int j = 0; j < entries_num; j++ )
      if( ! entries[ j ]->isDelimiter() )
      if( ! entries[ j ]->isDelimiter() )
      {
      {
         max_name_length = std::max( max_name_length,
         max_name_length = std::max( max_name_length,
@@ -44,7 +36,7 @@ void ConfigDescription::printUsage( const char* program_name ) const
      }
      }
   max_name_length += 2; // this is for '--'
   max_name_length += 2; // this is for '--'


   for( j = 0; j < entries_num; j ++ )
   for( int j = 0; j < entries_num; j++ )
   {
   {
      if( entries[ j ]->isDelimiter() )
      if( entries[ j ]->isDelimiter() )
      {
      {
@@ -81,11 +73,12 @@ void ConfigDescription::printUsage( const char* program_name ) const
   std::cout << std::endl;
   std::cout << std::endl;
}
}


void Config::ConfigDescription :: addMissingEntries( Config::ParameterContainer& parameter_container ) const
void
ConfigDescription::
addMissingEntries( Config::ParameterContainer& parameter_container ) const
{
{
   int i;
   const int size = entries.size();
   const int size = entries.getSize();
   for( int i = 0; i < size; i++ )
   for( i = 0; i < size; i ++ )
   {
   {
      const char* entry_name = entries[ i ]->name.getString();
      const char* entry_name = entries[ i ]->name.getString();
      if( entries[ i ]->hasDefaultValue &&
      if( entries[ i ]->hasDefaultValue &&
@@ -93,57 +86,54 @@ void Config::ConfigDescription :: addMissingEntries( Config::ParameterContainer&
      {
      {
         if( entries[ i ]->getEntryType() == "String" )
         if( entries[ i ]->getEntryType() == "String" )
         {
         {
            parameter_container. addParameter< String >(
            ConfigEntry< String >& entry = dynamic_cast< ConfigEntry< String >& >( *entries[ i ] );
               entry_name,
            parameter_container.addParameter< String >( entry_name, entry.defaultValue );
               ( ( ConfigEntry< String >* ) entries[ i ] ) -> defaultValue );
            continue;
            continue;
         }
         }
         if( entries[ i ]->getEntryType() == "bool" )
         if( entries[ i ]->getEntryType() == "bool" )
         {
         {
            parameter_container. addParameter< bool >(
            ConfigEntry< bool >& entry = dynamic_cast< ConfigEntry< bool >& >( *entries[ i ] );
               entry_name,
            parameter_container.addParameter< bool >( entry_name, entry.defaultValue );
               ( ( ConfigEntry< bool >* ) entries[ i ] ) -> defaultValue );
            continue;
            continue;
         }
         }
         if( entries[ i ]->getEntryType() == "int" )
         if( entries[ i ]->getEntryType() == "int" )
         {
         {
            parameter_container. addParameter< int >(
            ConfigEntry< int >& entry = dynamic_cast< ConfigEntry< int >& >( *entries[ i ] );
               entry_name,
            parameter_container.addParameter< int >( entry_name, entry.defaultValue );
               ( ( ConfigEntry< int >* ) entries[ i ] ) -> defaultValue );
            continue;
            continue;
         }
         }
         if( entries[ i ]->getEntryType() == "double" )
         if( entries[ i ]->getEntryType() == "double" )
         {
         {
            parameter_container. addParameter< double >(
            ConfigEntry< double >& entry = dynamic_cast< ConfigEntry< double >& >( *entries[ i ] );
               entry_name,
            parameter_container.addParameter< double >( entry_name, entry.defaultValue );
               ( ( ConfigEntry< double >* ) entries[ i ] ) -> defaultValue );
            continue;
            continue;
         }
         }
      }
      }
   }
   }
}
}


bool Config::ConfigDescription :: checkMissingEntries( Config::ParameterContainer& parameter_container,
bool
Config::ConfigDescription::
checkMissingEntries( Config::ParameterContainer& parameter_container,
                     bool printUsage,
                     bool printUsage,
                     const char* programName ) const
                     const char* programName ) const
{
{
   int i;
   const int size = entries.size();
   const int size = entries. getSize();
   std::vector< std::string > missingParameters;
   Containers::List< String > missingParameters;
   for( int i = 0; i < size; i++ )
   for( i = 0; i < size; i ++ )
   {
   {
      const char* entry_name = entries[ i ] -> name.getString();
      const char* entry_name = entries[ i ] -> name.getString();
      if( entries[ i ] -> required &&
      if( entries[ i ] -> required &&
          ! parameter_container.checkParameter( entry_name ) )
          ! parameter_container.checkParameter( entry_name ) )
         missingParameters.Append( entry_name );
         missingParameters.push_back( entry_name );
   }
   }
   if( missingParameters.getSize() != 0 )
   if( missingParameters.size() > 0 )
   {
   {
      std::cerr << "Some mandatory parameters are misssing. They are listed at the end. " << std::endl;
      std::cerr << "Some mandatory parameters are misssing. They are listed at the end. " << std::endl;
      if( printUsage )
      if( printUsage )
         this->printUsage( programName );
         this->printUsage( programName );
      std::cerr << "Add the following missing parameters to the command line: " << std::endl << "   ";
      std::cerr << "Add the following missing parameters to the command line: " << std::endl << "   ";
      for( int i = 0; i < missingParameters.getSize(); i++ )
      for( int i = 0; i < (int) missingParameters.size(); i++ )
         std::cerr << "--" << missingParameters[ i ] << " ... ";
         std::cerr << "--" << missingParameters[ i ] << " ... ";
      std::cerr << std::endl;
      std::cerr << std::endl;
      return false;
      return false;
+66 −67
Original line number Original line Diff line number Diff line
@@ -10,8 +10,23 @@


#pragma once
#pragma once


#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 <TNL/Assert.h>
#include <TNL/String.h>
#include <TNL/String.h>
#include <TNL/Containers/List.h>
#include <TNL/param-types.h>
#include <TNL/param-types.h>
#include <TNL/Config/ConfigEntryType.h>
#include <TNL/Config/ConfigEntryType.h>
#include <TNL/Config/ConfigEntry.h>
#include <TNL/Config/ConfigEntry.h>
@@ -26,12 +41,6 @@ class ParameterContainer;
class ConfigDescription
class ConfigDescription
{
{
public:
public:

   /**
    * \brief Basic constructor.
    */
   ConfigDescription();

   /**
   /**
    * \brief Adds new entry to the configuration description.
    * \brief Adds new entry to the configuration description.
    *
    *
@@ -43,8 +52,8 @@ class ConfigDescription
   void addEntry( const String& name,
   void addEntry( const String& name,
                  const String& description )
                  const String& description )
   {
   {
      currentEntry = new ConfigEntry< EntryType >( name, description, false );
      entries.push_back( std::make_unique< ConfigEntry< EntryType > >( name, description, false ) );
      entries.Append( currentEntry );
      currentEntry = entries.back().get();
   }
   }


   /**
   /**
@@ -58,8 +67,8 @@ class ConfigDescription
   void addRequiredEntry( const String& name,
   void addRequiredEntry( const String& name,
                          const String& description )
                          const String& description )
   {
   {
      currentEntry = new ConfigEntry< EntryType >( name, description, true );
      entries.push_back( std::make_unique< ConfigEntry< EntryType > >( name, description, true ) );
      entries.Append( currentEntry );
      currentEntry = entries.back().get();
   }
   }


   /**
   /**
@@ -75,11 +84,8 @@ class ConfigDescription
                  const String& description,
                  const String& description,
                  const EntryType& defaultValue )
                  const EntryType& defaultValue )
   {
   {
      currentEntry = new ConfigEntry< EntryType >( name,
      entries.push_back( std::make_unique< ConfigEntry< EntryType > >( name, description, false, defaultValue ) );
                                                   description,
      currentEntry = entries.back().get();
                                                   false,
                                                   defaultValue );
      entries. Append( currentEntry );
   }
   }


   /**
   /**
@@ -93,8 +99,8 @@ class ConfigDescription
   void addList( const String& name,
   void addList( const String& name,
                 const String& description )
                 const String& description )
   {
   {
      currentEntry = new ConfigEntryList< EntryType >( name, description, false );
      entries.push_back( std::make_unique< ConfigEntryList< EntryType > >( name, description, false ) );
      entries.Append( currentEntry );
      currentEntry = entries.back().get();
   }
   }


   /**
   /**
@@ -108,8 +114,8 @@ class ConfigDescription
   void addRequiredList( const String& name,
   void addRequiredList( const String& name,
                         const String& description )
                         const String& description )
   {
   {
      currentEntry = new ConfigEntryList< EntryType >( name, description, true );
      entries.push_back( std::make_unique< ConfigEntryList< EntryType > >( name, description, true ) );
      entries.Append( currentEntry );
      currentEntry = entries.back().get();
   }
   }


   /**
   /**
@@ -125,11 +131,8 @@ class ConfigDescription
                 const String& description,
                 const String& description,
                 const EntryType& defaultValue )
                 const EntryType& defaultValue )
   {
   {
      currentEntry = new ConfigEntryList< EntryType >( name,
      entries.push_back( std::make_unique< ConfigEntryList< EntryType > >( name, description, false, defaultValue ) );
                                                          description,
      currentEntry = entries.back().get();
                                                          false,
                                                          defaultValue );
      entries. Append( currentEntry );
   }
   }


   /**
   /**
@@ -142,8 +145,9 @@ class ConfigDescription
   template< typename EntryType >
   template< typename EntryType >
   void addEntryEnum( const EntryType& entryEnum )
   void addEntryEnum( const EntryType& entryEnum )
   {
   {
      TNL_ASSERT( this->currentEntry,);
      TNL_ASSERT_TRUE( this->currentEntry, "there is no current entry" );
      ( ( ConfigEntry< EntryType >* ) currentEntry )->getEnumValues().Append( entryEnum );
      ConfigEntry< EntryType >& entry = dynamic_cast< ConfigEntry< EntryType >& >( *currentEntry );
      entry.getEnumValues().push_back( entryEnum );
   }
   }


   /**
   /**
@@ -154,8 +158,9 @@ class ConfigDescription
    */
    */
   void addEntryEnum( const char* entryEnum )
   void addEntryEnum( const char* entryEnum )
   {
   {
      TNL_ASSERT( this->currentEntry,);
      TNL_ASSERT_TRUE( this->currentEntry, "there is no current entry" );
      ( ( ConfigEntry< String >* ) currentEntry )->getEnumValues().Append( String( entryEnum ) );
      ConfigEntry< String >& entry = dynamic_cast< ConfigEntry< String >& >( *currentEntry );
      entry.getEnumValues().push_back( String( entryEnum ) );
   }
   }


   /**
   /**
@@ -165,8 +170,8 @@ class ConfigDescription
    */
    */
   void addDelimiter( const String& delimiter )
   void addDelimiter( const String& delimiter )
   {
   {
      entries.Append( new ConfigDelimiter( delimiter ) );
      entries.push_back( std::make_unique< ConfigDelimiter >( delimiter ) );
      currentEntry = 0;
      currentEntry = nullptr;
   }
   }


   /**
   /**
@@ -176,10 +181,11 @@ class ConfigDescription
    */
    */
   const ConfigEntryBase* getEntry( const String& name ) const
   const ConfigEntryBase* getEntry( const String& name ) const
   {
   {
      for( int i = 0; i < entries.getSize(); i++ )
      const int entries_num = entries.size();
      for( int i = 0; i < entries_num; i++ )
         if( entries[ i ]->name == name )
         if( entries[ i ]->name == name )
            return entries[ i ];
            return entries[ i ].get();
      return NULL;
      return nullptr;
   }
   }




@@ -187,32 +193,34 @@ class ConfigDescription
   //const String getEntryType( const char* name ) const;
   //const String getEntryType( const char* name ) const;


   //! Returns zero pointer if there is no default value
   //! Returns zero pointer if there is no default value
   template< class T > const T* getDefaultValue( const String& name ) const
   template< class T >
   const T* getDefaultValue( const String& name ) const
   {
   {
      int i;
      const int entries_num = entries.size();
      const int entries_num = entries. getSize();
      for( int i = 0; i < entries_num; i++ )
      for( i = 0; i < entries_num; i ++ )
         if( entries[ i ]->name == name ) {
         if( entries[ i ] -> name == name )
            if( entries[ i ]->hasDefaultValue ) {
         {
               const ConfigEntry< T >& entry = dynamic_cast< ConfigEntry< T >& >( *entries[ i ] );
            if( entries[ i ] -> hasDefaultValue )
               return entry->default_value;
               return ( ( ConfigEntry< T > * ) entries[ i ] ) -> default_value;
            }
            else return NULL;
            return nullptr;
         }
         }
      std::cerr << "Asking for the default value of unknown parameter." << std::endl;
      std::cerr << "Asking for the default value of unknown parameter." << std::endl;
      return NULL;
      return nullptr;
   }
   }
 
 
   //! Returns zero pointer if there is no default value
   //! Returns zero pointer if there is no default value
   template< class T > T* getDefaultValue( const String& name )
   template< class T >
   {
   T* getDefaultValue( const String& name )
      int i;
      const int entries_num = entries. getSize();
      for( i = 0; i < entries_num; i ++ )
         if( entries[ i ] -> name == name )
   {
   {
            if( entries[ i ] -> hasDefaultValue )
      const int entries_num = entries.size();
               return ( ( ConfigEntry< T > * ) entries[ i ] ) -> default_value;
      for( int i = 0; i < entries_num; i++ )
            else return NULL;
         if( entries[ i ] -> name == name ) {
            if( entries[ i ] -> hasDefaultValue ) {
               ConfigEntry< T >& entry = dynamic_cast< ConfigEntry< T >& >( *entries[ i ] );
               return entry->default_value;
            }
            return nullptr;
         }
         }
      std::cerr << "Asking for the default value of unknown parameter." << std::endl;
      std::cerr << "Asking for the default value of unknown parameter." << std::endl;
      return NULL;
      return NULL;
@@ -243,19 +251,10 @@ class ConfigDescription


   //bool parseConfigDescription( const char* file_name );
   //bool parseConfigDescription( const char* file_name );


   /**
    * \brief Basic destructor.
    */
   ~ConfigDescription();

protected:
protected:

   std::vector< std::unique_ptr< ConfigEntryBase > > entries;
   Containers::List< ConfigEntryBase* > entries;
   ConfigEntryBase* currentEntry = nullptr;

   ConfigEntryBase* currentEntry;

};
};


} //namespace Config
} //namespace Config
} //namespace TNL
} //namespace TNL
+32 −33
Original line number Original line Diff line number Diff line
@@ -10,8 +10,9 @@


#pragma once
#pragma once


#include <vector>

#include <TNL/Config/ConfigEntryBase.h>
#include <TNL/Config/ConfigEntryBase.h>
#include <TNL/Containers/List.h>


namespace TNL {
namespace TNL {
namespace Config {
namespace Config {
@@ -21,7 +22,7 @@ struct ConfigEntry : public ConfigEntryBase
{
{
   EntryType defaultValue;
   EntryType defaultValue;


   Containers::List< EntryType > enumValues;
   std::vector< EntryType > enumValues;


   public:
   public:


@@ -62,14 +63,14 @@ struct ConfigEntry : public ConfigEntryBase
      return convertToString( defaultValue );
      return convertToString( defaultValue );
   };
   };


   Containers::List< EntryType >& getEnumValues()
   std::vector< EntryType >& getEnumValues()
   {
   {
      return this->enumValues;
      return this->enumValues;
   }
   }


   bool hasEnumValues() const
   bool hasEnumValues() const
   {
   {
      if( enumValues.getSize() != 0 )
      if( enumValues.size() > 0 )
         return true;
         return true;
      return false;
      return false;
   }
   }
@@ -78,7 +79,7 @@ struct ConfigEntry : public ConfigEntryBase
   {
   {
      std::cout << "- Can be:           ";
      std::cout << "- Can be:           ";
      int i;
      int i;
      for( i = 0; i < enumValues.getSize() - 1; i++ )
      for( i = 0; i < (int) enumValues.size() - 1; i++ )
         std::cout << enumValues[ i ] << ", ";
         std::cout << enumValues[ i ] << ", ";
      std::cout << enumValues[ i ];
      std::cout << enumValues[ i ];
      std::cout << " ";
      std::cout << " ";
@@ -86,10 +87,10 @@ struct ConfigEntry : public ConfigEntryBase


   bool checkValue( const EntryType& value ) const
   bool checkValue( const EntryType& value ) const
   {
   {
      if( this->enumValues.getSize() != 0 )
      if( this->enumValues.size() > 0 )
      {
      {
         bool found( false );
         bool found( false );
         for( int i = 0; i < this->enumValues.getSize(); i++ )
         for( int i = 0; i < (int) this->enumValues.size(); i++ )
            if( value == this->enumValues[ i ] )
            if( value == this->enumValues[ i ] )
            {
            {
               found = true;
               found = true;
@@ -104,9 +105,7 @@ struct ConfigEntry : public ConfigEntryBase
         }
         }
      }
      }
      return true;
      return true;
   };
   }
   
   //~ConfigEntry(){};
};
};


} // namespace Config
} // namespace Config
Loading