36const std::vector<IdDictRegion*>&
48 if (
"dummy" ==
region->name())
continue;
52 if (
region->is_empty())
continue;
71 ent->set_index(
index);
74 ent->resolve_references(idd, dictionary);
81 const std::string& tag) {
83 std::cout <<
"IdDictGroup::generate_implementation>" << std::endl;
90 ent->generate_implementation(idd, dictionary, tag);
104 std::cout <<
"IdDictGroup::generate_implementation - mismatch of sizes: regions/entries "
118 ent->reset_implementation();
140 std::map< ExpandedIdentifier, std::unique_ptr<IdDictDictEntry> >
regions;
146 auto first = itr.
begin();
147 auto last = itr.
end();
151 std::cout <<
"IdDictDictionary::sort - WARNING empty region cannot sort "
156 std::cout <<
"IdDictGroup::sort - WARNING region map size is NOT the same as the vector size. Map size "
162 for (
size_t vecIt = 0;
auto& p :
regions) {
163 m_entries[vecIt++] = std::move(p.second);
180 impl.ored_field().get_indices(), 0)
191 size_t ipos = children.size();
192 while (ipos > 0 && children[ipos-1] == 0) {
196 c = children[ipos-1];
198 while (ipos2 > 0 && children[ipos2-1] == c) {
201 if (ipos2 > 0)
return;
221 std::vector<const IdDictFieldImplementation*>* impls )
const
250 if (
index < prefix.fields()) {
252 validx = n.m_impl.ored_field().get_value_index (val);
255 validx = n.m_impl.unpackToIndex (
id);
257 val = n.m_impl.ored_field().get_value_at (validx);
258 }
catch (
const std::out_of_range&) {
265 if (n.m_children.index() == 0) {
267 const auto& children = std::get<0> (n.m_children);
268 if (validx < children.size()) {
269 inode = children[validx];
277 const auto& children = std::get<1> (n.m_children);
278 if (validx < children.first) {
279 inode = children.second;
292 unpackedId.
add (val);
298 if (n.m_impl.field().match (val)) {
299 impls->push_back (&n.m_impl);
301 else if (n.m_other_impls) {
304 impls->push_back (ii);
309 if (unpackedId.
fields() != impls->size()) std::abort();
344 index_vector indices;
346 if (
impl.field().isEnumerated()) {
347 const element_vector& vals =
impl.field().get_values();
348 indices.reserve (vals.size());
349 for (element_type v : vals) {
353 else if (
impl.field().isBounded()) {
354 auto [minval, maxval] =
impl.field().get_minmax();
357 indices.resize (maxidx - minidx + 1);
358 std::iota (indices.begin(), indices.end(), minidx);
372 auto& children = std::get<0> (n.m_children);
376 if (ifield ==
re.n_implementation()) {
377 index_vector indices = get_field_indices (n, prev_impl);
378 for (
size_t idx : indices) {
385 if (prev_impl.
bits() != n.m_impl.bits() ||
386 prev_impl.
bits_offset() != n.m_impl.bits_offset() ||
387 prev_impl.
ored_field() != n.m_impl.ored_field())
395 if (n.m_impl.field() != prev_impl.
field()) {
396 if (!n.m_other_impls) {
397 n.m_other_impls = std::make_unique<std::vector<const IdDictFieldImplementation*> > (1, &prev_impl);
400 if (std::ranges::find_if (*n.m_other_impls,
402 { return a->field() == prev_impl.field(); })
403 == n.m_other_impls->end())
405 n.m_other_impls->push_back (&prev_impl);
416 auto children = [&]() -> std::vector<unsigned>& {
return std::get<0> (
m_region_tree[
inode].m_children); };
418 unsigned new_node = 0;
419 std::vector<unsigned> nodes_seen;
422 for (
size_t idx : indices) {
425 unsigned next_node = children().at (idx);
431 if (next_node != 0) {
434 if (std::ranges::find (nodes_seen, next_node) == nodes_seen.end()) {
436 nodes_seen.push_back (next_node);
443 children().at(idx) = new_node;
453 children().at(idx) = new_node;
468 [[maybe_unused]]
unsigned iregion = 0;
471 if (
re->fieldSize() == 0 ||
re->name() ==
"dummy") {
499 std::cout <<
"===== IdDictGroup " <<
m_name <<
"\n";
510 std::cout <<
"Regions:\n";
512 std::cout <<
" " << iregion++ <<
" " <<
re->name() <<
" " <<
re->group_name() <<
" " <<
re->tag() <<
"\n";
513 size_t nimpl =
re->n_implementation();
515 for (
size_t i = 0; i < nimpl; ++i) {
517 std::cout << (first ?
" " :
"; ") <<
impl.field() <<
" " <<
impl.ored_field() <<
" " <<
impl.bits() <<
"/" <<
impl.bits_offset();
532 if (n.m_children.index() == 0) {
533 sz += std::get<0>(n.m_children).size();
536 std::cout <<
"Region Tree totsize " <<
sz <<
"\n";
538 std::cout <<
" " <<
inode++ <<
" " << n.m_impl.field()
539 <<
" " << n.m_impl.ored_field() <<
" -- ";
541 if (n.m_children.index() == 0) {
542 const auto& children = std::get<0> (n.m_children);
546 for (
size_t i = 0; uint64_t c : children) {
549 if (!first) std::cout <<
" ";
552 std::cout << istart <<
"-";
554 std::cout << i-1 <<
":";
568 if (!first) std::cout <<
" ";
569 if (istart != children.size()-1) {
570 std::cout << istart <<
"-";
572 std::cout << children.size()-1 <<
":";
582 const auto& children = std::get<1> (n.m_children);
583 if (children.first == 1) {
587 std::cout <<
"0-" << children.first-1 <<
":";
593 std::cout << children.second;
596 if (n.m_other_impls) {
604 std::cout << ii->
field();
const boost::regex re(r_e)
void add(element_type value)
Append a value into a new field.
void clear()
Erase all fields.
IdDictRegion * selected_region()
Currently selected region.
IdDictFieldImplementation is used to capture the specification of a single field of an Identifier.
size_type bits_offset() const
const Range::field & ored_field() const
const Range::field & field() const
const std::vector< IdDictRegion * > & regions()
Non-const access to regions.
bool m_generated_implementation
std::vector< IdDictRegionTreeNode > m_region_tree
The list of region nodes.
void add_dictentry(std::unique_ptr< IdDictDictEntry > entry)
std::vector< std::unique_ptr< IdDictDictEntry > > m_entries
void build_region_tree()
Take the list of regions and build a tree structure for fast unpacking.
int unpack(const Identifier &id, const ExpandedIdentifier &prefix, size_t index2, ExpandedIdentifier &unpackedId, std::vector< const IdDictFieldImplementation * > *impls=nullptr) const
Unpack the value_type id to an expanded Identifier, considering the provided prefix (result will incl...
void dump_tree() const
Dump the tree structure built from the regions for fast unpacking.
std::vector< IdDictRegion * > m_regions
void dump_regions() const
Dump the list of regions for this group.
void reset_implementation()
const IdDictRegion & region(size_t index) const
void generate_implementation(const IdDictMgr &idd, IdDictDictionary &dictionary, const std::string &tag="")
void add_tree_field(const IdDictRegion &re, unsigned ifield, unsigned inode)
Recursively add new nodes to the tree structure.
MultiRange build_multirange() const
Get MultiRange for this group.
const std::string & name() const
void dump() const
Dump regions and tree for this group.
void resolve_references(IdDictMgr &idd, IdDictDictionary &dictionary, size_t &index)
ExpandedIdentifier::size_type size_type
std::vector< element_type > element_vector
size_type get_value_index(element_type value) const
ExpandedIdentifier::element_type element_type
bool match(element_type value) const
The basic match operation Given a value, test to see if it satisfies the constraints for this field.
std::vector< size_type > index_vector
A MultiRange combines several Ranges.
This iterator is able to generate all possible identifiers, from a fully bounded Range.
RangeIterator end() const
RangeIterator begin() const
A Range describes the possible ranges for the field values of an ExpandedIdentifier.
Tree structure for fast unpacking.
const IdDictFieldImplementation & m_impl
Reference to the the implementation field.
std::variant< std::vector< unsigned >, ChildPair > m_children
void optimize()
Compress the vector of node indices, if they are all the same.
static constexpr unsigned END
Special value used to indicate that we've reached the end.
IdDictRegionTreeNode(const IdDictFieldImplementation &impl)
Constructor, taking a reference to the implementation.