Open Chinese Convert  1.0.3
A project for conversion between Traditional and Simplified Chinese
Segments.hpp
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 }
 All Classes Functions