You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.4 KiB
98 lines
2.4 KiB
#ifndef MODGMT_STRCOMP_H |
|
#define MODGMT_STRCOMP_H |
|
#include <memory> |
|
#include <set> |
|
#include <string> |
|
|
|
// Compare string with template |
|
class TemplateComparator |
|
{ |
|
TemplateComparator() = delete; |
|
TemplateComparator(const TemplateComparator&) = delete; |
|
TemplateComparator(TemplateComparator&&) = delete; |
|
|
|
struct Block |
|
{ |
|
using pBlock=std::unique_ptr<struct Block>; |
|
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 block<c.block;} |
|
bool compare(const std::string& str, const char c) const {return c==str[block->b+offset];} |
|
Cursor(const struct Block* b, size_t o):block(b),offset(o) {} |
|
}; |
|
|
|
using Cursors=std::set<struct Cursor>; |
|
using pCursor=std::set<struct Cursor>::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; pos<str.length(); ++pos) if(!CmpSmb(str[pos])) return false; |
|
return true; |
|
} |
|
|
|
std::string Template2Name() const |
|
{ |
|
const struct Block* b=root.get(); |
|
std::string res; |
|
while(true) |
|
{ |
|
// Processing current block |
|
switch(b->type) |
|
{ |
|
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
|
|
|