28 #include <type_traits>
54 bool match(
const Properties&,
const Ex::iterator&,
bool ignore_parent_rel=
false,
bool ignore_properties=
false)
const;
69 typedef std::pair<std::string, Ex::iterator>
kvpair_t;
158 virtual void latex(std::ostream&)
const;
160 virtual std::string
name()
const=0;
206 virtual std::string
name()
const
208 return std::string(
"Stay Away");
217 virtual std::string
name()
const
219 return std::string(
"PropertyInherit");
241 typedef internal_property_map_t::iterator
iterator;
261 typedef std::multimap<nset_t::iterator, pat_prop_pair_t, nset_it_less>
property_map_t;
279 template<
class T>
const T*
get(Ex::iterator,
bool ignore_parent_rel=
false)
const;
280 template<
class T>
const T*
get(Ex::iterator,
int& serialnum,
bool doserial=
true,
bool ignore_parent_rel=
false)
const;
282 template<
class T>
const T*
get(Ex::iterator,
const std::string& label)
const;
283 template<
class T>
const T*
get(Ex::iterator,
int& serialnum,
const std::string& label,
bool doserial=
true)
const;
285 template<
class T>
const T*
get(Ex::iterator, Ex::iterator,
bool ignore_parent_rel=
false)
const;
286 template<
class T>
const T*
get(Ex::iterator, Ex::iterator,
int&,
int&,
bool ignore_parent_rel=
false)
const;
292 std::pair<const T*, const pattern *>
get_with_pattern(Ex::iterator,
int& serialnum,
293 const std::string& label,
294 bool doserial=
true,
bool ignore_parent_rel=
false)
const;
298 const std::string& label,
299 bool doserial=
true,
bool ignore_parent_rel=
false)
const;
303 template<
class T> Ex::iterator
head(Ex::iterator,
bool ignore_parent_rel=
false)
const;
334 return get<T>(it, tmp,
false, ignore_parent_rel);
338 const T*
Properties::get(Ex::iterator it,
int& serialnum,
bool doserial,
bool ignore_parent_rel)
const
340 auto ret = get_with_pattern<T>(it, serialnum,
"", doserial, ignore_parent_rel);
346 bool doserial,
bool ignore_parent_rel)
const
350 auto ret = get_with_pattern_ext<T>(it, *compptr, serialnum, label, doserial, ignore_parent_rel);
357 int& serialnum,
const std::string& label,
358 bool doserial,
bool ignore_parent_rel)
const
360 std::pair<const T*, const pattern *> ret;
367 std::pair<property_map_t::const_iterator, property_map_t::const_iterator> pit=
props.equal_range(it->name_only());
372 bool wildcards=
false;
377 bool ignore_properties=
false;
378 if(std::is_same<T, Accent>::value) ignore_properties=
true;
381 property_map_t::const_iterator walk=pit.first;
382 while(walk!=pit.second) {
383 if(wildcards==(*walk).second.first->children_wildcard()) {
385 ret.first=dynamic_cast<const T *>((*walk).second.second);
387 if((*walk).second.first->match_ext(*
this, it, comp, ignore_parent_rel, ignore_properties)) {
388 ret.second=(*walk).second.first;
393 serialnum=
serial_number( (*walk).second.second, (*walk).second.first );
399 if(dynamic_cast<const PropertyInherit *>((*walk).second.second))
401 else if(
dynamic_cast<const Inherit<T> *
>((*walk).second.second))
406 if(!wildcards && !ret.first) {
414 if(!ret.first && inherits) {
416 Ex::sibling_iterator sib=it.begin();
417 while(sib!=it.end()) {
418 std::pair<const T*, const pattern *> tmp=get_with_pattern<T>((Ex::iterator)(sib), serialnum, label, doserial);
432 const T* Properties::get(Ex::iterator it,
const std::string& label)
const
435 return get<T>(it, tmp, label,
false);
439 const T* Properties::get(Ex::iterator it,
int& serialnum,
const std::string& label,
bool doserial)
const
441 auto ret=get_with_pattern<T>(it, serialnum, label, doserial,
false);
446 const T* Properties::get(Ex::iterator it1, Ex::iterator it2,
bool ignore_parent_rel)
const
449 return get<T>(it1,it2,tmp1,tmp2, ignore_parent_rel);
453 const T* Properties::get(Ex::iterator it1, Ex::iterator it2,
int& serialnum1,
int& serialnum2,
bool ignore_parent_rel)
const
459 bool inherits1=
false, inherits2=
false;
460 std::pair<property_map_t::const_iterator, property_map_t::const_iterator> pit1=props.equal_range(it1->name_only());
461 std::pair<property_map_t::const_iterator, property_map_t::const_iterator> pit2=props.equal_range(it2->name_only());
463 property_map_t::const_iterator walk1=pit1.first;
464 while(walk1!=pit1.second) {
465 if((*walk1).second.first->match(*
this, it1, ignore_parent_rel)) {
466 ret1=dynamic_cast<const T *>((*walk1).second.second);
468 property_map_t::const_iterator walk2=pit2.first;
469 while(walk2!=pit2.second) {
470 if((*walk2).second.first->match(*
this, it2, ignore_parent_rel)) {
471 ret2=dynamic_cast<const T *>((*walk2).second.second);
473 if(ret1==ret2 && walk1!=walk2) {
474 serialnum1=serial_number( (*walk1).second.second, (*walk1).second.first );
475 serialnum2=serial_number( (*walk2).second.second, (*walk2).second.first );
481 if(dynamic_cast<const PropertyInherit *>((*walk2).second.second))
486 if(dynamic_cast<const PropertyInherit *>((*walk1).second.second))
493 if(!found && (inherits1 || inherits2)) {
494 Ex::sibling_iterator sib1, sib2;
495 if(inherits1) sib1=it1.begin();
497 bool keepgoing1=
true;
499 bool keepgoing2=
true;
500 if(inherits2) sib2=it2.begin();
503 const T* tmp=get<T>((Ex::iterator)(sib1), (Ex::iterator)(sib2), serialnum1, serialnum2, ignore_parent_rel);
509 if(!inherits2 || ++sib2==it2.end())
513 if(!inherits1 || ++sib1==it1.end())
525 Ex::iterator Properties::head(Ex::iterator it,
bool ignore_parent_rel)
const
529 if(get<PropertyInherit>(dn, ignore_parent_rel)) {