Initial patch.
[vuplus_webkit] / Source / JavaScriptCore / wtf / text / TextPosition.h
index 6ddfb2c..1f0e8e5 100644 (file)
 
 namespace WTF {
 
-/*
- * Text Position
- *
- * TextPosition structure specifies coordinates within an text resource. It is used mostly
- * for saving script source position.
- *
- * Later TextPosition0 and TextPosition1 and both number types can be merged together quite easily.
- *
- * 0-based and 1-based
- *
- * Line and column numbers could be interpreted as zero-based or 1-based. Since
- * both practices coexist in WebKit source base, 'int' type should be replaced with
- * a dedicated wrapper types, so that compiler helped us with this ambiguity.
- *
- * Here we introduce 2 types of numbers: ZeroBasedNumber and OneBasedNumber and
- * 2 corresponding types of TextPosition structure. While only one type ought to be enough,
- * this is done to keep transition to the new types as transparent as possible:
- * e.g. in areas where 0-based integers are used, TextPosition0 should be introduced. This
- * way all changes will remain trackable.
- *
- * Later both number types can be merged in one type quite easily.
- *
- * For type safety and for the future type merge it is important that all operations in API
- * that accept or return integer have a name explicitly defining base of integer. For this reason
- * int-receiving constructors are hidden from API.
- */
+// An abstract number of element in a sequence. The sequence has a first element.
+// This type should be used instead of integer because 2 contradicting traditions can
+// call a first element '0' or '1' which makes integer type ambiguous.
+class OrdinalNumber {
+public:
+    static OrdinalNumber fromZeroBasedInt(int zeroBasedInt) { return OrdinalNumber(zeroBasedInt); }
+    static OrdinalNumber fromOneBasedInt(int oneBasedInt) { return OrdinalNumber(oneBasedInt - 1); }
+    OrdinalNumber() { }
+
+    int zeroBasedInt() const { return m_zeroBasedValue; }
+    int oneBasedInt() const { return m_zeroBasedValue + 1; }
 
-template<typename T>
+    bool operator==(OrdinalNumber other) { return m_zeroBasedValue == other.m_zeroBasedValue; }
+    bool operator!=(OrdinalNumber other) { return !((*this) == other); }
+
+    static OrdinalNumber first() { return OrdinalNumber(0); }
+    static OrdinalNumber beforeFirst() { return OrdinalNumber(-1); }
+
+private:
+    OrdinalNumber(int zeroBasedInt) : m_zeroBasedValue(zeroBasedInt) { }
+    int m_zeroBasedValue;
+};
+
+
+// TextPosition structure specifies coordinates within an text resource. It is used mostly
+// for saving script source position.
 class TextPosition {
 public:
-    TextPosition(T line, T column)
+    TextPosition(OrdinalNumber line, OrdinalNumber column)
         : m_line(line)
         , m_column(column)
     {
     }
-    TextPosition() {}
+    TextPosition() { }
     bool operator==(const TextPosition& other) { return m_line == other.m_line && m_column == other.m_column; }
     bool operator!=(const TextPosition& other) { return !((*this) == other); }
 
     // A 'minimum' value of position, used as a default value.
-    static TextPosition<T> minimumPosition() { return TextPosition<T>(T::base(), T::base()); }
+    static TextPosition minimumPosition() { return TextPosition(OrdinalNumber::first(), OrdinalNumber::first()); }
 
     // A value with line value less than a minimum; used as an impossible position.
-    static TextPosition<T> belowRangePosition() { return TextPosition<T>(T::belowBase(), T::belowBase()); }
+    static TextPosition belowRangePosition() { return TextPosition(OrdinalNumber::beforeFirst(), OrdinalNumber::beforeFirst()); }
 
-    T m_line;
-    T m_column;
+    OrdinalNumber m_line;
+    OrdinalNumber m_column;
 };
 
-class OneBasedNumber;
-
-// An int wrapper that always reminds you that the number should be 0-based
-class ZeroBasedNumber {
-public:
-    static ZeroBasedNumber fromZeroBasedInt(int zeroBasedInt) { return ZeroBasedNumber(zeroBasedInt); }
-
-    ZeroBasedNumber() {}
-
-    int zeroBasedInt() const { return m_value; }
-    int convertAsOneBasedInt() const { return m_value + 1; }
-    OneBasedNumber convertToOneBased() const;
-
-    bool operator==(ZeroBasedNumber other) { return m_value == other.m_value; }
-    bool operator!=(ZeroBasedNumber other) { return !((*this) == other); }
-
-    static ZeroBasedNumber base() { return 0; }
-    static ZeroBasedNumber belowBase() { return -1; }
-
-private:
-    ZeroBasedNumber(int value) : m_value(value) {}
-    int m_value;
-};
-
-// An int wrapper that always reminds you that the number should be 1-based
-class OneBasedNumber {
-public:
-    static OneBasedNumber fromOneBasedInt(int oneBasedInt) { return OneBasedNumber(oneBasedInt); }
-    OneBasedNumber() {}
-
-    int oneBasedInt() const { return m_value; }
-    int convertAsZeroBasedInt() const { return m_value - 1; }
-    ZeroBasedNumber convertToZeroBased() const { return ZeroBasedNumber::fromZeroBasedInt(m_value - 1); }
-
-    bool operator==(OneBasedNumber other) { return m_value == other.m_value; }
-    bool operator!=(OneBasedNumber other) { return !((*this) == other); }
-
-    static OneBasedNumber base() { return 1; }
-    static OneBasedNumber belowBase() { return 0; }
-
-private:
-    OneBasedNumber(int value) : m_value(value) {}
-    int m_value;
-};
-
-typedef TextPosition<ZeroBasedNumber> TextPosition0;
-typedef TextPosition<OneBasedNumber> TextPosition1;
-
-inline TextPosition0 toZeroBasedTextPosition(const TextPosition1& position)
-{
-    return TextPosition0(position.m_line.convertToZeroBased(), position.m_column.convertToZeroBased());
 }
 
-inline TextPosition1 toOneBasedTextPosition(const TextPosition0& position)
-{
-    return TextPosition1(position.m_line.convertToOneBased(), position.m_column.convertToOneBased());
-}
-
-inline OneBasedNumber ZeroBasedNumber::convertToOneBased() const
-{
-    return OneBasedNumber::fromOneBasedInt(m_value + 1);
-}
-
-}
+using WTF::OrdinalNumber;
 
-using WTF::TextPosition0;
-using WTF::TextPosition1;
+using WTF::TextPosition;
 
 #endif // TextPosition_h