From 9f4a3c6758a3a0b971f85c866080b98f9a4292ae Mon Sep 17 00:00:00 2001
From: "jan.nijtmans" <nijtmans@users.sourceforge.net>
Date: Sun, 27 Jan 2013 23:38:17 +0000
Subject: New experiment (ended), regarding non-shimmering "string length"

---
 generic/tclDictObj.c   |  6 ++++++
 generic/tclInt.h       |  2 ++
 generic/tclListObj.c   |  1 +
 generic/tclStringObj.c | 11 +++++++++++
 4 files changed, 20 insertions(+)

diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c
index e602c9f..c235d9d 100644
--- a/generic/tclDictObj.c
+++ b/generic/tclDictObj.c
@@ -138,6 +138,8 @@ typedef struct ChainEntry {
  */
 
 typedef struct Dict {
+    int numChars;		/* The number of chars in the string. -1 means
+				 * this value has not been calculated. */
     Tcl_HashTable table;	/* Object hash table to store mapping in. */
     ChainEntry *entryChainHead;	/* Linked list of all entries in the
 				 * dictionary. Used for doing traversal of the
@@ -388,6 +390,7 @@ DupDictInternalRep(
      * Initialise other fields.
      */
 
+    newDict->numChars = -1;
     newDict->epoch = 0;
     newDict->chain = NULL;
     newDict->refcount = 1;
@@ -709,6 +712,7 @@ SetDictFromAny(
      */
 
     TclFreeIntRep(objPtr);
+    dict->numChars = -1;
     dict->epoch = 0;
     dict->chain = NULL;
     dict->refcount = 1;
@@ -1397,6 +1401,7 @@ Tcl_NewDictObj(void)
     Tcl_InvalidateStringRep(dictPtr);
     dict = ckalloc(sizeof(Dict));
     InitChainTable(dict);
+    dict->numChars = -1;
     dict->epoch = 0;
     dict->chain = NULL;
     dict->refcount = 1;
@@ -1446,6 +1451,7 @@ Tcl_DbNewDictObj(
     Tcl_InvalidateStringRep(dictPtr);
     dict = ckalloc(sizeof(Dict));
     InitChainTable(dict);
+    dict->numChars = -1;
     dict->epoch = 0;
     dict->chain = NULL;
     dict->refcount = 1;
diff --git a/generic/tclInt.h b/generic/tclInt.h
index df1507d..74ca252 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -2406,6 +2406,8 @@ typedef enum TclEolTranslation {
  */
 
 typedef struct List {
+    int numChars;		/* The number of chars in the string. -1 means
+				 * this value has not been calculated. */
     int refCount;
     int maxElemCount;		/* Total number of element array slots. */
     int elemCount;		/* Current number of list elements. */
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index 6cbb10f..bdadaec 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -109,6 +109,7 @@ NewListIntRep(
 	return NULL;
     }
 
+    listRepPtr->numChars = -1;
     listRepPtr->canonicalFlag = 0;
     listRepPtr->refCount = 0;
     listRepPtr->maxElemCount = objc;
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
index 64c661b..040c287 100644
--- a/generic/tclStringObj.c
+++ b/generic/tclStringObj.c
@@ -483,6 +483,17 @@ Tcl_GetCharLength(
 	return length;
     }
 
+    if ((objPtr->typePtr == &tclDictType)
+           || (objPtr->typePtr == &tclListType)) {
+	List *list = objPtr->internalRep.twoPtrValue.ptr1;
+	if (list->numChars == -1) {
+	    (void) TclGetString(objPtr);
+	    TclNumUtfChars(numChars, objPtr->bytes, objPtr->length);
+	    list->numChars = numChars;
+	}
+	return list->numChars;
+    }
+
     /*
      * OK, need to work with the object as a string.
      */
-- 
cgit v0.12