00001 /*!@file Component/ParamMap.H I/O operations for parameter files */ 00002 00003 // //////////////////////////////////////////////////////////////////// // 00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2001 by the // 00005 // University of Southern California (USC) and the iLab at USC. // 00006 // See http://iLab.usc.edu for information about this project. // 00007 // //////////////////////////////////////////////////////////////////// // 00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00010 // in Visual Environments, and Applications'' by Christof Koch and // 00011 // Laurent Itti, California Institute of Technology, 2001 (patent // 00012 // pending; application number 09/912,225 filed July 23, 2001; see // 00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00014 // //////////////////////////////////////////////////////////////////// // 00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00016 // // 00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00018 // redistribute it and/or modify it under the terms of the GNU General // 00019 // Public License as published by the Free Software Foundation; either // 00020 // version 2 of the License, or (at your option) any later version. // 00021 // // 00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00025 // PURPOSE. See the GNU General Public License for more details. // 00026 // // 00027 // You should have received a copy of the GNU General Public License // 00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00030 // Boston, MA 02111-1307 USA. // 00031 // //////////////////////////////////////////////////////////////////// // 00032 // 00033 // Primary maintainer for this file: Rob Peters <rjpeters@klab.caltech.edu> 00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Component/ParamMap.H $ 00035 // $Id: ParamMap.H 14376 2011-01-11 02:44:34Z pez $ 00036 // 00037 00038 #ifndef PARAMMAP_H_DEFINED 00039 #define PARAMMAP_H_DEFINED 00040 00041 #include "rutz/shared_ptr.h" 00042 #include "Util/Types.H" 00043 00044 #include <iosfwd> 00045 #include <vector> 00046 00047 // on some platforms sys/types.h must be included for 'uint' type. 00048 #ifdef MACHINE_OS_DARWIN 00049 #include <sys/types.h> 00050 #endif 00051 00052 00053 //! Allows reading and writing of parameters to and from files or streams 00054 /*! ParamMap allows reading and writing of arbitrarily nested data structes 00055 to and from files or other streams. */ 00056 class ParamMap 00057 { 00058 ParamMap(const ParamMap&); // not allowed 00059 ParamMap& operator=(const ParamMap&); // not allowed 00060 00061 public: 00062 //! Convenience function to create a new ParamMap from a .pmap file. 00063 static rutz::shared_ptr<ParamMap> loadPmapFile(const std::string& fname); 00064 00065 //! Compatibility function to create a new ParamMap from a .conf file. 00066 /*! See readConfig for details on the format of a .conf file. Basically, 00067 it is similar to the .pmap format, except that comments must be 00068 bracketed by whitespace-separated '#' characters on both sides, and 00069 that there is no nesting of data structures. */ 00070 static rutz::shared_ptr<ParamMap> loadConfFile(const std::string& fname); 00071 00072 //! Convenience function to create a new ParamMap from an equivalent 00073 // map 00074 //template <class T> 00075 // static rutz::shared_ptr<ParamMap> loadC_Map(const std::map <std::string, T>); 00076 00077 //! Return codes when getting params from the map. 00078 enum ReturnCode 00079 { 00080 MISSING, //!< the param was not found 00081 UNCHANGED, //!< the param was found, but the value was unchanged 00082 CHANGED, //!< the param was found and its value was changed 00083 }; 00084 00085 //! Default construct with an empty map. 00086 ParamMap(); 00087 00088 //! Construct and load() from \a fname. 00089 ParamMap(const std::string& fname); 00090 00091 //! Destructor. 00092 ~ParamMap(); 00093 00094 //! A class for iterating over the ParamMap's keys (i.e. param names). 00095 class key_iterator; 00096 00097 //! Get an iterator to the beginning of the keys sequence. 00098 key_iterator keys_begin() const; 00099 00100 //! Get an iterator to one-past-the-end of the keys sequence. 00101 key_iterator keys_end() const; 00102 00103 //! Load in a parameter map from the given input stream. 00104 void load(std::istream& istrm); 00105 00106 //! Convenience overload of the other load(). 00107 /*! In this case we just build an istream internally from the given 00108 filename, and then load() from that.*/ 00109 void load(const std::string& fname); 00110 00111 //! Write a formatted parameter map to the given output stream. 00112 /*! The indentlev parameter is only used internally by ParamMap, and can 00113 be safely ignored by external callers. */ 00114 void format(std::ostream& ostrm, int indentlev = 0) const; 00115 00116 //! Convenience overload of the other format(). 00117 /*! In this case we just build an ostream internally from the given 00118 filename, and then format() from that.*/ 00119 void format(const std::string& fname) const; 00120 00121 //! Query whether the parameter map has a particular named parameter. 00122 bool hasParam(const std::string& paramname) const; 00123 00124 //! Query whether the parameter map is a leaf or not 00125 bool isLeaf(const std::string& paramname) const; 00126 00127 uint getsize() const; 00128 // ###################################################################### 00129 /*! @name Functions to extract named values from the ParamMap 00130 00131 There are several kinds of functions that differ in how they handle 00132 named parameters that are not found in the ParamMap. The first kind 00133 look for a named parameter, and trigger and error if that parameter 00134 is not found. The second kind take a default value as an additional 00135 argument, and return that value if the named parameter is not 00136 found. The third kind take a destination by reference, and leave that 00137 destination unchanged if the parameter is not found, and additional 00138 return a ReturnCode specifying with the parameter was missing, 00139 found-and-changed, or found-and-unchanged. */ 00140 //@{ 00141 00142 //! Get a named parameter as a nested parameter map. 00143 /*! Triggers an error if there is no parameter with the given name. */ 00144 rutz::shared_ptr<ParamMap> getSubpmap(const std::string& paramname) const; 00145 00146 //! Get a named parameter as a string value. 00147 /*! Triggers an error if there is no parameter with the given name. */ 00148 std::string getStringParam(const std::string& paramname) const; 00149 00150 //! Get a named parameter as a 'double' value. 00151 /*! Triggers an error if there is no parameter with the given name. */ 00152 double getDoubleParam(const std::string& paramname) const; 00153 00154 //! Get a named parameter as an 'int' value. 00155 /*! Triggers an error if there is no parameter with the given name. */ 00156 int getIntParam(const std::string& paramname) const; 00157 00158 //! Get a named parameter as a string value, or return the default value. 00159 /*! The default value will be returned if the named parameter is not 00160 found.*/ 00161 std::string getStringParam(const std::string& paramname, const std::string& defval) const; 00162 00163 //! Get a named parameter as a 'double' value, or return the default value. 00164 /*! The default value will be returned if the named parameter is not 00165 found.*/ 00166 double getDoubleParam(const std::string& paramname, const double defval) const; 00167 00168 //! Get a named parameter as an 'int' value, or return the default value. 00169 /*! The default value will be returned if the named parameter is not 00170 found.*/ 00171 int getIntParam(const std::string& paramname, const int defval) const; 00172 00173 //! Returns the submap for the given name. 00174 /*! If a submap for the given name exists, a rutz::shared_ptr to it 00175 is returned. If no submap for the given name has yet been 00176 created, one is created, and a rutz::shared_ptr to it is 00177 returned. This function differs from getSubpmap(), which only 00178 returns existing submaps. */ 00179 rutz::shared_ptr<ParamMap> lookupSubpmap(const std::string& paramname); 00180 00181 //! Get the named parameter, or do nothing if the parameter is missing. 00182 /*! The ReturnCode describes what happened when looking up the param. */ 00183 ReturnCode queryStringParam(const std::string& paramname, std::string& result) const; 00184 00185 //! Get the named parameter, or do nothing if the parameter is missing. 00186 /*! The ReturnCode describes what happened when looking up the param. */ 00187 ReturnCode queryDoubleParam(const std::string& paramname, double& result) const; 00188 00189 //! Get the named parameter, or do nothing if the parameter is missing. 00190 /*! The ReturnCode describes what happened when looking up the param. */ 00191 ReturnCode queryIntParam(const std::string& paramname, int& result) const; 00192 00193 //@} 00194 00195 // ###################################################################### 00196 /*! @name Functions to place named values into the ParamMap */ 00197 00198 //! Add a nested parameter map with a given name. 00199 void putSubpmap(const std::string& paramname, const rutz::shared_ptr<ParamMap>& val); 00200 00201 //! Add a string value with a given name. 00202 void putStringParam(const std::string& paramname, const std::string& val); 00203 00204 //! Add a double-precision floating point value with a given name. 00205 void putDoubleParam(const std::string& paramname, double val); 00206 00207 //! Add an integral value with a given name. 00208 void putIntParam(const std::string& paramname, int val); 00209 00210 //! Replace a submap 00211 void replaceSubpmap(const std::string& paramname, const rutz::shared_ptr<ParamMap>& val); 00212 00213 //! Replace string-param 00214 void replaceStringParam(const std::string& paramname, const std::string& val); 00215 00216 //! Replace double-param 00217 void replaceDoubleParam(const std::string& paramname, double val); 00218 00219 //! Replace int-param 00220 void replaceIntParam(const std::string& paramname, int val); 00221 00222 //! Remove all params from the ParamMap 00223 void clear(); 00224 00225 //! Remove a single param from the ParamMap 00226 void erase(const std::string& paramname); 00227 00228 //@} 00229 00230 //! For testing/debugging only. 00231 /*! Prints the raw contents of this parameter map to standard output. */ 00232 void print(const std::string& name) const; 00233 00234 private: 00235 struct Impl; 00236 Impl* const rep; 00237 }; 00238 00239 class ParamMap::key_iterator 00240 { 00241 public: 00242 //! Destructor. 00243 ~key_iterator(); 00244 //! Copy constructor. 00245 key_iterator(const key_iterator& other); 00246 //! Assignment operator. 00247 key_iterator& operator=(const key_iterator&); 00248 00249 //! Dereference to get the key (i.e., parameter name). 00250 const std::string& operator*() const; 00251 00252 //! Pre-increment operator. 00253 key_iterator& operator++(); 00254 00255 //! Equality comparison. 00256 bool operator==(const key_iterator& other) const; 00257 00258 //! Inequality comparison. 00259 bool operator!=(const key_iterator& other) const; 00260 00261 private: 00262 void swap(key_iterator& other); 00263 00264 //! Default construct. 00265 key_iterator(); 00266 00267 friend class ParamMap; 00268 00269 struct IterRep; 00270 IterRep* const rep; 00271 }; 00272 00273 // ###################################################################### 00274 /* So things look consistent in everyone's emacs... */ 00275 /* Local Variables: */ 00276 /* indent-tabs-mode: nil */ 00277 /* End: */ 00278 00279 #endif // !PARAMMAP_H_DEFINED