Dict.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2012-2016, High Performance Humanoid Technologies (H2T),
5  * Karlsruhe Institute of Technology (KIT), all rights reserved.
6  *
7  * ArmarX is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * ArmarX is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program. If not, see <http://www.gnu.org/licenses/>.
18  *
19  * @author Fabian Peller-Konrad (fabian dot peller-konrad at kit dot edu)
20  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
21  * GNU General Public License
22  */
23 
24 // Header
25 #include "Dict.h"
26 
27 // ArmarX
28 #include <SimoxUtility/algorithm/string/string_conversion.h>
29 
31 
33 
34 namespace armarx::aron::data
35 {
36 
37  // constructors
38  Dict::Dict(const Path& path) :
39  detail::ContainerVariant<data::dto::Dict, Dict>::ContainerVariant(data::Descriptor::DICT,
40  path)
41  {
42  }
43 
44  Dict::Dict(const data::dto::DictPtr& o, const Path& path) :
45  detail::ContainerVariant<data::dto::Dict, Dict>::ContainerVariant(o,
46  data::Descriptor::DICT,
47  path)
48  {
49  for (const auto& [key, dataPtr] : this->aron->elements)
50  {
51  childrenNavigators[key] = Variant::FromAronDTO(dataPtr, path.withElement(key));
52  }
53  }
54 
55  Dict::Dict(const std::map<std::string, VariantPtr>& m, const Path& path) : Dict(path)
56  {
57  for (const auto& [key, dataPtr] : m)
58  {
59  addElement(key, dataPtr);
60  }
61  }
62 
63  // operators
64  bool
65  Dict::operator==(const Dict& other) const
66  {
67  for (const auto& [key, nav] : childrenNavigators)
68  {
69  if (not(other.hasElement(key)))
70  {
71  return false;
72  }
73  if (!nav)
74  {
75  return !((bool)other.getElement(key));
76  }
77  if (not(*nav == *other.getElement(key)))
78  {
79  return false;
80  }
81  }
82  return true;
83  }
84 
85  bool
86  Dict::operator==(const DictPtr& other) const
87  {
88  if (!other)
89  {
90  return false;
91  }
92  return *this == *other;
93  }
94 
96  Dict::operator[](const std::string& s) const
97  {
98  return getElement(s);
99  }
100 
101  Dict&
102  Dict::operator=(const Dict& other)
103  {
104  this->aron = other.aron;
105  this->childrenNavigators = other.childrenNavigators;
106  return *this;
107  }
108 
109  DictPtr
110  Dict::clone(const Path& p) const
111  {
112  DictPtr ret(new Dict(p));
113  for (const auto& [key, val] : getElements())
114  {
115  if (val)
116  {
117  ret->addElement(key, val->cloneAsVariant());
118  }
119  else
120  {
121  ret->addElement(key, nullptr);
122  }
123  }
124  return ret;
125  }
126 
127  // static methods
128  DictPtr
130  {
131  if (!aron)
132  {
133  return nullptr;
134  }
135  return std::make_shared<Dict>(aron);
136  }
137 
139  Dict::ToAronDictDTO(const DictPtr& navigator)
140  {
141  return navigator ? navigator->toAronDictDTO() : nullptr;
142  }
143 
146  {
147  return aron;
148  }
149 
150  // public member functions
151  std::vector<std::string>
153  {
154  std::vector<std::string> ret;
155  for (const auto& [key, _] : childrenNavigators)
156  {
157  ret.push_back(key);
158  }
159  return ret;
160  }
161 
162  std::string
164  {
165  return simox::alg::to_string(getAllKeys(), ", ");
166  }
167 
168  void
169  Dict::addElement(const std::string& key, const VariantPtr& data)
170  {
171  // Please note that the data may be null (indicating that a non existing maybetype has been added)
172 
173  if (hasElement(key))
174  {
175  ARMARX_TRACE;
176  throw error::AronException(__PRETTY_FUNCTION__,
177  "The key '" + key + "' already exists in a aron dict.");
178  }
179  setElement(key, data);
180  }
181 
182  void
183  Dict::addElementCopy(const std::string& key, const VariantPtr& data)
184  {
185  // Please note that the data may be null (indicating that a non existing maybetype has been added)
186 
187  if (hasElement(key))
188  {
189  ARMARX_TRACE;
190  throw error::AronException(__PRETTY_FUNCTION__,
191  "The key '" + key + "' already exists in a aron dict.");
192  }
193  setElementCopy(key, data);
194  }
195 
196  void
198  {
199  if (d == nullptr)
200  {
201  return;
202  }
203 
204  // merge and overwrite
205  for (const auto& [k, v] : getElements())
206  {
207  this->setElement(k, v);
208  }
209  }
210 
211  void
213  {
214  if (d == nullptr)
215  {
216  return;
217  }
218 
219  // merge and overwrite
220  for (const auto& [k, v] : getElements())
221  {
222  this->setElementCopy(k, v);
223  }
224  }
225 
226  bool
227  Dict::hasElement(const std::string& key) const
228  {
229  return childrenNavigators.count(key) > 0;
230  }
231 
232  VariantPtr
233  Dict::getElement(const std::string& key) const
234  {
235  auto it = childrenNavigators.find(key);
236  if (it == childrenNavigators.end())
237  {
238  ARMARX_TRACE;
239  throw error::AronException(__PRETTY_FUNCTION__,
240  "Could not find key '" + key +
241  "'. But I found the following keys: [" +
242  simox::alg::join(this->getAllKeys(), ", ") + "]",
243  getPath());
244  }
245  return it->second;
246  }
247 
248  std::map<std::string, VariantPtr>
250  {
251  return childrenNavigators;
252  }
253 
254  void
255  Dict::setElement(const std::string& key, const VariantPtr& data)
256  {
257  // Please note that the data may be null (indicating that a non existing maybetype has been added)
258 
259  if (data)
260  {
261  const auto& p = data->getPath();
262  if (not p.hasDirectPrefix(this->getPath()))
263  {
264  ARMARX_DEBUG << "An element added to a dict does not have a correct path set. This "
265  "may cause errors. Please use setElemetCopy() instead.";
266  }
267  }
268 
269  this->childrenNavigators[key] = data;
270  if (data)
271  {
272  this->aron->elements[key] = data->toAronDTO();
273  }
274  else
275  {
276  this->aron->elements[key] = nullptr;
277  }
278  }
279 
280  void
281  Dict::setElementCopy(const std::string& key, const VariantPtr& data)
282  {
283  // Please note that the data may be null (indicating that a non existing maybetype has been added)
284 
285  VariantPtr copy = nullptr;
286  if (data)
287  {
288  Path newPath = getPath().withElement(key);
289  copy = data->cloneAsVariant(newPath);
290  }
291  setElement(key, copy);
292  }
293 
294  void
295  Dict::removeElement(const std::string& key)
296  {
297  childrenNavigators.erase(key);
298  aron->elements.erase(key);
299  }
300 
301  void
303  {
304  childrenNavigators.clear();
305  aron->elements.clear();
306  }
307 
308  VariantPtr
309  Dict::at(const std::string& s) const
310  {
311  return getElement(s);
312  }
313 
314  // virtual implementations
315  std::string
317  {
318  return "Dict";
319  }
320 
321  std::string
323  {
324  return "armarx::aron::data::Dict";
325  }
326 
327  // TODO
330  {
331  ARMARX_TRACE;
332  throw error::NotImplementedYetException(__PRETTY_FUNCTION__);
333  }
334 
335  bool
337  {
338  if (!type)
339  return true;
340 
341  type::Descriptor typeDesc = type->getDescriptor();
342 
343  switch (typeDesc)
344  {
346  {
347  ARMARX_TRACE;
348  auto objectTypeNav = type::Object::DynamicCastAndCheck(type);
349 
350  // here we need to iterate over the elements of the type. That must be fulfilled.
351  // If this dict has more members that its fine.
352  for (const auto& [key, childTypeNav] : objectTypeNav->getMemberTypes())
353  {
354  if (!this->hasElement(key))
355  {
356  return false; // key must exist
357  }
358 
359  if (!childTypeNav)
360  {
361  continue; // no information whih is fine --> continue
362  }
363 
364  auto childNav = this->getElement(key);
365  if (childNav)
366  {
367  if (not childNav->fullfillsType(childTypeNav))
368  {
369  return false;
370  }
371  // else childnav fulfills type which is fine --> continue
372  continue;
373  }
374  else
375  {
376  if (childTypeNav->getMaybe() == type::Maybe::NONE)
377  {
378  return false;
379  }
380  // else: childTypeNav == maybe && nav == null which is fine --> continue
381  continue;
382  }
383  }
384  return true;
385  }
387  {
388  ARMARX_TRACE;
389  auto dictTypeNav = type::Dict::DynamicCastAndCheck(type);
390  for (const auto& [key, childNav] : childrenNavigators)
391  {
392  (void)key;
393  auto childTypeNav = dictTypeNav->getAcceptedType();
394  if (!childNav)
395  {
396  if (childTypeNav && childTypeNav->getMaybe() == type::Maybe::NONE)
397  {
398  return false;
399  }
400  // else childTypeNav is null or maybe and childNav is null which is fine.
401  continue;
402  }
403  if (!childNav->fullfillsType(childTypeNav))
404  {
405  return false;
406  }
407  }
408  return true;
409  }
410  default:
411  return false;
412  }
413  }
414 
415  std::vector<VariantPtr>
417  {
418  std::vector<VariantPtr> ret(childrenNavigators.size());
419  for (const auto& [key, nav] : childrenNavigators)
420  {
421  ret.push_back(nav);
422  }
423  return ret;
424  }
425 
426  size_t
428  {
429  return childrenNavigators.size();
430  }
431 
432  VariantPtr
433  Dict::navigateAbsolute(const Path& path) const
434  {
435  if (!path.hasElement())
436  {
437  ARMARX_TRACE;
438  throw error::AronException(
439  __PRETTY_FUNCTION__, "Could not navigate without a valid path", path);
440  }
441  std::string el = path.getFirstElement();
442  if (!hasElement(el))
443  {
444  ARMARX_TRACE;
446  __PRETTY_FUNCTION__, "Could not find an element of a path.", el, path);
447  }
448 
449  if (path.size() == 1)
450  {
451  return childrenNavigators.at(el);
452  }
453  else
454  {
456  if (!childrenNavigators.at(el))
457  {
458  ARMARX_TRACE;
459  throw error::AronException(__PRETTY_FUNCTION__,
460  "Could not navigate into a NULL member. Seems like the "
461  "member is optional and not set.",
462  next);
463  }
464  return childrenNavigators.at(el)->navigateAbsolute(next);
465  }
466  }
467 } // namespace armarx::aron::data
armarx::aron::Path::withElement
Path withElement(const std::string &, bool escape=false) const
Definition: Path.cpp:161
armarx::aron::data::Dict::recalculateType
type::VariantPtr recalculateType() const override
recalculate the type of a data variant. Please not tha the mapping ist NOT bijective,...
Definition: Dict.cpp:329
armarx::aron::Path::getFirstElement
std::string getFirstElement() const
Definition: Path.cpp:102
armarx::aron::error::AronException
A base class for aron exceptions.
Definition: Exception.h:42
armarx::aron::type::VariantPtr
std::shared_ptr< Variant > VariantPtr
Definition: forward_declarations.h:11
armarx::aron::ret
ReaderT::InputType T & ret
Definition: rw.h:21
armarx::aron::data::Dict::removeElement
void removeElement(const std::string &key)
Definition: Dict.cpp:295
armarx::aron::data::Variant::FromAronDTO
static VariantPtr FromAronDTO(const data::dto::GenericDataPtr &, const Path &=Path())
create a variant from a dto object
Definition: Variant.cpp:39
armarx::aron::Path::hasElement
bool hasElement() const
Definition: Path.cpp:113
armarx::aron::data::Dict::addElementCopy
void addElementCopy(const std::string &key, const VariantPtr &=nullptr)
Definition: Dict.cpp:183
armarx::aron::Path::size
size_t size() const
Definition: Path.cpp:119
armarx::aron::data::Variant::getPath
Path getPath() const
get the path
Definition: Variant.h:110
armarx::aron::data::Dict::getElement
VariantPtr getElement(const std::string &) const
Definition: Dict.cpp:233
trace.h
armarx::aron::data::Variant::path
const Path path
Definition: Variant.h:156
armarx::aron::data::Dict::operator=
Dict & operator=(const Dict &)
Definition: Dict.cpp:102
detail
Definition: OpenCVUtil.cpp:127
armarx::aron::data::Descriptor
Descriptor
Definition: Descriptor.h:193
armarx::aron::error::NotImplementedYetException
The NotImplementedYetException class.
Definition: Exception.h:88
armarx::aron::data::detail::SpecializedVariantBase< data::dto::Dict, Dict >::clone
virtual PointerType clone() const
Definition: SpecializedVariant.h:82
armarx::aron::data::Dict::mergeAndReplace
void mergeAndReplace(const DictPtr &d)
Definition: Dict.cpp:197
Dict.h
armarx::aron::data::Dict::FromAronDictDTO
static PointerType FromAronDictDTO(const data::dto::DictPtr &aron)
Definition: Dict.cpp:129
armarx::aron::data::Dict::getAllKeys
std::vector< std::string > getAllKeys() const
Definition: Dict.cpp:152
armarx::aron::data::Dict::navigateAbsolute
VariantPtr navigateAbsolute(const Path &path) const override
naviate absolute
Definition: Dict.cpp:433
armarx::aron::Path
The Path class.
Definition: Path.h:36
armarx::aron::data::VariantPtr
std::shared_ptr< Variant > VariantPtr
Definition: forward_declarations.h:11
armarx::aron::data::Dict::operator==
bool operator==(const Dict &) const override
Definition: Dict.cpp:65
armarx::aron::error::ValueNotValidException
The ValueNotValidException class.
Definition: Exception.h:145
ARMARX_TRACE
#define ARMARX_TRACE
Definition: trace.h:69
armarx::aron::data::Dict::fullfillsType
bool fullfillsType(const type::VariantPtr &) const override
checks, if the current data variant fullfills the given type
Definition: Dict.cpp:336
armarx::aron::data::Dict::addElement
void addElement(const std::string &key, const VariantPtr &=nullptr)
Definition: Dict.cpp:169
copy
Use of this software is granted under one of the following two to be chosen freely by the user Boost Software License Version Marcin Kalicinski Permission is hereby free of to any person or organization obtaining a copy of the software and accompanying documentation covered by this and transmit the and to prepare derivative works of the and to permit third parties to whom the Software is furnished to do all subject to the including the above license this restriction and the following must be included in all copies of the in whole or in and all derivative works of the unless such copies or derivative works are solely in the form of machine executable object code generated by a source language processor THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF FITNESS FOR A PARTICULAR TITLE AND NON INFRINGEMENT IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN TORT OR ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE The MIT Marcin Kalicinski Permission is hereby free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to copy
Definition: license.txt:39
data
uint8_t data[1]
Definition: EtherCATFrame.h:68
ARMARX_DEBUG
#define ARMARX_DEBUG
Definition: Logging.h:177
armarx::aron::data::Dict::clear
void clear()
Definition: Dict.cpp:302
scene3D::NONE
@ NONE
Definition: ManipulatorMode.h:38
armarx::aron::data::Dict::hasElement
bool hasElement(const std::string &) const
Definition: Dict.cpp:227
armarx::aron::data::Dict::Dict
Dict(const Path &path=Path())
Definition: Dict.cpp:38
armarx::aron::data::Dict::ToAronDictDTO
static data::dto::DictPtr ToAronDictDTO(const PointerType &navigator)
Definition: Dict.cpp:139
armarx::to_string
const std::string & to_string(const std::string &s)
Definition: StringHelpers.h:40
armarx::aron::data::Dict::at
VariantPtr at(const std::string &) const
Definition: Dict.cpp:309
armarx::aron::data
A convenience header to include all aron files (full include, not forward declared)
Definition: aron_conversions.cpp:3
armarx::aron::data::DictPtr
std::shared_ptr< Dict > DictPtr
Definition: Dict.h:41
armarx::aron::data::Dict::operator[]
VariantPtr operator[](const std::string &) const
Definition: Dict.cpp:96
armarx::ctrlutil::v
double v(double t, double v0, double a0, double j)
Definition: CtrlUtil.h:39
armarx::aron::data::Dict::getElements
std::map< std::string, VariantPtr > getElements() const
Definition: Dict.cpp:249
armarx::aron::type::Descriptor::OBJECT
@ OBJECT
armarx::aron::Path::withDetachedFirstElement
Path withDetachedFirstElement() const
Definition: Path.cpp:205
armarx::aron::type::detail::SpecializedVariantBase< type::dto::AronObject, Object >::DynamicCastAndCheck
static std::shared_ptr< Object > DynamicCastAndCheck(const VariantPtr &n)
Definition: SpecializedVariant.h:124
armarx::aron::type::Descriptor::DICT
@ DICT
armarx::aron::data::Dict::mergeAndReplaceCopy
void mergeAndReplaceCopy(const DictPtr &d)
Definition: Dict.cpp:212
armarx::aron::data::Dict::setElementCopy
void setElementCopy(const std::string &, const VariantPtr &=nullptr)
Definition: Dict.cpp:281
armarx::aron::data::Dict::getChildren
std::vector< VariantPtr > getChildren() const override
get the children of a data variant
Definition: Dict.cpp:416
armarx::aron::data::Dict::childrenSize
size_t childrenSize() const override
get the children size of a data variant
Definition: Dict.cpp:427
armarx::aron::data::Dict::getAllKeysAsString
std::string getAllKeysAsString() const
Definition: Dict.cpp:163
armarx::aron::data::Dict::getFullName
std::string getFullName() const override
get the full str representation of this variant
Definition: Dict.cpp:322
armarx::aron::type::Descriptor
Descriptor
Definition: Descriptor.h:76
armarx::aron::data::Dict::getShortName
std::string getShortName() const override
get a short str representation of this variant
Definition: Dict.cpp:316
armarx::ctrlutil::s
double s(double t, double s0, double v0, double a0, double j)
Definition: CtrlUtil.h:33
Factory.h
armarx::aron::data::detail::SpecializedVariantBase< data::dto::Dict, Dict >::aron
AronDataType::PointerType aron
Definition: SpecializedVariant.h:154
armarx::aron::data::Dict::setElement
void setElement(const std::string &, const VariantPtr &=nullptr)
Definition: Dict.cpp:255
armarx::aron::data::Dict
Definition: Dict.h:44
armarx::aron::data::Dict::toAronDictDTO
data::dto::DictPtr toAronDictDTO() const
Definition: Dict.cpp:145