ICU 73.2  73.2
edits.h
Go to the documentation of this file.
00001 // © 2016 and later: Unicode, Inc. and others.
00002 // License & terms of use: http://www.unicode.org/copyright.html
00003 
00004 // edits.h
00005 // created: 2016dec30 Markus W. Scherer
00006 
00007 #ifndef __EDITS_H__
00008 #define __EDITS_H__
00009 
00010 #include "unicode/utypes.h"
00011 
00012 #if U_SHOW_CPLUSPLUS_API
00013 
00014 #include "unicode/uobject.h"
00015 
00021 U_NAMESPACE_BEGIN
00022 
00023 class UnicodeString;
00024 
00080 class U_COMMON_API Edits final : public UMemory {
00081 public:
00086     Edits() :
00087             array(stackArray), capacity(STACK_CAPACITY), length(0), delta(0), numChanges(0),
00088             errorCode_(U_ZERO_ERROR) {}
00094     Edits(const Edits &other) :
00095             array(stackArray), capacity(STACK_CAPACITY), length(other.length),
00096             delta(other.delta), numChanges(other.numChanges),
00097             errorCode_(other.errorCode_) {
00098         copyArray(other);
00099     }
00106     Edits(Edits &&src) noexcept :
00107             array(stackArray), capacity(STACK_CAPACITY), length(src.length),
00108             delta(src.delta), numChanges(src.numChanges),
00109             errorCode_(src.errorCode_) {
00110         moveArray(src);
00111     }
00112 
00117     ~Edits();
00118 
00125     Edits &operator=(const Edits &other);
00126 
00135     Edits &operator=(Edits &&src) noexcept;
00136 
00141     void reset() noexcept;
00142 
00148     void addUnchanged(int32_t unchangedLength);
00154     void addReplace(int32_t oldLength, int32_t newLength);
00165     UBool copyErrorTo(UErrorCode &outErrorCode) const;
00166 
00172     int32_t lengthDelta() const { return delta; }
00177     UBool hasChanges() const { return numChanges != 0; }
00178 
00183     int32_t numberOfChanges() const { return numChanges; }
00184 
00203     struct U_COMMON_API Iterator final : public UMemory {
00208         Iterator() :
00209                 array(nullptr), index(0), length(0),
00210                 remaining(0), onlyChanges_(false), coarse(false),
00211                 dir(0), changed(false), oldLength_(0), newLength_(0),
00212                 srcIndex(0), replIndex(0), destIndex(0) {}
00217         Iterator(const Iterator &other) = default;
00222         Iterator &operator=(const Iterator &other) = default;
00223 
00232         UBool next(UErrorCode &errorCode) { return next(onlyChanges_, errorCode); }
00233 
00253         UBool findSourceIndex(int32_t i, UErrorCode &errorCode) {
00254             return findIndex(i, true, errorCode) == 0;
00255         }
00256 
00276         UBool findDestinationIndex(int32_t i, UErrorCode &errorCode) {
00277             return findIndex(i, false, errorCode) == 0;
00278         }
00279 
00302         int32_t destinationIndexFromSourceIndex(int32_t i, UErrorCode &errorCode);
00303 
00326         int32_t sourceIndexFromDestinationIndex(int32_t i, UErrorCode &errorCode);
00327 
00335         UBool hasChange() const { return changed; }
00336 
00343         int32_t oldLength() const { return oldLength_; }
00344 
00354         int32_t newLength() const { return newLength_; }
00355 
00363         int32_t sourceIndex() const { return srcIndex; }
00364 
00380         int32_t replacementIndex() const {
00381             // TODO: Throw an exception if we aren't in a change edit?
00382             return replIndex;
00383         }
00384 
00392         int32_t destinationIndex() const { return destIndex; }
00393 
00394 #ifndef U_HIDE_INTERNAL_API
00395 
00400         UnicodeString& toString(UnicodeString& appendTo) const;
00401 #endif  // U_HIDE_INTERNAL_API
00402 
00403     private:
00404         friend class Edits;
00405 
00406         Iterator(const uint16_t *a, int32_t len, UBool oc, UBool crs);
00407 
00408         int32_t readLength(int32_t head);
00409         void updateNextIndexes();
00410         void updatePreviousIndexes();
00411         UBool noNext();
00412         UBool next(UBool onlyChanges, UErrorCode &errorCode);
00413         UBool previous(UErrorCode &errorCode);
00415         int32_t findIndex(int32_t i, UBool findSource, UErrorCode &errorCode);
00416 
00417         const uint16_t *array;
00418         int32_t index, length;
00419         // 0 if we are not within compressed equal-length changes.
00420         // Otherwise the number of remaining changes, including the current one.
00421         int32_t remaining;
00422         UBool onlyChanges_, coarse;
00423 
00424         int8_t dir;  // iteration direction: back(<0), initial(0), forward(>0)
00425         UBool changed;
00426         int32_t oldLength_, newLength_;
00427         int32_t srcIndex, replIndex, destIndex;
00428     };
00429 
00438     Iterator getCoarseChangesIterator() const {
00439         return Iterator(array, length, true, true);
00440     }
00441 
00450     Iterator getCoarseIterator() const {
00451         return Iterator(array, length, false, true);
00452     }
00453 
00462     Iterator getFineChangesIterator() const {
00463         return Iterator(array, length, true, false);
00464     }
00465 
00473     Iterator getFineIterator() const {
00474         return Iterator(array, length, false, false);
00475     }
00476 
00504     Edits &mergeAndAppend(const Edits &ab, const Edits &bc, UErrorCode &errorCode);
00505 
00506 private:
00507     void releaseArray() noexcept;
00508     Edits &copyArray(const Edits &other);
00509     Edits &moveArray(Edits &src) noexcept;
00510 
00511     void setLastUnit(int32_t last) { array[length - 1] = (uint16_t)last; }
00512     int32_t lastUnit() const { return length > 0 ? array[length - 1] : 0xffff; }
00513 
00514     void append(int32_t r);
00515     UBool growArray();
00516 
00517     static const int32_t STACK_CAPACITY = 100;
00518     uint16_t *array;
00519     int32_t capacity;
00520     int32_t length;
00521     int32_t delta;
00522     int32_t numChanges;
00523     UErrorCode errorCode_;
00524     uint16_t stackArray[STACK_CAPACITY];
00525 };
00526 
00527 U_NAMESPACE_END
00528 
00529 #endif /* U_SHOW_CPLUSPLUS_API */
00530 
00531 #endif  // __EDITS_H__