+ Microarchitecture optimizations + 64-bit support + Xilinx FPGA support + LLVM-16 support + Refactoring and quality control fixes
489 lines
15 KiB
C++
489 lines
15 KiB
C++
/*
|
|
* Copyright 1993-2010 NVIDIA Corporation. All rights reserved.
|
|
*
|
|
* Please refer to the NVIDIA end user license agreement (EULA) associated
|
|
* with this source code for terms and conditions that govern your use of
|
|
* this software. Any use, reproduction, disclosure, or distribution of
|
|
* this software and related documentation outside the terms of the EULA
|
|
* is strictly prohibited.
|
|
*
|
|
*/
|
|
|
|
/* CUda UTility Library */
|
|
|
|
#ifndef _CMDARGREADER_H_
|
|
#define _CMDARGREADER_H_
|
|
|
|
// includes, system
|
|
#include <map>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
#include <algorithm>
|
|
#include <typeinfo>
|
|
|
|
// includes, project
|
|
#include "exception.h"
|
|
|
|
//! Preprocessed command line arguments
|
|
//! @note Lazy evaluation: The arguments are converted from strings to
|
|
//! the correct data type upon request. Converted values are stored
|
|
//! in an additonal map so that no additional conversion is
|
|
//! necessary. Arrays of command line arguments are stored in
|
|
//! std::vectors
|
|
//! @note Usage:
|
|
//! const std::string* file =
|
|
//! CmdArgReader::getArg< std::string>( "model")
|
|
//! const std::vector< std::string>* files =
|
|
//! CmdArgReader::getArg< std::vector< std::string> >( "model")
|
|
//! @note All command line arguments begin with '--' followed by the token;
|
|
//! token and value are seperated by '='; example --samples=50
|
|
//! @note Arrays have the form --model=[one.obj,two.obj,three.obj]
|
|
//! (without whitespaces)
|
|
|
|
//! Command line argument parser
|
|
class CmdArgReader
|
|
{
|
|
template<class> friend class TestCmdArgReader;
|
|
|
|
protected:
|
|
|
|
//! @param self handle to the only instance of this class
|
|
static CmdArgReader* self;
|
|
|
|
public:
|
|
|
|
//! Public construction interface
|
|
//! @return a handle to the class instance
|
|
//! @param argc number of command line arguments (as given to main())
|
|
//! @param argv command line argument string (as given to main())
|
|
static void init( const int argc, const char** argv);
|
|
|
|
public:
|
|
|
|
//! Get the value of the command line argument with given name
|
|
//! @return A const handle to the requested argument.
|
|
//! If the argument does not exist or if it
|
|
//! is not from type T NULL is returned
|
|
//! @param name the name of the requested argument
|
|
//! @note T the type of the argument requested
|
|
template<class T>
|
|
static inline const T* getArg( const std::string& name);
|
|
|
|
//! Check if a command line argument with the given name exists
|
|
//! @return true if a command line argument with name \a name exists,
|
|
//! otherwise false
|
|
//! @param name name of the command line argument in question
|
|
static inline bool existArg( const std::string& name);
|
|
|
|
//! Get the original / raw argc program argument
|
|
static inline int& getRArgc();
|
|
|
|
//! Get the original / raw argv program argument
|
|
static inline char**& getRArgv();
|
|
|
|
public:
|
|
|
|
//! Destructor
|
|
~CmdArgReader();
|
|
|
|
protected:
|
|
|
|
//! Constructor, default
|
|
CmdArgReader();
|
|
|
|
private:
|
|
|
|
// private helper functions
|
|
|
|
//! Get the value of the command line argument with given name
|
|
//! @note Private helper function for 'getArg' to work on the members
|
|
//! @return A const handle to the requested argument. If the argument
|
|
//! does not exist or if it is not from type T a NULL pointer
|
|
//! is returned.
|
|
//! @param name the name of the requested argument
|
|
//! @note T the type of the argument requested
|
|
template<class T>
|
|
inline const T* getArgHelper( const std::string& name);
|
|
|
|
//! Check if a command line argument with name \a name exists
|
|
//! @return true if a command line argument of name \a name exists,
|
|
//! otherwise false
|
|
//! @param name the name of the requested argument
|
|
inline bool existArgHelper( const std::string& name) const;
|
|
|
|
//! Read args as token value pair into map for better processing
|
|
//! (Even the values remain strings until the parameter values is
|
|
//! requested by the program.)
|
|
//! @param argc the argument count (as given to 'main')
|
|
//! @param argv the char* array containing the command line arguments
|
|
void createArgsMaps( const int argc, const char** argv);
|
|
|
|
//! Helper for "casting" the strings from the map with the unprocessed
|
|
//! values to the correct
|
|
//! data type.
|
|
//! @return true if conversion succeeded, otherwise false
|
|
//! @param element the value as string
|
|
//! @param val the value as type T
|
|
template<class T>
|
|
static inline bool convertToT( const std::string& element, T& val);
|
|
|
|
public:
|
|
|
|
// typedefs internal
|
|
|
|
//! container for a processed command line argument
|
|
//! typeid is used to easily be able to decide if a re-requested token-value
|
|
//! pair match the type of the first conversion
|
|
typedef std::pair< const std::type_info*, void*> ValType;
|
|
//! map of already converted values
|
|
typedef std::map< std::string, ValType > ArgsMap;
|
|
//! iterator for the map of already converted values
|
|
typedef ArgsMap::iterator ArgsMapIter;
|
|
typedef ArgsMap::const_iterator ConstArgsMapIter;
|
|
|
|
//! map of unprocessed (means unconverted) token-value pairs
|
|
typedef std::map< std::string, std::string> UnpMap;
|
|
//! iterator for the map of unprocessed (means unconverted) token-value pairs
|
|
typedef std::map< std::string, std::string>::iterator UnpMapIter;
|
|
|
|
private:
|
|
|
|
#ifdef _WIN32
|
|
# pragma warning( disable: 4251)
|
|
#endif
|
|
|
|
//! rargc original value of argc
|
|
static int rargc;
|
|
|
|
//! rargv contains command line arguments in raw format
|
|
static char** rargv;
|
|
|
|
//! args Map containing the already converted token-value pairs
|
|
ArgsMap args;
|
|
|
|
//! args Map containing the unprocessed / unconverted token-value pairs
|
|
UnpMap unprocessed;
|
|
|
|
//! iter Iterator for the map with the already converted token-value
|
|
//! pairs (to avoid frequent reallocation)
|
|
ArgsMapIter iter;
|
|
|
|
//! iter Iterator for the map with the unconverted token-value
|
|
//! pairs (to avoid frequent reallocation)
|
|
UnpMapIter iter_unprocessed;
|
|
|
|
#ifdef _WIN32
|
|
# pragma warning( default: 4251)
|
|
#endif
|
|
|
|
private:
|
|
|
|
//! Constructor, copy (not implemented)
|
|
CmdArgReader( const CmdArgReader&);
|
|
|
|
//! Assignment operator (not implemented)
|
|
CmdArgReader& operator=( const CmdArgReader&);
|
|
};
|
|
|
|
// variables, exported (extern)
|
|
|
|
// functions, inlined (inline)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Conversion function for command line argument arrays
|
|
//! @note This function is used each type for which no template specialization
|
|
//! exist (which will cause errors if the type does not fulfill the std::vector
|
|
//! interface).
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
/*static*/ inline bool
|
|
CmdArgReader::convertToT( const std::string& element, T& val)
|
|
{
|
|
// preallocate storage
|
|
val.resize( std::count( element.begin(), element.end(), ',') + 1);
|
|
|
|
unsigned int i = 0;
|
|
std::string::size_type pos_start = 1; // leave array prefix '['
|
|
std::string::size_type pos_end = 0;
|
|
|
|
// do for all elements of the comma seperated list
|
|
while( std::string::npos != ( pos_end = element.find(',', pos_end+1)) )
|
|
{
|
|
// convert each element by the appropriate function
|
|
if ( ! convertToT< typename T::value_type >(
|
|
std::string( element, pos_start, pos_end - pos_start), val[i]))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
pos_start = pos_end + 1;
|
|
++i;
|
|
}
|
|
|
|
std::string tmp1( element, pos_start, element.length() - pos_start - 1);
|
|
|
|
// process last element (leave array postfix ']')
|
|
if ( ! convertToT< typename T::value_type >( std::string( element,
|
|
pos_start,
|
|
element.length() - pos_start - 1),
|
|
val[i]))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// possible to process all elements?
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Conversion function for command line arguments of type int
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template<>
|
|
inline bool
|
|
CmdArgReader::convertToT<int>( const std::string& element, int& val)
|
|
{
|
|
std::istringstream ios( element);
|
|
ios >> val;
|
|
|
|
bool ret_val = false;
|
|
if ( ios.eof())
|
|
{
|
|
ret_val = true;
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Conversion function for command line arguments of type float
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template<>
|
|
inline bool
|
|
CmdArgReader::convertToT<float>( const std::string& element, float& val)
|
|
{
|
|
std::istringstream ios( element);
|
|
ios >> val;
|
|
|
|
bool ret_val = false;
|
|
if ( ios.eof())
|
|
{
|
|
ret_val = true;
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Conversion function for command line arguments of type double
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template<>
|
|
inline bool
|
|
CmdArgReader::convertToT<double>( const std::string& element, double& val)
|
|
{
|
|
std::istringstream ios( element);
|
|
ios >> val;
|
|
|
|
bool ret_val = false;
|
|
if ( ios.eof())
|
|
{
|
|
ret_val = true;
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Conversion function for command line arguments of type string
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template<>
|
|
inline bool
|
|
CmdArgReader::convertToT<std::string>( const std::string& element,
|
|
std::string& val)
|
|
{
|
|
val = element;
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Conversion function for command line arguments of type bool
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template<>
|
|
inline bool
|
|
CmdArgReader::convertToT<bool>( const std::string& element, bool& val)
|
|
{
|
|
// check if value is given as string-type { true | false }
|
|
if ( "true" == element)
|
|
{
|
|
val = true;
|
|
return true;
|
|
}
|
|
else if ( "false" == element)
|
|
{
|
|
val = false;
|
|
return true;
|
|
}
|
|
// check if argument is given as integer { 0 | 1 }
|
|
else
|
|
{
|
|
int tmp;
|
|
if ( convertToT<int>( element, tmp))
|
|
{
|
|
if ( 1 == tmp)
|
|
{
|
|
val = true;
|
|
return true;
|
|
}
|
|
else if ( 0 == tmp)
|
|
{
|
|
val = false;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Get the value of the command line argument with given name
|
|
//! @return A const handle to the requested argument. If the argument does
|
|
//! not exist or if it is not from type T NULL is returned
|
|
//! @param T the type of the argument requested
|
|
//! @param name the name of the requested argument
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
/*static*/ const T*
|
|
CmdArgReader::getArg( const std::string& name)
|
|
{
|
|
if( ! self)
|
|
{
|
|
RUNTIME_EXCEPTION("CmdArgReader::getArg(): CmdArgReader not initialized.");
|
|
return NULL;
|
|
}
|
|
|
|
return self->getArgHelper<T>( name);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Check if a command line argument with the given name exists
|
|
//! @return true if a command line argument with name \a name exists,
|
|
//! otherwise false
|
|
//! @param name name of the command line argument in question
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/*static*/ inline bool
|
|
CmdArgReader::existArg( const std::string& name)
|
|
{
|
|
if( ! self)
|
|
{
|
|
RUNTIME_EXCEPTION("CmdArgReader::getArg(): CmdArgReader not initialized.");
|
|
return false;
|
|
}
|
|
|
|
return self->existArgHelper( name);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! @brief Get the value of the command line argument with given name
|
|
//! @return A const handle to the requested argument. If the argument does
|
|
//! not exist or if it is not from type T NULL is returned
|
|
//! @param T the type of the argument requested
|
|
//! @param name the name of the requested argument
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
template<class T>
|
|
const T*
|
|
CmdArgReader::getArgHelper( const std::string& name)
|
|
{
|
|
// check if argument already processed and stored in correct type
|
|
if ( args.end() != (iter = args.find( name)))
|
|
{
|
|
if ( (*(iter->second.first)) == typeid( T) )
|
|
{
|
|
return (T*) iter->second.second;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
T* tmp = new T;
|
|
|
|
// check the array with unprocessed values
|
|
if ( unprocessed.end() != (iter_unprocessed = unprocessed.find( name)))
|
|
{
|
|
// try to "cast" the string to the type requested
|
|
if ( convertToT< T >( iter_unprocessed->second, *tmp))
|
|
{
|
|
// add the token element pair to map of already converted values
|
|
args[name] = std::make_pair( &(typeid( T)), (void*) tmp);
|
|
|
|
return tmp;
|
|
}
|
|
}
|
|
|
|
// not used while not inserted into the map -> cleanup
|
|
delete tmp;
|
|
}
|
|
|
|
// failed, argument not available
|
|
return NULL;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Check if a command line argument with name \a name exists
|
|
//! @return true if a command line argument of name \a name exists,
|
|
//! otherwise false
|
|
//! @param name the name of the requested argument
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
inline bool
|
|
CmdArgReader::existArgHelper( const std::string& name) const
|
|
{
|
|
bool ret_val = false;
|
|
|
|
// check if argument already processed and stored in correct type
|
|
if( args.end() != args.find( name))
|
|
{
|
|
ret_val = true;
|
|
}
|
|
else
|
|
{
|
|
|
|
// check the array with unprocessed values
|
|
if ( unprocessed.end() != unprocessed.find( name))
|
|
{
|
|
ret_val = true;
|
|
}
|
|
}
|
|
|
|
return ret_val;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Get the original / raw argc program argument
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/*static*/ inline int&
|
|
CmdArgReader::getRArgc()
|
|
{
|
|
if( ! self)
|
|
{
|
|
RUNTIME_EXCEPTION("CmdArgReader::getRArgc(): CmdArgReader not initialized.");
|
|
}
|
|
|
|
return rargc;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//! Get the original / raw argv program argument
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/*static*/ inline char**&
|
|
CmdArgReader::getRArgv()
|
|
{
|
|
if( ! self)
|
|
{
|
|
RUNTIME_EXCEPTION("CmdArgReader::getRArgc(): CmdArgReader not initialized.");
|
|
}
|
|
|
|
return rargv;
|
|
}
|
|
|
|
// functions, exported (extern)
|
|
|
|
#endif // #ifndef _CMDARGREADER_H_
|