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 for (size_t i = index1; i <= index2; ++i) {
658 const IdDictFieldImplementation& impl = region.implementation(i);
659
660 size_t position = Identifier::NBITS - impl.bits_offset() - impl.bits();
661
662 Identifier::value_type mask = (((Identifier::value_type) 1 << impl.bits()) - 1) << position;
663
664 mask ^= Identifier::ALL_BITS;
665
666 packedId &= (mask);
667 }
668 return(0);
669}
670
678int IdDictDictionary::unpack(const std::string& group,
679 const Identifier& id,
680 const ExpandedIdentifier& prefix,
681 size_t index2,
682 ExpandedIdentifier& unpackedId) const
683{
684 const IdDictGroup* g = find_group (group);
685 int ret = 1;
686 if (g) {
687 ret = g->unpack (id, prefix, index2, unpackedId);
688 }
689 return ret;
690}
691
699int IdDictDictionary::unpack(const std::string& group,
700 const Identifier& id,
701 const ExpandedIdentifier& prefix,
702 size_t index2,
703 const std::string& sep,
704 std::string& unpackedId) const
705{
706 const IdDictGroup* g = find_group (group);
707 ExpandedIdentifier unpacked;
708 std::vector<const IdDictFieldImplementation*> impls;
709 int ret = 1;
710 if (g) {
711 ret = g->unpack (id, prefix, index2, unpacked, &impls);
712 }
713 if (ret == 0) {
714 assert (unpacked.fields() == impls.size());
715 for (size_t i = 0; i < unpacked.fields(); ++i) {
716 // Add value to string
717
718 std::string str_value("nil");
719
720 const IdDictFieldImplementation& impl = *impls[i];
721 ExpandedIdentifier::element_type value = unpacked[i];
722
723 // The policy below is:
724 // - if a value is a character string or name, just add this name
725 // - if a value is a number, then prefix it with the
726 // name of the field
727 //
728 // NOTE: min/max is a number, but for value/label we
729 // distinguish between number and name by looking for an IdDictLabel
730 const IdDictRange* range = impl.range();
731 const IdDictLabel* label = range->field()->find_label(range->label());
732 switch (range->specification()) {
734 // For a range of values (numbers), add in the field name
735 str_value = range->field()->name() + ' '+std::to_string(value);
736 break;
737
740 str_value = "";
741 if (!label) {
742 // Is a number, add in field name
743 str_value += range->field()->name() + ' ';
744 }
745 str_value += range->label();
746 break;
747
750 str_value = "";
751 // Is a name
752 if (label) {
753 // Found label with "find_label" on the field
754 if (label->valued()) {
755 str_value += range->label();
756 }
757 } else {
758 // If not found with the "find" above, we must
759 // get the value and name from the range
760 // itself.
761
762 unsigned int index1 = 0;
763 for (int v : range->values()) {
764 if (value == v) break;
765 ++index1;
766 }
767
768 if (index1 < range->labels().size()) {
769 if (isNumber(range->labels()[index1])) {
770 str_value += range->field()->name() + ' ';
771 }
772 str_value += range->labels()[index1];
773 } else {
774 std::cout << "IdDictDictionary::unpack - Could not find value." << std::endl;
775 std::cout << "value " << value << std::endl;
776 std::cout << "field values " << std::endl;
777 for (int v : range->values()) {
778 std::cout << v << " ";
779 }
780 std::cout << std::endl;
781 }
782 }
783 break;
784
786
787 std::cout << "unknown" << std::endl;
788
789 break;
790 }
791
792 if (i > 0) unpackedId += sep;
793 unpackedId += str_value;
794 }
795 }
796
797 return ret;
798}
799
808int
810 size_t first_field_index,
811 size_t field_index,
812 size_t region_index,
813 int& field) const {
814 field = 0;
815
816 if (m_do_checks) {
817 // Check regions
818 if (region_index >= m_regions.size()) {
819 std::cout << "IdDictDictionary::unpack - region index too large. Index, nregions "
820 << region_index << " " << m_regions.size() << std::endl;
821 return(1);
822 }
823 }
824
825 const IdDictRegion& region = *m_regions.at(region_index);
826
827 if (m_do_checks) {
828 // check number of fields
829 if (field_index >= region.n_implementation()) {
830 std::cout << "IdDictDictionary::unpack - field index too large. Index, nfields "
831 << field_index << " " << region.n_implementation()
832 << std::endl;
833 return(1);
834 }
835 }
836
837 const IdDictFieldImplementation& impl = region.implementation(field_index);
838 size_t prefix_offset = 0;
839
840 size_t position = Identifier::NBITS; // overall bit position
841
842 // One or more fields missing from prefix, get the offset
843 if (first_field_index) {
844 if (m_do_checks) {
845 if (first_field_index >= region.n_implementation()) {
846 std::cout << "IdDictDictionary::unpack - first_field_index too large. Index, nfields "
847 << first_field_index << " " << region.n_implementation()
848 << std::endl;
849 return(1);
850 }
851 }
852
853 // One or more fields missing from prefix, get the offset
854 prefix_offset = region.implementation(first_field_index).bits_offset();
855
856 if (m_do_checks) {
857 // Should have a non-zero number of bits
858 if (impl.bits() == 0) {
859 std::cout << "IdDictDictionary::unpack - no bits for this field. Region, field indexes "
860 << region_index << " " << field_index << std::endl;
861 return(1);
862 }
863
864 // Check the shift value
865 if (impl.bits() + impl.bits_offset() - prefix_offset > position) {
866 std::cout << "IdDictDictionary::unpack - bits + offset too large. Region, field indexes, bits, offset "
867 << region_index << " " << field_index << " "
868 << impl.bits() << " " << impl.bits_offset() << " " << prefix_offset
869 << std::endl;
870 return(1);
871 }
872 }
873 }
874
875 Identifier::value_type mask = (static_cast<Identifier::value_type>(1) << impl.bits()) - 1;
876
877 size_t index = id.extract(position -= impl.bits() + impl.bits_offset() - prefix_offset, mask);
878
879 field = index;
880 if (impl.decode_index()) field = impl.ored_field().get_value_at(index);
881
882
883 return(0);
884}
885
895int
897 size_t first_field_index,
898 size_t begin_field_index,
899 size_t end_field_index,
900 size_t region_index,
901 Identifier& idout) const {
902 idout = Identifier();
903 if (region_index >= m_regions.size()) {
904 std::cout << "IdDictDictionary::copy - region index too large. Index, nregions "
905 << region_index << " " << m_regions.size() << std::endl;
906 return(1);
907 }
908
909 const IdDictRegion& region = *m_regions[region_index];
910
911 if (first_field_index >= region.n_implementation() ||
912 begin_field_index >= region.n_implementation() ||
913 end_field_index >= region.n_implementation()) {
914 std::cout << "IdDictDictionary::copy - field index too large. Indexes first, begin, end, nfields "
915 << first_field_index << " "
916 << begin_field_index << " "
917 << end_field_index << " "
918 << region.n_implementation()
919 << std::endl;
920 return(1);
921 }
922
923 size_t missing_offset = 0;
924 if (first_field_index) {
925 if (first_field_index > begin_field_index) {
926 std::cout << "IdDictDictionary::copy - first_field_index > begin_field_index. Indexes "
927 << first_field_index << " " << begin_field_index << std::endl;
928 return(1);
929 }
930 // One or more fields missing from prefix, get the offset
931 missing_offset = region.implementation(first_field_index).bits_offset();
932 }
933
934 size_t prefix_offset = 0;
935 if (begin_field_index) {
936 if (begin_field_index > end_field_index) {
937 std::cout << "IdDictDictionary::copy - begin_field_index > end_field_index. Indexes "
938 << begin_field_index << " " << end_field_index << std::endl;
939 return(1);
940 }
941 // One or more fields missing from prefix, get the offset
942 prefix_offset = region.implementation(begin_field_index).bits_offset();
943 }
944
945 const IdDictFieldImplementation& impl = region.implementation(end_field_index);
946 size_t suffix_offset = impl.bits() + impl.bits_offset();
947
948 size_t position = Identifier::NBITS; // overall bit position
949
950 if (position < prefix_offset - missing_offset) {
951 std::cout << "IdDictDictionary::copy - position < prefix + missing. "
952 << prefix_offset << " " << missing_offset << std::endl;
953 return(1);
954 }
955
956
957 if (position < suffix_offset + missing_offset) {
958 std::cout << "IdDictDictionary::copy - position < suffix + missing. "
959 << suffix_offset << " " << missing_offset << std::endl;
960 return(1);
961 }
962
963
964 // prepare the mask for copying
965
966 Identifier::value_type mask = Identifier::ALL_BITS;
967
968 Identifier::value_type prefix_mask =
969 prefix_offset ? (static_cast<Identifier::value_type>(1) << (position - prefix_offset + missing_offset)) - 1 : 0;
970
971 Identifier::value_type suffix_mask =
972 (static_cast<Identifier::value_type>(1) << (position - suffix_offset + missing_offset)) - 1;
973
974 mask -= prefix_mask + suffix_mask;
975
976 idout = idin.mask_shift(mask, missing_offset);
977
978
979 return(0);
980}
981
982bool
984 return(m_do_checks);
985}
986
987void
991
992bool
994 return(m_do_neighbours);
995}
996
997void
1001
1027 // check #1
1028
1030
1031 if (mr.has_overlap()) return(false);
1032
1033
1034 return(true);
1035}
1036
1048 // verify
1049 if (verify()) {
1050 std::map< ExpandedIdentifier, IdDictDictEntry* > regions;
1051
1052 for (auto& g : m_groups) {
1053 g->sort();
1054 }
1055 } else {
1056 std::cout << "IdDictDictionary::sort - WARNING verify is FALSE - cannot sort "
1057 << std::endl;
1058 }
1059}
1060
1062 m_subregions.clear();
1063 m_fields.clear();
1064 m_groups.clear();
1065}
1066
1067
1068void
1070{
1071 std::cout << "=== IdDictDictionary " << m_name << " " << m_version << " "
1072 << m_date << " " << m_author << "\n";
1073 for (const auto& g : m_groups) {
1074 g->dump();
1075 }
1076 std::cout.flush();
1077}
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