Scarab  v2.2.0
Project 8 C++ Utility Library
param_node.hh
Go to the documentation of this file.
1 /*
2  * param_node.hh
3  *
4  * Created on: Jan 14, 2014
5  * Author: nsoblath
6  */
7 
8 #ifndef SCARAB_PARAM_NODE_HH_
9 #define SCARAB_PARAM_NODE_HH_
10 
11 #include "param_value.hh"
12 
13 #include <boost/iterator/iterator_adaptor.hpp>
14 #include <boost/type_traits/is_convertible.hpp>
15 #include <boost/utility/enable_if.hpp>
16 
17 #include <map>
18 
19 namespace scarab
20 {
21  class param_value;
22  class param_array;
23 
24  // This special iterator class is used to allow the param_node iterator to point to a `param` object instead of a `std::unique_ptr<param>` object.
25  // In param_array we just used boost::indirect_iterator, but that doesn't work quite as simply for map-like objects.
26  // Note that unlike a normal map iterator, *iterator gives the `param` object, and iterator.name() gives the key.
27  template< class x_key, class x_value, class x_iiterator >
28  class map_deref_iterator : public boost::iterator_adaptor< map_deref_iterator< x_key, x_value, x_iiterator >, x_iiterator, x_value, boost::bidirectional_traversal_tag >
29  {
30  private:
31  // used for the conversion constructor below
32  struct enabler {};
33 
34  public:
36  map_deref_iterator::iterator_adaptor_()
37  {}
38  map_deref_iterator( const x_iiterator& other ) :
39  map_deref_iterator::iterator_adaptor_( other )
40  {}
41 
42  // converts from iterator to const_iterator, but the enable_if business prevents converting from const_iterator to iterator
43  template< class x_other_value, class x_other_iiterator >
44  map_deref_iterator( const map_deref_iterator< x_key, x_other_value, x_other_iiterator > & other, typename boost::enable_if< boost::is_convertible< x_other_value, x_value >, enabler >::type = enabler() ) :
45  map_deref_iterator::iterator_adaptor_( other.base )
46  {}
47 
48  const x_key& name() const
49  {
50  return this->base()->first;
51  }
52 
53  private:
54  friend class boost::iterator_core_access;
55 
56  x_value& dereference() const
57  {
58  return *this->base()->second;
59  }
60 
61  };
62 
63  typedef std::map< std::string, std::unique_ptr< param > > param_node_contents;
64 
67 
68 
69  class SCARAB_API param_node : public param
70  {
71  public:
72  typedef param_node_contents contents;
73  typedef param_node_iterator iterator;
74  typedef param_node_const_iterator const_iterator;
75  typedef contents::value_type contents_type;
76 
77  param_node();
78  param_node( const param_node& orig );
79  param_node( param_node&& orig );
80  virtual ~param_node();
81 
82  param_node& operator=( const param_node& rhs );
83  param_node& operator=( param_node&& rhs );
84 
85  virtual param_ptr_t clone() const;
86  virtual param_ptr_t move_clone();
87 
88  virtual bool is_null() const;
89  virtual bool is_node() const;
90 
91  virtual bool has_subset( const param& a_subset ) const;
92 
93  unsigned size() const;
94  bool empty() const;
95 
96  bool has( const std::string& a_name ) const;
97  unsigned count( const std::string& a_name ) const;
98 
101  std::string get_value( const std::string& a_name, const std::string& a_default ) const;
102  std::string get_value( const std::string& a_name, const char* a_default ) const;
105  template< typename XValType >
106  XValType get_value( const std::string& a_name, XValType a_default ) const;
107 
110  const param& operator[]( const std::string& a_name ) const;
113  param& operator[]( const std::string& a_name );
114 
117  bool add( const std::string& a_name, const param& a_value );
120  bool add( const std::string& a_name, param&& a_value );
123  bool add( const std::string& a_name, param_ptr_t a_value_ptr );
126  bool add( const std::string& a_name, param_value&& a_value );
127 
129  void replace( const std::string& a_name, const param& a_value );
131  void replace( const std::string& a_name, param&& a_value );
133  void replace( const std::string& a_name, param_ptr_t a_value_ptr );
135  void replace( const std::string& a_name, param_value&& a_value );
136 
140  void merge( const param_node& a_object );
141 
142  void erase( const std::string& a_name );
143  param_ptr_t remove( const std::string& a_name );
144  void clear();
145 
146  iterator begin();
147  const_iterator begin() const;
148 
149  iterator end();
150  const_iterator end() const;
151 
152  virtual std::string to_string() const;
153 
154  protected:
155  contents f_contents;
156 
157  };
158 
159 
160  template< typename XValType >
161  inline XValType param_node::get_value( const std::string& a_name, XValType a_default ) const
162  {
163  return has( a_name ) ? operator[]( a_name ).as_value().as< XValType >() : a_default;
164  }
165 
167  {
168  //std::cout << "param_node::clone" << std::endl;
169  return std::unique_ptr< param_node >( new param_node( *this ) );
170  }
171 
173  {
174  return std::unique_ptr< param_node >( new param_node( std::move(*this) ) );
175  }
176 
177  inline bool param_node::is_null() const
178  {
179  return false;
180  }
181 
182  inline bool param_node::is_node() const
183  {
184  return true;
185  }
186 
187  inline unsigned param_node::size() const
188  {
189  return f_contents.size();
190  }
191  inline bool param_node::empty() const
192  {
193  return f_contents.empty();
194  }
195 
196  inline bool param_node::has( const std::string& a_name ) const
197  {
198  return f_contents.count( a_name ) > 0;
199  }
200 
201  inline unsigned param_node::count( const std::string& a_name ) const
202  {
203  return f_contents.count( a_name );
204  }
205 
206  inline std::string param_node::get_value( const std::string& a_name, const std::string& a_default ) const
207  {
208  return has( a_name ) ? operator[]( a_name ).to_string() : a_default;
209  }
210 
211  inline std::string param_node::get_value( const std::string& a_name, const char* a_default ) const
212  {
213  return get_value( a_name, std::string( a_default ) );
214  }
215 
216  inline const param& param_node::operator[]( const std::string& a_name ) const
217  {
218  return *f_contents.at( a_name );
219  }
220 
221  inline param& param_node::operator[]( const std::string& a_name )
222  {
223  return *f_contents.at( a_name );
224  }
225 
226  inline bool param_node::add( const std::string& a_name, const param& a_value )
227  {
228  contents::iterator it = f_contents.find( a_name );
229  if( it == f_contents.end() )
230  {
231  f_contents.insert( contents_type( a_name, a_value.clone() ) );
232  return true;
233  }
234  return false;
235  }
236 
237  inline bool param_node::add( const std::string& a_name, param&& a_value )
238  {
239  contents::iterator it = f_contents.find( a_name );
240  if( it == f_contents.end() )
241  {
242  f_contents.insert( contents_type( a_name, a_value.move_clone() ) );
243  return true;
244  }
245  return false;
246  }
247 
248  inline bool param_node::add( const std::string& a_name, param_ptr_t a_value_ptr )
249  {
250  contents::iterator it = f_contents.find( a_name );
251  if( it == f_contents.end() )
252  {
253  f_contents.insert( contents_type( a_name, std::move(a_value_ptr) ) );
254  return true;
255  }
256  return false;
257  }
258 
259  inline bool param_node::add( const std::string& a_name, param_value&& a_value )
260  {
261  contents::iterator it = f_contents.find( a_name );
262  if( it == f_contents.end() )
263  {
264  f_contents.insert( contents_type( a_name, a_value.move_clone() ) );
265  return true;
266  }
267  return false;
268  }
269 
270  inline void param_node::replace( const std::string& a_name, const param& a_value )
271  {
272  f_contents[ a_name ] = a_value.clone();
273  return;
274  }
275 
276  inline void param_node::replace( const std::string& a_name, param&& a_value )
277  {
278  f_contents[ a_name ] = a_value.move_clone();
279  return;
280  }
281 
282  inline void param_node::replace( const std::string& a_name, param_ptr_t a_value_ptr )
283  {
284  f_contents[ a_name ] = std::move(a_value_ptr);
285  return;
286  }
287 
288  inline void param_node::replace( const std::string& a_name, param_value&& a_value )
289  {
290  f_contents[ a_name ] = a_value.move_clone();
291  return;
292  }
293 
294  inline void param_node::erase( const std::string& a_name )
295  {
296  contents::iterator it = f_contents.find( a_name );
297  if( it != f_contents.end() )
298  {
299  f_contents.erase( it );
300  }
301  return;
302  }
303 
304  inline param_ptr_t param_node::remove( const std::string& a_name )
305  {
306  contents::iterator it = f_contents.find( a_name );
307  if( it != f_contents.end() )
308  {
309  param_ptr_t removed( std::move( it->second ) );
310  f_contents.erase( it );
311  return removed;
312  }
313  return param_ptr_t();
314  }
315 
316  inline void param_node::clear()
317  {
318  f_contents.clear();
319  return;
320  }
321 
323  {
324  return iterator( f_contents.begin() );
325  }
326 
328  {
329  return const_iterator( f_contents.cbegin() );
330  }
331 
333  {
334  return iterator( f_contents.end() );
335  }
336 
338  {
339  return const_iterator( f_contents.cend() );
340  }
341 
342  SCARAB_API std::ostream& operator<<(std::ostream& out, const param_node& value);
343 
344 } /* namespace scarab */
345 
346 #endif /* SCARAB_PARAM_NODE_HH_ */
void replace(const std::string &a_name, const param &a_value)
Creates a copy of a_value; overwrites if the key exits.
Definition: param_node.hh:270
unsigned count(const std::string &a_name) const
Definition: param_node.hh:201
void erase(const std::string &a_name)
Definition: param_node.hh:294
iterator begin()
Definition: param_node.hh:322
#define SCARAB_API
Definition: scarab_api.hh:24
virtual bool is_null() const
Definition: param_node.hh:177
virtual param_ptr_t move_clone()
Definition: param_node.hh:172
std::string type(const x_type &a_param)
Definition: typename.hh:22
std::map< std::string, std::unique_ptr< param > > param_node_contents
Definition: param_node.hh:63
contents::value_type contents_type
Definition: param_node.hh:75
unsigned size() const
Definition: param_node.hh:187
map_deref_iterator(const map_deref_iterator< x_key, x_other_value, x_other_iiterator > &other, typename boost::enable_if< boost::is_convertible< x_other_value, x_value >, enabler >::type=enabler())
Definition: param_node.hh:44
param_node_iterator iterator
Definition: param_node.hh:73
virtual bool is_node() const
Definition: param_node.hh:182
bool has(const std::string &a_name) const
Definition: param_node.hh:196
const x_key & name() const
Definition: param_node.hh:48
virtual param_ptr_t clone() const
Definition: param_node.hh:166
const param & operator[](const std::string &a_name) const
Definition: param_node.hh:216
param_node_const_iterator const_iterator
Definition: param_node.hh:74
bool empty() const
Definition: param_node.hh:191
SCARAB_API std::ostream & operator<<(std::ostream &out, const param_array &a_value)
Definition: param_array.cc:110
map_deref_iterator(const x_iiterator &other)
Definition: param_node.hh:38
std::unique_ptr< param > param_ptr_t
Definition: param_base.hh:23
std::string get_value(const std::string &a_name, const std::string &a_default) const
Definition: param_node.hh:206
std::string to_string(std::uint64_t x)
Definition: date.h:7722
param_ptr_t remove(const std::string &a_name)
Definition: param_node.hh:304
map_deref_iterator< std::string, param, param_node_contents::iterator > param_node_iterator
Definition: param_node.hh:65
bool add(const std::string &a_name, const param &a_value)
Definition: param_node.hh:226
param_node_contents contents
Definition: param_node.hh:72
x_value & dereference() const
Definition: param_node.hh:56
virtual param_ptr_t clone() const
map_deref_iterator< std::string, const param, param_node_contents::const_iterator > param_node_const_iterator
Definition: param_node.hh:66