args.h 5.24 KB
Newer Older
1 2 3 4 5 6 7
#pragma once

#include <string>
#include <map>
#include <cstdlib>
#include <iostream>

Laurent Belcour's avatar
Laurent Belcour committed
8 9
#include "common.h"

10 11
/*! \brief A useful class for storing the high-level arguments of a program
 *  or a function.
12 13
 *  \ingroup core
 *  \internal
14 15 16 17 18
 *
 *  The set of parameters are parsed from the command line using the 
 *  constructor. They are stored as std::string in a std::map.
 *  \todo add functionalities to provide new parameters values.
 */
19 20 21 22 23
class arguments
{
	public: // functions

		// Constructor and destructor
Laurent Belcour's avatar
Laurent Belcour committed
24 25
		arguments()
		{
26
        }
27
		arguments(int argc, char** const argv)
28
        {
29 30
			for(int i=0; i<argc; ++i)
			{
31 32
                std::string temp(argv[i]) ;
                std::string key, data ;
33 34 35 36

				if(temp.compare(0, 2, "--") == 0)
				{
					key = temp.substr(2, temp.size()-2) ;
37 38
					int j = i+1;
					while(j < argc) 
39
					{
40
						std::string next(argv[j]) ;
41 42
						if(next.compare(0, 2, "--") != 0)
						{
43
							data.append(next) ;
44
						}
45 46 47 48 49
						else
						{
							break ;
						}
						++j;
50 51 52 53
					}
				}
				_map.insert(std::pair<std::string, std::string>(key, data)) ;
			}
54 55 56 57
        }
        ~arguments()
        {
        }
58

59
		//! \brief is the elements in the command line ?
60 61 62 63 64 65 66 67 68 69
		bool is_defined(const std::string& key) const
		{
			if(_map.count(key) > 0)
			{
				return true ;
			}
			else
			{
				return false ;
			}
70
        }
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

        //! \brief is the data at the given key in a vector format?
        //! No matter the type of the data, this function will test is the
        //! mapped string is of type "[ .... ]".
        //! It returns false if there is no associated entry.
        bool is_vec(const std::string& key) const
        {
            if(_map.count(key) > 0)
            {
                return _map.find(key)->second[0] == '[' ;
            }
            else
            {
                return false ;
            }
        }

88
		//! \brief access the element stored value
89 90 91 92 93 94 95 96
		std::string operator[](const std::string& key) const
		{
			if(_map.count(key) > 0)
			{
				return _map.find(key)->second ;
			}
			else
			{
97
                //std::cerr << "Underfined request to key : \"" << key << "\"" << std::endl ;
98 99
				return std::string() ;
			}
100
        }
101 102 103 104 105
		//! \brief acces to the float value associated with the parameter
		//! \a key.
		//!
		//! The \a default_value argument will be returned if the \a key
		//! has no associated value.
106
		float get_float(const std::string& key, float default_value = 0.0f) const
107
		{
108
			if(_map.count(key) > 0)
Laurent Belcour's avatar
Laurent Belcour committed
109
				return atof(_map.find(key)->second.c_str()) ;
110
			else
111
				return default_value ;
Laurent Belcour's avatar
Laurent Belcour committed
112
		}
113 114 115 116 117
		//! \brief acces to the integer value associated with the parameter
		//! \a key.
		//!
		//! The \a default_value argument will be returned if the \a key
		//! has no associated value.
118
		int get_int(const std::string& key, int default_value = 0) const
119
		{
120
			if(_map.count(key) > 0)
Laurent Belcour's avatar
Laurent Belcour committed
121
				return atoi(_map.find(key)->second.c_str()) ;
122
			else
123
				return default_value ;
Laurent Belcour's avatar
Laurent Belcour committed
124
		} 
125 126 127 128 129
		//! \brief acces to a vector of float of size \a size associated with
		//! the parameter \a key.
		//!
		//! The \a default_value argument will be returned if the \a key
		//! has no associated value.
130
		vec get_vec(const std::string& key, int size, float default_value = 0.0f) const
Laurent Belcour's avatar
Laurent Belcour committed
131
		{
132
			vec res(size);
133 134 135
            for(int i=0; i<size; ++i)
                res[i] = default_value;

Laurent Belcour's avatar
Laurent Belcour committed
136 137
			if(_map.count(key) > 0)
			{
Laurent Belcour's avatar
Laurent Belcour committed
138
				std::string s = _map.find(key)->second;
139
				if(s[0] == '[') // Is an array of type [a, b, c]
Laurent Belcour's avatar
Laurent Belcour committed
140 141
				{
					int i = 0;
142
					size_t pos = 1;
143
					while(pos != std::string::npos && i<size)
Laurent Belcour's avatar
Laurent Belcour committed
144
					{
145
						size_t ppos = s.find(',', pos);
Laurent Belcour's avatar
Laurent Belcour committed
146 147 148

						if(ppos != std::string::npos)
						{
149
                            res[i] = atof(s.substr(pos, ppos-pos).c_str());
Laurent Belcour's avatar
Laurent Belcour committed
150 151 152
							pos = ppos+1;
							++i;
						}
153 154
						else
						{
155 156
                            std::string temp = s.substr(pos, std::string::npos);
                            res[i] = atof(temp.substr(0, temp.size()-1).c_str());
157 158 159
							pos = ppos;
							++i;
						}
Laurent Belcour's avatar
Laurent Belcour committed
160 161 162 163 164 165
					}
					return res;
				}
			}

			float val = get_float(key, default_value);
166 167 168 169
			for(int i=0; i<size; ++i)
			{
				res[i] = val;
			}
Laurent Belcour's avatar
Laurent Belcour committed
170 171
			return res;
		}
172

173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
        std::vector<std::string> get_vec(const std::string& key) const
        {
            std::vector<std::string> res;
            if(_map.count(key) > 0)
            {
                std::string s = _map.find(key)->second;
                std::cout << s << std::endl;
                if(s[0] == '[') // Is an array of type [a, b, c]
                {
                    int i = 0;
                    size_t pos = 1;
                    while(pos != std::string::npos)
                    {
                        size_t ppos = s.find(',', pos);

                        if(ppos != std::string::npos)
                        {
                            res.push_back(s.substr(pos, ppos-pos));
                            pos = ppos+1;
                        }
                        else
                        {
                            std::string temp = s.substr(pos, std::string::npos);
                            res.push_back(temp.substr(0, temp.size()-1));
                            pos = ppos;
                        }
                    }
                }
            }

            return res;
        }

206 207 208 209 210
	private: // data

		std::map<std::string, std::string> _map ;

} ;