diff --git a/src/rime/algo/calculus.cc b/src/rime/algo/calculus.cc index 38b0bcf708..df1ae662ec 100644 --- a/src/rime/algo/calculus.cc +++ b/src/rime/algo/calculus.cc @@ -4,9 +4,9 @@ // // 2012-01-17 GONG Chen // -#include #include #include +#include #include namespace rime { @@ -31,9 +31,8 @@ Calculation* Calculus::Parse(const string& definition) { size_t sep = definition.find_first_not_of("zyxwvutsrqponmlkjihgfedcba"); if (sep == string::npos) return NULL; - vector args; - boost::split(args, definition, - boost::is_from_range(definition[sep], definition[sep])); + const string& delim = definition.substr(sep, 1); + vector args = strings::split(definition, delim); if (args.empty()) return NULL; auto it = factories_.find(args[0]); diff --git a/src/rime/algo/strings.h b/src/rime/algo/strings.h index fe963088ae..0f99f78f3d 100644 --- a/src/rime/algo/strings.h +++ b/src/rime/algo/strings.h @@ -35,6 +35,32 @@ inline string join(std::initializer_list&& container, T&& delim) { return join(std::begin(container), std::end(container), delim); } +inline void trim_left(string& str) { + str.erase(str.begin(), + std::find_if(str.begin(), str.end(), + [](unsigned char ch) { return !std::isspace(ch); })); +} + +inline void trim_right(string& str) { + str.erase(std::find_if(str.rbegin(), str.rend(), + [](unsigned char ch) { return !std::isspace(ch); }) + .base(), + str.end()); +} + +inline void trim(string& str) { + trim_right(str); + trim_left(str); +} + +inline bool starts_with(const string& str, const string& prefix) { + return str.rfind(prefix, 0) == 0; +} + +inline bool ends_with(const string& str, const string& suffix) { + return str.find(suffix, str.length() - suffix.length()) != std::string::npos; +} + } // namespace strings } // namespace rime diff --git a/src/rime/config/config_data.cc b/src/rime/config/config_data.cc index 7258a460ed..15413eb2ef 100644 --- a/src/rime/config/config_data.cc +++ b/src/rime/config/config_data.cc @@ -6,9 +6,9 @@ #include #include #include -#include #include #include +#include #include #include #include @@ -207,15 +207,13 @@ bool ConfigData::TraverseWrite(const string& path, an item) { } vector ConfigData::SplitPath(const string& path) { - vector keys; - auto is_separator = boost::is_any_of("/"); - auto trimmed_path = boost::trim_left_copy_if(path, is_separator); - boost::split(keys, trimmed_path, is_separator); + auto trimmed_path = path.substr(strings::starts_with(path, "/")); + vector keys = strings::split(trimmed_path, "/"); return keys; } string ConfigData::JoinPath(const vector& keys) { - return boost::join(keys, "/"); + return strings::join(keys, "/"); } an ConfigData::Traverse(const string& path) { diff --git a/src/rime/dict/reverse_lookup_dictionary.cc b/src/rime/dict/reverse_lookup_dictionary.cc index b9d1042c6e..3781f14cbe 100644 --- a/src/rime/dict/reverse_lookup_dictionary.cc +++ b/src/rime/dict/reverse_lookup_dictionary.cc @@ -8,12 +8,12 @@ #include #include #include -#include #include #include #include #include #include +#include #include #include @@ -107,7 +107,7 @@ bool ReverseDb::Build(DictSettings* settings, // save reverse lookup entries for (const auto& v : rev_table) { const string& key(v.first); - string value(boost::algorithm::join(v.second, " ")); + string value(strings::join(v.second, " ")); key_trie_builder.Add(key, 0.0, &key_ids[i]); value_trie_builder.Add(value, 0.0, &value_ids[i]); ++i; @@ -115,7 +115,7 @@ bool ReverseDb::Build(DictSettings* settings, // save stems for (const auto& v : stems) { string key(v.first + kStemKeySuffix); - string value(boost::algorithm::join(v.second, " ")); + string value(strings::join(v.second, " ")); key_trie_builder.Add(key, 0.0, &key_ids[i]); value_trie_builder.Add(value, 0.0, &value_ids[i]); ++i; diff --git a/src/rime/dict/table_db.cc b/src/rime/dict/table_db.cc index 59bc2cd391..90cee066e9 100644 --- a/src/rime/dict/table_db.cc +++ b/src/rime/dict/table_db.cc @@ -4,7 +4,7 @@ // // 2013-04-18 GONG Chen // -#include +#include #include #include @@ -22,7 +22,7 @@ static bool rime_table_entry_parser(const Tsv& row, return false; } string code(row[1]); - boost::algorithm::trim(code); + strings::trim(code); *key = code + " \t" + row[0]; UserDbValue v; if (row.size() >= 3 && !row[2].empty()) { @@ -42,13 +42,13 @@ static bool rime_table_entry_formatter(const string& key, Tsv* tsv) { Tsv& row(*tsv); // key ::= code phrase - boost::algorithm::split(row, key, boost::algorithm::is_any_of("\t")); + row = strings::split(key, "\t"); if (row.size() != 2 || row[0].empty() || row[1].empty()) return false; UserDbValue v(value); if (v.commits < 0) // deleted entry return false; - boost::algorithm::trim(row[0]); // remove trailing space + strings::trim(row[0]); // remove trailing space row[0].swap(row[1]); row.push_back(std::to_string(v.commits)); return true; diff --git a/src/rime/dict/tsv.cc b/src/rime/dict/tsv.cc index 733d1958cb..d20968557b 100644 --- a/src/rime/dict/tsv.cc +++ b/src/rime/dict/tsv.cc @@ -5,7 +5,7 @@ // 2013-04-14 GONG Chen // #include -#include +#include #include #include #include @@ -24,15 +24,15 @@ int TsvReader::operator()(Sink* sink) { bool enable_comment = true; while (getline(fin, line)) { ++line_no; - boost::algorithm::trim_right(line); + strings::trim_right(line); // skip empty lines and comments if (line.empty()) continue; if (enable_comment && line[0] == '#') { - if (boost::starts_with(line, "#@")) { + if (strings::starts_with(line, "#@")) { // metadata line.erase(0, 2); - boost::algorithm::split(row, line, boost::algorithm::is_any_of("\t")); + row = strings::split(line, "\t"); if (row.size() != 2 || !sink->MetaPut(row[0], row[1])) { LOG(WARNING) << "invalid metadata at line " << line_no << "."; } @@ -43,7 +43,7 @@ int TsvReader::operator()(Sink* sink) { continue; } // read a tsv entry - boost::algorithm::split(row, line, boost::algorithm::is_any_of("\t")); + row = strings::split(line, "\t"); if (!parser_(row, &key, &value) || !sink->Put(key, value)) { LOG(WARNING) << "invalid entry at line " << line_no << "."; continue; diff --git a/src/rime/dict/user_db.cc b/src/rime/dict/user_db.cc index 7813091960..02a8fdcd83 100644 --- a/src/rime/dict/user_db.cc +++ b/src/rime/dict/user_db.cc @@ -6,7 +6,7 @@ // #include #include -#include +#include #include #include #include @@ -25,8 +25,7 @@ string UserDbValue::Pack() const { } bool UserDbValue::Unpack(const string& value) { - vector kv; - boost::split(kv, value, boost::is_any_of(" ")); + vector kv = strings::split(value, " "); for (const string& k_eq_v : kv) { size_t eq = k_eq_v.find('='); if (eq == string::npos) @@ -83,7 +82,7 @@ static bool userdb_entry_formatter(const string& key, const string& value, Tsv* tsv) { Tsv& row(*tsv); - boost::algorithm::split(row, key, boost::algorithm::is_any_of("\t")); + row = strings::split(key, "\t"); if (row.size() != 2 || row[0].empty() || row[1].empty()) return false; row.push_back(value); @@ -107,7 +106,7 @@ bool UserDbHelper::UpdateUserInfo() { } bool UserDbHelper::IsUniformFormat(const string& file_name) { - return boost::ends_with(file_name, plain_userdb_extension); + return strings::ends_with(file_name, plain_userdb_extension); } bool UserDbHelper::UniformBackup(const string& snapshot_file) { @@ -147,10 +146,10 @@ string UserDbHelper::GetDbName() { string name; if (!db_->MetaFetch("/db_name", &name)) return name; - auto ext = boost::find_last(name, ".userdb"); - if (!ext.empty()) { + auto ext = name.rfind(".userdb"); + if (ext != std::string::npos) { // remove ".userdb.*" - name.erase(ext.begin(), name.end()); + name.erase(ext, name.length() - ext); } return name; } diff --git a/src/rime/gear/script_translator.cc b/src/rime/gear/script_translator.cc index 9506c9e7c4..b0383b6ecd 100644 --- a/src/rime/gear/script_translator.cc +++ b/src/rime/gear/script_translator.cc @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include @@ -18,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -214,7 +214,7 @@ string ScriptTranslator::Spell(const Code& code) { vector syllables; if (!dict_ || !dict_->Decode(code, &syllables) || syllables.empty()) return result; - result = boost::algorithm::join(syllables, string(1, delimiters_.at(0))); + result = strings::join(syllables, string(1, delimiters_.at(0))); comment_formatter_.Apply(&result); return result; } diff --git a/src/rime/gear/switch_translator.cc b/src/rime/gear/switch_translator.cc index ffaa3cfb4d..62bede49f9 100644 --- a/src/rime/gear/switch_translator.cc +++ b/src/rime/gear/switch_translator.cc @@ -4,7 +4,7 @@ // // 2013-05-26 GONG Chen // -#include +#include #include #include #include @@ -184,7 +184,7 @@ void FoldedOptions::Append(const SwitchOption& option, size_t state_index) { } void FoldedOptions::Finish() { - text_ = prefix_ + boost::algorithm::join(labels_, separator_) + suffix_; + text_ = prefix_ + strings::join(labels_, separator_) + suffix_; } class SwitchTranslation : public FifoTranslation { diff --git a/src/rime/gear/unity_table_encoder.cc b/src/rime/gear/unity_table_encoder.cc index 79852f7e31..35bb1de3f0 100644 --- a/src/rime/gear/unity_table_encoder.cc +++ b/src/rime/gear/unity_table_encoder.cc @@ -4,7 +4,7 @@ // // 2013-08-31 GONG Chen // -#include +#include #include #include #include @@ -62,7 +62,7 @@ bool UnityTableEncoder::TranslateWord(const string& word, string str_list; if (rev_dict_->LookupStems(word, &str_list) || rev_dict_->ReverseLookup(word, &str_list)) { - boost::split(*code, str_list, boost::is_any_of(" ")); + *code = strings::split(str_list, " "); return !code->empty(); } return false; @@ -80,7 +80,7 @@ size_t UnityTableEncoder::LookupPhrases(UserDictEntryIterator* result, } bool UnityTableEncoder::HasPrefix(const string& key) { - return boost::starts_with(key, kEncodedPrefix); + return strings::starts_with(key, kEncodedPrefix); } bool UnityTableEncoder::AddPrefix(string* key) {