28 #include <type_traits>
53 bool match(
const Properties&,
const Ex::iterator&,
bool ignore_parent_rel=
false,
bool ignore_properties=
false)
const;
63 typedef std::pair<std::string, Ex::iterator>
kvpair_t;
152 virtual void latex(std::ostream&)
const;
154 virtual std::string
name()
const=0;
200 virtual std::string
name()
const
202 return std::string(
"Stay Away");
211 virtual std::string
name()
const
213 return std::string(
"PropertyInherit");
235 typedef internal_property_map_t::iterator
iterator;
255 typedef std::multimap<nset_t::iterator, pat_prop_pair_t, nset_it_less>
property_map_t;
273 template<
class T>
const T*
get(Ex::iterator,
bool ignore_parent_rel=
false)
const;
274 template<
class T>
const T*
get()
const;
275 template<
class T>
const T*
get_composite(Ex::iterator,
bool ignore_parent_rel=
false)
const;
276 template<
class T>
const T*
get_composite(Ex::iterator,
int& serialnum,
bool doserial=
true,
bool ignore_parent_rel=
false)
const;
278 template<
class T>
const T*
get_composite(Ex::iterator,
const std::string& label)
const;
279 template<
class T>
const T*
get_composite(Ex::iterator,
int& serialnum,
const std::string& label,
bool doserial=
true)
const;
281 template<
class T>
const T*
get_composite(Ex::iterator, Ex::iterator,
bool ignore_parent_rel=
false)
const;
282 template<
class T>
const T*
get_composite(Ex::iterator, Ex::iterator,
int&,
int&,
bool ignore_parent_rel=
false)
const;
285 std::pair<const T*, const pattern *>
get_with_pattern(Ex::iterator,
int& serialnum,
bool doserial=
true,
bool ignore_parent_rel=
false)
const;
289 template<
class T> Ex::iterator
head(Ex::iterator,
bool ignore_parent_rel=
false)
const;
314 return get_composite<T>(it, ignore_parent_rel);
321 return get_composite<T>(it, tmp,
false, ignore_parent_rel);
327 auto ret = get_with_pattern<T>(it, serialnum, doserial, ignore_parent_rel);
334 std::pair<const T*, const pattern *> ret;
341 std::pair<property_map_t::const_iterator, property_map_t::const_iterator> pit=
props.equal_range(it->name_only());
346 bool wildcards=
false;
351 bool ignore_properties=
false;
352 if(std::is_same<T, Accent>::value) ignore_properties=
true;
355 property_map_t::const_iterator walk=pit.first;
356 while(walk!=pit.second) {
357 if(wildcards==(*walk).second.first->children_wildcard()) {
359 ret.first=dynamic_cast<const T *>((*walk).second.second);
361 if((*walk).second.first->match(*
this, it, ignore_parent_rel, ignore_properties)) {
362 ret.second=(*walk).second.first;
364 std::pair<pattern_map_t::const_iterator, pattern_map_t::const_iterator>
365 pm=
pats.equal_range((*walk).second.second);
367 while(pm.first!=pm.second) {
368 if((*pm.first).second==(*walk).second.first)
378 if(dynamic_cast<const PropertyInherit *>((*walk).second.second))
380 else if(
dynamic_cast<const Inherit<T> *
>((*walk).second.second))
385 if(!wildcards && !ret.first) {
396 if(!ret.first && inherits) {
398 Ex::sibling_iterator sib=it.begin();
399 while(sib!=it.end()) {
400 std::pair<const T*, const pattern *> tmp=get_with_pattern<T>((Ex::iterator)(sib), serialnum, doserial);
417 return get_composite<T>(it, tmp, label,
false);
425 std::pair<property_map_t::const_iterator, property_map_t::const_iterator> pit=
props.equal_range(it->name_only());
430 bool wildcards=
false;
435 bool ignore_properties=
false;
436 if(std::is_same<T, Accent>::value) ignore_properties=
true;
439 property_map_t::const_iterator walk=pit.first;
440 while(walk!=pit.second) {
441 if(wildcards==(*walk).second.first->children_wildcard()) {
442 if((*walk).second.first->match(*
this, it,
false, ignore_properties)) {
443 ret=dynamic_cast<const T *>((*walk).second.second);
446 if(ret->label!=label && ret->label!=
"all")
450 serialnum=
serial_number( (*walk).second.second, (*walk).second.first );
454 if(dynamic_cast<const PropertyInherit *>((*walk).second.second))
456 else if(
dynamic_cast<const Inherit<T> *
>((*walk).second.second))
462 if(!wildcards && !ret) wildcards=
true;
467 if(!ret && inherits) {
468 Ex::sibling_iterator sib=it.begin();
469 while(sib!=it.end()) {
470 const T* tmp=get_composite<T>((Ex::iterator)(sib), serialnum, label, doserial);
485 return get_composite<T>(it1,it2,tmp1,tmp2, ignore_parent_rel);
495 bool inherits1=
false, inherits2=
false;
496 std::pair<property_map_t::const_iterator, property_map_t::const_iterator> pit1=
props.equal_range(it1->name_only());
497 std::pair<property_map_t::const_iterator, property_map_t::const_iterator> pit2=
props.equal_range(it2->name_only());
499 property_map_t::const_iterator walk1=pit1.first;
500 while(walk1!=pit1.second) {
501 if((*walk1).second.first->match(*
this, it1, ignore_parent_rel)) {
502 ret1=dynamic_cast<const T *>((*walk1).second.second);
504 property_map_t::const_iterator walk2=pit2.first;
505 while(walk2!=pit2.second) {
506 if((*walk2).second.first->match(*
this, it2, ignore_parent_rel)) {
507 ret2=dynamic_cast<const T *>((*walk2).second.second);
509 if(ret1==ret2 && walk1!=walk2) {
510 serialnum1=
serial_number( (*walk1).second.second, (*walk1).second.first );
511 serialnum2=
serial_number( (*walk2).second.second, (*walk2).second.first );
517 if(dynamic_cast<const PropertyInherit *>((*walk2).second.second))
522 if(dynamic_cast<const PropertyInherit *>((*walk1).second.second))
529 if(!found && (inherits1 || inherits2)) {
530 Ex::sibling_iterator sib1, sib2;
531 if(inherits1) sib1=it1.begin();
533 bool keepgoing1=
true;
535 bool keepgoing2=
true;
536 if(inherits2) sib2=it2.begin();
539 const T* tmp=get_composite<T>((Ex::iterator)(sib1), (Ex::iterator)(sib2), serialnum1, serialnum2, ignore_parent_rel);
545 if(!inherits2 || ++sib2==it2.end())
549 if(!inherits1 || ++sib1==it1.end())
565 nset_t::iterator nit=
name_set.insert(std::string(
"")).first;
566 std::pair<property_map_t::const_iterator, property_map_t::const_iterator> pit=
567 props.equal_range(nit);
568 while(pit.first!=pit.second) {
569 ret=dynamic_cast<const T *>((*pit.first).second.second);
581 if(get<PropertyInherit>(dn, ignore_parent_rel)) {