Commit MetaInfo

Revision9c2e3f015a61142d744b79abbf00d13c6a429fc3 (tree)
Time2017-08-22 01:07:32
Author <exeal@user...>

Log Message

Introduced internal kernel.locations.detail namespace.

Change Summary

Incremental Difference

diff -r 59da0b8eadb2 -r 9c2e3f015a61 ascension/ascension/kernel/locations.hpp
--- a/ascension/ascension/kernel/locations.hpp Sun Aug 20 00:09:56 2017 +0900
+++ b/ascension/ascension/kernel/locations.hpp Tue Aug 22 01:07:32 2017 +0900
@@ -97,6 +97,11 @@
9797 CodePoint characterAt(const PointProxy& p, bool useLineFeed = false);
9898 Position updatePosition(const Position& position, const DocumentChange& change, Direction gravity) BOOST_NOEXCEPT;
9999 /// @}
100+
101+ namespace detail {
102+ Position updatePositionForDeletion(const Position& position, const Region& region, Direction gravity) BOOST_NOEXCEPT;
103+ Position updatePositionForInsertion(const Position& position, const Region& region, Direction gravity) BOOST_NOEXCEPT;
104+ }
100105 }
101106 }
102107 }
diff -r 59da0b8eadb2 -r 9c2e3f015a61 ascension/src/kernel/locations.cpp
--- a/ascension/src/kernel/locations.cpp Sun Aug 20 00:09:56 2017 +0900
+++ b/ascension/src/kernel/locations.cpp Tue Aug 22 01:07:32 2017 +0900
@@ -14,6 +14,7 @@
1414 #include <ascension/kernel/document.hpp>
1515 #include <ascension/kernel/document-character-iterator.hpp>
1616 #include <ascension/kernel/locations.hpp>
17+#include <boost/core/ignore_unused.hpp>
1718
1819
1920 namespace ascension {
@@ -287,7 +288,7 @@
287288 inline Position nextWord(const PointProxy& p, Direction direction, Index words, text::WordBreakIteratorBase::Component component) {
288289 text::WordBreakIterator<DocumentCharacterIterator> i(
289290 DocumentCharacterIterator(document(p), document(p).accessibleRegion(), position(p)),
290- component, detail::identifierSyntax(p)); // this may throw BadPositionException
291+ component, kernel::detail::identifierSyntax(p)); // this may throw BadPositionException
291292 if(direction == Direction::forward())
292293 i += words;
293294 else
@@ -379,11 +380,11 @@
379380 * <h3>Insertion</h3>
380381 * When "DEF" is inserted between "abc" and "ghi" ('|' is the position to update):
381382 * <table>
382- * <tr><th>@a gravity</th><th>Before</th><th>After</th></tr>
383- * <tr><td>Any</td><td><code>a b|c g h i</code></td><td><code>a b|c D E F g h i</code></td></tr>
384- * <tr><td>@c Direction#forward()</td><td><code>a b c|g h i</code></td><td><code>a b c D E F|g h i</code></td></tr>
385- * <tr><td>@c Direction#backward()</td><td><code>a b c|g h i</code></td><td><code>a b c|D E F< g h i</code></td></tr>
386- * <tr><td>Any</td><td><code>a b c g|h i</code></td><td><code>a b c D E F g|h i</code></td></tr>
383+ * <tr><th>Case</th><th>@a gravity</th><th>Before</th><th>After</th></tr>
384+ * <tr><td>(I-1)</td><td>Any</td><td><code>a b|c g h i</code></td><td><code>a b|c D E F g h i</code></td></tr>
385+ * <tr><td>(I-2a)</td><td>@c Direction#forward()</td><td><code>a b c|g h i</code></td><td><code>a b c D E F|g h i</code></td></tr>
386+ * <tr><td>(I-2b)</td><td>@c Direction#backward()</td><td><code>a b c|g h i</code></td><td><code>a b c|D E F g h i</code></td></tr>
387+ * <tr><td>(I-3)</td><td>Any</td><td><code>a b c g|h i</code></td><td><code>a b c D E F g|h i</code></td></tr>
387388 * </table>
388389 *
389390 * <h3>Deletion</h3>
@@ -407,35 +408,47 @@
407408 * @see viewer#locations#updateTextHit
408409 */
409410 Position updatePosition(const Position& position, const DocumentChange& change, Direction gravity) BOOST_NOEXCEPT {
410- Position newPosition(position);
411- if(!boost::empty(change.erasedRegion())) { // deletion
412- if(position < *boost::const_end(change.erasedRegion())) { // the end is behind the current line
413- if(position <= *boost::const_begin(change.erasedRegion()))
414- return newPosition;
415- else // in the region
416- newPosition = *boost::const_begin(change.erasedRegion());
417- } else if(line(position) > line(*boost::const_end(change.erasedRegion()))) // in front of the current line
418- newPosition.line -= boost::size(change.erasedRegion().lines()) - 1;
419- else { // the end is the current line
420- if(line(position) == line(*boost::const_begin(change.erasedRegion()))) // the region is single-line
421- newPosition.offsetInLine -= offsetInLine(*boost::const_end(change.erasedRegion())) - offsetInLine(*boost::const_begin(change.erasedRegion()));
422- else { // the region is multiline
423- newPosition.line -= boost::size(change.erasedRegion().lines()) - 1;
424- newPosition.offsetInLine -= offsetInLine(*boost::const_end(change.erasedRegion())) - offsetInLine(*boost::const_begin(change.erasedRegion()));
411+ return detail::updatePositionForInsertion(
412+ detail::updatePositionForDeletion(
413+ position, change.erasedRegion(), gravity), change.insertedRegion(), gravity);
414+ }
415+
416+ namespace detail {
417+ /// @internal Implements @c updatePosition function.
418+ Position updatePositionForDeletion(const Position& position, const Region& region, Direction gravity) BOOST_NOEXCEPT {
419+ boost::ignore_unused(gravity);
420+ assert(*boost::const_begin(region) <= *boost::const_end(region));
421+ Position p(position);
422+ if(!boost::empty(region)) {
423+ const auto& b = *boost::const_begin(region), e = *boost::const_end(region);
424+ if(p > b) { // !(D-1)
425+ if(p <= e) // (D-2)
426+ p = b;
427+ else { // (D-3)
428+ p.offsetInLine -= (line(position) == line(e) ? offsetInLine(e) : 0) - (line(position) == line(b) ? offsetInLine(b) : 0);
429+ p.line -= boost::size(region.lines()) - 1;
430+ }
425431 }
426432 }
433+ return p;
427434 }
428- if(!boost::empty(change.insertedRegion())) { // insertion
429- if(newPosition == *boost::const_begin(change.insertedRegion())) {
430- if(gravity == Direction::forward())
431- newPosition = *boost::const_end(change.insertedRegion());
432- } else if(newPosition > *boost::const_begin(change.insertedRegion())) {
433- if(line(*boost::const_begin(change.insertedRegion())) == line(newPosition))
434- newPosition.offsetInLine += offsetInLine(*boost::const_end(change.insertedRegion())) - offsetInLine(*boost::const_begin(change.insertedRegion()));
435- newPosition.line += boost::size(change.insertedRegion().lines()) - 1;
435+
436+ /// @internal Implements @c updatePosition function.
437+ Position updatePositionForInsertion(const Position& position, const Region& region, Direction gravity) BOOST_NOEXCEPT {
438+ assert(*boost::const_begin(region) <= *boost::const_end(region));
439+ Position p(position);
440+ if(!boost::empty(region)) {
441+ const auto& b = *boost::const_begin(region), e = *boost::const_end(region);
442+ if(gravity == Direction::forward()) // (I-2a)
443+ p = e;
444+ else if(p > b) { // (I-3) & !(I-1) & !(I-2b)
445+ if(line(p) == line(b))
446+ p.offsetInLine += offsetInLine(e) - offsetInLine(b);
447+ p.line += boost::size(region.lines()) - 1;
448+ }
436449 }
450+ return p;
437451 }
438- return newPosition;
439452 }
440453 }
441454 }
Show on old repository browser