GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
options_map.hpp
1 /**
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 /**
24  * Also contains code that is Copyright 2011 Yahoo! Inc. All rights
25  * reserved.
26  *
27  * Contributed under the iCLA for:
28  * Joseph Gonzalez ([email protected])
29  *
30  */
31 
32 
33 #ifndef GRAPHLAB_OPTIONS_MAP_HPP
34 #define GRAPHLAB_OPTIONS_MAP_HPP
35 #include <map>
36 #include <sstream>
37 #include <ostream>
38 #include <istream>
39 #include <boost/lexical_cast.hpp>
41 #include <graphlab/util/stl_util.hpp>
42 #include <graphlab/util/generics/robust_cast.hpp>
43 
44 namespace graphlab {
45 
46  /**
47  options data structure. Defines a collection of key->value pairs
48  where the key is a string, and the value is an arbitrary data
49  type. The options_map class will invisibly cast between string,
50  integer and double data types.
51  */
52  class options_map {
53  public:
54 
55  options_map() {};
56 
57  explicit options_map(std::string &s) {
58  parse_string(s);
59  };
60 
61  /**
62  * Add an option -> value pair where value is a string.
63  * Don't use. set_option() prefered.
64  */
65  inline void set_option_str(const std::string &opt,
66  const std::string &val) {
67  options[opt].strval = val;
68  try {
69  options[opt].intval = boost::lexical_cast<int>(val);
70  } catch(boost::bad_lexical_cast& error) {options[opt].intval = 0; }
71  try {
72  options[opt].dblval = boost::lexical_cast<double>(val);
73  } catch(boost::bad_lexical_cast& error) { options[opt].dblval = 0.0; }
74 
75  if (val == "true" || val == "TRUE" ||
76  val == "yes" || val == "YES" || val == "1") options[opt].boolval = true;
77  }
78 
79  template <typename T>
80  void set_option(const std::string& opt, const T& val) {
81  if (boost::is_convertible<T, std::string>::value) {
82  set_option_str(opt, robust_cast<std::string>(val));
83  } else {
84  options[opt].strval = robust_cast<std::string>(val);
85  options[opt].intval = robust_cast<int>(val);
86  options[opt].dblval = robust_cast<double>(val);
87  options[opt].boolval = robust_cast<bool>(val);
88  }
89  }
90 
91  /**
92  * Test if the option has been created
93  */
94  inline bool is_set(const std::string& opt) const {
95  return options.find(opt) != options.end();
96  }
97 
98 
99  /**
100  * Reads a string option
101  */
102  inline bool get_option(const std::string& opt, std::string& val) const {
103  std::map<std::string, option_values>::const_iterator i = options.find(opt);
104  if (i == options.end()) return false;
105  val = i->second.strval;
106  return true;
107  }
108 
109  /**
110  * Reads a string option
111  */
112  inline bool get_option(const std::string& opt, bool& val) const {
113  std::map<std::string, option_values>::const_iterator i = options.find(opt);
114  if (i == options.end()) return false;
115  val = i->second.boolval;
116  return true;
117  }
118 
119 
120  /**
121  * Reads a integer option
122  */
123  template <typename IntType>
124  inline bool get_option(const std::string& opt, IntType& val) const {
125  std::map<std::string, option_values>::const_iterator i = options.find(opt);
126  if (i == options.end()) return false;
127  val = i->second.intval;
128  return true;
129  }
130 
131  /**
132  * Reads a float option
133  */
134  inline bool get_option(const std::string& opt, float& val) const {
135  std::map<std::string, option_values>::const_iterator i = options.find(opt);
136  if (i == options.end()) return false;
137  val = i->second.dblval;
138  return true;
139  }
140 
141  /**
142  * Reads a double option
143  */
144  inline bool get_option(const std::string& opt, double& val) const {
145  std::map<std::string, option_values>::const_iterator i = options.find(opt);
146  if (i == options.end()) return false;
147  val = i->second.dblval;
148  return true;
149  }
150 
151 
152  /**
153  * Erases an option
154  */
155  inline void erase_option(const std::string &opt) {
156  options.erase(opt);
157  }
158 
159  /**
160  * Clears all options
161  */
162  void clear_options() {
163  options.clear();
164  }
165 
166 
167  /**
168  * Parses an option stream of the form "a=b c=d ..."
169  */
170  inline bool parse_options(std::istream& s) {
171  options.clear();
172  std::string opt, value;
173  // read till the equal
174  while(s.good()) {
175  getline(s, opt, '=');
176  if (s.bad() || s.eof()) return false;
177 
178  getline(s, value, ' ');
179  if (s.bad()) return false;
180  set_option_str(trim(opt), trim(value));
181  }
182  return true;
183  }
184 
185  /// The internal storage of the options
187  std::string strval;
188  int intval;
189  double dblval;
190  bool boolval;
191  option_values () : intval(0), dblval(0), boolval(false) { }
192  };
193 
194 
195  std::vector<std::string> get_option_keys() const {
196  std::map<std::string, option_values>::const_iterator iter = options.begin();
197  std::vector<std::string> ret;
198  while (iter != options.end()) {
199  ret.push_back(iter->first);
200  ++iter;
201  }
202  return ret;
203  }
204 
205  /**
206  * Parse a comma delimited series of key1=value1,key2=value2
207  */
208  void parse_string(std::string arguments);
209 
210  std::map<std::string, option_values> options;
211 
212  };
213 
214 
215  std::ostream& operator<<(std::ostream& out,
216  const graphlab::options_map& opts);
217 
218 
219 } // end of graphlab namespace
220 
221 
222 
223 
224 #endif
225