25 #ifndef FAUDES_BASESET_H
26 #define FAUDES_BASESET_H
48 template<
class T,
class Attr,
class Cmp>
class TAttrMap;
97 template<
class T,
class Cmp=std::less<T> >
104 using Type::operator=;
105 using Type::operator==;
106 using Type::operator!=;
109 template<
class TP,
class AP,
class CP>
friend class TAttrMap;
135 TBaseSet(
const std::string& rFilename,
const std::string& rLabel =
"BaseSet");
148 const std::string&
Name(
void)
const;
156 void Name(
const std::string& rName);
190 virtual std::string
Str(
const T& rElem)
const;
225 virtual bool Valid(
const T& rElem)
const;
247 virtual Iterator
Erase(
const Iterator& pos);
295 virtual Iterator
Inject(
const Iterator& pos,
const T& rElem);
336 Iterator
Find(
const T& rElem)
const;
373 void DValid(
const std::string& rMessage=
"")
const;
408 const typename std::set<T,Cmp>::const_iterator& sit,
414 if(pBaseSet && att) {
423 pBaseSet(fit.pBaseSet),
427 pBaseSet->AttachIterator(
this);
434 if(mAttached) pBaseSet->DetachIterator(
this);
439 std::stringstream rstr;
440 rstr <<
"[dit base " << pBaseSet <<
" a" << mAttached <<
" data " << pBaseSet->pSet;
441 if(pBaseSet) rstr <<
" elem " << pBaseSet->Str(**
this);
448 #ifdef FAUDES_DEBUG_CODE
450 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator= invalid iterator: no baseset");
455 if(mAttached)
if(pBaseSet==rSrc.
pBaseSet) {
456 std::set<T,Cmp>::const_iterator::operator= (rSrc);
460 if(mAttached) pBaseSet->DetachIterator(
this);
461 std::set<T,Cmp>::const_iterator::operator= (rSrc);
473 void StlIterator(
const typename std::set<T,Cmp>::const_iterator& sit) {
474 std::set<T,Cmp>::const_iterator::operator= (sit);
478 const typename std::set<T,Cmp>::const_iterator&
StlIterator(
void)
const {
497 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):DValid(): invalid iterator: no baseset");
500 pBaseSet->DValid(
"Iterator");
504 const T* operator-> (
void)
const {
505 #ifdef FAUDES_DEBUG_CODE
507 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator->: invalid iterator: no baseset");
511 return std::set<T,Cmp>::const_iterator::operator-> ();
515 const T& operator* (
void)
const {
516 #ifdef FAUDES_DEBUG_CODE
518 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator*: invalid iterator: no baseset");
522 return std::set<T,Cmp>::const_iterator::operator* ();
527 #ifdef FAUDES_DEBUG_CODE
529 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator==: invalid iterator: no baseset");
533 return *
static_cast< const typename std::set<T,Cmp>::const_iterator *
>(
this) == rOther;
538 #ifdef FAUDES_DEBUG_CODE
540 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator!=: invalid iterator: no baseset");
544 return *
static_cast< const typename std::set<T,Cmp>::const_iterator *
>(
this) != rOther;
549 #ifdef FAUDES_DEBUG_CODE
551 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator++: invalid iterator: no baseset");
556 std::set<T,Cmp>::const_iterator::operator++ (step);
562 #ifdef FAUDES_DEBUG_CODE
564 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator++: invalid iterator: no baseset");
568 std::set<T,Cmp>::const_iterator::operator++ ();
574 #ifdef FAUDES_DEBUG_CODE
576 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator--: invalid iterator: no baseset");
580 Iterator old(pBaseSet, *
this,
true);
581 std::set<T,Cmp>::const_iterator::operator-- (step);
587 #ifdef FAUDES_DEBUG_CODE
589 FD_ERR(
"TBaseSet<T,Cmp>::Iterator(" <<
this <<
"):operator--: invalid iterator: no baseset");
593 std::set<T,Cmp>::const_iterator::operator-- ();
612 #ifdef DONT_TRACK_REFERENCES
623 std::set<T,Cmp>::const_iterator()
627 Iterator(
const Iterator& fit) :
628 std::set<T,Cmp>::const_iterator(fit)
632 Iterator(
const typename std::set<T,Cmp>::const_iterator& sit) :
633 std::set<T,Cmp>::const_iterator(sit)
638 const TBaseSet<T,Cmp>* pBaseSet,
639 const typename std::set<T,Cmp>::const_iterator& sit) :
640 std::set<T,Cmp>::const_iterator(sit)
644 void StlIterator(
const typename std::set<T,Cmp>::const_iterator& sit) {
645 std::set<T,Cmp>::const_iterator::operator= (sit);
649 const typename std::set<T,Cmp>::const_iterator& StlIterator(
void)
const {
654 void Invalidate(
void) {};
787 virtual void AttributeTry(
const T& rElem,
const Type& rAttr) { (void) rElem; (void) rAttr; };
925 typedef typename std::set<T,Cmp>::iterator
iterator;
942 typedef typename std::map<T,AttributeVoid*>::iterator
aiterator;
1027 template<
class T,
class Cmp>
1029 FD_DC(
"FAUDES_DEBUG_CONTAINER: SetUnion(TBaseSet<T,Cmp>): res at " << &rRes);
1033 if(&rSetA==&rSetB && &rSetA==&rRes) {rRes.
Name(name);
return;}
1035 if(&rSetA==&rSetB) {rRes.
Assign(rSetA); rRes.
Name(name);
return;}
1037 if(&rSetA==&rRes) {rRes.
InsertSet(rSetB); rRes.
Name(name);
return;};
1039 if(&rSetB==&rRes) {rRes.
InsertSet(rSetA); rRes.
Name(name);
return;};
1044 FD_DC(
"FAUDES_DEBUG_CONTAINER: SetUnion(TBaseSet<T,Cmp>): done, res at " << &rRes <<
" #" << rRes.
Size());
1057 template<
class T,
class Cmp >
1062 if(&rSetA==&rSetB && &rSetA==&rRes) {rRes.
Name(name);
return;}
1064 if(&rSetA==&rSetB) { rRes.
Assign(rSetA); rRes.
Name(name);
return;}
1066 if(&rSetA==&rRes) {rRes.
RestrictSet(rSetB); rRes.
Name(name);
return;};
1068 if(&rSetB==&rRes) {rRes.
RestrictSet(rSetA); rRes.
Name(name);
return;};
1086 template<
class T,
class Cmp >
1091 if(&rSetA==&rSetB) { rRes.
Clear(); rRes.
Name(name);
return;}
1093 if(&rSetA==&rRes) {rRes.
EraseSet(rSetB); rRes.
Name(name);
return;};
1120 template<
class T,
class Cmp >
1122 return rSetA==rSetB;
1136 template<
class T,
class Cmp >
1138 return rSetA<=rSetB;
1160 #define THIS TBaseSet<T,Cmp>
1161 #define TEMP template<class T, class Cmp>
1180 TEMP std::set<T,Cmp> THIS::msEmptySet=std::set<T,Cmp>();
1181 TEMP std::map<T,AttributeVoid*> THIS::msEmptyAttributes=std::map<T,AttributeVoid*>();
1188 pAttributes(&msEmptyAttributes),
1191 mpClients(new std::list<
TBaseSet<T,Cmp>* >),
1194 pTypeDefinition(NULL)
1197 FD_DC(
"TBaseSet(" <<
this <<
")::TBaseSet()");
1203 TEMP THIS::TBaseSet(
const std::string& rFileName,
const std::string& rLabel) :
1207 pAttributes(&msEmptyAttributes),
1210 mpClients(new std::list<
TBaseSet<T,Cmp>* >),
1213 pTypeDefinition(NULL)
1216 FD_DC(
"TBaseSet(" <<
this <<
")::TBaseSet()");
1220 Read(rFileName,rLabel);
1228 pAttributes(&msEmptyAttributes),
1231 mpClients(new std::list<
TBaseSet<T,Cmp>* >),
1234 pTypeDefinition(NULL)
1237 FD_DC(
"TBaseSet(" <<
this <<
")::TBaseSet(rOtherSet " << &rOtherSet <<
"): fake copy construct");
1240 #ifdef FAUDES_DEBUG_CODE
1248 FD_DC(
"TBaseSet(" <<
this <<
")::~TBaseSet()");
1251 pHostSet->DetachClient(
this);
1252 if(mpClients)
delete mpClients;
1255 typename std::set< Iterator* >::const_iterator iit;
1256 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1257 (**iit).Invalidate();
1260 if(mpSet)
delete mpSet;
1262 for(
aiterator ait=mpAttributes->begin(); ait!=mpAttributes->end(); ++ait)
1264 delete mpAttributes;
1271 FD_DC(
"TBaseSet(" <<
this <<
"/" << this->Name() <<
")::DoAssign(rOtherSet " << &rSourceSet <<
"): shallow copy -- src attr# " << rSourceSet.pAttributes->size());
1272 FD_DC(
"TBaseSet():DoAssign(): " <<
typeid(*this->AttributeType()).name() <<
" <== " <<
typeid(*rSourceSet.AttributeType()).name());
1274 if(
this==&rSourceSet)
return;
1276 mMyName=rSourceSet.mMyName;
1278 if(pHostSet==rSourceSet.pHostSet)
return;
1281 pHostSet->DetachClient(
this);
1288 for(
aiterator ait=mpAttributes->begin(); ait!=mpAttributes->end(); ++ait)
1290 delete mpAttributes;
1299 if(
typeid(*rSourceSet.AttributeType())==
typeid(*this->AttributeType())) {
1300 pHostSet=rSourceSet.pHostSet;
1301 pHostSet->AttachClient(
this);
1302 pSet=rSourceSet.pSet;
1303 pAttributes=rSourceSet.pAttributes;
1307 mpSet =
new std::set<T,Cmp>();
1308 *mpSet = *rSourceSet.pSet;
1310 mpAttributes =
new std::map<T,AttributeVoid*>();
1311 if(
typeid(*this->AttributeType()) !=
typeid(
const AttributeVoid)) {
1312 for(
aiterator ait=rSourceSet.pAttributes->begin(); ait!=rSourceSet.pAttributes->end(); ++ait) {
1314 (*mpAttributes)[ait->first]=attr;
1317 pAttributes = mpAttributes;
1321 typename std::set< Iterator* >::iterator iit;
1322 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1323 (**iit).Invalidate();
1333 #ifdef FAUDES_DEBUG_CODE
1334 DValid(
"PostFakeAssignment");
1336 FD_DC(
"TBaseSet(" <<
this <<
")::DoAssign(rOtherSet " << &rSourceSet <<
"): fake copy -- done with attr# " << pAttributes->size());
1341 FD_DC(
"TBaseSet(" <<
this <<
")::Detach(void)");
1342 #ifdef FAUDES_DEBUG_CODE
1343 DValid(
"PreDetach");
1348 if(flag==SetOnly) pAttributes->clear();
1353 THIS* fake_const =
const_cast< THIS*
>(
this);
1355 #ifdef FAUDES_DEBUG_CODE
1358 if(pSet!=&msEmptySet)
1360 if(mpClients->empty()) {
1361 FD_ERR(
"TBaseSet(" <<
this <<
")::Detach(): missed detach (?)");
1363 fake_const->mDetached=
true;
1368 std::set<T,Cmp>* scopy =
new std::set<T,Cmp>();
1372 std::map<T,AttributeVoid*>* acopy =
new std::map<T,AttributeVoid*>();
1373 if(flag==AttrIncl) {
1374 for(
aiterator ait=pAttributes->begin(); ait!=pAttributes->end(); ++ait) {
1376 (*acopy)[ait->first]=attr;
1385 FD_DC(
"TBaseSet(" <<
this <<
")::Detach(): allocate and copy, strategie A");
1387 THIS* newhost = *mpClients->begin();
1388 #ifdef FAUDES_DEBUG_CODE
1389 if(newhost->mpClients)
1390 FD_ERR(
"TBaseSet(" <<
this <<
")::Detach(): new host used to heve clients (?)");
1392 newhost->pHostSet=newhost;
1393 newhost->mpSet=scopy;
1394 newhost->pSet=scopy;
1395 newhost->mpAttributes=acopy;
1396 newhost->pAttributes=acopy;
1397 newhost->mpClients=mpClients;
1398 newhost->DetachClient(newhost);
1400 typename std::list< THIS* >::const_iterator rit;
1401 for(rit=newhost->mpClients->begin();rit!=newhost->mpClients->end(); ++rit) {
1402 (*rit)->pHostSet=newhost;
1403 (*rit)->pSet=newhost->pSet;
1404 (*rit)->pAttributes=newhost->pAttributes;
1407 typename std::set< Iterator* >::iterator iit;
1408 for(rit=newhost->mpClients->begin(); rit!=newhost->mpClients->end(); ++rit) {
1409 for(iit=(*rit)->mIterators.begin(); iit!=(*rit)->mIterators.end(); ++iit) {
1410 if((**iit).StlIterator()==pSet->end())
1411 **iit=
Iterator(
this, scopy->end());
1413 **iit=
Iterator(
this, scopy->find(***iit));
1417 for(iit=newhost->mIterators.begin(); iit!=newhost->mIterators.end(); ++iit) {
1418 if((**iit).StlIterator()==pSet->end())
1419 **iit=
Iterator(
this, scopy->end());
1421 **iit=
Iterator(
this, scopy->find(***iit));
1424 fake_const->mpSet=pSet;
1425 fake_const->mpAttributes=pAttributes;
1426 fake_const->mpClients=
new std::list< TBaseSet<T,Cmp>* >;
1427 fake_const->mDetached=
true;
1429 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit)
1431 fake_const->mIterators.clear();
1439 FD_DC(
"TBaseSet(" <<
this <<
")::Detach(): allocate and copy, strategie B");
1441 fake_const->RelinkClients();
1442 pHostSet->DetachClient(fake_const);
1444 fake_const->mpSet = scopy;
1445 fake_const->mpAttributes=acopy;
1447 typename std::set< Iterator* >::iterator iit;
1448 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1449 if((**iit).StlIterator()==pSet->end())
1450 **iit=
Iterator(
this, mpSet->end());
1452 **iit=
Iterator(
this, mpSet->find(***iit));
1455 fake_const->pHostSet=fake_const;
1456 fake_const->pSet=mpSet;
1457 fake_const->pAttributes=mpAttributes;
1458 fake_const->mDetached=
true;
1459 if(fake_const->mpClients)
delete fake_const->mpClients;
1460 fake_const->mpClients=
new std::list< TBaseSet<T,Cmp>* >;
1464 #ifdef FAUDES_DEBUG_CODE
1465 DValid(
"PostDetach");
1467 FD_DC(
"TBaseSet(" <<
this <<
")::Detach(): done");
1472 FD_DC(
"TBaseSet(" <<
this <<
")::Lock(void)");
1473 #ifdef FAUDES_DEBUG_CODE
1483 THIS* fake_const =
const_cast< THIS*
>(
this);
1486 typename std::set< Iterator* >::const_iterator iit;
1487 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1490 fake_const->mIterators.clear();
1493 fake_const->mLocked=
true;
1495 #ifdef FAUDES_DEBUG_CODE
1502 TEMP inline void THIS::RelinkClients(
void) {
1503 FD_DC(
"TBaseSet::RelinkClients(" <<
this <<
")")
1504 #ifdef FAUDES_DEBUG_CODE
1505 DValid(
"PreRelink");
1509 if(!mpClients)
return;
1511 if(mpClients->empty())
return;
1513 FD_DC(
"TBaseSet::RelinkClients(" <<
this <<
"): doit")
1516 THIS* newhost = *mpClients->begin();
1517 #ifdef FAUDES_DEBUG_CODE
1518 if(newhost->pHostSet!=
this)
1519 FD_ERR(
"BaseSet::RelinkRefernces: old reference must have this as provider");
1520 if(newhost->mpClients)
1521 FD_ERR(
"TBaseSet(" <<
this <<
")::RelinkClients(void): client is a host (?)");
1523 newhost->pHostSet=newhost;
1524 newhost->mpSet=mpSet;
1526 newhost->mpAttributes=mpAttributes;
1527 newhost->pAttributes=pAttributes;
1528 newhost->mpClients=mpClients;
1529 newhost->DetachClient(newhost);
1531 typename std::list< THIS* >::const_iterator rit;
1532 for(rit=newhost->mpClients->begin();rit!=newhost->mpClients->end(); ++rit) {
1533 (*rit)->pHostSet=newhost;
1539 pAttributes=newhost->pAttributes;
1541 newhost->AttachClient(
this);
1543 #ifdef FAUDES_DEBUG_CODE
1544 DValid(
"PostRelink");
1546 FD_DC(
"TBaseSet::RelinkClients(" <<
this <<
"): done")
1553 const_cast< THIS*
>(
this)->mpClients->push_back(pRef);
1555 const_cast< THIS*
>(
this)->mDetached=
false;
1560 FD_DC(
"TBaseSet::DetachClient(" <<
this <<
"):" << pRef);
1562 if(!mpClients)
return;
1563 if(mpClients->empty())
return;
1566 THIS* fake_const =
const_cast< THIS*
>(
this);
1567 #ifdef FAUDES_DEBUG_CODE
1569 typename std::list< TBaseSet<T,Cmp>* >
::iterator cit;
1571 for(cit=fake_const->mpClients->begin(); cit!=fake_const->mpClients->end(); ++cit) {
1572 if(*cit==pRef) cf=
true;
1575 FD_ERR(
"TBaseSet::DetachClient(" <<
this <<
"): client not found " << pRef);
1588 typename std::list< TBaseSet<T,Cmp>* >
::iterator rit;
1589 for(rit=fake_const->mpClients->begin(); rit!=fake_const->mpClients->end(); ++rit) {
1590 if(*rit!=pRef)
continue;
1591 fake_const->mpClients->erase(rit);
1595 if(mpClients->empty() && (pSet!=&msEmptySet)) fake_const->mDetached=
true;
1596 FD_DC(
"TBaseSet::DetachClient(" <<
this <<
"): done.");
1603 FD_DC(
"TBaseSet::AttachIterator(" <<
this <<
"):" << pFit)
1604 const_cast< THIS*
>(
this)->mIterators.insert(pFit);
1610 FD_DC(
"TBaseSet::DetachIterator(" <<
this <<
"):" << pFit)
1611 const_cast< THIS*
>(
this)->mIterators.erase(pFit);
1615 TEMP void THIS::DValid(
const std::string& rMessage)
const {
1616 typename std::set< Iterator* >::const_iterator iit;
1617 typename std::list< THIS* >::const_iterator rit;
1618 #ifdef FAUDES_DEBUG_CONTAINER
1619 std::cerr <<
"TBaseSet(" <<
this <<
")::DValid(): " << rMessage <<
" source "
1620 << pHostSet <<
" " << (pHostSet->pSet==&msEmptySet ?
"+e+" :
"+f+") <<
1621 (mLocked ?
" +l+" :
" ") << (mDetached ?
" +d+" :
" ") <<
" -- refs ";
1622 if(pHostSet->mpClients)
1623 for(rit=pHostSet->mpClients->begin(); rit!=pHostSet->mpClients->end(); ++rit)
1624 std::cerr << *rit <<
" ";
1625 std::cerr <<
"-- its ";
1626 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit)
1627 std::cerr << *iit <<
" ";
1628 std::cerr <<
"-- attr #" << pAttributes->size();
1629 if(mpAttributes) std::cerr <<
"(" << mpAttributes->size() <<
") ";
1630 else std::cerr <<
" ";
1631 std::cerr << (pAttributes==&msEmptyAttributes ?
"+e+ " :
"+f+ ") << std::endl;
1634 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1635 if((*iit)->pBaseSet!=
this) {
1636 FD_WARN(
"BaseSet("<<
this <<
"," << rMessage <<
"): invalid iterator (baseset): "<< *iit);
1641 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1642 if(!(*iit)->mAttached) {
1643 FD_WARN(
"BaseSet("<<
this <<
"," << rMessage <<
"): invalid iterator (attached): "<< *iit);
1648 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1649 typename std::set<T,Cmp>::const_iterator vit;
1650 for(vit=pSet->begin(); vit!= pSet->end(); ++vit) {
1651 if(vit==(**iit).StlIterator())
break;
1653 if(vit!=(**iit).StlIterator()) {
1654 FD_WARN(
"BaseSet("<<
this <<
"," << rMessage <<
"): invalid iterator (stl) "<< *iit);
1655 (**iit).StlIterator(pSet->end());
1660 if(pHostSet==NULL) {
1661 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): no host found");
1665 if(pHostSet->pHostSet != pHostSet) {
1666 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): inconsistent host");
1670 if((mpSet!=NULL) && (pHostSet !=
this)) {
1671 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): double data");
1675 if(pHostSet!=
this && mpClients!=NULL) {
1676 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): cannot be client and have clients oneself");
1680 if(pHostSet->mpClients==NULL) {
1681 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): refers to invalid host (a)");
1685 if(pHostSet!=
this && pHostSet->mpClients->empty()) {
1686 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): refers to invalid host (b)");
1690 if((pHostSet ==
this) && (mpSet==NULL) && (pSet!=&msEmptySet)) {
1691 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): no data");
1695 if((pHostSet==
this) && (pSet!=&msEmptySet) && (mpClients==NULL)) {
1696 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): host with no client list");
1700 if((pHostSet ==
this) && (pSet != mpSet) && (pSet!=&msEmptySet)) {
1701 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): data pointer mismatch A");
1705 if(pSet != pHostSet->pSet) {
1706 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): data pointer mismatch B");
1711 for(rit=pHostSet->mpClients->begin(); rit!=pHostSet->mpClients->end(); ++rit) {
1712 if((*rit)==
this) hf=
true;
1713 if((*rit)->pHostSet== pHostSet)
continue;
1714 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): invalid client " << (*rit));
1717 if(!hf && (pHostSet!=
this)) {
1718 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): client not registered with host");
1722 if(pHostSet!=
this && *mClientRecord!=
this) {
1723 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): refers to invalid host (c)");
1727 if(mDetached && mpClients==NULL) {
1728 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): invalid detached flag A");
1732 if(mDetached && !mpClients->empty()) {
1733 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): invalid detached flag B");
1737 if(mDetached && (pSet==&msEmptySet)) {
1738 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): detached empty set");
1742 if(mLocked && (mpClients==NULL)) {
1743 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): locked reference (a)");
1747 if(!msEmptySet.empty()) {
1748 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): invalid empty set");
1752 if(!msEmptyAttributes.empty()) {
1753 FD_WARN(
"BaseSet(" <<
this <<
"," << rMessage <<
"): invalid empty attributes");
1756 #ifdef FAUDES_DEBUG_CONTAINER
1757 std::cerr <<
"TBaseSet(" <<
this <<
")::DValid(): passed" << std::endl;
1764 TEMP const std::string& THIS::Name(
void)
const {
1769 TEMP void THIS::Name(
const std::string& rName) {
1777 if(!pTypeDefinition) {
1779 THIS* fake_const =
const_cast< THIS*
>(
this);
1782 return pTypeDefinition;
1786 TEMP const std::string& THIS::XElementTag(
void)
const {
1787 if(mXElementTag.empty()) {
1789 THIS* fake_const =
const_cast< THIS*
>(
this);
1790 fake_const->mXElementTag=
"Element";
1792 if(fdp) fake_const->mXElementTag=fdp->
XElementTag();
1794 return mXElementTag;
1798 TEMP void THIS::XElementTag(
const std::string& rTag) {
1804 TEMP const std::string& THIS::TypeName(
void)
const {
1805 if(mFaudesTypeName.empty()) {
1807 THIS* fake_const =
const_cast< THIS*
>(
this);
1809 if(fdp) fake_const->mFaudesTypeName=fdp->
Name();
1811 return mFaudesTypeName;
1815 TEMP void THIS::TypeName(
const std::string& rType) {
1816 mFaudesTypeName=rType;
1821 TEMP std::string THIS::Str(
const T& rElem)
const {
1829 return (
Idx) pSet->size();
1833 TEMP bool THIS::Empty(
void)
const {
1834 return pSet->empty();
1841 std::string label=rLabel;
1842 if(label==
"") label=Name();
1843 if(label==
"") label=
"BaseSet";
1844 FD_DC(
"TBaseSet(" <<
this <<
")::DoWrite(..): section " << label <<
" #" << Size());
1854 BASE::DoSWrite(rTw);
1856 if(pHostSet->mpClients) shares=pHostSet->mpClients->size();
1863 #ifdef FAUDES_DEBUG_CODE
1870 BASE::DoSWrite(rTw);
1872 if(pHostSet->mpClients) shares=pHostSet->mpClients->size();
1875 if(pAttributes->size()!=0)
1877 if(pAttributes->size()!=0) {
1886 std::string label=rLabel;
1887 if(label==
"") label=Name();
1888 if(label==
"") label=
"BaseSet";
1895 TEMP typename THIS::Iterator THIS::ThisIterator(
const typename std::set<T,Cmp>::const_iterator& sit)
const {
1900 TEMP inline typename THIS::Iterator THIS::Begin(
void)
const {
1901 return ThisIterator(pSet->begin());
1905 TEMP inline typename THIS::Iterator THIS::End(
void)
const {
1906 return ThisIterator(pSet->end());
1912 FD_DC(
"TBaseSet(" <<
this <<
")::Clear()");
1913 #ifdef FAUDES_DEBUG_CODE
1917 if(pSet==&msEmptySet)
return;
1919 FD_DC(
"TBaseSet(" <<
this <<
")::Clear(): doit");
1920 FD_DC(
"TBaseSet(" <<
this <<
")::Clear(): type " <<
typeid(*this).name());
1922 if(mLocked) Detach(SetOnly);
1925 pHostSet->DetachClient(
this);
1928 if(!mpClients) mpClients=
new std::list< TBaseSet<T,Cmp>* >;
1937 for(
aiterator ait=mpAttributes->begin(); ait!=mpAttributes->end(); ++ait) {
1938 FD_DC(
"TBaseSet(" <<
this <<
")::Clear(): del attr " << ait->second);
1941 delete mpAttributes;
1946 pAttributes=&msEmptyAttributes;
1948 typename std::set< Iterator* >::iterator iit;
1949 for(iit=mIterators.begin(); iit!=mIterators.end(); ++iit) {
1950 (**iit).Invalidate();
1955 #ifdef FAUDES_DEBUG_CODE
1956 DValid(
"PostClear");
1958 FD_DC(
"TBaseSet(" <<
this <<
")::Clear(): done");
1963 TEMP inline bool THIS::Valid(
const T& rElem)
const {
1969 TEMP bool THIS::Insert(
const T& rElem) {
1970 #ifdef FAUDES_CHECKED
1972 std::stringstream errstr;
1973 errstr <<
"refuse to insert invalid element" << std::endl;
1974 throw Exception(
"BaseSet::Insert", errstr.str(), 61);
1977 if(!mDetached) Detach();
1978 return pSet->insert(rElem).second;
1982 TEMP typename THIS::Iterator THIS::Inject(
const Iterator& pos,
const T& rElem) {
1983 if(!mDetached) Detach();
1985 return ThisIterator(pSet->insert(dst,rElem));
1990 TEMP void THIS::Inject(
const T& rElem) {
1991 if(!mDetached) Detach();
1992 pSet->insert(pSet->end(),rElem);
1997 FD_DC(
"TBaseSet(" <<
this <<
")::InsertSet(" << &rOtherSet <<
")");
1998 if(!mDetached) Detach();
2007 while ((it1 != pSet->end()) && (it2 != rOtherSet.
pSet->end())) {
2011 else if (*it1 == *it2) {
2020 while (it2 != rOtherSet.
pSet->end()) {
2028 TEMP bool THIS::Erase(
const T& rElem) {
2029 if(!mDetached) Detach();
2030 return (pSet->erase(rElem)!=0);
2036 #ifdef FAUDES_CHECKED
2038 std::stringstream errstr;
2039 errstr <<
"iterator out of range " << std::endl;
2040 throw Exception(
"BaseSet::Erase", errstr.str(), 62);
2046 return ThisIterator(del);
2052 FD_DC(
"TBaseSet(" <<
this <<
")::EraseSet(" << &rOtherSet <<
")");
2053 if(!mDetached) Detach();
2057 while ((it != pSet->end()) && (oit != rOtherSet.
pSet->end())) {
2059 it=pSet->lower_bound(*oit);
2061 else if (*it == *oit) {
2066 oit=rOtherSet.
pSet->lower_bound(*it);
2074 FD_DC(
"TBaseSet(" <<
this <<
")::RestrictSet(" << &rOtherSet <<
")");
2075 if(!mDetached) Detach();
2079 while ((it != pSet->end()) && (oit != rOtherSet.
pSet->end())) {
2083 else if (*it == *oit) {
2088 oit=rOtherSet.
pSet->lower_bound(*it);
2091 while(it != pSet->end()) {
2099 FD_DC(
"TBaseSet(" <<
this <<
")::Disjoint(" << &rOtherSet <<
")");
2101 if(pSet->empty())
return true;
2102 if(rOtherSet.
pSet->empty())
return true;
2103 if(*pSet->rbegin()<*rOtherSet.
pSet->begin())
return true;
2104 if(*rOtherSet.
pSet->rbegin()<*pSet->begin())
return true;
2105 if(rOtherSet.
pSet==pSet)
return false;
2109 while ((it != pSet->end()) && (oit != rOtherSet.
pSet->end())) {
2110 if (*it < *oit) { it++;
continue;}
2111 if (*it == *oit) {
return false; }
2119 TEMP typename THIS::Iterator THIS::Find(
const T& rElem)
const {
2120 return ThisIterator(pSet->find(rElem));
2124 TEMP bool THIS::Exists(
const T& rElem)
const {
2125 return pSet->find(rElem) != pSet->end();
2154 FD_DC(
"TBaseSet::DoEqual()");
2156 if(pSet == rOtherSet.
pSet)
return true;
2158 return ( *pSet == *rOtherSet.
pSet );
2163 FD_DC(
"BaseSet::op<=()");
2164 return ( std::includes(rOtherSet.
pSet->begin(), rOtherSet.
pSet->end(), pSet->begin(), pSet->end()) ) ;
2169 FD_DC(
"BaseSet::op>=()");
2170 return ( std::includes(pSet->begin(), pSet->end(), rOtherSet.
pSet->begin(), rOtherSet.
pSet->end()) );
2175 return *pSet < *rOtherSet.
pSet;
2186 TEMP bool THIS::AttributeTest(
const Type& rAttr)
const {
2187 return AttributeType()->Cast(&rAttr)!=NULL;
2192 return (
Idx) pAttributes->size();
2196 TEMP void THIS::ClearAttributes(
void) {
2198 if(this->pAttributes->size()==0)
return;
2200 this->Detach(SetOnly);
2206 FD_DC(
"TBaseSet::EqualAttributes(TBaseSet)");
2208 FD_DC(
"TBaseSet::EqualAttributes(TBaseSet): 1");
2209 if(
typeid(*rOtherSet.
AttributeType())!=
typeid(*this->AttributeType()))
2212 FD_DC(
"TBaseSet::EqualAttributes(TBaseSet): 2");
2216 FD_DC(
"TBaseSet::EqualAttributes(TBaseSet): 3");
2218 if(this->AttributesSize()==0)
2223 while ((ait1 != pAttributes->end()) && (ait2 != rOtherSet.
pAttributes->end())) {
2224 if (ait1->first < ait2->first) {
2227 else if (ait1->first == ait2->first) {
2228 FD_DC(
"TBaseSet::EqualAttributes(TBaseSet): cmp " << ait1->second->ToString()
2229 <<
" vs " << ait2->second->ToString());
2230 if( ! ait1->second->Equal(*ait2->second))
return false;
2239 FD_DC(
"TBaseSet::EqualAttributes(TBaseSet): pass");
2248 this->DoAssign(rSourceSet);
2250 this->Detach(SetOnly);
2256 FD_DC(
"TBaseSet::Attributes("<<
this<<
")");
2259 std::stringstream errstr;
2260 errstr <<
"cannot cast attribute " << std::endl;
2261 throw Exception(
"TBaseSet::Attributes(otherset)", errstr.str(), 63);
2264 if(
typeid(*this->AttributeType())==
typeid(
const AttributeVoid))
return;
2266 this->Detach(AttrIncl);
2269 while ((it1 != pSet->end()) && (it2 != rOtherSet.
pSet->end())) {
2273 else if (*it1 == *it2) {
2274 DoAttribute(*it1,&rOtherSet.
Attribute(*it2));
2282 FD_DC(
"TBaseSet::Attributes(): copy ok");
2290 std::stringstream errstr;
2291 errstr <<
"cannot get attribute for TBaseSet \"" << mMyName <<
"\" type " <<
typeid(*this).name();
2292 throw Exception(
"TBaseSet::Attributep(rElem)", errstr.str(), 63);
2306 TEMP void THIS::Attribute(
const T& rElem,
const Type& rAttr) {
2309 #ifdef FAUDES_CHECKED
2310 if (!Exists(rElem)) {
2311 std::stringstream errstr;
2312 errstr <<
"element not member of set" << std::endl;
2313 throw Exception(
"TBaseSet::Attribute(elem,attr)", errstr.str(), 60);
2316 if(!AttributeTest(rAttr)) {
2317 std::stringstream errstr;
2318 errstr <<
"cannot cast attribute " << std::endl;
2319 throw Exception(
"TBaseSet::Attribute(elem,attr)", errstr.str(), 63);
2326 TEMP void THIS::ClrAttribute(
const T& rElem) {
2335 ait=this->pAttributes->find(rElem);
2336 if(ait==this->pAttributes->end())
return NULL;
2342 FD_DC(
"TBaseSet::DoAttributeExplicit(elem)");
2343 #ifdef FAUDES_DEBUG_CODE
2344 if(this->pAttributes!=this->::mpAttributes) {
2345 FD_ERR(
"TBaseSet::DoAttributeExplicit(elem): attributes not detached");
2350 ait=this->pAttributes->find(rElem);
2351 if(ait!=this->pAttributes->end())
2355 FD_DC(
"TBaseSet::DoAttributeExplicit(Elem): inserting explicit default " << attr <<
" type " <<
typeid(*attr).name());
2356 (*this->pAttributes)[rElem]=attr;
2361 TEMP void THIS::DoAttribute(
const T& rElem,
const Type* pAttr) {
2362 FD_DC(
"TBaseSet::DoAttribute([v] " << this->Str(rElem) <<
", ...)");
2363 #ifdef FAUDES_DEBUG_CODE
2364 if(this->pAttributes!=this->mpAttributes) {
2365 FD_ERR(
"TBaseSet::DoAttribute([v] set): attributes not detached");
2371 if(!this->AttributeType()->Cast(pAttr)) newattr=NULL;
2375 ait=this->pAttributes->find(rElem);
2376 if(ait!=this->pAttributes->end() )
2377 oldattr=ait->second;
2380 FD_DC(
"TBaseSet::DoAttribute([v] " << this->Str(rElem) <<
", ...): default 1");
2381 if(oldattr==NULL)
return;
2383 this->pAttributes->erase(ait);
2388 FD_DC(
"TBaseSet::DoAttribute([v] " << this->Str(rElem) <<
", ...): default 2");
2389 if(oldattr==NULL)
return;
2391 this->pAttributes->erase(ait);
2394 FD_DC(
"TBaseSet::DoAttribute([v] " << this->Str(rElem) <<
", ...): " << newattr->
ToString());
2399 (*this->pAttributes)[rElem]=attr;
2403 FD_DC(
"TBaseSet::DoAttribute([v] " << this->Str(rElem) <<
", ...): " << newattr->
ToString());
2404 oldattr->
Assign(*newattr);
Classes AttributeVoid and AttributeFlags
#define FD_DC(message)
Debug: optional report on container operations.
#define FD_WARN(message)
Debug: always report warnings.
#define FD_ERR(message)
Debug: report more errors with file/line info.
#define FAUDES_OBJCOUNT_DEC(type)
#define FAUDES_OBJCOUNT_INC(type)
Debug: count objects, report on exit.
Runtime interface, registry for faudes-types and functions.
Runtime interface, faudes types.
#define FAUDES_TYPE_TIMPLEMENTATION_CAST(ftype, ctype, cbase, ctemp)
#define FAUDES_TYPE_TIMPLEMENTATION_EQUAL(ftype, ctype, cbase, ctemp)
#define FAUDES_TYPE_TDECLARATION(ftype, ctype, cbase)
faudes type declaration macro, template version
#define FAUDES_TYPE_TIMPLEMENTATION_ASSIGN(ftype, ctype, cbase, ctemp)
#define FAUDES_TYPE_TIMPLEMENTATION_COPY(ftype, ctype, cbase, ctemp)
#define FAUDES_TYPE_TIMPLEMENTATION_NEW(ftype, ctype, cbase, ctemp)
faudes type implementation macros, template version
virtual bool IsDefault(void) const
Test for default value.
const std::string & Name(void) const
Get name of the entety to document (aka faudes-type or faudes-function).
Attribute interface for TBaseSet.
Iterator class for high-level api to TBaseSet.
void DValid(void) const
Check validity (provoke abort error)
Iterator(const TBaseSet< T, Cmp > *pBaseSet, const typename std::set< T, Cmp >::const_iterator &sit, bool att=false)
Construct by members (used by TBaseSet to create temporary iterators)
void StlIterator(const typename std::set< T, Cmp >::const_iterator &sit)
Assign STL iterator only.
bool mAttached
Indicate that this iterator is attached to some baseset.
~Iterator(void)
Destructor.
Iterator(const Iterator &fit)
Copy constructor, copies container reference, incl attach.
const TBaseSet< T, Cmp > * pBaseSet
Order by reference for containers of Iterators <.
void Invalidate(void)
Invalidate.
const std::set< T, Cmp >::const_iterator & StlIterator(void) const
Get STL iterator only.
std::string DStr(void) const
report (debugging)
Iterator()
Default constructor, container unknown.
std::list< TBaseSet< T, Cmp > * > * mpClients
BaseSets, that use data hosted by us (NULL if we dont host data, emptyset if we host to ourself excl....
std::string mXElementTag
Current/cached name of elements (used protected accessor method)
std::map< T, AttributeVoid * > * mpAttributes
Attribute map, if this object hosts data (else NULL).
bool mDetached
Indicate "hosts data to myself only".
std::list< TBaseSet< T, Cmp > * >::iterator mClientRecord
Iterator to the client list that hosts our data (maintained by host)
std::string mMyName
Name of this BaseSet.
std::set< Iterator * > mIterators
Iterators that refer to this TBaseSet.
std::set< T, Cmp >::iterator iterator
STL iterator, non-const version.
std::set< T, Cmp > * mpSet
STL set, if this object hosts data (else NULL)
std::string mFaudesTypeName
Current/cached faudes type-name.
const TypeDefinition * pTypeDefinition
static empty STL client list
virtual void AttributeTry(const T &rElem, const Type &rAttr)
Attribute access.
std::map< T, AttributeVoid * > * pAttributes
Pointer to attribute map to operate on.
std::map< T, AttributeVoid * >::const_iterator const_aiterator
STL attribute iterator, const version.
std::set< T, Cmp >::const_iterator const_iterator
STL iterator, const version.
std::map< T, AttributeVoid * >::iterator aiterator
STL attribute iterator, non-const version.
bool mLocked
Indicate "dont re-allocate the STL set ever again".
std::set< T, Cmp > * pSet
Pointer on STL set to operate on.
TBaseSet< T, Cmp > * pHostSet
Pointer on BaseSet that hosts our data (THIS if we host)
DetachMode
Detach from extern storage (incl allocation and true copy)
A TokenReader reads sequential tokens from a file or string.
void ReadEnd(const std::string &rLabel)
Close the current section by matching the previous ReadBegin().
void ReadBegin(const std::string &rLabel)
Open a section by specified label.
A TokenWriter writes sequential tokens to a file, a string or stdout.
void WriteComment(const std::string &rComment)
Write comment in faudes format.
void WriteEnd(const std::string &rLabel)
Write end label.
void WriteBegin(const std::string &rLabel)
Write begin label.
A TypeDefinition defines a faudes-type in that it specifies a faudes-type name to identify the type a...
const std::string & XElementTag(void) const
Parameter access: Xml Element Tag.
static TypeRegistry * G()
Method to access the single global instance of the registry.
const TypeDefinition * Definitionp(const std::string &rTypeName) const
Look up the type definition by faudes-type name.
Base class of all libFAUDES objects that participate in the run-time interface.
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
Read configuration data from file with label specified.
std::string ToString(const std::string &rLabel="", const Type *pContext=0) const
Write configuration data to a string.
virtual Type & Assign(const Type &rSrc)
Assign configuration data from other object.
virtual Type * New(void) const
Construct on heap.
virtual Type * Copy(void) const
Construct on heap.
virtual bool Insert(const T &rElem)
Insert specified element.
bool DoEqual(const TBaseSet &rOtherSet) const
test equality
virtual const AttributeVoid * AttributeType(void) const
Attribute typeinfo.
virtual const std::string & XElementTag(void) const
Get name of elements (used for XML IO)
void DoAttribute(const T &rElem, const Type *pAttr)
set attribute in map (assume elem exists in set, NULL <=> set to default)
void Lock(void) const
Detach and lock any further reallocation.
virtual TBaseSet & AssignWithoutAttributes(const TBaseSet &rSourceSet)
Attribute access.
void DoAssign(const TBaseSet &rSourceSet)
assign my members
void Detach(DetachMode flag=AttrIncl) const
bool SetInclusion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB)
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Token output, see Type::DWrite for public wrappers.
void AttachClient(TBaseSet *pRef) const
Record that we provide contents to some other BaseSet.
bool SetEquality(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB)
virtual void TypeName(const std::string &rType)
Overwrite faudes-type name.
bool Empty(void) const
Test whether if the TBaseSet is Empty.
void DetachClient(TBaseSet *pRef) const
Record that we stop providing data for some TBaseSet.
void SetDifference(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
bool Exists(const T &rElem) const
Test existence of element.
virtual void Attributes(const TBaseSet &rOtherSet)
Attributes access.
virtual void Attribute(const T &rElem, const Type &rAttr)
Attribute access.
virtual bool Disjoint(const TBaseSet &rOtherSet) const
Test for this set to be disjoint witg other set.
void Name(const std::string &rName)
Set name of TBaseSet.
virtual void Clear(void)
Clear all set.
const AttributeVoid * DoAttribute(const T &rElem) const
get attribute from map (return null if elem does not exist in map)
void DetachIterator(Iterator *pFit) const
Record that an iterator stops to refer to this TBaseSet.
TBaseSet< T, Cmp >::Iterator ThisIterator(const typename std::set< T, Cmp >::const_iterator &sit) const
Convert STL iterator to API iterator.
Iterator Find(const T &rElem) const
Find element and return iterator.
virtual bool Valid(const T &rElem) const
Test validty of candidate element.
virtual Iterator Inject(const Iterator &pos, const T &rElem)
Insert specified element.
virtual void DoDWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Token output, debugging see Type::DWrite for public wrappers.
virtual void XElementTag(const std::string &rTag)
Configure the element name tag.
Idx AttributesSize(void) const
Attribute access.
static std::set< T, Cmp > msEmptySet
static empty STL set for default constructor
virtual bool AttributeTest(const Type &rAttr) const
Attribute typeinfo.
TBaseSet(const std::string &rFilename, const std::string &rLabel="BaseSet")
Constructor from file.
virtual const TypeDefinition * TypeDefinitionp(void) const
Reimplment from type to use chache.
Iterator End(void) const
Iterator to the end of set.
virtual ~TBaseSet(void)
Virtual destructor.
virtual void RestrictSet(const TBaseSet &rOtherSet)
Restrict elements given by other set.
virtual void InsertSet(const TBaseSet &rOtherSet)
Insert elements given by rOtherSet.
virtual AttributeVoid * Attributep(const T &rElem)
Attribute access.
bool EqualAttributes(const TBaseSet &rOtherSet) const
Attribute access.
Iterator Begin(void) const
Iterator to the begin of set.
virtual const std::string & TypeName(void) const
Get objects's type name.
virtual const AttributeVoid & Attribute(const T &rElem) const
Attribute access.
void RelinkClients(void)
Ensure that we do not host contents to anyone else.
void DValid(const std::string &rMessage="") const
Some validation of deferred copy mechanism (provoke abort)
AttributeVoid * DoAttributeExplicit(const T &rElem)
get attribute from map (insert explicit default if elem does not exist in map)
virtual bool Erase(const T &rElem)
Erase element by reference.
const std::string & Name(void) const
Return name of TBaseSet.
void SetUnion(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
void SetIntersection(const TBaseSet< T, Cmp > &rSetA, const TBaseSet< T, Cmp > &rSetB, TBaseSet< T, Cmp > &rRes)
virtual void EraseSet(const TBaseSet &rOtherSet)
Erase elements given by other set.
TBaseSet(const TBaseSet &rOtherSet)
Copy-constructor.
Idx Size(void) const
Get Size of TBaseSet.
virtual void Inject(const T &rElem)
Insert specified element.
TBaseSet(void)
Constructor.
void ClearAttributes(void)
Attribute access.
virtual std::string Str(const T &rElem) const
Return pretty printable element.
virtual Iterator Erase(const Iterator &pos)
Erase element by iterator.
void AttachIterator(Iterator *pFit) const
Record that an iterator refers to this TBaseSet.
virtual void ClrAttribute(const T &rElem)
Attribute access.
static std::map< T, AttributeVoid * > msEmptyAttributes
static empty STL map for default constructor
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
Token input, see Type::Read for public wrappers.
virtual void DoSWrite(TokenWriter &rTw) const
Token output, see Type::SWrite for public wrappers.
const std::string & FaudesTypeName(const Type &rObject)
Query type name.
libFAUDES resides within the namespace faudes.
uint32_t Idx
Type definition for index type (allways 32bit)
std::string CollapsString(const std::string &rString, unsigned int len)
Limit length of string, return head and tail of string.
std::string ToStringInteger(Int number)
integer to string