@@ -30,30 +30,31 @@ bool IsTrailingSurrogate(char32_t code_point) {
3030
3131} // namespace
3232
33- TextInputModel::TextInputModel ()
34- : selection_base_(text_.begin()), selection_extent_(text_.begin()) {}
33+ TextInputModel::TextInputModel () = default ;
3534
3635TextInputModel::~TextInputModel () = default ;
3736
3837void TextInputModel::SetText (const std::string& text) {
3938 std::wstring_convert<std::codecvt_utf8_utf16<char16_t >, char16_t >
4039 utf16_converter;
4140 text_ = utf16_converter.from_bytes (text);
42- selection_base_ = text_. begin () ;
43- selection_extent_ = selection_base_ ;
41+ selection_base_ = 0 ;
42+ selection_extent_ = 0 ;
4443}
4544
4645bool TextInputModel::SetSelection (size_t base, size_t extent) {
47- if (base > text_.size () || extent > text_.size ()) {
46+ auto max_pos = text_.length ();
47+ if (base > max_pos || extent > max_pos) {
4848 return false ;
4949 }
50- selection_base_ = text_. begin () + base;
51- selection_extent_ = text_. begin () + extent;
50+ selection_base_ = base;
51+ selection_extent_ = extent;
5252 return true ;
5353}
5454
5555void TextInputModel::DeleteSelected () {
56- selection_base_ = text_.erase (selection_start (), selection_end ());
56+ text_.erase (selection_start (), selection_end () - selection_start ());
57+ selection_base_ = selection_start ();
5758 selection_extent_ = selection_base_;
5859}
5960
@@ -75,7 +76,7 @@ void TextInputModel::AddText(const std::u16string& text) {
7576 if (selection_base_ != selection_extent_) {
7677 DeleteSelected ();
7778 }
78- selection_extent_ = text_.insert (selection_extent_, text. begin (), text. end () );
79+ text_.insert (selection_extent_, text);
7980 selection_extent_ += text.length ();
8081 selection_base_ = selection_extent_;
8182}
@@ -87,27 +88,32 @@ void TextInputModel::AddText(const std::string& text) {
8788}
8889
8990bool TextInputModel::Backspace () {
91+ // If there's a selection, delete it.
9092 if (selection_base_ != selection_extent_) {
9193 DeleteSelected ();
9294 return true ;
9395 }
94- if (selection_base_ != text_.begin ()) {
95- int count = IsTrailingSurrogate (*(selection_base_ - 1 )) ? 2 : 1 ;
96- selection_base_ = text_.erase (selection_base_ - count, selection_base_);
96+ // There's no selection; delete the preceding codepoint.
97+ if (selection_base_ != 0 ) {
98+ int count = IsTrailingSurrogate (text_.at (selection_base_ - 1 )) ? 2 : 1 ;
99+ text_.erase (selection_base_ - count, count);
100+ selection_base_ -= count;
97101 selection_extent_ = selection_base_;
98102 return true ;
99103 }
100- return false ; // No edits happened.
104+ return false ;
101105}
102106
103107bool TextInputModel::Delete () {
108+ // If there's a selection, delete it.
104109 if (selection_base_ != selection_extent_) {
105110 DeleteSelected ();
106111 return true ;
107112 }
108- if (selection_base_ != text_.end ()) {
109- int count = IsLeadingSurrogate (*selection_base_) ? 2 : 1 ;
110- selection_base_ = text_.erase (selection_base_, selection_base_ + count);
113+ // There's no selection; delete the following codepoint.
114+ if (selection_base_ != text_.length ()) {
115+ int count = IsLeadingSurrogate (text_.at (selection_base_)) ? 2 : 1 ;
116+ text_.erase (selection_base_, count);
111117 selection_extent_ = selection_base_;
112118 return true ;
113119 }
@@ -120,32 +126,32 @@ bool TextInputModel::DeleteSurrounding(int offset_from_cursor, int count) {
120126 for (int i = 0 ; i < -offset_from_cursor; i++) {
121127 // If requested start is before the available text then reduce the
122128 // number of characters to delete.
123- if (start == text_. begin () ) {
129+ if (start == 0 ) {
124130 count = i;
125131 break ;
126132 }
127- start -= IsTrailingSurrogate (* (start - 1 )) ? 2 : 1 ;
133+ start -= IsTrailingSurrogate (text_. at (start - 1 )) ? 2 : 1 ;
128134 }
129135 } else {
130- for (int i = 0 ; i < offset_from_cursor && start != text_.end (); i++) {
131- start += IsLeadingSurrogate (* start) ? 2 : 1 ;
136+ for (int i = 0 ; i < offset_from_cursor && start != text_.length (); i++) {
137+ start += IsLeadingSurrogate (text_. at ( start) ) ? 2 : 1 ;
132138 }
133139 }
134140
135141 auto end = start;
136- for (int i = 0 ; i < count && end != text_.end (); i++) {
137- end += IsLeadingSurrogate (* start) ? 2 : 1 ;
142+ for (int i = 0 ; i < count && end != text_.length (); i++) {
143+ end += IsLeadingSurrogate (text_. at ( start) ) ? 2 : 1 ;
138144 }
139145
140146 if (start == end) {
141147 return false ;
142148 }
143149
144- auto new_base = text_.erase (start, end);
150+ text_.erase (start, end - start );
145151
146152 // Cursor moves only if deleted area is before it.
147153 if (offset_from_cursor <= 0 ) {
148- selection_base_ = new_base ;
154+ selection_base_ = start ;
149155 }
150156
151157 // Clear selection.
@@ -155,22 +161,21 @@ bool TextInputModel::DeleteSurrounding(int offset_from_cursor, int count) {
155161}
156162
157163bool TextInputModel::MoveCursorToBeginning () {
158- if (selection_base_ == text_. begin () && selection_extent_ == text_. begin () )
164+ if (selection_base_ == 0 && selection_extent_ == 0 )
159165 return false ;
160166
161- selection_base_ = text_.begin ();
162- selection_extent_ = text_.begin ();
163-
167+ selection_base_ = 0 ;
168+ selection_extent_ = 0 ;
164169 return true ;
165170}
166171
167172bool TextInputModel::MoveCursorToEnd () {
168- if (selection_base_ == text_.end () && selection_extent_ == text_.end ())
173+ auto max_pos = text_.length ();
174+ if (selection_base_ == max_pos && selection_extent_ == max_pos)
169175 return false ;
170176
171- selection_base_ = text_.end ();
172- selection_extent_ = text_.end ();
173-
177+ selection_base_ = max_pos;
178+ selection_extent_ = max_pos;
174179 return true ;
175180}
176181
@@ -182,8 +187,8 @@ bool TextInputModel::MoveCursorForward() {
182187 return true ;
183188 }
184189 // If not at the end, move the extent forward.
185- if (selection_extent_ != text_.end ()) {
186- int count = IsLeadingSurrogate (* selection_base_) ? 2 : 1 ;
190+ if (selection_extent_ != text_.length ()) {
191+ int count = IsLeadingSurrogate (text_. at ( selection_base_) ) ? 2 : 1 ;
187192 selection_base_ += count;
188193 selection_extent_ = selection_base_;
189194 return true ;
@@ -200,8 +205,8 @@ bool TextInputModel::MoveCursorBack() {
200205 return true ;
201206 }
202207 // If not at the start, move the beginning backward.
203- if (selection_base_ != text_. begin () ) {
204- int count = IsTrailingSurrogate (* (selection_base_ - 1 )) ? 2 : 1 ;
208+ if (selection_base_ != 0 ) {
209+ int count = IsTrailingSurrogate (text_. at (selection_base_ - 1 )) ? 2 : 1 ;
205210 selection_base_ -= count;
206211 selection_extent_ = selection_base_;
207212 return true ;
@@ -218,7 +223,7 @@ std::string TextInputModel::GetText() const {
218223int TextInputModel::GetCursorOffset () const {
219224 // Measure the length of the current text up to the cursor.
220225 // There is probably a much more efficient way of doing this.
221- auto leading_text = text_.substr (0 , selection_extent_ - text_. begin () );
226+ auto leading_text = text_.substr (0 , selection_extent_);
222227 std::wstring_convert<std::codecvt_utf8_utf16<char16_t >, char16_t >
223228 utf8_converter;
224229 return utf8_converter.to_bytes (leading_text).size ();
0 commit comments