ATLAS Offline Software
Loading...
Searching...
No Matches
IdDictDictionary.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4
6
10#include "IdDict/IdDictGroup.h"
13#include "IdDict/IdDictMgr.h"
14#include "IdDict/IdDictRange.h"
15#include "src/Debugger.h"
16#include "src/get_bits.h"
18#include <iostream>
19
21
22static bool isNumber(const std::string& str) {
23 bool result = true;
24
25 for (unsigned int i = 0; i < str.size(); ++i) {
26 if (!isdigit(str[i])) return(false);
27 }
28 if (0 == str.size()) return(false);
29
30 return(result);
31}
32
35
37 const std::string& version /*= ""*/,
38 const std::string& date /*= ""*/,
39 const std::string& author /*= ""*/)
40 : m_name (name),
42 m_date (date),
43 m_author (author)
44{
45}
46
47const IdDictField* IdDictDictionary::find_field(const std::string& name) const {
48 auto it = m_fields.find(name);
49
50 if (it == m_fields.end()) {
51 // If parent exists, look for field there
52 if (m_parent_dict) {
53 it = m_parent_dict->m_fields.find(name);
54 if (it == m_parent_dict->m_fields.end()) {
55 return nullptr;
56 }
57 } else {
58 return nullptr;
59 }
60 }
61
62 return it->second.get();
63}
64
66 auto it = m_fields.find(name);
67
68 if (it == m_fields.end()) {
69 // If parent exists, look for field there
70 if (m_parent_dict) {
71 it = m_parent_dict->m_fields.find(name);
72 if (it == m_parent_dict->m_fields.end()) {
73 return nullptr;
74 }
75 } else {
76 return nullptr;
77 }
78 }
79
80 return it->second.get();
81}
82
83const IdDictLabel*
84IdDictDictionary::find_label(const std::string& field, const std::string& label) const {
85 const IdDictField* idField = find_field(field);
86
87 if (!idField) return nullptr;
88
89 return(idField->find_label(label));
90}
91
92int IdDictDictionary::get_label_value(const std::string& field, const std::string& label, int& value) const {
93 const IdDictLabel* idLabel = find_label(field, label);
94
95 if (!idLabel || !idLabel->valued()) return(1);
96
97 value = idLabel->value();
98 return(0);
99}
100
101IdDictField* IdDictDictionary::add_field(std::unique_ptr<IdDictField> field) {
102 if (!field) return nullptr;
103 return m_fields.emplace (field->name(), std::move(field)).first->second.get();
104}
105
108 auto it = m_subregions.find(name);
109 if (it == m_subregions.end()) return nullptr;
110 return it->second.get();
111}
112
113const IdDictRegion*
114IdDictDictionary::find_region(const std::string& region_name) const {
115 return find_region(region_name, "");
116}
117
119IdDictDictionary::find_region(const std::string& region_name, const std::string& group_name) {
120 for (IdDictRegion* region : m_regions) {
121 if (!region) continue;
122 if ((group_name != "") && (region->group_name() != group_name)) continue;
123 if ((region_name != "") && (region->name() != region_name)) continue;
124 return region;
125 }
126 return nullptr;
127}
128
129const IdDictRegion*
130IdDictDictionary::find_region(const std::string& region_name, const std::string& group_name) const {
131 for (IdDictRegion* region : m_regions) {
132 if (!region) continue;
133 if ((group_name != "") && (region->group_name() != group_name)) continue;
134 if ((region_name != "") && (region->name() != region_name)) continue;
135 return region;
136 }
137 return nullptr;
138}
139
141IdDictDictionary::find_group(const std::string& group_name) {
142 for (auto& g : m_groups) {
143 if (g && g->name() == group_name) return g.get();
144 }
145 return nullptr;
146}
147
148const IdDictGroup*
149IdDictDictionary::find_group(const std::string& group_name) const {
150 for (const auto& g : m_groups) {
151 if (g && g->name() == group_name) return g.get();
152 }
153 return nullptr;
154}
155
157IdDictDictionary::add_subregion(std::unique_ptr<IdDictSubRegion> subregion) {
158 if (!subregion) return nullptr;
159 return m_subregions.emplace (subregion->name(), std::move(subregion)).first->second.get();
160}
161
163 m_subdictionary_names.push_back(name);
164}
165
167{
168 m_parent_dict = parent_dict;
169}
170
171void IdDictDictionary::add_dictentry(std::unique_ptr<IdDictDictEntry> region) {
172 // Add region to corresponding group
173 IdDictGroup* group = find_group(region->group_name());
174
175 if (0 == group) {
176 m_groups.push_back(std::make_unique<IdDictGroup>(region->group_name()));
177 group = m_groups.back().get();
178 }
179 group->add_dictentry(std::move(region));
180}
181
185
187 for (auto& p : m_subregions) {
188 p.second->resolve_references(idd, *this);
189 }
190
191 for (size_t index = 0; auto& g : m_groups) {
192 g->resolve_references(idd, *this, index);
193 }
194}
195
197 const std::string& tag) {
198 if (Debugger::debug()) {
199 std::cout << "IdDictDictionary::generate_implementation>" << std::endl;
200 }
201
203 // Propagate to each region and copy their generation into the
204 // dict's vector.
205 for (auto& g : m_groups) {
206 g->generate_implementation(idd, *this, tag);
207 // Get regions from group and save in m_regions
208 for (IdDictRegion* re : g->regions()) {
209 m_regions.push_back(re);
210 }
211 }
212
213 // Loop again over groups and set the bit-packing - starting at
214 // level 0
215 for (auto& g : m_groups) {
216 // Copy to temporary vector all regions in the group. And
217 // look for regions in local m_regions vector for any
218 // regions "dummy", which come from reference
219 // dictionaries.
220 // Skip special group
221 if ("dummy" == g->name()) continue;
222
223 get_bits(m_regions, 0, g->name());
224 }
225
226 // Set integral over the number of bits
228
229 for (auto& g : m_groups) {
230 g->build_region_tree();
231 }
232
233 // Set neighbours for regions
235 for (itr = m_regions.begin(); itr != m_regions.end(); ++itr) {
236 (*itr)->find_neighbours(*this);
237 }
238
240 }
241}
242
245 m_regions.clear();
246 for (auto& g : m_groups) {
247 g->reset_implementation();
248 }
250 }
251}
252
253int
255 // Find first region that matches id
256
258
259 size_type i = 0;
260 for (it = m_regions.begin(); it != m_regions.end(); ++it, ++i) {
261 const IdDictRegion& region = *(*it);
262
263 Range range = region.build_range();
264
265 if (range.match(id) && range.fields() >= id.fields()) {
266 index = i;
267 return(0);
268 }
269 }
270
271 return(1);
272}
273
275 return find_region(id, "");
276}
277
278const IdDictRegion* IdDictDictionary::find_region(const ExpandedIdentifier& id, const std::string& group_name) const {
279 // Find first region that matches id
280
281 IdDictRegion* pRegion = 0;
282
284
285 for (it = m_regions.begin(); it != m_regions.end(); ++it) {
286 IdDictRegion& region = *(*it);
287 if ((group_name != "") && (region.group_name() != group_name)) continue;
288
289 Range range = region.build_range();
290
291 if (range.match(id) && range.fields() >= id.fields()) {
292 pRegion = &region;
293 }
294 }
295
296 return(pRegion);
297}
298
299void
301 // For each region, loop over its levels and set the bit offset
302 // for each FieldImplementation
303
304 for (IdDictRegion* region : m_regions) {
305 region->integrate_bits();
306 }
307}
308
311
312 for (auto& group : m_groups) {
313 MultiRange group_mr = group->build_multirange();
314
315 for (unsigned int i = 0; i < group_mr.size(); ++i) {
316 const Range& range = group_mr[i];
317 result.add(range);
318 }
319 }
320
321 return(result);
322}
323
325 const Range& prefix,
326 const std::string& last_field) const {
328
330 if ("" == last_field) {
331 // Take all fields
332 for (it = m_regions.begin(); it != m_regions.end(); ++it) {
333 const IdDictRegion& region = *(*it);
334
335 // skip regions created from parents
336 if ("dummy" == region.name()) continue;
337
338 // skip empty regions - may arise from alternate_regions
339 // where a tag selects an empty region
340 if (region.is_empty()) continue;
341
342 Range range(region.build_range());
343 // Check region selection
344 if (range.match(region_id)) result.add(std::move(range));
345 }
346 } else {
347 // Not all fields required
348 for (it = m_regions.begin(); it != m_regions.end(); ++it) {
349 const IdDictRegion& region = *(*it);
350
351 // skip regions created from parents
352 if ("dummy" == region.name()) continue;
353
354 // skip empty regions - may arise from alternate_regions
355 // where a tag selects an empty region
356 if (region.is_empty()) continue;
357
358 Range range(region.build_range());
359 // Check region selection
360 if (range.match(region_id)) {
361 // Build new range up to last_field and add it to result -
362 // remove duplicate ranges with addRangeToMR
363 Range new_range(prefix); // Prepend with prefix
364
365 size_t nimpl = region.n_implementation();
366 for (size_t i = 0; i < nimpl; ++i) {
367 const IdDictFieldImplementation& impl = region.implementation(i);
368
369// new_range.add(impl.m_field);
370 new_range.add(impl.range()->build_range());
371
372 if (last_field == impl.range()->field()->name()) {
373 break;
374 }
375 }
376 result.add(std::move(new_range));
377 }
378 }
379 }
380
381 return(result);
382}
383
385 const std::string& group_name,
386 const Range& prefix,
387 const std::string& last_field) const {
389
391 if ("" == last_field) {
392 // Take all fields
393 for (it = m_regions.begin(); it != m_regions.end(); ++it) {
394 const IdDictRegion& region = *(*it);
395
396 // skip regions created from parents
397 if ("dummy" == region.name()) continue;
398
399 // skip empty regions - may arise from alternate_regions
400 // where a tag selects an empty region
401 if (region.is_empty()) continue;
402
403 Range range(region.build_range());
404 // Check region selection
405 if (range.match(region_id) && region.group_name() == group_name) result.add(std::move(range));
406 }
407 } else {
408 // Not all fields required
409 for (it = m_regions.begin(); it != m_regions.end(); ++it) {
410 const IdDictRegion& region = *(*it);
411
412 // skip regions created from parents
413 if ("dummy" == region.name()) continue;
414
415 // skip empty regions - may arise from alternate_regions
416 // where a tag selects an empty region
417 if (region.is_empty()) continue;
418
419 Range range(region.build_range());
420 // Check region selection
421 if (range.match(region_id) && region.group_name() == group_name) {
422 // Build new range up to last_field and add it to result -
423 // remove duplicate ranges with addRangeToMR
424 Range new_range(prefix); // Prepend with prefix
425
426 size_t nimpl = region.n_implementation();
427 for (size_t i = 0; i < nimpl; ++i) {
428 const IdDictFieldImplementation& impl = region.implementation(i);
429
430// new_range.add(impl.m_field);
431 new_range.add(impl.range()->build_range());
432
433 if (last_field == impl.range()->field()->name()) {
434 break;
435 }
436 }
437 result.add(std::move(new_range));
438 }
439 }
440 }
441
442 return(result);
443}
444
457
458int
460 size_t index1,
461 size_t index2,
462 Identifier& packedId) const {
463 packedId = 0;
464
465
466 // Preconditions...
467
468 if (index2 < index1) {
469 // bad parameters.
470 return(1);
471 }
472
473 if (index1 >= id.fields()) {
474 // nothing very useful !!
475 return(1);
476 }
477
478 if (index2 >= id.fields()) {
479 // bad parameter...
480 return(1);
481 }
482
491
492 for (size_t k = 0; k < m_regions.size(); ++k) {
493 bool selected = true;
494
495 const IdDictRegion& region = *m_regions[k];
496
497 // Must skip empty regions - can arise when a tag selects an
498 // empty region
499 if (region.is_empty()) continue;
500
501 for (size_t i = 0; i < region.n_implementation(); ++i) {
502 if (i >= id.fields()) break;
503
504 const IdDictFieldImplementation& impl = region.implementation(i);
505
506 if (!impl.field().match(id[i])) {
507 selected = false;
508 break;
509 }
510 }
511
512 if (selected) {
513 size_t position = Identifier::NBITS;
514 // We have the proper region.
515 for (size_t i = index1; i <= index2; ++i) {
516 const IdDictFieldImplementation& impl = region.implementation(i);
517
518 Identifier::value_type index = impl.ored_field().get_value_index(id[i]);
519
520 if (0 == position && impl.bits() > 0) {
521 return(1);
522 }
523
524 position -= impl.bits();
525 packedId |= (index << position);
526 }
527 break;
528 }
529 }
530
531
532 return(0);
533}
534
535int
536IdDictDictionary::pack32(const int* fields,
537 size_t index1,
538 size_t index2,
539 size_t region_index,
540 Identifier& packedId,
541 size_t first_field_index) const {
542 // Preconditions...
543
544 if (m_do_checks) {
545 if (index2 < index1) {
546 // bad parameters.
547 std::cout << "IdDictDictionary::pack32 - index2 < index1 - 1,2"
548 << index1 << " " << index2 << std::endl;
549 return(1);
550 }
551
552 if (region_index >= m_regions.size()) {
553 // bad parameters.
554 std::cout << "IdDictDictionary::pack32 - region index incorrect - index,size"
555 << region_index << " " << m_regions.size() << std::endl;
556 return(1);
557 }
558 }
559
560
561 // Get the region
562 const IdDictRegion& region = *m_regions[region_index];
563
564 if (m_do_checks) {
565 if (region.is_empty()) {
566 std::cout << "IdDictDictionary::pack32 - region id empty" << std::endl;
567 // bad parameters.
568 return(1);
569 }
570 if (index1 < first_field_index) {
571 std::cout << "IdDictDictionary::pack32 - first_field_index > index1 "
572 << first_field_index << " " << index1 << std::endl;
573 return(1);
574 }
575 }
576
577 // Set the starting position
578 size_t position = Identifier::NBITS;
579 if (!first_field_index) {
580 const IdDictFieldImplementation& impl = region.implementation(index1);
581 position -= impl.bits_offset();
582 }
583
584 size_t field_index = 0;
585 for (size_t i = index1; i <= index2; ++i, ++field_index) {
586 const IdDictFieldImplementation& impl = region.implementation(i);
587
588 if (m_do_checks) {
589 // Field should be within allowed range
590 if (!impl.ored_field().match(fields[field_index])) {
591 std::cout << "IdDictDictionary::pack32 - field does NOT match: value, allowed values "
592 << fields[field_index] << " " << (std::string) impl.ored_field()
593 << std::endl;
594 // bad parameters.
595 return(1);
596 }
597
598 // Check that we don't try to go below 0
599 if (0 == position && impl.bits() > 0) {
600 std::cout << "IdDictDictionary::pack32 - going past 0" << std::endl;
601 return(1);
602 }
603 }
604
605 Identifier::value_type index;
606 if (impl.decode_index()) {
607 index = impl.ored_field().get_value_index(fields[field_index]);
608 } else {
609 index = (Identifier::value_type) fields[field_index];
610 }
611
612 position -= impl.bits();
613 packedId |= (index << position);
614 }
615
616
617 return(0);
618}
619
623int IdDictDictionary::reset(size_t index1,
624 size_t index2,
625 size_t region_index,
626 Identifier& packedId) const {
627 // Preconditions...
628
629 if (m_do_checks) {
630 if (index2 < index1) {
631 // bad parameters.
632 std::cout << "IdDictDictionary::pack32 - index2 < index1 - 1,2"
633 << index1 << " " << index2 << std::endl;
634 return(1);
635 }
636
637 if (region_index >= m_regions.size()) {
638 // bad parameters.
639 std::cout << "IdDictDictionary::pack32 - region index incorrect - index,size"
640 << region_index << " " << m_regions.size() << std::endl;
641 return(1);
642 }
643 }
644
645
646 // Get the region
647 const IdDictRegion& region = *m_regions[region_index];
648
649 if (m_do_checks) {
650 if (region.is_empty()) {
651 std::cout << "IdDictDictionary::pack32 - region id empty" << std::endl;
652 // bad parameters.
653 return(1);
654 }
655 }
656
657 size_t field_index = 0;
658 for (size_t i = index1; i <= index2; ++i, ++field_index) {
659 const IdDictFieldImplementation& impl = region.implementation(i);
660
661 size_t position = Identifier::NBITS - impl.bits_offset() - impl.bits();
662
663 Identifier::value_type mask = (((Identifier::value_type) 1 << impl.bits()) - 1) << position;
664
665 mask ^= Identifier::ALL_BITS;
666
667 packedId &= (mask);
668 }
669 return(0);
670}
671
679int IdDictDictionary::unpack(const std::string& group,
680 const Identifier& id,
681 const ExpandedIdentifier& prefix,
682 size_t index2,
683 ExpandedIdentifier& unpackedId) const
684{
685 const IdDictGroup* g = find_group (group);
686 int ret = 1;
687 if (g) {
688 ret = g->unpack (id, prefix, index2, unpackedId);
689 }
690 return ret;
691}
692
700int IdDictDictionary::unpack(const std::string& group,
701 const Identifier& id,
702 const ExpandedIdentifier& prefix,
703 size_t index2,
704 const std::string& sep,
705 std::string& unpackedId) const
706{
707 const IdDictGroup* g = find_group (group);
708 ExpandedIdentifier unpacked;
709 std::vector<const IdDictFieldImplementation*> impls;
710 int ret = 1;
711 if (g) {
712 ret = g->unpack (id, prefix, index2, unpacked, &impls);
713 }
714 if (ret == 0) {
715 assert (unpacked.fields() == impls.size());
716 for (size_t i = 0; i < unpacked.fields(); ++i) {
717 // Add value to string
718
719 std::string str_value("nil");
720
721 const IdDictFieldImplementation& impl = *impls[i];
722 ExpandedIdentifier::element_type value = unpacked[i];
723
724 // The policy below is:
725 // - if a value is a character string or name, just add this name
726 // - if a value is a number, then prefix it with the
727 // name of the field
728 //
729 // NOTE: min/max is a number, but for value/label we
730 // distinguish between number and name by looking for an IdDictLabel
731 const IdDictRange* range = impl.range();
732 const IdDictLabel* label = range->field()->find_label(range->label());
733 switch (range->specification()) {
735 // For a range of values (numbers), add in the field name
736 str_value = range->field()->name() + ' '+std::to_string(value);
737 break;
738
741 str_value = "";
742 if (!label) {
743 // Is a number, add in field name
744 str_value += range->field()->name() + ' ';
745 }
746 str_value += range->label();
747 break;
748
751 str_value = "";
752 // Is a name
753 if (label) {
754 // Found label with "find_label" on the field
755 if (label->valued()) {
756 str_value += range->label();
757 }
758 } else {
759 // If not found with the "find" above, we must
760 // get the value and name from the range
761 // itself.
762
763 unsigned int index1 = 0;
764 for (int v : range->values()) {
765 if (value == v) break;
766 ++index1;
767 }
768
769 if (index1 < range->labels().size()) {
770 if (isNumber(range->labels()[index1])) {
771 str_value += range->field()->name() + ' ';
772 }
773 str_value += range->labels()[index1];
774 } else {
775 std::cout << "IdDictDictionary::unpack - Could not find value." << std::endl;
776 std::cout << "value " << value << std::endl;
777 std::cout << "field values " << std::endl;
778 for (int v : range->values()) {
779 std::cout << v << " ";
780 }
781 std::cout << std::endl;
782 }
783 }
784 break;
785
787
788 std::cout << "unknown" << std::endl;
789
790 break;
791 }
792
793 if (i > 0) unpackedId += sep;
794 unpackedId += str_value;
795 }
796 }
797
798 return ret;
799}
800
809int
811 size_t first_field_index,
812 size_t field_index,
813 size_t region_index,
814 int& field) const {
815 field = 0;
816
817 if (m_do_checks) {
818 // Check regions
819 if (region_index >= m_regions.size()) {
820 std::cout << "IdDictDictionary::unpack - region index too large. Index, nregions "
821 << region_index << " " << m_regions.size() << std::endl;
822 return(1);
823 }
824 }
825
826 const IdDictRegion& region = *m_regions.at(region_index);
827
828 if (m_do_checks) {
829 // check number of fields
830 if (field_index >= region.n_implementation()) {
831 std::cout << "IdDictDictionary::unpack - field index too large. Index, nfields "
832 << field_index << " " << region.n_implementation()
833 << std::endl;
834 return(1);
835 }
836 }
837
838 const IdDictFieldImplementation& impl = region.implementation(field_index);
839 size_t prefix_offset = 0;
840
841 size_t position = Identifier::NBITS; // overall bit position
842
843 // One or more fields missing from prefix, get the offset
844 if (first_field_index) {
845 if (m_do_checks) {
846 if (first_field_index >= region.n_implementation()) {
847 std::cout << "IdDictDictionary::unpack - first_field_index too large. Index, nfields "
848 << first_field_index << " " << region.n_implementation()
849 << std::endl;
850 return(1);
851 }
852 }
853
854 // One or more fields missing from prefix, get the offset
855 prefix_offset = region.implementation(first_field_index).bits_offset();
856
857 if (m_do_checks) {
858 // Should have a non-zero number of bits
859 if (impl.bits() == 0) {
860 std::cout << "IdDictDictionary::unpack - no bits for this field. Region, field indexes "
861 << region_index << " " << field_index << std::endl;
862 return(1);
863 }
864
865 // Check the shift value
866 if (impl.bits() + impl.bits_offset() - prefix_offset > position) {
867 std::cout << "IdDictDictionary::unpack - bits + offset too large. Region, field indexes, bits, offset "
868 << region_index << " " << field_index << " "
869 << impl.bits() << " " << impl.bits_offset() << " " << prefix_offset
870 << std::endl;
871 return(1);
872 }
873 }
874 }
875
876 Identifier::value_type mask = (static_cast<Identifier::value_type>(1) << impl.bits()) - 1;
877
878 size_t index = id.extract(position -= impl.bits() + impl.bits_offset() - prefix_offset, mask);
879
880 field = index;
881 if (impl.decode_index()) field = impl.ored_field().get_value_at(index);
882
883
884 return(0);
885}
886
896int
898 size_t first_field_index,
899 size_t begin_field_index,
900 size_t end_field_index,
901 size_t region_index,
902 Identifier& idout) const {
903 idout = Identifier();
904 if (region_index >= m_regions.size()) {
905 std::cout << "IdDictDictionary::copy - region index too large. Index, nregions "
906 << region_index << " " << m_regions.size() << std::endl;
907 return(1);
908 }
909
910 const IdDictRegion& region = *m_regions[region_index];
911
912 if (first_field_index >= region.n_implementation() ||
913 begin_field_index >= region.n_implementation() ||
914 end_field_index >= region.n_implementation()) {
915 std::cout << "IdDictDictionary::copy - field index too large. Indexes first, begin, end, nfields "
916 << first_field_index << " "
917 << begin_field_index << " "
918 << end_field_index << " "
919 << region.n_implementation()
920 << std::endl;
921 return(1);
922 }
923
924 size_t missing_offset = 0;
925 if (first_field_index) {
926 if (first_field_index > begin_field_index) {
927 std::cout << "IdDictDictionary::copy - first_field_index > begin_field_index. Indexes "
928 << first_field_index << " " << begin_field_index << std::endl;
929 return(1);
930 }
931 // One or more fields missing from prefix, get the offset
932 missing_offset = region.implementation(first_field_index).bits_offset();
933 }
934
935 size_t prefix_offset = 0;
936 if (begin_field_index) {
937 if (begin_field_index > end_field_index) {
938 std::cout << "IdDictDictionary::copy - begin_field_index > end_field_index. Indexes "
939 << begin_field_index << " " << end_field_index << std::endl;
940 return(1);
941 }
942 // One or more fields missing from prefix, get the offset
943 prefix_offset = region.implementation(begin_field_index).bits_offset();
944 }
945
946 const IdDictFieldImplementation& impl = region.implementation(end_field_index);
947 size_t suffix_offset = impl.bits() + impl.bits_offset();
948
949 size_t position = Identifier::NBITS; // overall bit position
950
951 if (position < prefix_offset - missing_offset) {
952 std::cout << "IdDictDictionary::copy - position < prefix + missing. "
953 << prefix_offset << " " << missing_offset << std::endl;
954 return(1);
955 }
956
957
958 if (position < suffix_offset + missing_offset) {
959 std::cout << "IdDictDictionary::copy - position < suffix + missing. "
960 << suffix_offset << " " << missing_offset << std::endl;
961 return(1);
962 }
963
964
965 // prepare the mask for copying
966
967 Identifier::value_type mask = Identifier::ALL_BITS;
968
969 Identifier::value_type prefix_mask =
970 prefix_offset ? (static_cast<Identifier::value_type>(1) << (position - prefix_offset + missing_offset)) - 1 : 0;
971
972 Identifier::value_type suffix_mask =
973 (static_cast<Identifier::value_type>(1) << (position - suffix_offset + missing_offset)) - 1;
974
975 mask -= prefix_mask + suffix_mask;
976
977 idout = idin.mask_shift(mask, missing_offset);
978
979
980 return(0);
981}
982
983bool
985 return(m_do_checks);
986}
987
988void
992
993bool
995 return(m_do_neighbours);
996}
997
998void
1002
1028 // check #1
1029
1031
1032 if (mr.has_overlap()) return(false);
1033
1034
1035 return(true);
1036}
1037
1049 // verify
1050 if (verify()) {
1051 std::map< ExpandedIdentifier, IdDictDictEntry* > regions;
1052
1053 for (auto& g : m_groups) {
1054 g->sort();
1055 }
1056 } else {
1057 std::cout << "IdDictDictionary::sort - WARNING verify is FALSE - cannot sort "
1058 << std::endl;
1059 }
1060}
1061
1063 m_subregions.clear();
1064 m_fields.clear();
1065 m_groups.clear();
1066}
1067
1068
1069void
1071{
1072 std::cout << "=== IdDictDictionary " << m_name << " " << m_version << " "
1073 << m_date << " " << m_author << "\n";
1074 for (const auto& g : m_groups) {
1075 g->dump();
1076 }
1077 std::cout.flush();
1078}
const boost::regex re(r_e)
void get_bits(const RV &regions, size_t level, const std::string &group)
Definition get_bits.cxx:45
static bool isNumber(const std::string &str)
static const std::vector< std::string > regions
bool isNumber(const std::string &s)
Definition PoolSvc.cxx:52
static bool debug()
Definition Debugger.h:18
size_type fields() const
bool verify() const
Here, we verify global constraints : (this must only be applied after the resolve_references and gene...
std::vector< std::unique_ptr< IdDictGroup > > m_groups
bool do_checks() const
Checks are performed by default in debug compilation and NOT in optimized compilation.
IdDictSubRegion * add_subregion(std::unique_ptr< IdDictSubRegion > subregion)
int unpack(const std::string &group, const Identifier &id, const ExpandedIdentifier &prefix, size_t index2, ExpandedIdentifier &unpackedId) const
Unpack the value_type id to an expanded Identifier for a given group, considering the provided prefix...
std::map< std::string, std::unique_ptr< IdDictField > > m_fields
void resolve_references(IdDictMgr &idd)
void dump() const
Dump regions and trees for each group.
void add_dictentry(std::unique_ptr< IdDictDictEntry > entry)
regions_type::iterator regions_it
const IdDictLabel * find_label(const std::string &field, const std::string &label) const
IdDictDictionary * m_parent_dict
void set_do_checks(bool do_checks)
Identifier::size_type size_type
MultiRange build_multirange() const
Get MultiRange for full dictionary.
void set_do_neighbours(bool do_neighbours)
std::map< std::string, std::unique_ptr< IdDictSubRegion > > m_subregions
const std::string & version() const
Dictionary version.
int get_label_value(const std::string &field, const std::string &label, int &value) const
void generate_implementation(const IdDictMgr &idd, const std::string &tag="")
IdDictSubRegion * find_subregion(const std::string &subregion_name)
std::vector< IdDictRegion * > m_regions
IdDictGroup * find_group(const std::string &group_name)
int copy(const Identifier &idin, size_t first_field_index, size_t begin_field_index, size_t end_field_index, size_t region_index, Identifier &idout) const
Copy a number of fields of the value_type id into another value_type id.
void integrate_bits()
Set up integral of bits for efficient unpacking.
const std::string & name() const
Dictionary name.
void set_parent_dict(IdDictDictionary *parent_dict)
std::vector< IdDictRegion * > m_all_regions
IdDictField * add_field(std::unique_ptr< IdDictField > field)
const IdDictField * find_field(const std::string &name) const
int pack32(const ExpandedIdentifier &id, size_t index1, size_t index2, Identifier &packedId) const
Pack to 32bits the subset of id between (inclusive) index1 and index2 - this is generic,...
int reset(size_t index1, size_t index2, size_t region_index, Identifier &packedId) const
Reset fields from index1 to index2.
const IdDictRegion * find_region(const std::string &region_name) const
std::vector< std::string > m_subdictionary_names
const IdDictRegion & region(size_t i) const
Region at index i.
void add_region(IdDictRegion *region)
void add_subdictionary_name(const std::string &name)
regions_type::const_iterator regions_const_it
bool do_neighbours() const
Neighbour initialization is performed by default One can switch or query this mode for any idHelper w...
IdDictFieldImplementation is used to capture the specification of a single field of an Identifier.
const IdDictLabel * find_label(const std::string &name) const
int value() const
Definition IdDictLabel.h:51
bool valued() const
Definition IdDictLabel.h:58
value_type mask_shift(value_type mask, size_type shift) const
extract field(s) by masking first, then shifting
A MultiRange combines several Ranges.
Definition MultiRange.h:17
size_type size() const
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
void add(element_type value)
Add a required value. (ie. low = high = value)
std::string date()
sadly, includes a return at the end
Definition hcg.cxx:58
std::string label(const std::string &format, int i)
Definition label.h:19
void get_bits(const RV &regions, size_t level, const std::string &group)
Definition get_bits.cxx:45
Definition index.py:1