#ifndef MODGMT_STRCOMP_H #define MODGMT_STRCOMP_H #include #include #include // Compare string with template class TemplateComparator { TemplateComparator() = delete; TemplateComparator(const TemplateComparator&) = delete; TemplateComparator(TemplateComparator&&) = delete; struct Block { using pBlock=std::unique_ptr; enum Type {NOTDEF,TEXT,OPTIONAL,VARIANTS,DELIM}; size_t b,e; Type type; const struct Block* parent; pBlock next,child; Block() = delete; Block(const struct Block&) = delete; Block(struct Block&&) = delete; Block(Type t, const struct Block* p=nullptr):b(0),e(0),type(t),parent(p),next(nullptr),child(nullptr) {} Block(size_t bb, size_t ee, const struct Block* p=nullptr):b(bb),e(ee),type(TEXT),parent(p),next(nullptr),child(nullptr) {} }; struct Cursor { const struct Block* block; size_t offset; bool operator <(const struct Cursor& c) const {return blockb+offset];} Cursor(const struct Block* b, size_t o):block(b),offset(o) {} }; using Cursors=std::set; using pCursor=std::set::const_iterator; Block::pBlock Parse(); void InitCursors(const struct Block* blk); bool CmpSmb(const char c); Block::pBlock root; Cursors cursors; const std::string s; void Reset() { cursors.clear(); InitCursors(root.get()); } public: TemplateComparator(const char* str):s(str) {root=Parse();} TemplateComparator(const std::string& str):s(str) {root=Parse();} TemplateComparator(std::string&& str):s(std::move(str)) {root=Parse();} bool Compare(const std::string& str) { Reset(); for(size_t pos=0; postype) { case(Block::TEXT): {res+=s.substr(b->b,b->e-b->b); break;} case(Block::OPTIONAL): case(Block::VARIANTS): {b=b->child.get(); goto next;} case(Block::DELIM): {b=b->parent; break;} default: {} } // Go to next block while(true) { if(nullptr!=b->next) {b=b->next.get(); goto next;} if(nullptr!=b->parent) b=b->parent; else break; } if(nullptr==b->next && nullptr==b->parent) break; next: ; } return res; } }; #endif