Scarab  v2.4.11
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  template< typename T, typename std::enable_if< std::is_convertible< T, param_value >::value, T >::type* = nullptr >
127  bool add( const std::string& a_name, T a_value );
128 
130  void replace( const std::string& a_name, const param& a_value );
132  void replace( const std::string& a_name, param&& a_value );
134  void replace( const std::string& a_name, param_ptr_t a_value_ptr );
136  template< typename T, typename std::enable_if< std::is_convertible< T, param_value >::value, T >::type* = nullptr >
137  void replace( const std::string& a_name, T a_value );
138 
142  void merge( const param_node& a_object );
143 
144  void erase( const std::string& a_name );
145  param_ptr_t remove( const std::string& a_name );
146  void clear();
147 
148  iterator begin();
149  const_iterator begin() const;
150 
151  iterator end();
152  const_iterator end() const;
153 
154  virtual std::string to_string() const;
155 
156  protected:
157  contents f_contents;
158 
159  };
160 
161 
162  template< typename XValType >
163  inline XValType param_node::get_value( const std::string& a_name, XValType a_default ) const
164  {
165  return has( a_name ) ? operator[]( a_name ).as_value().as< XValType >() : a_default;
166  }
167 
169  {
170  //std::cout << "param_node::clone" << std::endl;
171  return std::unique_ptr< param_node >( new param_node( *this ) );
172  }
173 
175  {
176  return std::unique_ptr< param_node >( new param_node( std::move(*this) ) );
177  }
178 
179  inline bool param_node::is_null() const
180  {
181  return false;
182  }
183 
184  inline bool param_node::is_node() const
185  {
186  return true;
187  }
188 
189  inline unsigned param_node::size() const
190  {
191  return f_contents.size();
192  }
193  inline bool param_node::empty() const
194  {
195  return f_contents.empty();
196  }
197 
198  inline bool param_node::has( const std::string& a_name ) const
199  {
200  return f_contents.count( a_name ) > 0;
201  }
202 
203  inline unsigned param_node::count( const std::string& a_name ) const
204  {
205  return f_contents.count( a_name );
206  }
207 
208  inline std::string param_node::get_value( const std::string& a_name, const std::string& a_default ) const
209  {
210  return has( a_name ) ? operator[]( a_name ).to_string() : a_default;
211  }
212 
213  inline std::string param_node::get_value( const std::string& a_name, const char* a_default ) const
214  {
215  return get_value( a_name, std::string( a_default ) );
216  }
217 
218  inline const param& param_node::operator[]( const std::string& a_name ) const
219  {
220  return *f_contents.at( a_name );
221  }
222 
223  inline param& param_node::operator[]( const std::string& a_name )
224  {
225  return *f_contents.at( a_name );
226  }
227 
228  inline bool param_node::add( const std::string& a_name, const param& a_value )
229  {
230  contents::iterator it = f_contents.find( a_name );
231  if( it == f_contents.end() )
232  {
233  f_contents.insert( contents_type( a_name, a_value.clone() ) );
234  return true;
235  }
236  return false;
237  }
238 
239  inline bool param_node::add( const std::string& a_name, param&& a_value )
240  {
241  contents::iterator it = f_contents.find( a_name );
242  if( it == f_contents.end() )
243  {
244  f_contents.insert( contents_type( a_name, a_value.move_clone() ) );
245  return true;
246  }
247  return false;
248  }
249 
250  inline bool param_node::add( const std::string& a_name, param_ptr_t a_value_ptr )
251  {
252  contents::iterator it = f_contents.find( a_name );
253  if( it == f_contents.end() )
254  {
255  f_contents.insert( contents_type( a_name, std::move(a_value_ptr) ) );
256  return true;
257  }
258  return false;
259  }
260 
261  template< typename T, typename std::enable_if< std::is_convertible< T, param_value >::value, T >::type* >
262  inline bool param_node::add( const std::string& a_name, T a_value )
263  {
264  //static_assert(std::is_convertible< T, param_value >::value, "Cannot convert type to param_value" );
265  contents::iterator it = f_contents.find( a_name );
266  if( it == f_contents.end() )
267  {
268  f_contents.insert( contents_type( a_name, param_ptr_t( new param_value( a_value ) ) ) );
269  return true;
270  }
271  return false;
272  }
273 
274  inline void param_node::replace( const std::string& a_name, const param& a_value )
275  {
276  f_contents[ a_name ] = a_value.clone();
277  return;
278  }
279 
280  inline void param_node::replace( const std::string& a_name, param&& a_value )
281  {
282  f_contents[ a_name ] = a_value.move_clone();
283  return;
284  }
285 
286  inline void param_node::replace( const std::string& a_name, param_ptr_t a_value_ptr )
287  {
288  f_contents[ a_name ] = std::move(a_value_ptr);
289  return;
290  }
291 
292  template< typename T, typename std::enable_if< std::is_convertible< T, param_value >::value, T >::type* >
293  inline void param_node::replace( const std::string& a_name, T a_value )
294  {
295  f_contents[ a_name ] = param_ptr_t( new param_value( a_value ) );
296  return;
297  }
298 
299 
300  inline void param_node::erase( const std::string& a_name )
301  {
302  contents::iterator it = f_contents.find( a_name );
303  if( it != f_contents.end() )
304  {
305  f_contents.erase( it );
306  }
307  return;
308  }
309 
310  inline param_ptr_t param_node::remove( const std::string& a_name )
311  {
312  contents::iterator it = f_contents.find( a_name );
313  if( it != f_contents.end() )
314  {
315  param_ptr_t removed( std::move( it->second ) );
316  f_contents.erase( it );
317  return removed;
318  }
319  return param_ptr_t();
320  }
321 
322  inline void param_node::clear()
323  {
324  f_contents.clear();
325  return;
326  }
327 
329  {
330  return iterator( f_contents.begin() );
331  }
332 
334  {
335  return const_iterator( f_contents.cbegin() );
336  }
337 
339  {
340  return iterator( f_contents.end() );
341  }
342 
344  {
345  return const_iterator( f_contents.cend() );
346  }
347 
348  SCARAB_API std::ostream& operator<<(std::ostream& out, const param_node& value);
349 
350 } /* namespace scarab */
351 
352 #endif /* SCARAB_PARAM_NODE_HH_ */
unsigned size() const
Definition: param_node.hh:189
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:274
virtual param_ptr_t clone() const
void erase(const std::string &a_name)
Definition: param_node.hh:300
virtual bool is_null() const
Definition: param_node.hh:179
x_value & dereference() const
Definition: param_node.hh:56
iterator begin()
Definition: param_node.hh:328
virtual bool is_node() const
Definition: param_node.hh:184
#define SCARAB_API
Definition: scarab_api.hh:24
virtual param_ptr_t move_clone()
Definition: param_node.hh:174
std::string type(const x_type &a_param)
Definition: typename.hh:24
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
enabler
Simple empty scoped class.
Definition: CLI11.hpp:714
bool empty() const
Definition: param_node.hh:193
const param & operator[](const std::string &a_name) const
Definition: param_node.hh:218
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
std::string get_value(const std::string &a_name, const std::string &a_default) const
Definition: param_node.hh:208
const x_key & name() const
Definition: param_node.hh:48
unsigned count(const std::string &a_name) const
Definition: param_node.hh:203
virtual param_ptr_t clone() const
Definition: param_node.hh:168
param_node_const_iterator const_iterator
Definition: param_node.hh:74
SCARAB_API std::ostream & operator<<(std::ostream &out, const param_array &a_value)
Definition: param_array.cc:167
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 to_string(std::uint64_t x)
Definition: date.h:7722
param_ptr_t remove(const std::string &a_name)
Definition: param_node.hh:310
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:228
param_node_contents contents
Definition: param_node.hh:72
bool has(const std::string &a_name) const
Definition: param_node.hh:198
map_deref_iterator< std::string, const param, param_node_contents::const_iterator > param_node_const_iterator
Definition: param_node.hh:66