Commit MetaInfo

Revision466d227e850ff97db16e8d30194a84d56c17771c (tree)
Time2017-08-18 01:39:38
Author <exeal@user...>

Log Message

Removed kernel.positions namespace and moved its members into kernel.locations.

Added kernel.locations.makePointProxy free function.

Change Summary

Incremental Difference

diff -r bff74f815a7b -r 466d227e850f ascension/ascension/kernel/document.hpp
--- a/ascension/ascension/kernel/document.hpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/ascension/kernel/document.hpp Fri Aug 18 01:39:38 2017 +0900
@@ -316,17 +316,6 @@
316316 const Region& region, const text::Newline& newline = text::Newline::USE_INTRINSIC_VALUE);
317317 /// @}
318318
319- namespace positions {
320- Index absoluteOffset(const Document& document, const Position& at, bool fromAccessibleStart);
321-// bool isOutsideOfAccessibleRegion(const Document& document, const Position& position) BOOST_NOEXCEPT;
322- bool isOutsideOfDocumentRegion(const Document& document, const Position& position) BOOST_NOEXCEPT;
323- Position shrinkToAccessibleRegion(const Document& document, const Position& position) BOOST_NOEXCEPT;
324- Region shrinkToAccessibleRegion(const Document& document, const Region& region) BOOST_NOEXCEPT;
325- Position shrinkToDocumentRegion(const Document& document, const Position& position) BOOST_NOEXCEPT;
326- Region shrinkToDocumentRegion(const Document& document, const Region& region) BOOST_NOEXCEPT;
327- Position updatePosition(const Position& position, const DocumentChange& change, Direction gravity) BOOST_NOEXCEPT;
328- } // namespace positions
329-
330319
331320 // inline implementation //////////////////////////////////////////////////////////////////////////////////////
332321
@@ -365,13 +354,6 @@
365354 return document.replace(Region::makeEmpty(at), text);
366355 }
367356
368- /// Returns @c true if the given position is outside of the document.
369- inline bool positions::isOutsideOfDocumentRegion(
370- const Document& document, const Position& position) BOOST_NOEXCEPT {
371- return line(position) >= document.numberOfLines()
372- || offsetInLine(position) > document.lineLength(line(position));
373- }
374-
375357 /**
376358 * @overload
377359 * @tparam InputIterator UTF-16 character sequence type
@@ -404,45 +386,6 @@
404386 return replace(region, boost::const_begin(text), boost::const_end(text));
405387 }
406388
407- /**
408- * Shrinks the given position into the accessible region of the document.
409- * @param document The document
410- * @param position The source position. This value can be outside of the document
411- * @return The result
412- */
413- inline Position positions::shrinkToAccessibleRegion(const Document& document, const Position& position) BOOST_NOEXCEPT {
414- if(!document.isNarrowed())
415- return shrinkToDocumentRegion(document, position);
416- const Region accessibleRegion(document.accessibleRegion());
417- if(position < *boost::const_begin(accessibleRegion))
418- return *boost::const_begin(accessibleRegion);
419- else if(position > *boost::const_end(accessibleRegion))
420- return *boost::const_end(accessibleRegion);
421- return Position(line(position), std::min(offsetInLine(position), document.lineLength(line(position))));
422- }
423-
424- /**
425- * Shrinks the given region into the accessible region of the document.
426- * @param document The document
427- * @param region The source region. This value can intersect with outside of the document
428- * @return The result. This may not be normalized
429- */
430- inline Region positions::shrinkToAccessibleRegion(const Document& document, const Region& region) BOOST_NOEXCEPT {
431- return Region(shrinkToAccessibleRegion(document, *boost::const_begin(region)), shrinkToAccessibleRegion(document, *boost::const_end(region)));
432- }
433-
434- /// Shrinks the given position into the document region.
435- inline Position positions::shrinkToDocumentRegion(const Document& document, const Position& position) BOOST_NOEXCEPT {
436- Position p(std::min(line(position), document.numberOfLines() - 1), 0);
437- p.offsetInLine = std::min(offsetInLine(position), document.lineLength(line(p)));
438- return p;
439- }
440-
441- /// Shrinks the given region into the document region. The result may not be normalized.
442- inline Region positions::shrinkToDocumentRegion(const Document& document, const Region& region) BOOST_NOEXCEPT {
443- return Region(shrinkToDocumentRegion(document, *boost::const_begin(region)), shrinkToDocumentRegion(document, *boost::const_end(region)));
444- }
445-
446389 /// Returns the bookmarker of the document.
447390 inline Bookmarker& Document::bookmarker() BOOST_NOEXCEPT {return *bookmarker_;}
448391
diff -r bff74f815a7b -r 466d227e850f ascension/ascension/kernel/locations.hpp
--- a/ascension/ascension/kernel/locations.hpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/ascension/kernel/locations.hpp Fri Aug 18 01:39:38 2017 +0900
@@ -11,25 +11,25 @@
1111 #define ASCENSION_LOCATIONS_HPP
1212 #include <ascension/direction.hpp>
1313 #include <ascension/corelib/text/code-point.hpp>
14-#include <ascension/kernel/position.hpp>
14+#include <ascension/kernel/region.hpp>
1515 #include <utility> // std.pair
1616
1717 namespace ascension {
1818 namespace kernel {
1919 class Document;
20+ class DocumentChange;
2021
2122 /**
2223 * Provides several functions related to locations in document.
23- * Many functions in this namespace take a @c std#pair&lt;const Document&amp;, const Position&amp;&gt; which
24- * describes a position in the document. @c Point and @c viewer#VisualPoint classes have conversion operators
25- * into this type.
24+ * Many functions in this namespace take a @c PointProxy which describes a position in the document. @c Point
25+ * and @c viewer#VisualPoint classes have conversion operators into this type.
2626 * @note All functions are *affected* by accessible region of the document.
2727 * @see viewer#locations
2828 */
2929 namespace locations {
3030 /// Character unit defines what is one character.
3131 enum CharacterUnit {
32- UTF16_CODE_UNIT, ///< UTF-16 code unit.
32+ UTF16_CODE_UNIT, ///< UTF-16 code unit. A surrogate pair is treated as two characters.
3333 UTF32_CODE_UNIT, ///< UTF-32 code unit. A surrogate pair is treated as one character.
3434 GRAPHEME_CLUSTER, ///< A grapheme cluster is a character.
3535 GLYPH_CLUSTER ///< A glyph is a character (not implemented).
@@ -38,21 +38,59 @@
3838 /// Describes a position in the document.
3939 typedef std::pair<const Document&, Position> PointProxy;
4040
41+ /**
42+ * Returns a @c PointProxy from the given document and position.
43+ * @param document The document
44+ * @param position The position
45+ * @return A @c PointProxy
46+ */
47+ inline PointProxy makePointProxy(const Document& document, const Position& position) BOOST_NOEXCEPT {
48+ return std::make_pair(std::ref(document), position);
49+ }
50+
51+ /// @defgroup special_locations_in_document Special Locations in Document
52+ /// @note All functions are *affected* by accessible region of the document.
53+ /// @{
4154 Position beginningOfDocument(const PointProxy& p);
4255 Position beginningOfLine(const PointProxy& p);
43- CodePoint characterAt(const PointProxy& p, bool useLineFeed = false);
4456 Position endOfDocument(const PointProxy& p);
4557 Position endOfLine(const PointProxy& p);
4658 bool isBeginningOfDocument(const PointProxy& p);
4759 bool isBeginningOfLine(const PointProxy& p);
4860 bool isEndOfDocument(const PointProxy& p);
4961 bool isEndOfLine(const PointProxy& p);
62+ /// @}
63+
64+ /// @defgroup motions_in_document Motions in Document
65+ /// @note All functions are *affected* by accessible region of the document.
66+ /// @{
5067 boost::optional<Position> nextBookmark(const PointProxy& p, Direction direction, Index marks = 1);
51- Position nextCharacter(const PointProxy& p,
52- Direction direction, CharacterUnit characterUnit, Index offset = 1);
68+ Position nextCharacter(const PointProxy& p, Direction direction, CharacterUnit characterUnit, Index offset = 1);
5369 Position nextLine(const PointProxy& p, Direction direction, Index lines = 1);
5470 Position nextWord(const PointProxy& p, Direction direction, Index words = 1);
5571 Position nextWordEnd(const PointProxy& p, Direction direction, Index words = 1);
72+ /// @}
73+
74+ /// @defgroup regions_of_document Regions of Document
75+ /// @{
76+ bool isOutsideOfDocumentRegion(const PointProxy& p) BOOST_NOEXCEPT;
77+ Position shrinkToDocumentRegion(const PointProxy& p) BOOST_NOEXCEPT;
78+ Region shrinkToDocumentRegion(const Document& document, const Region& region) BOOST_NOEXCEPT;
79+ /// @}
80+
81+ /// @defgroup accessible_regions_of_document Accessible Regions of Document
82+ /// @{
83+// bool isOutsideOfAccessibleRegion(const PointProxy& p) BOOST_NOEXCEPT;
84+ Position shrinkToAccessibleRegion(const PointProxy& p) BOOST_NOEXCEPT;
85+ Region shrinkToAccessibleRegion(const Document& document, const Region& region) BOOST_NOEXCEPT;
86+ /// @}
87+
88+ /// @defgroup miscellaneous_locational_functions Miscellaneous Locational Functions
89+ /// @{
90+ Index absoluteOffset(const PointProxy& p, bool fromAccessibleStart);
91+ CodePoint characterAt(const PointProxy& p, bool useLineFeed = false);
92+ Position updatePosition(const Position& position, const DocumentChange& change, Direction gravity) BOOST_NOEXCEPT;
93+ /// @}
5694 }
5795 }
5896 }
diff -r bff74f815a7b -r 466d227e850f ascension/src/content-assist/default-content-assistant.cpp
--- a/ascension/src/content-assist/default-content-assistant.cpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/src/content-assist/default-content-assistant.cpp Fri Aug 18 01:39:38 2017 +0900
@@ -150,7 +150,7 @@
150150 close();
151151 completionSession_->replacementRegion = kernel::Region(
152152 *boost::const_begin(completionSession_->replacementRegion),
153- kernel::positions::updatePosition(*boost::const_end(completionSession_->replacementRegion), change, Direction::forward()));
153+ kernel::locations::updatePosition(*boost::const_end(completionSession_->replacementRegion), change, Direction::forward()));
154154 if(!boost::empty(change.insertedRegion()) && !encompasses(replacementRegion, change.insertedRegion()))
155155 close();
156156
diff -r bff74f815a7b -r 466d227e850f ascension/src/kernel/document.cpp
--- a/ascension/src/kernel/document.cpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/src/kernel/document.cpp Fri Aug 18 01:39:38 2017 +0900
@@ -82,81 +82,6 @@
8282 return out.flush();
8383 }
8484
85-
86- // kernel.positions free functions ////////////////////////////////////////////////////////////////////////////
87-
88- /**
89- * Returns absolute character offset of the specified position from the start of the document.
90- * @param document The document
91- * @param at The position
92- * @param fromAccessibleStart
93- * @throw BadPositionException @a at is outside of @a document
94- * @throw DocumentAccessViolationException @a fromAccessibleStart is @c true and @a at is before the accessible
95- * region of @a document
96- */
97- Index positions::absoluteOffset(const Document& document, const Position& at, bool fromAccessibleStart) {
98- if(at > *boost::const_end(document.region()))
99- throw BadPositionException(at);
100- else if(fromAccessibleStart && at < *boost::const_begin(document.accessibleRegion()))
101- throw DocumentAccessViolationException();
102- Index offset = 0;
103- const Position start(*boost::const_begin(fromAccessibleStart ? document.accessibleRegion() : document.region()));
104- for(Index i = line(start); ; ++i) {
105- if(i == line(at)) {
106- offset += offsetInLine(at);
107- break;
108- } else {
109- offset += document.lineLength(i) + 1; // +1 is for a newline character
110- if(i == line(start))
111- offset -= offsetInLine(start);
112- }
113- }
114- return offset;
115- }
116-
117- /**
118- * Adapts the specified position to the document change.
119- * @param position The original position
120- * @param change The content of the document change
121- * @param gravity The gravity which determines the direction to which the position should move if a text was
122- * inserted at the position. If @c Direction#forward() is specified, the position will move to
123- * the start of the inserted text (no movement occur). Otherwise, move to the end of the
124- * inserted text
125- * @return The result position
126- */
127- Position positions::updatePosition(const Position& position, const DocumentChange& change, Direction gravity) BOOST_NOEXCEPT {
128- Position newPosition(position);
129- if(!boost::empty(change.erasedRegion())) { // deletion
130- if(position < *boost::const_end(change.erasedRegion())) { // the end is behind the current line
131- if(position <= *boost::const_begin(change.erasedRegion()))
132- return newPosition;
133- else // in the region
134- newPosition = *boost::const_begin(change.erasedRegion());
135- } else if(line(position) > line(*boost::const_end(change.erasedRegion()))) // in front of the current line
136- newPosition.line -= boost::size(change.erasedRegion().lines()) - 1;
137- else { // the end is the current line
138- if(line(position) == line(*boost::const_begin(change.erasedRegion()))) // the region is single-line
139- newPosition.offsetInLine -= offsetInLine(*boost::const_end(change.erasedRegion())) - offsetInLine(*boost::const_begin(change.erasedRegion()));
140- else { // the region is multiline
141- newPosition.line -= boost::size(change.erasedRegion().lines()) - 1;
142- newPosition.offsetInLine -= offsetInLine(*boost::const_end(change.erasedRegion())) - offsetInLine(*boost::const_begin(change.erasedRegion()));
143- }
144- }
145- }
146- if(!boost::empty(change.insertedRegion())) { // insertion
147- if(newPosition == *boost::const_begin(change.insertedRegion())) {
148- if(gravity == Direction::forward())
149- newPosition = *boost::const_end(change.insertedRegion());
150- } else if(newPosition > *boost::const_begin(change.insertedRegion())) {
151- if(line(*boost::const_begin(change.insertedRegion())) == line(newPosition))
152- newPosition.offsetInLine += offsetInLine(*boost::const_end(change.insertedRegion())) - offsetInLine(*boost::const_begin(change.insertedRegion()));
153- newPosition.line += boost::size(change.insertedRegion().lines()) - 1;
154- }
155- }
156- return newPosition;
157- }
158-
159-
16085 namespace {
16186 #ifdef _DEBUG
16287 // for Document.length_ diagnostic
diff -r bff74f815a7b -r 466d227e850f ascension/src/kernel/locations.cpp
--- a/ascension/src/kernel/locations.cpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/src/kernel/locations.cpp Fri Aug 18 01:39:38 2017 +0900
@@ -7,7 +7,6 @@
77 * @date 2016-05-22 Separated from point.cpp.
88 */
99
10-#include <ascension/corelib/numeric-range-algorithm/encompasses.hpp>
1110 #include <ascension/corelib/text/character-property.hpp> // text.ucd.BinaryProperty
1211 #include <ascension/corelib/text/grapheme-break-iterator.hpp>
1312 #include <ascension/corelib/text/word-break-iterator.hpp>
@@ -29,18 +28,49 @@
2928 inline const Position& position(const T& p) BOOST_NOEXCEPT {
3029 return std::get<1>(p);
3130 }
32- template<typename T>
33- inline Position shrinkToAccessibleRegion(const T& p) BOOST_NOEXCEPT {
34- return positions::shrinkToAccessibleRegion(document(p), position(p));
31+ inline Index line(const PointProxy& p) BOOST_NOEXCEPT {
32+ return kernel::line(position(p));
33+ }
34+ inline Index offsetInLine(const PointProxy& p) BOOST_NOEXCEPT {
35+ return kernel::offsetInLine(position(p));
3536 }
3637 template<typename T>
3738 inline void throwIfOutsideOfDocument(const T& p) {
38- if(positions::isOutsideOfDocumentRegion(document(p), position(p)))
39+ if(isOutsideOfDocumentRegion(p))
3940 throw BadPositionException(position(p));
4041 }
4142 }
4243
4344 /**
45+ * Returns absolute character offset of the specified position from the start of the document.
46+ * @param document The document
47+ * @param p The position
48+ * @param fromAccessibleStart
49+ * @throw BadPositionException @a p is outside of the document
50+ * @throw DocumentAccessViolationException @a fromAccessibleStart is @c true and @a p is before the
51+ * accessible region of the document
52+ */
53+ Index absoluteOffset(const PointProxy& p, bool fromAccessibleStart) {
54+ if(position(p) > *boost::const_end(document(p).region()))
55+ throw BadPositionException(position(p));
56+ else if(fromAccessibleStart && position(p) < *boost::const_begin(document(p).accessibleRegion()))
57+ throw DocumentAccessViolationException();
58+ Index offset = 0;
59+ const Position start(*boost::const_begin(fromAccessibleStart ? document(p).accessibleRegion() : document(p).region()));
60+ for(Index i = line(start); ; ++i) {
61+ if(i == line(p)) {
62+ offset += offsetInLine(p);
63+ break;
64+ } else {
65+ offset += document(p).lineLength(i) + 1; // +1 is for a newline character
66+ if(i == line(start))
67+ offset -= offsetInLine(start);
68+ }
69+ }
70+ return offset;
71+ }
72+
73+ /**
4474 * Returns the beginning of the accessible region of the document.
4575 * @param p The base point
4676 * @return The destination
@@ -57,7 +87,7 @@
5787 */
5888 Position beginningOfLine(const PointProxy& p) {
5989 throwIfOutsideOfDocument(p);
60- return positions::shrinkToAccessibleRegion(document(p), Position::bol(position(p)));
90+ return shrinkToAccessibleRegion(makePointProxy(document(p), Position::bol(position(p))));
6191 }
6292
6393 /**
@@ -68,10 +98,10 @@
6898 * @return The code point of the character, or @c INVALID_CODE_POINT if @a p is the end of the document
6999 */
70100 CodePoint characterAt(const PointProxy& p, bool useLineFeed /* = false */) {
71- const String& lineString = document(p).lineString(line(position(p)));
72- if(offsetInLine(position(p)) == lineString.length())
73- return (line(position(p)) == document(p).numberOfLines() - 1) ? text::INVALID_CODE_POINT : (useLineFeed ? text::LINE_FEED : text::LINE_SEPARATOR);
74- return text::utf::decodeFirst(std::begin(lineString) + offsetInLine(position(p)), std::end(lineString));
101+ const auto& lineString = document(p).lineString(line(p));
102+ if(offsetInLine(p) == lineString.length())
103+ return (line(p) == document(p).numberOfLines() - 1) ? text::INVALID_CODE_POINT : (useLineFeed ? text::LINE_FEED : text::LINE_SEPARATOR);
104+ return text::utf::decodeFirst(std::begin(lineString) + offsetInLine(p), std::end(lineString));
75105 }
76106
77107 /**
@@ -91,8 +121,8 @@
91121 */
92122 Position endOfLine(const PointProxy& p) {
93123 throwIfOutsideOfDocument(p);
94- const auto ln = line(position(p));
95- return positions::shrinkToAccessibleRegion(document(p), Position(ln, document(p).lineLength(ln)));
124+ const auto ln = line(p);
125+ return shrinkToAccessibleRegion(makePointProxy(document(p), Position(ln, document(p).lineLength(ln))));
96126 }
97127
98128 /**
@@ -130,7 +160,7 @@
130160 /**
131161 * Returns @c true if the given point is the end of the line.
132162 * @param p The point to check
133- * @return true if @a is the end of the line
163+ * @return true if @a p is the end of the line
134164 * @throw BadPositionException @a p is outside of the document
135165 */
136166 bool isEndOfLine(const PointProxy& p) {
@@ -138,6 +168,15 @@
138168 }
139169
140170 /**
171+ * Returns @c true if the given position is outside of the document.
172+ * @param p The point to check
173+ * @return true if @a p is outside of the document
174+ */
175+ bool isOutsideOfDocumentRegion(const PointProxy& p) BOOST_NOEXCEPT {
176+ return line(p) >= document(p).numberOfLines() || offsetInLine(p) > document(p).lineLength(line(p));
177+ }
178+
179+ /**
141180 * Returns the beginning of the next bookmarked line.
142181 * @param p The base point
143182 * @param direction The direction
@@ -149,7 +188,7 @@
149188 */
150189 boost::optional<Position> nextBookmark(const PointProxy& p, Direction direction, Index marks /* = 1 */) {
151190 throwIfOutsideOfDocument(p);
152- const auto temp(document(p).bookmarker().next(line(position(p)), direction, true, marks));
191+ const auto temp(document(p).bookmarker().next(line(p), direction, true, marks));
153192 if(temp != boost::none) {
154193 const auto bookmark = boost::get(temp);
155194 const auto accessibleRegion(document(p).accessibleRegion());
@@ -207,8 +246,7 @@
207246 while(i.hasPrevious() && offset-- > 0) --i;
208247 return i.tell();
209248 } else if(characterUnit == locations::GRAPHEME_CLUSTER) {
210- text::GraphemeBreakIterator<DocumentCharacterIterator> i(
211- DocumentCharacterIterator(document(p), document(p).accessibleRegion(), position(p)));
249+ text::GraphemeBreakIterator<DocumentCharacterIterator> i(DocumentCharacterIterator(document(p), document(p).accessibleRegion(), position(p)));
212250 i.next((direction == Direction::forward()) ? offset : -static_cast<SignedIndex>(offset));
213251 return i.base().tell();
214252 } else if(characterUnit == locations::GLYPH_CLUSTER) {
@@ -283,6 +321,100 @@
283321 Position nextWordEnd(const PointProxy& p, Direction direction, Index words /* = 1 */) {
284322 return nextWord(p, direction, words, text::WordBreakIteratorBase::END_OF_SEGMENT);
285323 }
324+
325+ /**
326+ * Shrinks the given position into the accessible region of the document.
327+ * @param p The source position. This value can be outside of the document
328+ * @return The result
329+ */
330+ Position shrinkToAccessibleRegion(const PointProxy& p) BOOST_NOEXCEPT {
331+ if(!document(p).isNarrowed())
332+ return shrinkToDocumentRegion(p);
333+ const auto accessibleRegion(document(p).accessibleRegion());
334+ if(position(p) < *boost::const_begin(accessibleRegion))
335+ return *boost::const_begin(accessibleRegion);
336+ else if(position(p) > *boost::const_end(accessibleRegion))
337+ return *boost::const_end(accessibleRegion);
338+ return Position(line(p), std::min(offsetInLine(p), document(p).lineLength(line(p))));
339+ }
340+
341+ /**
342+ * Shrinks the given region into the accessible region of the document.
343+ * @param document The document
344+ * @param region The source region. This value can intersect with outside of the document
345+ * @return The result. This may not be normalized
346+ */
347+ Region shrinkToAccessibleRegion(const Document& document, const Region& region) BOOST_NOEXCEPT {
348+ return Region(
349+ shrinkToAccessibleRegion(makePointProxy(document, *boost::const_begin(region))),
350+ shrinkToAccessibleRegion(makePointProxy(document, *boost::const_end(region))));
351+ }
352+
353+ /**
354+ * Shrinks the given position into the document region.
355+ * @param p The position
356+ * @return The result
357+ */
358+ Position shrinkToDocumentRegion(const PointProxy& p) BOOST_NOEXCEPT {
359+ Position q(std::min(line(p), document(p).numberOfLines() - 1), 0);
360+ q.offsetInLine = std::min(offsetInLine(q), document(p).lineLength(line(q)));
361+ return q;
362+ }
363+
364+ /**
365+ * Shrinks the given region into the document region. The result may not be normalized.
366+ * @param document The document
367+ * @param region The region to shrink
368+ * @return The result
369+ */
370+ Region shrinkToDocumentRegion(const Document& document, const Region& region) BOOST_NOEXCEPT {
371+ return Region(
372+ shrinkToDocumentRegion(makePointProxy(document, *boost::const_begin(region))),
373+ shrinkToDocumentRegion(makePointProxy(document, *boost::const_end(region))));
374+ }
375+
376+ /**
377+ * Adapts the specified position to the document change.
378+ * @param position The original position
379+ * @param change The content of the document change
380+ * @param gravity The gravity which determines the direction to which the position should move if a text
381+ * was inserted at the position. If @c Direction#forward() is specified, the position will
382+ * move to the start of the inserted text (no movement occur). Otherwise, move to the end of
383+ * the inserted text
384+ * @return The result position
385+ */
386+ Position updatePosition(const Position& position, const DocumentChange& change, Direction gravity) BOOST_NOEXCEPT {
387+ Position newPosition(position);
388+ if(!boost::empty(change.erasedRegion())) { // deletion
389+ if(position < *boost::const_end(change.erasedRegion())) { // the end is behind the current line
390+ if(position <= *boost::const_begin(change.erasedRegion()))
391+ return newPosition;
392+ else // in the region
393+ newPosition = *boost::const_begin(change.erasedRegion());
394+ }
395+ else if(line(position) > line(*boost::const_end(change.erasedRegion()))) // in front of the current line
396+ newPosition.line -= boost::size(change.erasedRegion().lines()) - 1;
397+ else { // the end is the current line
398+ if(line(position) == line(*boost::const_begin(change.erasedRegion()))) // the region is single-line
399+ newPosition.offsetInLine -= offsetInLine(*boost::const_end(change.erasedRegion())) - offsetInLine(*boost::const_begin(change.erasedRegion()));
400+ else { // the region is multiline
401+ newPosition.line -= boost::size(change.erasedRegion().lines()) - 1;
402+ newPosition.offsetInLine -= offsetInLine(*boost::const_end(change.erasedRegion())) - offsetInLine(*boost::const_begin(change.erasedRegion()));
403+ }
404+ }
405+ }
406+ if(!boost::empty(change.insertedRegion())) { // insertion
407+ if(newPosition == *boost::const_begin(change.insertedRegion())) {
408+ if(gravity == Direction::forward())
409+ newPosition = *boost::const_end(change.insertedRegion());
410+ } else if(newPosition > *boost::const_begin(change.insertedRegion())) {
411+ if(line(*boost::const_begin(change.insertedRegion())) == line(newPosition))
412+ newPosition.offsetInLine += offsetInLine(*boost::const_end(change.insertedRegion())) - offsetInLine(*boost::const_begin(change.insertedRegion()));
413+ newPosition.line += boost::size(change.insertedRegion().lines()) - 1;
414+ }
415+ }
416+ return newPosition;
417+ }
286418 }
287419 }
288420 }
diff -r bff74f815a7b -r 466d227e850f ascension/src/kernel/point.cpp
--- a/ascension/src/kernel/point.cpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/src/kernel/point.cpp Fri Aug 18 01:39:38 2017 +0900
@@ -9,6 +9,7 @@
99 #include <ascension/corelib/text/character-property.hpp> // text.ucd.BinaryProperty
1010 #include <ascension/kernel/document.hpp>
1111 #include <ascension/kernel/document-character-iterator.hpp>
12+#include <ascension/kernel/locations.hpp>
1213 #include <ascension/kernel/point.hpp>
1314 #include <boost/core/ignore_unused.hpp>
1415
@@ -117,7 +118,7 @@
117118 assert(!isDocumentDisposed());
118119 assert(adaptsToDocument());
119120 // normalize();
120- const Position newPosition(positions::updatePosition(position(), change, gravity()));
121+ const Position newPosition(locations::updatePosition(position(), change, gravity()));
121122 if(newPosition != position())
122123 moveTo(newPosition); // TODO: this may throw...
123124 }
@@ -146,11 +147,11 @@
146147 Point& Point::moveTo(const Position& to) {
147148 if(isDocumentDisposed())
148149 throw DocumentDisposedException();
149- else if(positions::isOutsideOfDocumentRegion(document(), to))
150+ else if(locations::isOutsideOfDocumentRegion(locations::makePointProxy(document(), to)))
150151 throw BadPositionException(to);
151152 Position destination(to);
152153 aboutToMove(destination);
153- destination = positions::shrinkToDocumentRegion(document(), destination);
154+ destination = locations::shrinkToDocumentRegion(locations::makePointProxy(document(), destination));
154155 const Position from(position());
155156 position_ = destination;
156157 moved(from);
diff -r bff74f815a7b -r 466d227e850f ascension/src/rules/lexical-partitioner.cpp
--- a/ascension/src/rules/lexical-partitioner.cpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/src/rules/lexical-partitioner.cpp Fri Aug 18 01:39:38 2017 +0900
@@ -10,6 +10,7 @@
1010 #include <ascension/corelib/utility.hpp> // detail.searchBound
1111 #include <ascension/kernel/document.hpp>
1212 #include <ascension/kernel/document-character-iterator.hpp>
13+#include <ascension/kernel/locations.hpp>
1314 #include <ascension/log.hpp>
1415 #include <ascension/rules/lexical-partitioner.hpp>
1516 #include <ascension/rules/transition-rule.hpp>
@@ -61,8 +62,8 @@
6162 if(p.start < *boost::const_begin(change.erasedRegion()))
6263 continue;
6364 else if(p.start > *boost::const_end(change.erasedRegion())) {
64- p.start = kernel::positions::updatePosition(p.start, change, Direction::forward());
65- p.tokenStart = kernel::positions::updatePosition(p.tokenStart, change, Direction::forward());
65+ p.start = kernel::locations::updatePosition(p.start, change, Direction::forward());
66+ p.tokenStart = kernel::locations::updatePosition(p.tokenStart, change, Direction::forward());
6667 } else if(((i + 1 < c) ? partitions_[i + 1]->start : *boost::const_end(doc.region())) <= *boost::const_end(change.erasedRegion())) {
6768 // this partition is encompassed with the deleted region
6869 delete partitions_[i];
@@ -83,8 +84,8 @@
8384 if(!boost::empty(change.insertedRegion())) {
8485 for(std::size_t i = 1, c = partitions_.size(); i < c; ++i) {
8586 Partition& p = *partitions_[i];
86- p.start = kernel::positions::updatePosition(p.start, change, Direction::forward());
87- p.tokenStart = kernel::positions::updatePosition(p.tokenStart, change, Direction::forward());
87+ p.start = kernel::locations::updatePosition(p.start, change, Direction::forward());
88+ p.tokenStart = kernel::locations::updatePosition(p.tokenStart, change, Direction::forward());
8889 }
8990 }
9091 verify();
diff -r bff74f815a7b -r 466d227e850f ascension/src/viewer/caret.cpp
--- a/ascension/src/viewer/caret.cpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/src/viewer/caret.cpp Fri Aug 18 01:39:38 2017 +0900
@@ -190,7 +190,7 @@
190190 /// @see VisualPoint#aboutToMove
191191 void Caret::aboutToMove(TextHit& to) {
192192 const auto ip(insertionPosition(document(), to));
193- if(kernel::positions::isOutsideOfDocumentRegion(document(), ip))
193+ if(kernel::locations::isOutsideOfDocumentRegion(kernel::locations::makePointProxy(document(), ip)))
194194 throw kernel::BadPositionException(ip, "Caret tried to move outside of document.");
195195 VisualPoint::aboutToMove(to);
196196 }
diff -r bff74f815a7b -r 466d227e850f ascension/src/viewer/visual-locations.cpp
--- a/ascension/src/viewer/visual-locations.cpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/src/viewer/visual-locations.cpp Fri Aug 18 01:39:38 2017 +0900
@@ -36,16 +36,16 @@
3636 return insertionPosition(document(p), hit(p));
3737 }
3838 inline kernel::Position normalPosition(const PointProxy& p) BOOST_NOEXCEPT {
39- return kernel::positions::shrinkToAccessibleRegion(document(p), position(p));
39+ return kernel::locations::shrinkToAccessibleRegion(kernel::locations::makePointProxy(document(p), position(p)));
4040 }
4141 inline TextHit normalHit(const PointProxy& p) BOOST_NOEXCEPT {
42- const auto np(kernel::positions::shrinkToAccessibleRegion(document(p), hit(p).characterIndex()));
43- if(np != hit(p).characterIndex() || kernel::locations::isEndOfLine(std::make_pair(std::ref(document(p)), np)))
42+ const auto np(kernel::locations::shrinkToAccessibleRegion(kernel::locations::makePointProxy(document(p), hit(p).characterIndex())));
43+ if(np != hit(p).characterIndex() || kernel::locations::isEndOfLine(kernel::locations::makePointProxy(document(p), np)))
4444 return TextHit::leading(np);
4545 return hit(p);
4646 }
4747 inline std::pair<const kernel::Document&, kernel::Position> kernelProxy(const PointProxy& p) {
48- return std::make_pair(std::ref(document(p)), position(p));
48+ return kernel::locations::makePointProxy(document(p), position(p));
4949 }
5050 inline graphics::font::TextHit<> inlineHit(const TextHit& hit) BOOST_NOEXCEPT {
5151 return graphics::font::transformTextHit(hit, [](const kernel::Position& p) {
diff -r bff74f815a7b -r 466d227e850f ascension/src/viewer/visual-point.cpp
--- a/ascension/src/viewer/visual-point.cpp Tue Aug 01 00:30:21 2017 +0900
+++ b/ascension/src/viewer/visual-point.cpp Fri Aug 18 01:39:38 2017 +0900
@@ -390,16 +390,16 @@
390390 #endif
391391 namespace {
392392 inline bool isOutsideOfDocumentRegion(const kernel::Document& document, const TextHit& hit) BOOST_NOEXCEPT {
393- return kernel::positions::isOutsideOfDocumentRegion(document, insertionPosition(document, hit));
393+ return kernel::locations::isOutsideOfDocumentRegion(kernel::locations::makePointProxy(document, insertionPosition(document, hit)));
394394 }
395395 inline TextHit shrinkToDocumentRegion(const kernel::Document& document, const TextHit& hit) BOOST_NOEXCEPT {
396396 if(kernel::line(hit.characterIndex()) >= document.numberOfLines())
397- return TextHit::leading(kernel::locations::endOfDocument(std::make_pair(std::ref(document), hit.characterIndex())));
397+ return TextHit::leading(kernel::locations::endOfDocument(kernel::locations::makePointProxy(document, hit.characterIndex())));
398398 const Index line = kernel::line(hit.characterIndex());
399399 if(kernel::offsetInLine(hit.characterIndex()) < document.lineLength(line))
400400 return hit;
401401 else
402- return TextHit::leading(kernel::locations::endOfLine(std::make_pair(std::ref(document), hit.characterIndex())));
402+ return TextHit::leading(kernel::locations::endOfLine(kernel::locations::makePointProxy(document, hit.characterIndex())));
403403 }
404404 }
405405
Show on old repository browser