Bug 1344629 - Part 2: Add nsTStringRepr as the new root of the string hierarchy. r?dbaron draft
authorDavid Major <dmajor@mozilla.com>
Tue, 14 Mar 2017 10:01:35 +1300
changeset 497903 cb4f192668cb78913114ccf55c17faa399e7ec5c
parent 497902 87c0a503fc3a430dbdb91807cb6bad01c6ba40d3
child 497904 cbd7fe1bf8ead6e217c9dcfe1d4d9f6578dd6621
push id49065
push userdmajor@mozilla.com
push dateTue, 14 Mar 2017 02:26:46 +0000
reviewersdbaron
bugs1344629
milestone55.0a1
Bug 1344629 - Part 2: Add nsTStringRepr as the new root of the string hierarchy. r?dbaron I've named it after the similar ns(C)StringRepr in the rust bindings code. This is just the minimal definition of the structure. Bulk move of methods coming in next patch. MozReview-Commit-ID: 4aQrpIWRTm7
xpcom/string/nsTSubstring.cpp
xpcom/string/nsTSubstring.h
xpcom/string/string-template-def-char.h
xpcom/string/string-template-def-unichar.h
xpcom/string/string-template-undef.h
--- a/xpcom/string/nsTSubstring.cpp
+++ b/xpcom/string/nsTSubstring.cpp
@@ -9,19 +9,17 @@
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/Printf.h"
 
 using double_conversion::DoubleToStringConverter;
 
 #ifdef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
 nsTSubstring_CharT::nsTSubstring_CharT(char_type* aData, size_type aLength,
                                        uint32_t aFlags)
-  : mData(aData),
-    mLength(aLength),
-    mFlags(aFlags)
+  : nsTStringRepr_CharT(aData, aLength, aFlags)
 {
   if (aFlags & F_OWNED) {
     STRING_STAT_INCREMENT(Adopt);
     MOZ_LOG_CTOR(mData, "StringAdopt", 1);
   }
 }
 #endif /* XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE */
 
--- a/xpcom/string/nsTSubstring.h
+++ b/xpcom/string/nsTSubstring.h
@@ -45,35 +45,79 @@ public:
   }
 
   virtual int operator()(const char_type*, const char_type*,
                          uint32_t, uint32_t) const override;
 };
 
 class nsTSubstringSplitter_CharT;
 
+namespace mozilla {
+namespace detail {
+
 /**
- * nsTSubstring is the most abstract class in the string hierarchy. It
- * represents a single contiguous array of characters, which may or may not
- * be null-terminated. This type is not instantiated directly.  A sub-class
- * is instantiated instead.  For example, see nsTString.
+ * nsTStringRepr defines a string's memory layout and some accessor methods.
+ * This class exists so that nsTLiteralString can avoid inheriting
+ * nsTSubstring's destructor. All methods on this class must be const because
+ * literal strings are not writable.
+ *
+ * This class is an implementation detail and should not be instantiated
+ * directly, nor used in any way outside of the string code itself. It is
+ * buried in a namespace to discourage its use in function parameters.
+ * If you need to take a parameter, use [const] ns[C]Substring&.
+ * If you need to instantiate a string, use ns[C]String or descendents.
+ *
+ * NAMES:
+ *   nsStringRepr for wide characters
+ *   nsCStringRepr for narrow characters
+ *
+ */
+class nsTStringRepr_CharT
+{
+public:
+  typedef CharT                               char_type;
+
+  typedef uint32_t                            size_type;
+
+protected:
+  nsTStringRepr_CharT() = delete; // Never instantiate directly
+
+  constexpr
+  nsTStringRepr_CharT(char_type* aData, size_type aLength, uint32_t aFlags)
+    : mData(aData)
+    , mLength(aLength)
+    , mFlags(aFlags)
+  {
+  }
+
+  char_type*  mData;
+  size_type   mLength;
+  uint32_t    mFlags;
+};
+
+} // namespace detail
+} // namespace mozilla
+
+/**
+ * nsTSubstring is an abstract string class. From an API perspective, this
+ * class is the root of the string class hierarchy. It represents a single
+ * contiguous array of characters, which may or may not be null-terminated.
+ * This type is not instantiated directly. A sub-class is instantiated
+ * instead. For example, see nsTString.
  *
  * NAMES:
  *   nsAString for wide characters
  *   nsACString for narrow characters
  *
- * Many of the accessors on nsTSubstring are inlined as an optimization.
  */
-class nsTSubstring_CharT
+class nsTSubstring_CharT : public mozilla::detail::nsTStringRepr_CharT
 {
 public:
   typedef mozilla::fallible_t                 fallible_t;
 
-  typedef CharT                               char_type;
-
   typedef nsCharTraits<char_type>             char_traits;
   typedef char_traits::incompatible_char_type incompatible_char_type;
 
   typedef nsTSubstring_CharT                  self_type;
   typedef self_type                           base_string_type;
 
   typedef self_type                           substring_type;
   typedef nsTSubstringTuple_CharT             substring_tuple_type;
@@ -82,17 +126,16 @@ public:
   typedef nsReadingIterator<char_type>        const_iterator;
   typedef nsWritingIterator<char_type>        iterator;
 
   typedef nsTStringComparator_CharT           comparator_type;
 
   typedef char_type*                          char_iterator;
   typedef const char_type*                    const_char_iterator;
 
-  typedef uint32_t                            size_type;
   typedef uint32_t                            index_type;
 
 public:
 
   // this acts like a virtual destructor
   ~nsTSubstring_CharT()
   {
     Finalize();
@@ -845,19 +888,17 @@ public:
 
 public:
 
   /**
    * this is public to support automatic conversion of tuple to string
    * base type, which helps avoid converting to nsTAString.
    */
   MOZ_IMPLICIT nsTSubstring_CharT(const substring_tuple_type& aTuple)
-    : mData(nullptr)
-    , mLength(0)
-    , mFlags(F_NONE)
+    : nsTStringRepr_CharT(nullptr, 0, F_NONE)
   {
     Assign(aTuple);
   }
 
   size_t SizeOfExcludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf)
   const;
   size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf)
   const;
@@ -886,50 +927,41 @@ public:
   {
     ::NS_ABORT_OOM(aLength * sizeof(char_type));
   }
 
 protected:
 
   friend class nsTSubstringTuple_CharT;
 
-  char_type*  mData;
-  size_type   mLength;
-  uint32_t    mFlags;
-
   // default initialization
   nsTSubstring_CharT()
-    : mData(char_traits::sEmptyBuffer)
-    ,  mLength(0)
-    ,  mFlags(F_TERMINATED)
+    : nsTStringRepr_CharT(char_traits::sEmptyBuffer, 0, F_TERMINATED)
   {
   }
 
   // copy-constructor, constructs as dependent on given object
   // (NOTE: this is for internal use only)
   nsTSubstring_CharT(const self_type& aStr)
-    : mData(aStr.mData)
-    ,  mLength(aStr.mLength)
-    ,  mFlags(aStr.mFlags & (F_TERMINATED | F_VOIDED))
+    : nsTStringRepr_CharT(aStr.mData, aStr.mLength,
+                          aStr.mFlags & (F_TERMINATED | F_VOIDED))
   {
   }
 
  /**
    * allows for direct initialization of a nsTSubstring object.
    */
   // XXXbz or can I just include nscore.h and use NS_BUILD_REFCNT_LOGGING?
 #if defined(DEBUG) || defined(FORCE_BUILD_REFCNT_LOGGING)
 #define XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
   nsTSubstring_CharT(char_type* aData, size_type aLength, uint32_t aFlags);
 #else
 #undef XPCOM_STRING_CONSTRUCTOR_OUT_OF_LINE
   nsTSubstring_CharT(char_type* aData, size_type aLength, uint32_t aFlags)
-    : mData(aData)
-    , mLength(aLength)
-    , mFlags(aFlags)
+    : nsTStringRepr_CharT(aData, aLength, aFlags)
   {
   }
 #endif /* DEBUG || FORCE_BUILD_REFCNT_LOGGING */
 
   /**
    * this function releases mData and does not change the value of
    * any of its member variables.  in other words, this function acts
    * like a destructor.
@@ -1089,16 +1121,21 @@ public:
   //   non-terminated substrings are always dependent.
   //
   //   F_VOIDED implies F_TERMINATED, and moreover it implies that mData
   //   points to char_traits::sEmptyBuffer.  Therefore, F_VOIDED is
   //   mutually exclusive with F_SHARED, F_OWNED, and F_FIXED.
   //
 };
 
+static_assert(sizeof(nsTSubstring_CharT) ==
+              sizeof(mozilla::detail::nsTStringRepr_CharT),
+              "Don't add new data fields to nsTSubstring_CharT. "
+              "Add to nsTStringRepr_CharT instead.");
+
 int NS_FASTCALL
 Compare(const nsTSubstring_CharT::base_string_type& aLhs,
         const nsTSubstring_CharT::base_string_type& aRhs,
         const nsTStringComparator_CharT& = nsTDefaultStringComparator_CharT());
 
 
 inline bool
 operator!=(const nsTSubstring_CharT::base_string_type& aLhs,
--- a/xpcom/string/string-template-def-char.h
+++ b/xpcom/string/string-template-def-char.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 // IWYU pragma: private, include "nsString.h"
 
 #define CharT                               char
 #define CharT_is_char                       1
 #define nsTAString_IncompatibleCharT        nsAString
 #define nsTString_CharT                     nsCString
+#define nsTStringRepr_CharT                 nsCStringRepr
 #define nsTFixedString_CharT                nsFixedCString
 #define nsTAutoString_CharT                 nsAutoCString
 #define nsTSubstring_CharT                  nsACString
 #define PrintfAppend_CharT                  PrintfAppend_nsACString
 #define nsTSubstringTuple_CharT             nsCSubstringTuple
 #define nsTStringComparator_CharT           nsCStringComparator
 #define nsTDefaultStringComparator_CharT    nsDefaultCStringComparator
 #define nsTDependentString_CharT            nsDependentCString
--- a/xpcom/string/string-template-def-unichar.h
+++ b/xpcom/string/string-template-def-unichar.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 // IWYU pragma: private, include "nsString.h"
 
 #define CharT                               char16_t
 #define CharT_is_PRUnichar                  1
 #define nsTAString_IncompatibleCharT        nsACString
 #define nsTString_CharT                     nsString
+#define nsTStringRepr_CharT                 nsStringRepr
 #define nsTFixedString_CharT                nsFixedString
 #define nsTAutoString_CharT                 nsAutoString
 #define nsTSubstring_CharT                  nsAString
 #define PrintfAppend_CharT                  PrintfAppend_nsAString
 #define nsTSubstringTuple_CharT             nsSubstringTuple
 #define nsTStringComparator_CharT           nsStringComparator
 #define nsTDefaultStringComparator_CharT    nsDefaultStringComparator
 #define nsTDependentString_CharT            nsDependentString
--- a/xpcom/string/string-template-undef.h
+++ b/xpcom/string/string-template-undef.h
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 // IWYU pragma: private, include "nsString.h"
 
 #undef CharT
 #undef CharT_is_PRUnichar
 #undef CharT_is_char
 #undef nsTAString_IncompatibleCharT
 #undef nsTString_CharT
+#undef nsTStringRepr_CharT
 #undef nsTFixedString_CharT
 #undef nsTAutoString_CharT
 #undef nsTSubstring_CharT
 #undef PrintfAppend_CharT
 #undef nsTSubstringTuple_CharT
 #undef nsTStringComparator_CharT
 #undef nsTDefaultStringComparator_CharT
 #undef nsTDependentString_CharT