Open Chinese Convert: Segments.hpp Source File

Open Chinese Convert 1.3.0+g2c978160d.dirty A project for conversion between Traditional and Simplified Chinese

Loading...
Searching...
No Matches
Segments.hpp
1/*
2 * Open Chinese Convert
3 *
4 * Copyright 2010-2014 Carbo Kuo <byvoid@byvoid.com>
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19#pragma once
20
21#include <iterator>
22#include <sstream>
23
24#include "Common.hpp"
25
26namespace opencc {
31 class OPENCC_EXPORT Segments {
32public:
33 Segments() {}
34
35 Segments(std::initializer_list<const char*> initList) {
36 for (const char* item : initList) {
37 AddSegment(item);
38 }
39 }
40
41 Segments(std::initializer_list<std::string> initList) {
42 for (const std::string& item : initList) {
43 AddSegment(item);
44 }
45 }
46
47 void AddSegment(const char* unmanagedString) {
48 indexes.push_back(std::make_pair(unmanaged.size(), false));
49 unmanaged.push_back(unmanagedString);
50 }
51
52 void AddSegment(const std::string& str) {
53 indexes.push_back(std::make_pair(managed.size(), true));
54 managed.push_back(str);
55 }
56
57 class iterator {
58 public:
59 using iterator_category = std::input_iterator_tag;
60 using value_type = const char*;
61
62 iterator(const Segments* const _segments, size_t _cursor)
63 : segments(_segments), cursor(_cursor) {}
64
65 iterator& operator++() {
66 cursor++;
67 return *this;
68 }
69
70 bool operator==(const iterator& that) const {
71 return cursor == that.cursor && segments == that.segments;
72 }
73
74 bool operator!=(const iterator& that) const {
75 return !this->operator==(that);
76 }
77
78 const char* operator*() const { return segments->At(cursor); }
79
80 private:
81 const Segments* const segments;
82 size_t cursor;
83 };
84
85 const char* At(size_t cursor) const {
86 const auto& index = indexes[cursor];
87 if (index.second) {
88 return managed[index.first].c_str();
89 } else {
90 return unmanaged[index.first];
91 }
92 }
93
94 size_t Length() const { return indexes.size(); }
95
96 iterator begin() const { return iterator(this, 0); }
97
98 iterator end() const { return iterator(this, indexes.size()); }
99
100 std::string ToString() const {
101 // TODO implement a nested structure to reduce concatenation,
102 // like a purely functional differential list
103 std::ostringstream buffer;
104 for (const char* segment : *this) {
105 buffer << segment;
106 }
107 return buffer.str();
108 }
109
110private:
111 Segments(const Segments&) {}
112
113 std::vector<const char*> unmanaged;
114 std::vector<std::string> managed;
115 // index, managed
116 std::vector<std::pair<size_t, bool>> indexes;
117};
118} // namespace opencc