Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Geant4/LUPI.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 # <<BEGIN-copyright>>
0003 # Copyright 2019, Lawrence Livermore National Security, LLC.
0004 # This file is part of the gidiplus package (https://github.com/LLNL/gidiplus).
0005 # gidiplus is licensed under the MIT license (see https://opensource.org/licenses/MIT).
0006 # SPDX-License-Identifier: MIT
0007 # <<END-copyright>>
0008 */
0009 
0010 #ifndef LUPI_hpp_included
0011 #define LUPI_hpp_included 1
0012 
0013 #include <sys/stat.h>
0014 #include <string>
0015 #include <vector>
0016 #include <list>
0017 #include <map>
0018 #include <stdexcept>
0019 #include <iostream>
0020 #ifndef _WIN32
0021     #include <time.h>
0022     #include <sys/time.h>
0023 #endif
0024 
0025 #include <LUPI_defines.hpp>
0026 #include <statusMessageReporting.h>
0027 
0028 #define LUPI_XML_verionEncoding "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
0029 
0030 #ifndef LUPI_PATH_MAX
0031 #define LUPI_PATH_MAX ( 4 * 4096 )
0032 #endif
0033 
0034 #if defined (GIDIP_HAVE_COMPILER_FLOATING_POINT_EXCEPTIONS)
0035 void LUPI_FPE_enable( char const *a_file, int a_line );
0036 void LUPI_FPE_disable_and_clear( char const *a_file, int a_line );
0037 void LUPI_FPE_test( char const *a_file, int a_line );
0038 #endif
0039 
0040 namespace LUPI {
0041 
0042 #ifdef _WIN32
0043 #define LUPI_FILE_SEPARATOR   "\\"
0044 #else
0045 #define LUPI_FILE_SEPARATOR   "/"
0046 #endif
0047 
0048 #define GNDS_formatVersion_1_10Chars "1.10"
0049 #define GNDS_formatVersion_2_0Chars "2.0"
0050 #define GNDS_formatVersion_2_0_LLNL_4Chars "2.0.LLNL_4"
0051 #define GNDS_formatVersion_2_1Chars "2.1"
0052 
0053 void deprecatedFunction( std::string const &a_functionName, std::string const &a_replacementName, std::string const &a_asOf );
0054 
0055 /*
0056 ============================================================
0057 ====================== FormatVersion =======================
0058 ============================================================
0059 */
0060 class FormatVersion {
0061 
0062     private:
0063         std::string m_format;               /**< The GNDS format version. */
0064         int m_major;                        /**< The GNDS format major value as an integer. */
0065         int m_minor;                        /**< The GNDS format minor value as an integer. */
0066         std::string m_patch;                /**< The GNDS format patch string. This will be an empty string except for unofficial formats. */
0067 
0068     public:
0069         FormatVersion( );
0070         FormatVersion( std::string const &a_formatVersion );
0071         FormatVersion( FormatVersion const &a_formatVersion );
0072         FormatVersion &operator=( FormatVersion const &a_rhs );
0073 
0074         std::string const &format( ) const { return( m_format ); }
0075         int major( ) const { return( m_major ); }
0076         int minor( ) const { return( m_minor ); }
0077         std::string const &patch( ) const { return( m_patch ); }
0078 
0079         bool setFormat( std::string const &a_formatVersion );
0080         bool supported( ) const ;
0081 };
0082 
0083 /*
0084 ============================================================
0085 ========================= Exception ========================
0086 ============================================================
0087 */
0088 class Exception : public std::runtime_error {
0089 
0090     public :
0091         explicit Exception( std::string const &a_message );
0092 };
0093 
0094 /*
0095 ============================================================
0096 ================== StatusMessageReporting ==================
0097 ============================================================
0098 */
0099 
0100 class StatusMessageReporting {
0101 
0102     public:
0103         enum class Status { ok, info, warning, error };
0104 
0105     private:
0106         statusMessageReporting m_smr;
0107 
0108     public:
0109         StatusMessageReporting( );
0110         ~StatusMessageReporting( );
0111         
0112         statusMessageReporting *smr( ) { return( &m_smr ); }
0113         bool isOk( ) { return( smr_isOk( &m_smr ) ); }
0114         bool isInfo( ) { return( smr_isInfo( &m_smr ) ); }
0115         bool isWarning( ) { return( smr_isWarning( &m_smr ) ); }
0116         bool isError( ) { return( smr_isError( &m_smr ) ); }
0117         void clear( ) { smr_release( &m_smr ); }
0118         std::string constructMessage( std::string a_prefix, int a_reports = 1, bool a_clear = false );
0119         std::string constructFullMessage( std::string const &a_prefix, int a_reports = 1, bool a_clear = false );
0120 };
0121 
0122 /*
0123 ============================================================
0124 ====================== ArgumentParser ======================
0125 ============================================================
0126 */
0127 
0128 enum class ArgumentType { True, False, Count, Store, Append, Positional };
0129 
0130 class ArgumentBase;
0131 
0132 class ArgumentParser {
0133 
0134     private:
0135         std::string m_codeName;                                 /**< The name of the code that is using **ArgumentParser**. */
0136         std::string m_descriptor;                               /**< The descriptor that is printed when help (i.e., '-h') is entered. */
0137         std::vector<ArgumentBase *> m_arguments;                /**< The list of arguments (positional and optional) supported. */
0138 
0139         void add2( ArgumentBase *a_argumentBase );
0140 
0141     public:
0142         ArgumentParser( std::string const &a_codeName, std::string const &a_descriptor = "" );
0143         ~ArgumentParser( );
0144 
0145         std::string const &codeName( ) const { return( m_codeName ); }
0146         std::string const &descriptor( ) const { return( m_descriptor ); }
0147         template<typename T> T *add( std::string const &a_name, std::string const &a_descriptor, int a_minimumNeeded = 1, int a_maximumNeeded = 1 );
0148         ArgumentBase *add( ArgumentType a_argumentType, std::string const &a_name, std::string const &a_descriptor, 
0149                 int a_minimumNeeded = -2, int a_maximumNeeded = -2 );
0150         void addAlias( std::string const &a_name, std::string const &a_alias );
0151         void addAlias( ArgumentBase const * const a_argumentBase, std::string const &a_alias );
0152         bool hasName( std::string const &a_name ) const ;
0153         bool isOptionalArgument( std::string const &a_name ) const ;
0154         void parse( int a_argc, char **a_argv, bool a_printArguments = true );
0155         template<typename T> T *get( std::size_t a_name );
0156         void help( ) const ;
0157         void usage( ) const ;
0158         virtual void printStatus( std::string a_indent ) const ;
0159 };
0160 
0161 /* *********************************************************************************************************//**
0162  * Creates a new argument, adds the argument to *this* and returns a pointer the the newly created argument.
0163  *
0164  * @param a_name                [in]    The name of the argument.
0165  * @param a_descriptor          [in]    The argument's description, displayed when the help option is enetered.
0166  * @param a_minimumNeeded       [in]    The minimum number of required time *this* argument must be entered.
0167  * @param a_maximumNeeded       [in]    The maximum number of required time *this* argument must be entered.
0168  *
0169  * @return                              A pointer to the created argument.
0170  ***********************************************************************************************************/
0171 
0172 template<typename T> T *ArgumentParser::add( std::string const &a_name, std::string const &a_descriptor, int a_minimumNeeded, int a_maximumNeeded ) {
0173 
0174     T *argument = new T( a_name, a_descriptor, a_minimumNeeded, a_maximumNeeded );
0175     add2( argument );
0176 
0177     return( argument );
0178 }
0179 
0180 /*
0181 ============================================================
0182 ======================= ArgumentBase =======================
0183 ============================================================
0184 */
0185 
0186 class ArgumentBase {
0187 
0188     private:
0189         ArgumentType m_argumentType;                        /**< The enum for arguent type of *this*. */
0190         std::vector<std::string> m_names;                   /**< The allowed names for *this*. */
0191         std::string m_descriptor;                           /**< The desciption printed help. */
0192         int m_minimumNeeded;                                /**< Minimum number of times *this* argument is required on the command line. */
0193         int m_maximumNeeded;                                /**< Maximum number of times *this* argument is required on the command line. */
0194         std::size_t m_counts;                               /**< The number of time this argument was entered on the command line. */
0195         std::vector<std::string> m_values;                  /**< list of values entered for this argument. Only used for types Store, Append and Positional. */
0196 
0197         void addAlias( std::string const &a_name );                         /**< Adds the alias *a_name* to *this*. */
0198         virtual std::string printStatus2( ) const ;                         /**< For internal use. Called by method **printStatus**. */
0199         virtual void printStatus3( std::string const &a_indent ) const ;
0200 
0201         friend void ArgumentParser::addAlias( std::string const &a_name, std::string const &a_alias );
0202 
0203     public:
0204         ArgumentBase( ArgumentType a_argumentType, std::string const &a_name, std::string const &a_descriptor, int a_minimumNeeded, int a_maximumNeeded );
0205         virtual ~ArgumentBase( ) = 0 ;
0206 
0207         ArgumentType argumentType( ) const { return( m_argumentType ); }
0208         std::string const &name( ) const { return( m_names[0] ); }
0209         std::vector<std::string> const &names( ) { return( m_names ); }
0210         bool hasName( std::string const &a_name ) const ;
0211         std::string const &descriptor( ) const { return( m_descriptor ); }
0212         int minimumNeeded( ) const { return( m_minimumNeeded ); }
0213         int maximumNeeded( ) const { return( m_maximumNeeded ); }
0214         std::size_t counts( ) const { return( m_counts ); }
0215 
0216         virtual std::string const &value( std::size_t a_index = 0 ) const ;
0217         std::vector<std::string> const &values( ) const { return( m_values ); }
0218         virtual bool isOptionalArgument( ) const { return( true ); }
0219         virtual bool requiresAValue( ) const { return( false ); }
0220         virtual int parse( ArgumentParser const &a_argumentParser, int a_index, int a_argc, char **a_argv );
0221         std::string usage( bool a_requiredOption ) const ;
0222         void printStatus( std::string a_indent ) const ;
0223 };
0224 
0225 /*
0226 ============================================================
0227 ======================= OptionBoolean ======================
0228 ============================================================
0229 */
0230 
0231 class OptionBoolean : public ArgumentBase {
0232 
0233     private:
0234         bool m_default;
0235 
0236     public:
0237         OptionBoolean( ArgumentType a_argumentType, std::string const &a_name, std::string const &a_descriptor, bool a_default );
0238         virtual ~OptionBoolean( ) = 0 ;
0239 
0240         bool _default( ) const { return( m_default ); }
0241         std::string printStatus2( ) const ;
0242 };
0243 
0244 /*
0245 ============================================================
0246 ======================== OptionTrue ========================
0247 ============================================================
0248 */
0249 
0250 class OptionTrue : public OptionBoolean {
0251 
0252     public:
0253         OptionTrue( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
0254         ~OptionTrue( ) { }
0255 };
0256 
0257 /*
0258 ============================================================
0259 ======================= OptionFalse ========================
0260 ============================================================
0261 */
0262 
0263 class OptionFalse : public OptionBoolean {
0264 
0265     public:
0266         OptionFalse( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
0267         ~OptionFalse( ) { }
0268 };
0269 
0270 /*
0271 ============================================================
0272 ====================== OptionCounter =======================
0273 ============================================================
0274 */
0275 
0276 class OptionCounter : public ArgumentBase {
0277 
0278     public:
0279         OptionCounter( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
0280         ~OptionCounter( ) { }
0281 
0282         std::string printStatus2( ) const ;
0283 };
0284 
0285 /*
0286 ============================================================
0287 ======================= OptionStore ========================
0288 ============================================================
0289 */
0290 
0291 class OptionStore : public ArgumentBase {
0292 
0293     public:
0294         OptionStore( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
0295         ~OptionStore( ) { }
0296 
0297         std::string const &value( std::size_t a_index = 0 ) const ;
0298         bool requiresAValue( ) const { return( true ); }
0299         void printStatus3( std::string const &a_indent ) const ;
0300 };
0301 
0302 /*
0303 ============================================================
0304 ======================= OptionAppend =======================
0305 ============================================================
0306 */
0307 
0308 class OptionAppend : public ArgumentBase {
0309 
0310     public:
0311         OptionAppend( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 0, int a_maximumNeeded = -1 );
0312         ~OptionAppend( ) { }
0313 
0314         bool requiresAValue( ) const { return( true ); }
0315         void printStatus3( std::string const &a_indent ) const ;
0316 };
0317 
0318 /*
0319 ============================================================
0320 ======================== Positional ========================
0321 ============================================================
0322 */
0323 
0324 class Positional : public ArgumentBase {
0325 
0326     public:
0327         Positional( std::string const &a_name, std::string const &a_descriptor = "", int a_minimumNeeded = 1, int a_maximumNeeded = 1 );
0328         ~Positional( ) { }
0329 
0330         bool isOptionalArgument( ) const { return( false ); }
0331         bool requiresAValue( ) const { return( true ); }
0332         void printStatus3( std::string const &a_indent ) const ;
0333 };
0334 
0335 /*
0336 ============================================================
0337 ======================== DeltaTime =========================
0338 ============================================================
0339 */
0340 
0341 #ifndef _WIN32
0342 
0343 #define LUPI_DeltaTime_toStringFormatIncremental "incremental: CPU %8.3fs, wall %8.3fs"
0344 #define LUPI_DeltaTime_toStringFormatTotal "total: CPU %8.3fs, wall %8.3fs"
0345 
0346 class DeltaTime {
0347 
0348     private:
0349         double m_CPU_time;
0350         double m_wallTime;
0351         double m_CPU_timeIncremental;
0352         double m_wallTimeIncremental;
0353 
0354     public:
0355         DeltaTime( );
0356         DeltaTime( double a_CPU_time, double a_wallTime, double a_CPU_timeIncremental, double a_wallTimeIncremental );
0357         DeltaTime( DeltaTime const &deltaTime );
0358         ~DeltaTime( ) { }
0359 
0360         double CPU_time( ) const { return( m_CPU_time ); }
0361         double wallTime( ) const { return( m_wallTime ); }
0362         double CPU_timeIncremental( ) const { return( m_CPU_timeIncremental ); }
0363         double wallTimeIncremental( ) const { return( m_wallTimeIncremental ); }
0364         std::string toString( std::string a_formatIncremental = LUPI_DeltaTime_toStringFormatIncremental,
0365                 std::string a_format = LUPI_DeltaTime_toStringFormatTotal, std::string a_sep = "; " );
0366 };
0367 
0368 /*
0369 ============================================================
0370 ========================== Timer ===========================
0371 ============================================================
0372 */
0373 
0374 class Timer {
0375 
0376     private:
0377         clock_t m_CPU_time;
0378         struct timeval m_wallTime;
0379         clock_t m_CPU_timeIncremental;
0380         struct timeval m_wallTimeIncremental;
0381 
0382     public:
0383         Timer( );
0384         ~Timer( ) { }
0385 
0386         DeltaTime deltaTime( );
0387         DeltaTime deltaTimeAndReset( );
0388         void reset( );
0389 };
0390 
0391 #endif          // End of not _WIN32 defined.
0392 
0393 namespace FileInfo {        // Should be using std::filesystem stuff but this requires C++ 17.
0394 
0395 std::string realPath( std::string const &a_path );
0396 std::string _basename( std::string const &a_path );
0397 std::string basenameWithoutExtension( std::string const &a_path );
0398 std::string _dirname( std::string const &a_path );
0399 bool exists( std::string const &a_path );
0400 bool isDirectory( std::string const &a_path );
0401 bool createDirectories( std::string const &a_path );
0402 
0403 /*
0404 ============================================================
0405 ========================= FileStat =========================
0406 ============================================================
0407 */
0408 class FileStat {
0409 
0410     private:
0411         std::string m_path;             /**< The path that is stat-ed. */
0412         struct stat m_stat;             /**< The stat for the path. */
0413 
0414     public:
0415         FileStat( std::string const &a_path );
0416 
0417         std::string const &path( ) const { return( m_path ); }                              /**< Returns a reference to the **m_path** member. */
0418         struct stat const &statRef( ) const { return( m_stat ); }                           /**< Returns a reference to the **m_stat** member. */
0419 
0420         bool exists( );
0421         bool isDirectory( ) const { return( ( m_stat.st_mode & S_IFMT ) == S_IFDIR ); }           /**< Returns *true* if the path is a directory and *false* otherwise. */
0422         bool isRegularFile( ) const { return( ( m_stat.st_mode & S_IFMT ) == S_IFREG ); }   /**< Returns *true* if the path is a regular file and *false* otherwise. */
0423 };
0424 
0425 }               // End of namespace FileInfo.
0426 
0427 // Miscellaneous functions
0428 
0429 namespace Misc {
0430 
0431 std::string stripString( std::string const &a_string, bool a_left = true, bool a_right = true );
0432 std::vector<std::string> splitString( std::string const &a_string, char a_delimiter, bool a_strip = false );
0433 std::vector<std::string> splitString( std::string const &a_string, std::string const &a_delimiter, bool a_strip = false );
0434 std::string joinStrings( std::string const &a_sep, std::vector<std::string> a_strings );
0435 std::string replaceString( std::string const &a_string, std::string const &a_old, std::string const &a_new, bool a_all );
0436 std::vector<std::string> splitXLinkString( std::string const &a_string );
0437 bool stringToInt( std::string const &a_string, int &a_value );
0438 bool stringToSize_t( std::string const &a_string, std::size_t &a_value );
0439 
0440 std::string argumentsToString( char const *a_format, ... );
0441 std::string doubleToString3( char const *a_format, double a_value, bool a_reduceBits = false );
0442 std::string doubleToShortestString( double a_value, int a_significantDigits = 15, int a_favorEFormBy = 0 );
0443 
0444 void printCommand( std::string const &a_indent, int a_argc, char **a_argv );
0445 
0446 }               // End of namespace Misc.
0447 
0448 }               // End of namespace LUPI.
0449 
0450 #endif          // LUPI_hpp_included