Open Chinese Convert
1.0.3
A project for conversion between Traditional and Simplified Chinese
|
00001 /* 00002 * Open Chinese Convert 00003 * 00004 * Copyright 2010-2014 BYVoid <byvoid@byvoid.com> 00005 * 00006 * Licensed under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 00019 #pragma once 00020 00021 #include "Common.hpp" 00022 00023 namespace opencc { 00028 class OPENCC_EXPORT Segments { 00029 public: 00030 Segments() {} 00031 00032 Segments(std::initializer_list<const char*> initList) { 00033 for (const string& item : initList) { 00034 AddSegment(item); 00035 } 00036 } 00037 00038 Segments(std::initializer_list<string> initList) { 00039 for (const string& item : initList) { 00040 AddSegment(item); 00041 } 00042 } 00043 00044 void AddSegment(const char* unmanagedString) { 00045 indexes.push_back(std::make_pair(unmanaged.size(), false)); 00046 unmanaged.push_back(unmanagedString); 00047 } 00048 00049 void AddSegment(const string& str) { 00050 indexes.push_back(std::make_pair(managed.size(), true)); 00051 managed.push_back(str); 00052 } 00053 00054 class iterator : public std::iterator<std::input_iterator_tag, const char*> { 00055 public: 00056 iterator(const Segments* const _segments, size_t _cursor) 00057 : segments(_segments), cursor(_cursor) {} 00058 00059 iterator& operator++() { 00060 cursor++; 00061 return *this; 00062 } 00063 00064 bool operator==(const iterator& that) const { 00065 return cursor == that.cursor && segments == that.segments; 00066 } 00067 00068 bool operator!=(const iterator& that) const { 00069 return !this->operator==(that); 00070 } 00071 00072 const char* operator*() const { return segments->At(cursor); } 00073 00074 private: 00075 const Segments* const segments; 00076 size_t cursor; 00077 }; 00078 00079 const char* At(size_t cursor) const { 00080 const auto& index = indexes[cursor]; 00081 if (index.second) { 00082 return managed[index.first].c_str(); 00083 } else { 00084 return unmanaged[index.first]; 00085 } 00086 } 00087 00088 size_t Length() const { return indexes.size(); } 00089 00090 iterator begin() const { return iterator(this, 0); } 00091 00092 iterator end() const { return iterator(this, indexes.size()); } 00093 00094 string ToString() const { 00095 // TODO implement a nested structure to reduce concatenation, 00096 // like a purely functional differential list 00097 std::ostringstream buffer; 00098 for (const char* segment : *this) { 00099 buffer << segment; 00100 } 00101 return buffer.str(); 00102 } 00103 00104 private: 00105 Segments(const Segments&) {} 00106 00107 vector<const char*> unmanaged; 00108 vector<string> managed; 00109 // index, managed 00110 vector<std::pair<size_t, bool>> indexes; 00111 }; 00112 }