ADTF
Loading...
Searching...
No Matches
access_map.h
Go to the documentation of this file.
1
14
15#ifndef DD_DD_ACCESS_MAP_H_INCLUDED
16#define DD_DD_ACCESS_MAP_H_INCLUDED
17
21
22#include <memory>
23#include <sstream>
24#include <unordered_map>
25
26namespace ddl {
27namespace dd {
28namespace utility {
29
38 map_item_added,
39 map_item_removed,
40 map_item_changed,
41 map_item_renamed,
42 map_subitem_added,
43 map_subitem_removed,
44 map_subitem_changed,
45 map_subitem_renamed,
46 map_subitem_popped,
47 map_subitem_inserted,
48 map_item_removing,
49 map_subitem_removing,
50 map_item_renaming,
51 map_subitem_renaming
52};
53
60template <typename T>
62
69template <typename T>
71
78template <typename DDL_TYPE_TO_ACCESS, typename TYPE_VALIDATOR_CLASS>
79class TypeAccessMap : public TypeAccessMapObserver<DDL_TYPE_TO_ACCESS> {
80public:
82 typedef DDL_TYPE_TO_ACCESS access_type;
84 typedef std::shared_ptr<DDL_TYPE_TO_ACCESS> value_type;
86 typedef std::unordered_map<std::string, value_type> container_type;
88 typedef typename container_type::iterator iterator;
90 typedef typename container_type::const_iterator const_iterator;
103
104public:
109 TypeAccessMap() = delete;
116 TypeAccessMap(TYPE_VALIDATOR_CLASS* validator, const std::string& validation_info)
117 : _validator(validator), _validation_info(validation_info)
118 {
119 }
120
125 {
126 clear();
127 }
128
132 {
133 *this = std::move(other);
134 }
135
141 {
142 clear();
143 _validation_info = std::move(other._validation_info);
144 _types = std::move(other._types);
145 // the other will remove itself as observer with clear
146 for (const auto& current: _types) {
147 // the other will not observe this anymore
148 (static_cast<map_subject_type*>(current.second.get()))
149 ->detachObserver(static_cast<observer_type*>(&other));
150 // i want to observe this
151 (static_cast<map_subject_type*>(current.second.get()))
152 ->attachObserver(static_cast<observer_type*>(this));
153 }
154 _validator = nullptr;
155 return *this;
156 }
157
164 : _validator(nullptr), _validation_info(other._validation_info)
165 {
166 for (auto current: other._types) {
167 auto new_type = std::make_shared<DDL_TYPE_TO_ACCESS>(*current.second);
168 // i want to observe this
169 (static_cast<map_subject_type*>(new_type.get()))
170 ->attachObserver(static_cast<observer_type*>(this));
171 _types[current.first] = new_type;
172 }
173 }
174
181 {
182 clear();
183 _validation_info = other._validation_info;
184 for (auto current: other._types) {
185 auto new_type = std::make_shared<DDL_TYPE_TO_ACCESS>(*current.second);
186 // i want to observe this
187 (static_cast<map_subject_type*>(new_type.get()))
188 ->attachObserver(static_cast<observer_type*>(this));
189 _types[current.first] = new_type;
190 }
191 _validator = nullptr;
192 return *this;
193 }
194
195public:
202 std::shared_ptr<const DDL_TYPE_TO_ACCESS> get(const std::string& type_name) const
203 {
204 auto it_find = _types.find(type_name);
205 if (it_find != _types.cend()) {
206 std::shared_ptr<const DDL_TYPE_TO_ACCESS> const_return = it_find->second;
207 return const_return;
208 }
209 return {};
210 }
211
218 bool contains(const std::string& type_name) const
219 {
220 const auto& it_find = _types.find(type_name);
221 if (it_find != _types.cend()) {
222 return true;
223 }
224 return false;
225 }
226
233 bool contains(const DDL_TYPE_TO_ACCESS& type_to_find) const
234 {
235 const auto& it_find = _types.find(type_to_find.getName());
236 if (it_find != _types.cend()) {
237 return type_to_find == *(it_find->second);
238 }
239 return false;
240 }
241
248 bool contains(const TypeAccessMap& other) const
249 {
250 for (const auto& other_content: other._types) {
251 if (!contains(*(other_content.second))) {
252 return false;
253 }
254 }
255 return true;
256 }
257
265 std::shared_ptr<DDL_TYPE_TO_ACCESS> create(const DDL_TYPE_TO_ACCESS& type_to_add)
266 {
267 const auto type_found = access(type_to_add.getName());
268 // have a look if the type already exists here
269 if (type_found) {
270 // check if they are equal
271 if (*type_found != type_to_add) {
272 throw ddl::dd::Error(
273 _validation_info + "::create",
274 {type_to_add.getName()},
275 "value with the given name already exists and differs in " +
277 type_to_add));
278 }
279 return type_found;
280 }
281 else {
282 const bool already_exists_other_type =
283 _validator && _validator->validateContains(type_to_add);
284 if (already_exists_other_type) {
285 throw ddl::dd::Error(
286 _validation_info + "::create",
287 {type_to_add.getName()},
288 std::string("value with the given name already exists with another type of ") +
290 }
291 }
292 auto new_type_value = std::make_shared<DDL_TYPE_TO_ACCESS>(type_to_add);
293 // i want to observe this
294 (static_cast<map_subject_type*>(new_type_value.get()))
295 ->attachObserver(static_cast<observer_type*>(this));
296 _types[type_to_add.getName()] = new_type_value;
297 if (_validator) {
298 _validator->notifyChangedMapContent(
299 TypeAccessMapEventCode::map_item_added, *new_type_value, type_to_add.getName());
300 }
301 return new_type_value;
302 }
303
310 void add(const DDL_TYPE_TO_ACCESS& type_to_add)
311 {
312 create(type_to_add);
313 }
314
322 std::shared_ptr<DDL_TYPE_TO_ACCESS> create(DDL_TYPE_TO_ACCESS&& type_to_add)
323 {
324 const auto type_found = access(type_to_add.getName());
325 // have a look if the type already exists here
326 if (type_found) {
327 // check if they are equal
328 if (*type_found != type_to_add) {
329 throw ddl::dd::Error(
330 _validation_info + "::create",
331 {type_to_add.getName()},
332 "value with the given name already exists and differs in " +
334 type_to_add));
335 }
336 return type_found;
337 }
338 else {
339 // has already another type ?
340 const bool already_exists_other_type =
341 _validator && _validator->validateContains(type_to_add);
342 if (already_exists_other_type) {
343 throw ddl::dd::Error(
344 _validation_info + "::create",
345 {type_to_add.getName()},
346 std::string("value with the given name already exists with another type of ") +
348 }
349 }
350 auto new_type_value = std::make_shared<DDL_TYPE_TO_ACCESS>(std::move(type_to_add));
351 // i want to observe this
352 (static_cast<map_subject_type*>(new_type_value.get()))
353 ->attachObserver(static_cast<observer_type*>(this));
354 _types[new_type_value->getName()] = new_type_value;
355 if (_validator) {
356 _validator->notifyChangedMapContent(
357 TypeAccessMapEventCode::map_item_added, *new_type_value, new_type_value->getName());
358 }
359 return new_type_value;
360 }
361
368 void emplace(DDL_TYPE_TO_ACCESS&& type_to_add)
369 {
370 create(std::move(type_to_add));
371 }
372
378 void remove(const std::string& type_name)
379 {
380 auto removed_value = access(type_name);
381 if (removed_value) {
382 if (_validator) {
383 _validator->notifyChangedMapContent(
384 TypeAccessMapEventCode::map_item_removing, *removed_value, type_name);
385 }
386 _types.erase(type_name);
387 (static_cast<map_subject_type*>(removed_value.get()))
388 ->detachObserver(static_cast<observer_type*>(this));
389 if (_validator) {
390 _validator->notifyChangedMapContent(
391 TypeAccessMapEventCode::map_item_removed, *removed_value, type_name);
392 }
393 return;
394 }
395 throw ddl::dd::Error(
396 _validation_info + "::remove", {type_name}, "value with the given name does not exist");
397 }
398
404 std::shared_ptr<DDL_TYPE_TO_ACCESS> access(const std::string& type_name)
405 {
406 auto it_find = _types.find(type_name);
407 if (it_find != _types.end()) {
408 return it_find->second;
409 }
410 return {};
411 }
412
417 size_t getSize() const
418 {
419 return _types.size();
420 }
421
427 {
428 return _types.begin();
429 }
430
436 {
437 return _types.end();
438 }
439
445 {
446 return _types.cbegin();
447 }
448
454 {
455 return _types.cend();
456 }
457
463 {
464 return cbegin();
465 }
466
472 {
473 return cend();
474 }
475
482 bool operator==(const TypeAccessMap& other) const
483 {
484 if (getSize() != other.getSize()) {
485 return false;
486 }
487 else {
488 return contains(other);
489 }
490 }
491
498 bool operator!=(const TypeAccessMap& other) const
499 {
500 return !operator==(other);
501 }
502
506 void clear()
507 {
508 for (auto& current: _types) {
509 // unregister me as observer
510 (static_cast<map_subject_type*>(current.second.get()))
511 ->detachObserver(static_cast<observer_type*>(this));
512 }
513 _types.clear();
514 }
515
516public:
525 subject_type& subject_changed,
526 const std::string& additional_info)
527 {
528 if (event_code == map_item_renamed) {
529 bool already_exists = contains(subject_changed.getName());
530 if (_validator && !already_exists) {
531 // we ask the validator if it already exists
532 // this will check if the name might be unique with corresponding
533 // other maps ... this functionality is only possible with map! not with lists!
534 already_exists = _validator->validateContains(subject_changed);
535 }
536 if (already_exists) {
537 throw ddl::dd::Error(
538 _validation_info + "::modelChanged",
539 {subject_changed.getName()},
540 "Renaming not possible. Value with the given name already exists");
541 }
542 else {
543 // here additional info is the old name
544 iterator current = _types.find(additional_info);
545 // we need to readd it
546 auto value = current->second;
547 _types.erase(current);
548 _types[value->getName()] = value;
549 // after erasing do not touch the iterator anymore
550 }
551 }
552 if (_validator) {
553 // i should discover the shared_ptr here, but not needed at the moment .. so we try to
554 // get performance here
555 _validator->notifyChangedMapContent(event_code, subject_changed, additional_info);
556 }
557 }
558
559private:
568 void deepCopy(TypeAccessMap& destination, TYPE_VALIDATOR_CLASS* validator) const
569 {
570 destination = *this;
571 destination._validator = validator;
572 }
573 container_type _types;
574 TYPE_VALIDATOR_CLASS* _validator;
575 std::string _validation_info;
576};
577
578} // namespace utility
579} // namespace dd
580
581namespace utility {
585 using ::ddl::dd::utility::TypeAccessMap;
586} // namespace utility
587} // namespace ddl
588
589#endif // DD_DD_ACCESS_MAP_H_INCLUDED
Exception helper class to collect information while parsing, adding DD Objects or other failed operat...
Definition ddl_error.h:31
The ModelObserver utility template.
Definition access_observer.h:34
TypeAccessMapEventCode event_code_type
Definition access_observer.h:37
Model Subject utility to define a Model Subject that notifies one or more observers.
Definition access_observer.h:68
ModelObserverUtility< T, TypeAccessMapEventCode > observer_type
Definition access_observer.h:75
Utility class for observable named items where the order is NOT important.
Definition access_map.h:79
const_iterator cend() const
const end iterator access
Definition access_map.h:453
const_iterator end() const
range based end operator for const access
Definition access_map.h:471
TypeAccessMapObserver< BaseUnit > parent_type
Definition access_map.h:92
iterator begin()
the range based begin iterator
Definition access_map.h:426
parent_type::event_code_type event_code_type
Definition access_map.h:98
std::shared_ptr< BaseUnit > value_type
Definition access_map.h:84
TypeAccessMap & operator=(const TypeAccessMap &other)
copies (deepcopy!) and overwrite the current content.
Definition access_map.h:180
std::shared_ptr< DDL_TYPE_TO_ACCESS > access(const std::string &type_name)
change access to an item
Definition access_map.h:404
container_type::const_iterator const_iterator
Definition access_map.h:90
bool contains(const DDL_TYPE_TO_ACCESS &type_to_find) const
determines if the item is in this map.
Definition access_map.h:233
friend TYPE_VALIDATOR_CLASS
Definition access_map.h:102
bool operator!=(const TypeAccessMap &other) const
non equality operator.
Definition access_map.h:498
std::shared_ptr< DDL_TYPE_TO_ACCESS > create(DDL_TYPE_TO_ACCESS &&type_to_add)
creates the given item in place
Definition access_map.h:322
const_iterator cbegin() const
const begin iterator access
Definition access_map.h:444
TypeAccessMap & operator=(TypeAccessMap &&other)
move assignment operator
Definition access_map.h:140
void modelChanged(event_code_type event_code, subject_type &subject_changed, const std::string &additional_info)
overrides the observers utility function.
Definition access_map.h:524
size_t getSize() const
Get the Size.
Definition access_map.h:417
TypeAccessMap(TYPE_VALIDATOR_CLASS *validator, const std::string &validation_info)
CTOR.
Definition access_map.h:116
bool operator==(const TypeAccessMap &other) const
equality operator.
Definition access_map.h:482
bool contains(const TypeAccessMap &other) const
determines if the other is a subset of this map
Definition access_map.h:248
parent_type::subject_type subject_type
Definition access_map.h:100
std::shared_ptr< DDL_TYPE_TO_ACCESS > create(const DDL_TYPE_TO_ACCESS &type_to_add)
creates the given item by copy
Definition access_map.h:265
container_type::iterator iterator
Definition access_map.h:88
virtual ~TypeAccessMap()
DTOR.
Definition access_map.h:124
void add(const DDL_TYPE_TO_ACCESS &type_to_add)
adds the given item
Definition access_map.h:310
std::unordered_map< std::string, value_type > container_type
Definition access_map.h:86
void remove(const std::string &type_name)
item to remove
Definition access_map.h:378
void clear()
clears the list and remove this as observer
Definition access_map.h:506
TypeAccessMap(TypeAccessMap &&other)
move CTOR
Definition access_map.h:131
TypeAccessMapSubject< BaseUnit > map_subject_type
Definition access_map.h:94
TypeAccessMap()=delete
no default CTOR!
map_subject_type::observer_type observer_type
Definition access_map.h:96
void emplace(DDL_TYPE_TO_ACCESS &&type_to_add)
emplaces the given item
Definition access_map.h:368
bool contains(const std::string &type_name) const
determines is the type name exists in this map
Definition access_map.h:218
iterator end()
the range based end iterator
Definition access_map.h:435
std::shared_ptr< const DDL_TYPE_TO_ACCESS > get(const std::string &type_name) const
get the item with the given name type_name
Definition access_map.h:202
TypeAccessMap(const TypeAccessMap &other)
copies (deepcopy!) CTOR
Definition access_map.h:163
const_iterator begin() const
range based begin operator for const access
Definition access_map.h:462
definition of the old compatibility utility namespace
Definition datamodel_keyvalue.h:160
ModelObserverUtility< T, TypeAccessMapEventCode > TypeAccessMapObserver
helper template to observe map content.
Definition access_map.h:70
ModelSubjectUtility< T, TypeAccessMapEventCode > TypeAccessMapSubject
helper template to observe map content.
Definition access_map.h:61
TypeAccessMapEventCode
Internal event code to inform the parent DD Object about the change of an item within the list.
Definition access_map.h:37
definition of the dd namespace
Definition datamodel_base.h:26
@ validation_info
Validation Info.
Definition dd_infomodel_type.h:32
definition of the utility namespace
Definition ddl.h:66
definition of the ddl namespace
Definition codec.h:21
static constexpr auto _other_types
validation other types
Definition access_validation.h:41
static std::string getDifference(const T &, const T &)
validation difference message
Definition access_validation.h:45