BitShares-Core  5.0.0
BitShares blockchain implementation and command-line interface software
variant_object.cpp
Go to the documentation of this file.
1 #include <fc/variant_object.hpp>
3 #include <assert.h>
4 
5 
6 namespace fc
7 {
8  // ---------------------------------------------------------------
9  // entry
10 
12  variant_object::entry::entry( string k, variant v ) : _key(std::move(k)),_value(std::move(v)) {}
13  variant_object::entry::entry( entry&& e ) : _key(std::move(e._key)),_value(std::move(e._value)) {}
14  variant_object::entry::entry( const entry& e ) : _key(e._key),_value(e._value) {}
16  {
17  if( this != &e )
18  {
19  _key = e._key;
20  _value = e._value;
21  }
22  return *this;
23  }
25  {
26  std::swap( _key, e._key );
27  std::swap( _value, e._value );
28  return *this;
29  }
30 
31  const string& variant_object::entry::key()const
32  {
33  return _key;
34  }
35 
37  {
38  return _value;
39  }
41  {
42  return _value;
43  }
44 
46  {
47  std::swap( _value, v );
48  }
49 
50  // ---------------------------------------------------------------
51  // variant_object
52 
54  {
55  assert( _key_value != nullptr );
56  return _key_value->begin();
57  }
58 
60  {
61  return _key_value->end();
62  }
63 
65  {
66  return find( key.c_str() );
67  }
68 
70  {
71  for( auto itr = begin(); itr != end(); ++itr )
72  {
73  if( itr->key() == key )
74  {
75  return itr;
76  }
77  }
78  return end();
79  }
80 
81  const variant& variant_object::operator[]( const string& key )const
82  {
83  return (*this)[key.c_str()];
84  }
85 
86  const variant& variant_object::operator[]( const char* key )const
87  {
88  auto itr = find( key );
89  if( itr != end() ) return itr->value();
90  FC_THROW_EXCEPTION( key_not_found_exception, "Key ${key}", ("key",key) );
91  }
92 
93  size_t variant_object::size() const
94  {
95  return _key_value->size();
96  }
97 
99  :_key_value(std::make_shared<std::vector<entry>>() )
100  {
101  }
102 
104  : _key_value(std::make_shared<std::vector<entry>>())
105  {
106  _key_value->emplace_back(entry(std::move(key), std::move(val)));
107  }
108 
110  :_key_value( obj._key_value )
111  {
112  assert( _key_value != nullptr );
113  }
114 
116  : _key_value( std::move(obj._key_value) )
117  {
118  obj._key_value = std::make_shared<std::vector<entry>>();
119  assert( _key_value != nullptr );
120  }
121 
123  : _key_value(std::make_shared<std::vector<entry>>(*obj._key_value))
124  {
125  }
126 
128  : _key_value(std::move(obj._key_value))
129  {
130  assert( _key_value != nullptr );
131  }
132 
134  {
135  if (this != &obj)
136  {
137  std::swap(_key_value, obj._key_value );
138  assert( _key_value != nullptr );
139  }
140  return *this;
141  }
142 
144  {
145  if (this != &obj)
146  {
147  _key_value = obj._key_value;
148  }
149  return *this;
150  }
151 
153  {
154  _key_value = std::move(obj._key_value);
155  obj._key_value.reset( new std::vector<entry>() );
156  return *this;
157  }
158 
160  {
161  *_key_value = *obj._key_value;
162  return *this;
163  }
164 
165  void to_variant( const variant_object& var, variant& vo, uint32_t max_depth )
166  {
167  vo = variant(var);
168  }
169 
170  void from_variant( const variant& var, variant_object& vo, uint32_t max_depth )
171  {
172  vo = var.get_object();
173  }
174 
175  // ---------------------------------------------------------------
176  // mutable_variant_object
177 
179  {
180  return _key_value->begin();
181  }
182 
184  {
185  return _key_value->end();
186  }
187 
189  {
190  return _key_value->begin();
191  }
192 
194  {
195  return _key_value->end();
196  }
197 
199  {
200  return find( key.c_str() );
201  }
202 
204  {
205  for( auto itr = begin(); itr != end(); ++itr )
206  {
207  if( itr->key() == key )
208  {
209  return itr;
210  }
211  }
212  return end();
213  }
214 
216  {
217  return find( key.c_str() );
218  }
219 
221  {
222  for( auto itr = begin(); itr != end(); ++itr )
223  {
224  if( itr->key() == key )
225  {
226  return itr;
227  }
228  }
229  return end();
230  }
231 
232  const variant& mutable_variant_object::operator[]( const string& key )const
233  {
234  return (*this)[key.c_str()];
235  }
236 
237  const variant& mutable_variant_object::operator[]( const char* key )const
238  {
239  auto itr = find( key );
240  if( itr != end() ) return itr->value();
241  FC_THROW_EXCEPTION( key_not_found_exception, "Key ${key}", ("key",key) );
242  }
244  {
245  return (*this)[key.c_str()];
246  }
247 
249  {
250  auto itr = find( key );
251  if( itr != end() ) return itr->value();
252  _key_value->emplace_back(entry(key, variant()));
253  return _key_value->back().value();
254  }
255 
257  {
258  return _key_value->size();
259  }
260 
262  :_key_value(new std::vector<entry>)
263  {
264  }
265 
267  : _key_value(new std::vector<entry>())
268  {
269  _key_value->push_back(entry(std::move(key), std::move(val)));
270  }
271 
273  : _key_value( new std::vector<entry>(*obj._key_value) )
274  {
275  }
276 
278  : _key_value( new std::vector<entry>(*obj._key_value) )
279  {
280  }
281 
283  : _key_value(std::move(obj._key_value))
284  {
285  }
286 
288  {
289  *_key_value = *obj._key_value;
290  return *this;
291  }
292 
294  {
295  if (this != &obj)
296  {
297  _key_value = std::move(obj._key_value);
298  }
299  return *this;
300  }
301 
303  {
304  if (this != &obj)
305  {
306  *_key_value = *obj._key_value;
307  }
308  return *this;
309  }
310 
312  {
313  _key_value->reserve(s);
314  }
315 
316  void mutable_variant_object::erase( const string& key )
317  {
318  for( auto itr = begin(); itr != end(); ++itr )
319  {
320  if( itr->key() == key )
321  {
322  _key_value->erase(itr);
323  return;
324  }
325  }
326  }
327 
330  {
331  auto itr = find( key.c_str() );
332  if( itr != end() )
333  {
334  itr->set( std::move(var) );
335  }
336  else
337  {
338  _key_value->push_back( entry( std::move(key), std::move(var) ) );
339  }
340  return *this;
341  }
342 
346  mutable_variant_object& mutable_variant_object::operator()( string key, variant var, uint32_t max_depth )
347  {
348  _key_value->push_back( entry( std::move(key), std::move(var) ) );
349  return *this;
350  }
351 
353  {
354  for( const variant_object::entry& e : vo )
355  set( e.key(), e.value() );
356  return *this;
357  }
358 
360  {
361  if( &mvo == this ) // mvo(mvo) is no-op
362  return *this;
363  for( const mutable_variant_object::entry& e : mvo )
364  set( e.key(), e.value() );
365  return *this;
366  }
367 
370  _max_depth(m - 1),
371  _reached_depth_limit(m == 0),
372  _skip_on_exception(skip_on_exception)
373  {
374  if( !skip_on_exception )
375  FC_ASSERT( m > 0, "Recursion depth exceeded!" );
376  else if( m == 0 )
377  set( "__err_msg", "[ERROR: Recusion depth exceeded!]" );
378  }
379 
381  {
382  if( _reached_depth_limit )
383  // _skip_on_exception will always be true here
384  return *this;
385 
386  try
387  {
389  }
390  catch( ... )
391  {
392  if( !_skip_on_exception )
393  throw;
394  else
395  set( "__err_msg", "[ERROR: Caught exception in operator()( const variant_object& ).]" );
396  }
397  return *this;
398  }
399 
400  void to_variant( const mutable_variant_object& var, variant& vo, uint32_t max_depth )
401  {
402  vo = variant(var);
403  }
404 
405  void from_variant( const variant& var, mutable_variant_object& vo, uint32_t max_depth )
406  {
407  vo = var.get_object();
408  }
409 
410 } // namesapce fc
void erase(const string &key)
const variant & operator[](const string &key) const
iterator find(const string &key) const
variant_object & operator=(variant_object &&)
An order-perserving dictionary of variant&#39;s.
limited_mutable_variant_object(uint32_t max_depth, bool skip_on_exception=false)
const variant & operator[](const string &key) const
mutable_variant_object & operator()(string key, variant var, uint32_t max_depth=1)
variant_object & get_object()
Definition: variant.cpp:554
void to_variant(const flat_set< T, A... > &var, variant &vo, uint32_t _max_depth)
Definition: flat.hpp:105
iterator begin() const
iterator find(const string &key) const
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object&#39;s.
Definition: variant.hpp:198
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:378
variant_object::entry entry
a key/value pair
const variant & value() const
Defines exception&#39;s used by fc.
limited_mutable_variant_object & operator()(string key, T &&var)
std::vector< entry >::const_iterator iterator
entry & operator=(const entry &)
std::vector< entry >::iterator iterator
void from_variant(const variant &var, flat_set< T, A... > &vo, uint32_t _max_depth)
Definition: flat.hpp:116
iterator end() const
mutable_variant_object & set(string key, variant var)
Definition: api.hpp:15
mutable_variant_object & operator=(mutable_variant_object &&)
const string & key() const
An order-perserving dictionary of variant&#39;s.
size_t size() const