Initial commit with Aho-Corasick code.
authorRafał Długołęcki <kontakt@dlugolecki.net.pl>
Sat, 29 Jun 2013 16:38:27 +0000 (18:38 +0200)
committerRafał Długołęcki <kontakt@dlugolecki.net.pl>
Sat, 29 Jun 2013 16:38:27 +0000 (18:38 +0200)
src/algorithm.cpp [new file with mode: 0644]
src/algorithm.h [new file with mode: 0644]
src/main.cpp [new file with mode: 0644]
src/trie.h [new file with mode: 0644]
src/typedef.h [new file with mode: 0644]

diff --git a/src/algorithm.cpp b/src/algorithm.cpp
new file mode 100644 (file)
index 0000000..ffcc419
--- /dev/null
@@ -0,0 +1,185 @@
+#include <iostream>\r
+#include <vector>\r
+#include <string>\r
+\r
+#include "typedef.h"\r
+#include "algorithm.h"\r
+#include "trie.h"\r
+\r
+/**\r
+ * Adds patterns to trie.\r
+ */\r
+void aho::algorithm::add_patterns_to_trie() {\r
+       uint max_size_of_patterns = 0;\r
+\r
+       for(uint i = 0; i < this->patterns.size(); i++) {\r
+               max_size_of_patterns = max_size_of_patterns < this->patterns[i].size() ? this->patterns[i].size() : max_size_of_patterns;\r
+       }\r
+\r
+       for(uint letter_iterator = 0; letter_iterator < max_size_of_patterns; letter_iterator++) {\r
+               for(uint pattern_iterator = 0; pattern_iterator < this->patterns.size(); pattern_iterator++) {\r
+                       tstring current_pattern = this->patterns[pattern_iterator];\r
+\r
+                       if(letter_iterator < current_pattern.size()) {\r
+                               this->trie->add_child(new aho::trie(current_pattern.substr(0, letter_iterator + 1)));\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+void aho::algorithm::set_patterns_in_trie() {\r
+       //Iterate over all patterns\r
+       for(uint i = 0; i < this->patterns.size(); i++) {\r
+               //Return to root node.\r
+               class aho::trie * node = this->trie;\r
+               tstring pattern = this->patterns[i];\r
+\r
+               //Search for pattern in trie\r
+               for(uint j = 0; j < pattern.size(); j++) {\r
+                       node = node->get_child(pattern.substr(0, j + 1).c_str());\r
+               }\r
+               //Set found node as pattern\r
+               node->is_pattern(true);\r
+       }\r
+}\r
+\r
+void aho::algorithm::set_suffix_link() {\r
+       for(uint j = 0; j < this->list.size(); j++) {\r
+               class aho::trie * node = this->list[j];\r
+\r
+               for(uint k = 1; k < node->get_value().size(); k++) {\r
+                       tstring suffix = (node->get_value().substr(k));\r
+\r
+                       class aho::trie * found = NULL;\r
+                       if((found = this->trie->get_child(suffix, true)) != NULL) {\r
+                               if(node->get_suffix(found->get_value()) == NULL) {\r
+                                       node->add_suffix(found);\r
+                               }\r
+                               break;\r
+                       }\r
+                               \r
+               }\r
+       }\r
+       return;\r
+}\r
+\r
+void aho::algorithm::set_nodes_list() {\r
+       for(uint i = 0; i < this->patterns.size(); i++) {\r
+               for(uint j = 1; j <= this->patterns[i].size(); j++) {\r
+                       class aho::trie * node = this->get_node(this->patterns[i].substr(0, j));\r
+                       //TODO: Pozbyæ siê powtarzania\r
+                       if(!this->is_on_nodes_list(node)) {\r
+                               this->list.push_back(node);\r
+                       }\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+ * Checks if node exists on node list.\r
+ */\r
+bool aho::algorithm::is_on_nodes_list(class aho::trie * node) {\r
+       for(uint i = 0; i < this->list.size(); i++) {\r
+               if(this->list[i] == node) {\r
+                       return true;\r
+               }\r
+       }\r
+       return false;\r
+}\r
+\r
+/**\r
+ * Adds pattern to search in a subject text.\r
+ */\r
+void aho::algorithm::add_search_pattern(tstring pattern) {\r
+       this->patterns.push_back(pattern);\r
+\r
+       for(uint i = 0; i < pattern.size(); i++) {\r
+               if(this->letters.find(pattern[i]) == tstring::npos) {\r
+                       this->letters.push_back(pattern[i]);\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+ * Create trie.\r
+ */\r
+void aho::algorithm::generate_trie() {\r
+       this->add_patterns_to_trie();\r
+       this->set_patterns_in_trie();\r
+       this->set_nodes_list();\r
+       this->set_suffix_link();\r
+}\r
+\r
+/**\r
+ * Search subject text for patterns.\r
+ */\r
+void aho::algorithm::parse() {\r
+       uint length = this->subject.size();\r
+       class aho::trie * current_node = this->trie;\r
+\r
+               for(uint j = 0; j < length; j++) {\r
+                       tstring letter;\r
+                       letter = this->subject[j];\r
+\r
+                       tstring value(current_node->get_value() + letter);\r
+\r
+                       class aho::trie * node = current_node->get_child(value);\r
+                       class aho::trie * suffix_node = NULL;\r
+\r
+                       if(node == NULL) {\r
+                               //value = abc\r
+                               //szukaj najd³u¿szego sufixu w node'zie\r
+\r
+                               for(uint k = 1; k < value.size(); k++) {\r
+//                                     tstring suffix(current_node->get_value().substr(k));\r
+                                       if((suffix_node = current_node->get_suffix(value.substr(k))) != NULL) {\r
+                                               node = suffix_node;\r
+                                               break;\r
+                                       }\r
+                                       else if((suffix_node = current_node->get_suffix(current_node->get_value().substr(k))) != NULL) {\r
+                                               node = suffix_node;\r
+                                               j -= k;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+                       if(node) {\r
+                               if(this->is_pattern(node)) {\r
+\r
+                                       this->save_result(node->get_value(), j+2-node->get_value().size());\r
+\r
+/*\r
+W przypadku natrafienia na wêze³\r
+oznaczony jako koniec s³owa, algorytm wypisuje je jako znalezione w tek\9ccie oraz sprawdza, czy czasem w tym\r
+miejscu nie koñczy siê wiêcej wzorców przechodz¹c krawêdziami fail a¿ do korzenia sprawdzaj¹c, czy nie\r
+przechodzi po wierzcho³ku bêd¹cym koñcem wzorca.\r
+*/\r
+                                       //Sprawd\9f suffixy je\9cli istniej¹\r
+                                       class aho::trie * other = node->get_suffix();\r
+                                       while(other != NULL) {\r
+                                               if(this->is_pattern(other)) {\r
+                                                       this->save_result(other->get_value(), j+2-other->get_value().size());\r
+                                               }\r
+                                               if(other->get_child(other->get_value() + this->subject[j+1])) {\r
+                                                       break;\r
+                                               }\r
+                                               other = other->get_suffix();\r
+                                       }\r
+                                       if(!other) {\r
+                                               other = this->trie;\r
+                                       }\r
+                                       //Zgubi³ w¹tek, bo natrafi³ na literê, która nie jest dzieckiem.\r
+                                       //Przejecha³ po suffixach...\r
+                                       //Pozosta³o sprawdziæ, czy na podstawie\r
+                                       if(!node->get_child(node->get_value() + this->subject[j+1])) {\r
+                                               node = other;\r
+                                       }\r
+                               }\r
+                               current_node = node;\r
+                       }\r
+                       current_node = node ? node : this->trie;\r
+\r
+               }\r
+               \r
+       return;\r
+}
\ No newline at end of file
diff --git a/src/algorithm.h b/src/algorithm.h
new file mode 100644 (file)
index 0000000..053303d
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef AHO_ALGORITHM_H\r
+#define AHO_ALGORITHM_H\r
+\r
+#include <iostream>\r
+#include <vector>\r
+#include <string>\r
+\r
+#include "typedef.h"\r
+#include "trie.h"\r
+\r
+/*\r
+At each step, the current node is extended by finding its daughter,\r
+and if that doesn't exist, finding its suffix's daughter, \r
+and if that doesn't work, finding its suffix's suffix's daughter,\r
+finally ending in the root node if nothing's seen before.\r
+*/\r
+namespace aho {\r
+       \r
+//     class result {\r
+//     private:\r
+//     protected:\r
+//     public:\r
+//             tstring rslt;\r
+//             int position;\r
+//     };\r
+\r
+class algorithm {\r
+       private:\r
+       protected:\r
+               class aho::trie * trie;\r
+\r
+               std::vector<tstring> patterns;\r
+               tstring subject;\r
+               tstring letters;\r
+\r
+               std::vector<class aho::trie *> list;\r
+\r
+               void add_patterns_to_trie();\r
+\r
+               /**\r
+                * Sets which nodes in trie, are the searched patterns.\r
+                */\r
+               void set_patterns_in_trie();\r
+\r
+               /**\r
+                * Sets node list.\r
+                */\r
+               void set_nodes_list();\r
+\r
+               /**\r
+                * Sets suffix links for each pattern in trie.\r
+                */\r
+               void set_suffix_link();\r
+\r
+               /**\r
+                * Checks if node is a searched pattern.\r
+                */\r
+               virtual bool is_pattern(class aho::trie * node) {\r
+                       return node->is_pattern();\r
+               }\r
+\r
+               bool is_on_nodes_list(class aho::trie * node);\r
+               \r
+               /**\r
+                * Gets node by its value\r
+                */\r
+               class aho::trie * get_node(tstring value) {\r
+                       return this->trie->get_child(value, true);\r
+               }\r
+\r
+               /**\r
+                * Saves search results\r
+                */\r
+               virtual void save_result(tstring search, uint position) {\r
+                       printf("%s: %d\n", search.c_str(), position);\r
+               }\r
+       public:\r
+               /**\r
+                * Algorithm constructor. Initializes variables.\r
+                */\r
+               algorithm() : trie(new aho::trie(TXT(""))) {\r
+               }\r
+\r
+               /**\r
+                * Algorithm destructor.\r
+                */\r
+               ~algorithm() {\r
+                       if(this->trie != NULL) {\r
+                               delete this->trie;\r
+                       }\r
+               }\r
+               void add_search_pattern(tstring pattern);\r
+\r
+               /**\r
+                * Sets subject text in which patterns will be searched.\r
+                */\r
+               void set_search_subject(tstring subject) {\r
+                       this->subject = subject;\r
+               }\r
+\r
+               void generate_trie();\r
+               void parse();\r
+       };\r
+};\r
+\r
+#endif
\ No newline at end of file
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644 (file)
index 0000000..cb9b3c1
--- /dev/null
@@ -0,0 +1,42 @@
+#include <iostream>\r
+\r
+#include "typedef.h"\r
+#include "algorithm.h"\r
+#include "trie.h"\r
+\r
+int main(int argc, int **argv) {\r
+       class aho::algorithm * algorithm = new aho::algorithm();\r
+\r
+       tfstream file("test.txt");\r
+       uint number_of_words;\r
+       file >> number_of_words;\r
+\r
+       for(uint i = 0; i < number_of_words; i++) {\r
+               tstring word;\r
+               file >> word;\r
+               algorithm->add_search_pattern(word);\r
+               tcout << word;\r
+       }\r
+\r
+//     algorithm->add_search_pattern("Drogi");\r
+//     algorithm->add_search_pattern("Marszalku");\r
+//     algorithm->add_search_pattern("ze");\r
+//     algorithm->add_search_pattern("i");\r
+//     algorithm->add_search_pattern("Jak");\r
+       tstring subject;\r
+       tstring tmp;\r
+       while(!file.eof()) {\r
+               file >> tmp;\r
+               subject += tmp + " ";\r
+       }\r
+\r
+//     algorithm->set_search_subject("Drogi Marszalku, Wysoka Izbo. PKB ro\9cnie. Z drugiej strony, rozszerzenie bazy o nowe rekordy poci¹ga za sob¹ proces wdrozenia i unowocze\9cniania form dzia³alno\9cci wymaga sprecyzowania i unowocze\9cniania nowych propozycji. Ka¿dy ju¿ mówi³em jasne jest wa¿ne zadanie w kszta³towaniu kolejnych kroków w przygotowaniu i realizacji kolejnych kroków w okre\9claniu istniej¹cych kryteriów wymaga sprecyzowania i realizacji odpowiednich warunków administracyjno-finansowych. Jak ju¿ mówi³em jasne jest to, ze rozszerzenie bazy o tym, usprawnienie systemu powszechnego uczestnictwa. Przez ostatnie kilkana\9ccie lat odkryli\9cmy ze rozszerzenie naszej dzia³alno\9cci organizacyjnej rozszerza nam efekt obecnej sytuacji. Z drugiej strony, zakres i bogate do\9cwiadczenia pozwalaj¹ na uwadze, ze wdrozenie nowych, lepszych rozwi¹zañ wymaga niezwyk³ej precyzji w restrukturyzacji przedsiêbiorstwa. Jak ju¿ zapewne zd¹¿y³ zauwa¿yæ i¿ zakres i unowocze\9cniania postaw uczestników wobec zadañ programowych jest to, ze aktualna struktura organizacji koliduje z powodu nowych propozycji. Nasza propozycja. Praktyka dnia codziennego dowodzi, ze konsultacja z dotychczasowymi zasadami kierunków postêpowego wychowania. Reasumuj¹c. nowy model dzia³alno\9cci organizacyjnej ukazuje nam horyzonty kolejnych kroków w kszta³towaniu systemu szkolenia kadr koliduje z powodu obecnej sytuacji. W ten sposób dalszy rozwój ró¿nych form dzia³alno\9cci organizacyjnej jest zauwazenie, ze inwestowanie.");\r
+       algorithm->set_search_subject(subject);\r
+\r
+       algorithm->generate_trie();\r
+       algorithm->parse();\r
+\r
+       delete algorithm;\r
+\r
+       return 0;\r
+}
\ No newline at end of file
diff --git a/src/trie.h b/src/trie.h
new file mode 100644 (file)
index 0000000..6ccc965
--- /dev/null
@@ -0,0 +1,171 @@
+#ifndef AHO_TRIE_H\r
+#define AHO_TRIE_H\r
+\r
+#include <vector>\r
+#include <map>\r
+\r
+#include "typedef.h"\r
+\r
+namespace aho {\r
+       class trie {\r
+       public:\r
+               typedef trie    _Myt;\r
+               typedef tstring _string;\r
+       private:\r
+               _string value;\r
+               class aho::trie * parent;\r
+\r
+               std::map<_string, class aho::trie *> suffixes;\r
+               std::vector<class aho::trie *> children;\r
+\r
+               bool pattern;\r
+               \r
+               /**\r
+                * Checks if a trie node should be nested in current node.\r
+                * @param node Trie node which will be compared with current node.\r
+                * @return returns true if node should be nested. False otherwise.\r
+                */\r
+               bool should_be_nested(class aho::trie * node) {\r
+                       return this->value.size() < node->get_value().size() ? true : false;\r
+               }\r
+       protected:\r
+       public:\r
+               /**\r
+                * Trie class constructor. Initializes variables with default values.\r
+                * @param value text value of trie's node.\r
+                */\r
+               trie(_string _value) : parent(NULL), pattern(false), value(_value) { }\r
+               \r
+               /**\r
+                * Sets value of trie node.\r
+                * @param value Value which will be used to set the trie node value.\r
+                */\r
+               void set_value(_string value) {\r
+                       this->value = value;\r
+               }\r
+\r
+               /**\r
+                * Sets parent node of this trie node.\r
+                * @param parent Parent node for current trie node.\r
+                */\r
+               void set_parent(class aho::trie * node) {\r
+                       this->parent = node;\r
+               }\r
+               \r
+               /**\r
+                * Adds node to the trie.\r
+                * @param node Trie node which will be added to the current node.\r
+                */\r
+               void add_child(class aho::trie * node) {\r
+                       //Je¿eli powinien byæ zagnie¿d¿ony (bo d³u¿szy)\r
+                       if(this->should_be_nested(node)) {\r
+                               uint length = this->value.size() + 1;\r
+\r
+                               //Je¿eli nie znalaz³ wpisu o danym fragmencie nazwy...\r
+                               class aho::trie * tmp = this->get_child(node->get_value().substr(0, length));\r
+                               if(tmp == NULL) {\r
+                                       //Je¿eli to jest nadal fragment (nie jest to pe³na nazwa).\r
+                                       if(length < node->get_value().size()) {\r
+                                               tmp = new aho::trie(node->get_value().substr(0, length + 1));\r
+                                               tmp->set_parent(this);\r
+                                               node->set_parent(tmp);\r
+                                               tmp->add_child(node);\r
+                                               this->children.push_back(tmp);\r
+                                               //this->children[tmp->get_value()] = tmp;\r
+                                       }\r
+                                       //WARNING!\r
+                                       //Je¿eli to ju¿ jest pe³na nazwa...\r
+                                       else {\r
+                                               node->set_parent(this);\r
+                                               this->children.push_back(node);\r
+                                               //this->children[node->get_value()] = node;\r
+                                       }\r
+                               }\r
+                               //Je¿eli znalaz³ wpis o takim fragmencie nazwy, to rekursywnie...\r
+                               else {\r
+                                       if(length < node->get_value().size()) {\r
+                                               node->set_parent(tmp);\r
+                                               tmp->add_child(node);\r
+                                       }\r
+                               }\r
+                       }\r
+                       //TODO: (?)\r
+                       //Je¿eli ma nie byæ zagnie¿d¿ony...(Czyli, je¿eli powinien byæ dok³adnie na tym poziomie...)\r
+                       else {\r
+                               if(this->get_value() == node->get_value()) {\r
+                                       delete node;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               /**\r
+                * Sets suffix link of the current node with a given node.\r
+                * @param node Pointer to node, which will be linked as a suffix.\r
+                */\r
+               void add_suffix(class aho::trie * node) {\r
+                       this->suffixes[node->get_value()] = node;\r
+               }\r
+               \r
+               /**\r
+                * Gets value of current node.\r
+                * @return Returns node value.\r
+                */\r
+               _string get_value() {\r
+                       return this->value;\r
+               }\r
+               \r
+               /**\r
+                * Gets specific child node of the current one.\r
+                * @param value Specifies node which has argument's value set in value.\r
+                * @param recursive If true, longest passing node is searched recursively. Otherwise child node of current one with exactly same value is searched.\r
+                * @return Returns pointer to node, if the node has been found. NULL otherwise.\r
+                */\r
+               class aho::trie * get_child(_string value, bool recursive = false) {\r
+                       for(uint i = 0; i < this->children.size(); i++) {\r
+                               //Je¿eli znalaz³, to zwróæ\r
+                               if(this->children[i]->get_value() == value) {\r
+                                       return this->children[i];\r
+                               }\r
+                               else if(recursive && (this->children[i]->get_value().compare(value.substr(0, this->children[i]->get_value().size())) == 0)) {\r
+                                       return this->children[i]->get_child(value, recursive);\r
+                               }\r
+                       }\r
+\r
+                       return NULL;\r
+               }\r
+               \r
+               /**\r
+                * Gets node's suffix\r
+                * @param value text value of suffix.\r
+                * @return Returns pointer to suffix node, if the node has been found. NULL otherwise.\r
+                */\r
+               class aho::trie * get_suffix(_string value = TXT("")) {\r
+                       return this->suffixes[value];\r
+               }\r
+\r
+               /**\r
+                * Gets parent node of the current trie node.\r
+                */\r
+               class aho::trie * get_parent(){\r
+                       return this->parent;\r
+               }\r
+               \r
+               /**\r
+                * Checks if current node is one of patterns to search.\r
+                * @return Returns true, if node is one of patterns. False otherwise.\r
+                */\r
+               bool is_pattern() {\r
+                       return this->pattern;\r
+               }\r
+               \r
+               /**\r
+                * Sets node to be a pattern to search.\r
+                * @param pattern Specifies if node is a pattern.\r
+                */\r
+               void is_pattern(bool pattern) {\r
+                       this->pattern = pattern;\r
+               }\r
+       };\r
+};\r
+\r
+#endif
\ No newline at end of file
diff --git a/src/typedef.h b/src/typedef.h
new file mode 100644 (file)
index 0000000..2e48710
--- /dev/null
@@ -0,0 +1,129 @@
+/***************************************************************************\r
+ *   Copyright (C) 2008 by Rafa³ D³ugo³êcki                                *\r
+ *   dlugolecki.rafal@gmail.com                                            *\r
+ *   quayle@wp.pl                                                          *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version.                                   *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU General Public License     *\r
+ *   along with this program; if not, write to the                         *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+\r
+/* Rafa³ D³ugo³êcki */\r
+\r
+//\r
+// File:   typedef.h\r
+// Author: rafal\r
+//\r
+// Created on 29 lipiec 2008, 22:37\r
+//\r
+\r
+#ifndef _TYPEDEF_H\r
+#define        _TYPEDEF_H\r
+\r
+#include <iostream>\r
+#include <fstream>\r
+#include <ostream>\r
+#include <istream>\r
+#include <sstream>\r
+#include <string>\r
+#include <cctype>//for isalnum and others...\r
+#include <cwctype>//for wide version of above\r
+#include <typeinfo>\r
+\r
+#include "config.h"\r
+/*\r
+ * Typedefs\r
+ */\r
+typedef unsigned int uint;\r
+\r
+#ifdef USE_WCHAR\r
+  typedef wchar_t tchar;\r
+//these are not types but variables\r
+# define tcout std::wcout\r
+# define tcin std::wcin\r
+# define tcerr std::wcerr\r
+# define TXT(x) L##x\r
+# define TCHAR_TYPE TXT("wchar_t")\r
+\r
+//these are functions\r
+  \r
+# define tisalnum(c)    std::iswalnum(c)\r
+# define tisalpha(c)    std::iswalpha(c)\r
+# define tiscntrl(c)    std::iswcntrl(c)\r
+# define tisdigit(c)    std::iswdigit(c)\r
+# define tisgraph(c)    std::iswgraph(c)\r
+# define tislower(c)    std::iswlower(c)\r
+# define tisprint(c)    std::iswprint(c)\r
+# define tispunct(c)    std::iswpunct(c)\r
+# define tisspace(c)    std::iswspace(c)\r
+# define tisupper(c)    std::iswupper(c)\r
+# define tisxdigit(c)   std::iswxdigit(c)\r
+  \r
+#else\r
+  typedef char tchar;\r
+//these are not types but variables\r
+# define tcout std::cout\r
+# define tcin std::cin\r
+# define tcerr std::cerr\r
+# define TXT(x) x\r
+# define TCHAR_TYPE TXT("char")\r
+//these are functions\r
+  \r
+# define tisalnum(c)    std::isalnum(c)\r
+# define tisalpha(c)    std::isalpha(c)\r
+# define tiscntrl(c)    std::iscntrl(c)\r
+# define tisdigit(c)    std::isdigit(c)\r
+# define tisgraph(c)    std::isgraph(c)\r
+# define tislower(c)    std::islower(c)\r
+# define tisprint(c)    std::isprint(c)\r
+# define tispunct(c)    std::ispunct(c)\r
+# define tisspace(c)    std::isspace(c)\r
+# define tisupper(c)    std::isupper(c)\r
+# define tisxdigit(c)   std::isxdigit(c)\r
+  \r
+#endif\r
+\r
+#ifdef USE_ICU\r
+  typedef UChar tchar;\r
+//these are not types but variables\r
+# define tcout std::cout\r
+# define tcin std::cin\r
+# define tcerr std::cerr\r
+# define TXT(x) x\r
+# define TCHAR_TYPE TXT("wchar_t or uint16_t")\r
+#endif\r
+\r
+typedef std::basic_string <tchar>                               tstring;\r
+\r
+typedef std::basic_istream<tchar>                               tistream;\r
+typedef std::basic_ostream<tchar>                               tostream;\r
+\r
+typedef std::basic_fstream<tchar>                               tfstream;\r
+typedef std::basic_ifstream<tchar>                              tifstream;\r
+typedef std::basic_ofstream<tchar>                              tofstream;\r
+\r
+typedef std::basic_stringstream<tchar>                          tstringstream;\r
+typedef std::basic_istringstream<tchar>                         tistringstream;\r
+typedef std::basic_ostringstream<tchar>                         tostringstream;\r
+\r
+typedef std::basic_stringbuf<tchar>                             tstringbuf;\r
+typedef std::basic_filebuf<tchar>                               tfilebuf;\r
+\r
+#ifdef USE_BOOST\r
+# include <boost/algorithm/string.hpp>\r
+#endif\r
+\r
+\r
+\r
+#endif\r