瀏覽代碼

Merge pull request #6466 from ghalliday/issue12290

HPCC-12290 Reimplement jarray using templates

Reviewed-By: Jake Smith <jake.smith@lexisnexis.com>
Reviewed-By: Richard Chapman <rchapman@hpccsystems.com>
Richard Chapman 10 年之前
父節點
當前提交
ae93c0d76f
共有 100 個文件被更改,包括 609 次插入390 次删除
  1. 2 2
      common/deftype/deftype.cpp
  2. 1 1
      common/deftype/deftype.hpp
  3. 1 1
      common/deftype/deftype.ipp
  4. 1 1
      common/dllserver/dllserver.cpp
  5. 1 1
      common/environment/environment.cpp
  6. 2 2
      common/fileview2/fvrelate.cpp
  7. 4 4
      common/fileview2/fvrelate.ipp
  8. 1 1
      common/fileview2/fvsource.ipp
  9. 3 3
      common/remote/rmtfile.cpp
  10. 2 2
      common/roxiecommlib/roxiecommunicationclient.cpp
  11. 1 1
      common/thorhelper/roxiedebug.cpp
  12. 2 6
      common/thorhelper/thorralgo.ipp
  13. 8 8
      common/thorhelper/thorrparse.cpp
  14. 1 1
      common/thorhelper/thorrparse.hpp
  15. 2 2
      common/thorhelper/thorsoapcall.cpp
  16. 1 1
      common/thorhelper/thorstep2.cpp
  17. 1 1
      common/thorhelper/thorstep2.ipp
  18. 1 1
      common/thorhelper/thortalgo.cpp
  19. 1 1
      common/thorhelper/thortparse.cpp
  20. 2 2
      common/thorhelper/thorxmlread.cpp
  21. 1 1
      common/workunit/pkgimpl.hpp
  22. 2 2
      common/workunit/workflow.cpp
  23. 2 2
      common/workunit/workunit.cpp
  24. 1 1
      dali/base/daaudit.cpp
  25. 3 3
      dali/base/dadfs.cpp
  26. 1 1
      dali/base/dafdesc.cpp
  27. 5 5
      dali/base/dasds.cpp
  28. 1 1
      dali/base/dasess.cpp
  29. 3 3
      dali/dafilesrv/dafscontrol.cpp
  30. 1 1
      dali/daliadmin/daliadmin.cpp
  31. 3 3
      dali/datest/datest.cpp
  32. 2 2
      dali/dfu/dfuwu.cpp
  33. 3 3
      dali/dfuXRefLib/dfuxreflib.cpp
  34. 1 1
      dali/ft/daftdir.cpp
  35. 1 1
      dali/ft/filecopy.cpp
  36. 1 1
      dali/sasha/saarch.cpp
  37. 3 3
      dali/sasha/saverify.cpp
  38. 1 1
      dali/sasha/saxref.cpp
  39. 1 1
      ecl/ecl-bundle/ecl-bundle.cpp
  40. 1 1
      ecl/eclagent/eclagent.cpp
  41. 3 3
      ecl/eclagent/eclagent.ipp
  42. 1 1
      ecl/eclcc/eclcc.cpp
  43. 1 1
      ecl/eclplus/ListHelper.cpp
  44. 1 1
      ecl/hql/hqldesc.cpp
  45. 2 2
      ecl/hql/hqldsparam.cpp
  46. 1 1
      ecl/hql/hqlerror.cpp
  47. 1 1
      ecl/hql/hqlesp.cpp
  48. 12 23
      ecl/hql/hqlexpr.cpp
  49. 0 1
      ecl/hql/hqlexpr.hpp
  50. 1 1
      ecl/hql/hqlexpr.ipp
  51. 1 1
      ecl/hql/hqlfold.cpp
  52. 1 1
      ecl/hql/hqlgram.hpp
  53. 1 1
      ecl/hql/hqlgram.y
  54. 4 4
      ecl/hql/hqlgram2.cpp
  55. 2 2
      ecl/hql/hqlir.cpp
  56. 3 3
      ecl/hql/hqlthql.cpp
  57. 4 4
      ecl/hql/hqltrans.cpp
  58. 1 49
      ecl/hql/hqltrans.ipp
  59. 37 22
      ecl/hql/hqlutil.cpp
  60. 6 5
      ecl/hql/hqlutil.hpp
  61. 1 1
      ecl/hql/hqlxmldb.cpp
  62. 1 1
      ecl/hqlcpp/hqlcpp.ipp
  63. 7 4
      ecl/hqlcpp/hqlcppcase.cpp
  64. 2 2
      ecl/hqlcpp/hqlgraph.cpp
  65. 1 1
      ecl/hqlcpp/hqlhoist.hpp
  66. 2 2
      ecl/hqlcpp/hqlhtcpp.cpp
  67. 3 3
      ecl/hqlcpp/hqlregex.cpp
  68. 1 1
      ecl/hqlcpp/hqlregex.ipp
  69. 2 2
      ecl/hqlcpp/hqlresource.cpp
  70. 1 1
      ecl/hqlcpp/hqlresource.ipp
  71. 2 2
      ecl/hqlcpp/hqltomita.cpp
  72. 1 1
      ecl/hqlcpp/hqltomita.ipp
  73. 2 2
      ecl/hqlcpp/hqlttcpp.cpp
  74. 1 1
      ecl/hqlcpp/hqlwcpp.cpp
  75. 1 1
      ecl/hthor/hthorkey.cpp
  76. 2 2
      esp/bindings/SOAP/Platform/soaptype.hpp
  77. 1 1
      esp/platform/espp.hpp
  78. 1 1
      esp/scm/roxiecommlibscm.ecm
  79. 4 4
      esp/services/ws_smc/ws_smcService.cpp
  80. 1 1
      esp/services/ws_workunits/ws_workunitsQuerySets.cpp
  81. 1 1
      esp/services/ws_workunits/ws_workunitsService.cpp
  82. 4 4
      plugins/javaembed/javaembed.cpp
  83. 4 4
      plugins/pyembed/pyembed.cpp
  84. 4 4
      plugins/v8embed/v8embed.cpp
  85. 4 4
      roxie/ccd/ccdcontext.cpp
  86. 8 8
      roxie/ccd/ccdfile.cpp
  87. 1 1
      roxie/ccd/ccdkey.cpp
  88. 2 2
      roxie/ccd/ccdquery.hpp
  89. 2 2
      roxie/ccd/ccdserver.cpp
  90. 3 3
      roxie/ccd/ccdsnmp.cpp
  91. 1 1
      roxie/roxiemem/roxiemem.cpp
  92. 1 1
      system/hrpc/hrpcutil.cpp
  93. 2 2
      system/jhtree/jhtree.cpp
  94. 1 1
      system/jhtree/keybuild.cpp
  95. 1 1
      system/jhtree/keybuild.hpp
  96. 1 1
      system/jhtree/keydiff.cpp
  97. 0 1
      system/jlib/CMakeLists.txt
  98. 0 1
      system/jlib/jarray.cpp
  99. 374 108
      system/jlib/jarray.hpp
  100. 0 0
      system/jlib/jarray.tpp

+ 2 - 2
common/deftype/deftype.cpp

@@ -3846,7 +3846,7 @@ void XmlSchemaBuilder::endRecord(const char * name)
     attributes.pop();
     xml.append("</xs:complexType>").newline();
     xml.append("</xs:element>").newline();
-    optionalNesting = nesting.pop();
+    optionalNesting = nesting.popGet();
 }
 
 bool XmlSchemaBuilder::beginDataset(const char * name, const char * row, bool hasMixedContent, unsigned *updatePos)
@@ -3913,7 +3913,7 @@ void XmlSchemaBuilder::endDataset(const char * name, const char * row)
         xml.append("</xs:complexType>").newline();
         xml.append("</xs:element>").newline();
     }
-    optionalNesting = nesting.pop();
+    optionalNesting = nesting.popGet();
 }
 
 bool XmlSchemaBuilder::addSingleFieldDataset(const char * name, const char * childname, ITypeInfo & type)

+ 1 - 1
common/deftype/deftype.hpp

@@ -408,7 +408,7 @@ protected:
     IntArray stringSizes;
     IntArray decimalSizes;
     UnsignedArray nesting;
-    CopyArray setTypes;
+    ICopyArray setTypes;
     unsigned optionalNesting;
     bool addHeader;
 };

+ 1 - 1
common/deftype/deftype.ipp

@@ -507,7 +507,7 @@ class CEnumeratedTypeInfo : public CTypeInfo, public IEnumeratedTypeBuilder
 private:
     size32_t numValues;
     KeptHashTable valueMap;
-    Array valueList;
+    IArray valueList;
     Owned<ITypeInfo> base;
 
 public:

+ 1 - 1
common/dllserver/dllserver.cpp

@@ -348,7 +348,7 @@ IIterator * DllEntry::createLocationIterator()
 
 typedef IArrayOf<IDllLocation> LocationArray;
 
-int orderLocations(IInterface * * pLeft, IInterface * * pRight)
+int orderLocations(IInterface * const * pLeft, IInterface * const * pRight)
 {
     IDllLocation * left = (IDllLocation *)*pLeft;
     IDllLocation * right = (IDllLocation *)*pRight;

+ 1 - 1
common/environment/environment.cpp

@@ -329,7 +329,7 @@ class CEnvironmentFactory : public CInterface,
 {
 public:
     IMPLEMENT_IINTERFACE;
-    MAKEValueArray(SubscriptionId, SubscriptionIDs);
+    typedef ArrayOf<SubscriptionId> SubscriptionIDs;
     SubscriptionIDs subIDs;
     Mutex mutex;
     Owned<CSdsSubscription> subscription;

+ 2 - 2
common/fileview2/fvrelate.cpp

@@ -745,8 +745,8 @@ void ViewERdiagramVisitor::endIfBlock()
 
 void ViewERdiagramVisitor::endDataset(const char * name, const char * childname)
 {
-    activeFieldPrefix.setLength(savedFieldCounts.pop());
-    activeFieldCount = savedFieldCounts.pop();
+    activeFieldPrefix.setLength(savedFieldCounts.popGet());
+    activeFieldCount = savedFieldCounts.popGet();
 }
 
 void ViewERdiagramVisitor::endRecord(const char * name)

+ 4 - 4
common/fileview2/fvrelate.ipp

@@ -28,8 +28,8 @@ class ViewFile;
 class ViewRelation;
 typedef IArrayOf<ViewFile> ViewFileArray;
 typedef CIArrayOf<ViewRelation> ViewRelationArray;
-typedef CopyCIArrayOf<ViewFile> ViewFileCopyArray;
-typedef CopyCIArrayOf<ViewRelation> ViewRelationCopyArray;
+typedef CICopyArrayOf<ViewFile> ViewFileCopyArray;
+typedef CICopyArrayOf<ViewRelation> ViewRelationCopyArray;
 
 //---------------------------------------------------------------------------
 
@@ -178,7 +178,7 @@ public:
     CFileTreeBrowser * browser;
     unsigned maxRecursion;
     bool isEfficient;
-    CopyCIArrayOf<ViewFile> nestedFiles;
+    CICopyArrayOf<ViewFile> nestedFiles;
 };
 
 struct ViewWalkOptions : public ViewGatherOptions
@@ -293,7 +293,7 @@ protected:
     ViewRelation * relation;
     Owned<DelayedFilteredResultSetCursor> filtered;
     Owned<NotifyingResultSetCursor> notifier;
-    CopyCIArrayOf<CRelatedBrowseFile> children;
+    CICopyArrayOf<CRelatedBrowseFile> children;
 };
 
 

+ 1 - 1
common/fileview2/fvsource.ipp

@@ -330,7 +330,7 @@ protected:
     Owned<DataSourceMetaData> transformedMeta;
     HqlExprAttr transformedRecord;
     Owned<ILoadedDllEntry> loadedDll;
-    Array pluginDlls;
+    IArray pluginDlls;
     rowTransformFunction transformer;
     unsigned extraFieldsSize;
     unsigned openCount;

+ 3 - 3
common/remote/rmtfile.cpp

@@ -629,7 +629,7 @@ public:
 unsigned validateNodes(const SocketEndpointArray &eps,const char *dataDir, const char *mirrorDir, bool chkver, const char *script, unsigned scripttimeout, SocketEndpointArray &failures, UnsignedArray &failedcodes, StringArray &failedmessages, const char *filename)
 {
     // used for detecting duff nodes
-    PointerIArrayOf<ISocket> sockets;
+    IPointerArrayOf<ISocket> sockets;
     unsigned to=30*1000;
     unsigned n=eps.ordinality();    // use approx log scale (timeout is long but only for failure situation)
     while (n>1) {
@@ -649,7 +649,7 @@ unsigned validateNodes(const SocketEndpointArray &eps,const char *dataDir, const
     class casyncfor: public CAsyncFor
     {
         const SocketEndpointArray &eps;
-        const PointerIArrayOf<ISocket> &sockets;
+        const IPointerArrayOf<ISocket> &sockets;
         SocketEndpointArray &failures;
         StringArray &failedmessages;
         UnsignedArray &failedcodes;
@@ -660,7 +660,7 @@ unsigned validateNodes(const SocketEndpointArray &eps,const char *dataDir, const
         const char *script;
         unsigned scripttimeout;
 public:
-        casyncfor(const SocketEndpointArray &_eps,const PointerIArrayOf<ISocket> &_sockets,const char *_dataDir,const char *_mirrorDir,bool _chkv, const char *_script, unsigned _scripttimeout, const char *_filename,SocketEndpointArray &_failures, StringArray &_failedmessages,UnsignedArray &_failedcodes,CriticalSection &_sect)
+        casyncfor(const SocketEndpointArray &_eps,const IPointerArrayOf<ISocket> &_sockets,const char *_dataDir,const char *_mirrorDir,bool _chkv, const char *_script, unsigned _scripttimeout, const char *_filename,SocketEndpointArray &_failures, StringArray &_failedmessages,UnsignedArray &_failedcodes,CriticalSection &_sect)
             : eps(_eps), sockets(_sockets), dataDir(_dataDir), mirrorDir(_mirrorDir),
               failures(_failures), failedmessages(_failedmessages), failedcodes(_failedcodes), sect(_sect)
         { 

+ 2 - 2
common/roxiecommlib/roxiecommunicationclient.cpp

@@ -277,7 +277,7 @@ protected:
 
 public:
     IMPLEMENT_IINTERFACE;
-    CRoxieCommunicationClient(SocketEndpoint& _ep, unsigned _roxieTimeout)
+    CRoxieCommunicationClient(const SocketEndpoint& _ep, unsigned _roxieTimeout)
         :ep(_ep), roxieTimeout(_roxieTimeout)
     {
     }
@@ -535,7 +535,7 @@ public:
 
 
 
-IRoxieCommunicationClient* createRoxieCommunicationClient(SocketEndpoint &ep, unsigned roxieTimeout)
+IRoxieCommunicationClient* createRoxieCommunicationClient(const SocketEndpoint &ep, unsigned roxieTimeout)
 {
     return new CRoxieCommunicationClient(ep, roxieTimeout);
 }

+ 1 - 1
common/thorhelper/roxiedebug.cpp

@@ -212,7 +212,7 @@ void CDebugCommandHandler::doDebugCommand(IPropertyTree *query, IDebuggerContext
 
 //=======================================================================================
 
-MAKEValueArray(const RtlTypeInfo *, RtlTypeInfoArray);
+typedef ArrayOf<const RtlTypeInfo *> RtlTypeInfoArray;
 
 class SimpleFieldSearcher : public CInterface, implements IRowMatcher
 {

+ 2 - 6
common/thorhelper/thorralgo.ipp

@@ -122,11 +122,7 @@ public:
     byte flags;
 };
 
-inline ActiveStage & Array__Member2Param(ActiveStage & src)            { return src; }  
-inline void Array__Assign(ActiveStage & dest, ActiveStage & src)     { dest = src; }
-inline bool Array__Equal(const ActiveStage & m, const ActiveStage & p) { UNIMPLEMENTED; }
-
-MAKECopyArrayOf(ActiveStage, ActiveStage &, ActiveStageArray);
+typedef StructArrayOf<ActiveStage> ActiveStageArray;
 
 //---------------------------------------------------------------------------
 
@@ -189,7 +185,7 @@ public:
 
 protected:
     inline bool hasActiveStage()                            { return (curActiveStage != NotFound); }
-    inline ActiveStage & topStage()                         { return stages.item(curActiveStage); }
+    inline ActiveStage & topStage()                         { return stages.element(curActiveStage); }
 
 public:
     RegexStateCache & cache;

+ 8 - 8
common/thorhelper/thorrparse.cpp

@@ -839,8 +839,8 @@ RegexMatchAction RegexRecursivePattern::beginMatch(RegexState & state)
 
 RegexMatchAction RegexEndRecursivePattern::match(RegexState & state)
 {
-    RegexRecursivePattern & top = (RegexRecursivePattern &)state.stack.pop();
-    const void * saved = top.positionStack.pop();
+    RegexRecursivePattern & top = (RegexRecursivePattern &)state.stack.popGet();
+    const void * saved = top.positionStack.popGet();
     RegexMatchAction ret = matchNext(state);
     top.positionStack.append(saved);
     state.stack.append(top);
@@ -1502,7 +1502,7 @@ RegexMatchAction RegexDonePattern::beginMatch(RegexState & state)
 
 RegexMatchAction RegexEndNestedPattern::match(RegexState & state)
 {
-    RegexPattern & top = state.stack.pop();
+    RegexPattern & top = state.stack.popGet();
     RegexMatchAction ret = top.MATCH(state);
     state.stack.append(top);
     return ret;
@@ -1513,7 +1513,7 @@ RegexMatchAction RegexEndNestedPattern::beginMatch(RegexState & state)
 {
     ActiveStage & stage = pushStage(state);
     stage.setState(RSfinished);
-    stage.extra.nextPattern = &state.namedStack.pop();
+    stage.extra.nextPattern = &state.namedStack.popGet();
     return stage.extra.nextPattern->beginMatch(state);
 }
 
@@ -2592,7 +2592,7 @@ RegexMatchAction RegexAsciiDfaPattern::match(RegexState & state)
 
         while (potentialMatches.ordinality() > prevPotentialMatches)
         {
-            state.cur = (const byte *)potentialMatches.pop();
+            state.cur = (const byte *)potentialMatches.popGet();
             RegexMatchAction ret = matchNext(state);
             if (ret != RegexMatchBacktrack)
             {
@@ -2701,7 +2701,7 @@ RegexMatchAction RegexAsciiDfaPattern::nextAction(ActiveStage & stage, RegexStat
         {
             if (prevPotentialMatches < potentialMatches.ordinality())
             {
-                stage.followPosition = (const byte *)potentialMatches.pop();
+                stage.followPosition = (const byte *)potentialMatches.popGet();
                 stage.setMatched();
                 return RegexMatchContinue;
             }
@@ -3241,7 +3241,7 @@ ActiveStage & RegexState::pushStage()
         temp.state = RSinit;
         stages.append(temp);
     }
-    return stages.item(curActiveStage);
+    return stages.element(curActiveStage);
 }
 
 void RegexState::popStage()
@@ -3252,7 +3252,7 @@ void RegexState::popStage()
     tos.pattern->getTraceText(t);
     DBGLOG("%*s[%p]Pop %s", --patternDepth, "", tos.pattern, t.str());
 #endif
-    stages.item(curActiveStage).cleanup(*this);
+    stages.element(curActiveStage).cleanup(*this);
     curActiveStage--;
 }
 

+ 1 - 1
common/thorhelper/thorrparse.hpp

@@ -28,7 +28,7 @@ struct RegexXmlState;
 
 typedef CIArrayOf<RegexPattern> RegexPatternArray;
 typedef CIArrayOf<RegexNamed> RegexNamedArray;
-typedef CopyCIArrayOf<RegexPattern> RegexPatternCopyArray;
+typedef CICopyArrayOf<RegexPattern> RegexPatternCopyArray;
 
 
 //Used for serialization:

+ 2 - 2
common/thorhelper/thorsoapcall.cpp

@@ -1227,7 +1227,7 @@ int CWSCHelperThread::run()
                 {
                     if (master->aborted) {
                         while (inputRows.ordinality() > 0)
-                            master->rowProvider->releaseRow(inputRows.pop());
+                            master->rowProvider->releaseRow(inputRows.popGet());
                         return 0;
                     }
                     const void *r = master->rowProvider->getNextRow();
@@ -1247,7 +1247,7 @@ int CWSCHelperThread::run()
             }
 
             while (inputRows.ordinality() > 0)
-                master->rowProvider->releaseRow(inputRows.pop());
+                master->rowProvider->releaseRow(inputRows.popGet());
         }
     }
 

+ 1 - 1
common/thorhelper/thorstep2.cpp

@@ -56,7 +56,7 @@ So the latest approach is as follows:
    occasionally skips a long way (e.g. state) it will get corrected/used. 
 
   */
-int compareInitialInputOrder(CInterface * * _left, CInterface * * _right)
+int compareInitialInputOrder(CInterface * const * _left, CInterface * const * _right)
 {
     OrderedInput * left = static_cast<OrderedInput *>(*_left);
     OrderedInput * right = static_cast<OrderedInput *>(*_right);

+ 1 - 1
common/thorhelper/thorstep2.ipp

@@ -207,6 +207,6 @@ private:
 };
 
 void associateRemoteInputs(CIArrayOf<OrderedInput> & orderedInputs, unsigned numPriorityInputs);
-int compareInitialInputOrder(CInterface * * _left, CInterface * * _right);
+int compareInitialInputOrder(CInterface * const * _left, CInterface * const * _right);
 
 #endif

+ 1 - 1
common/thorhelper/thortalgo.cpp

@@ -1000,7 +1000,7 @@ StringBuffer & LRTable::trace(StringBuffer & out)
 //---------------------------------------------------------------------------
 //-- LRTableBuilder --
 
-static int compareActions(CInterface * * _left, CInterface * * _right)
+static int compareActions(CInterface * const * _left, CInterface * const * _right)
 {
     LRActionItem * left = static_cast<LRActionItem *>(*_left);
     LRActionItem * right = static_cast<LRActionItem *>(*_right);

+ 1 - 1
common/thorhelper/thortparse.cpp

@@ -981,7 +981,7 @@ TomitaResultIterator::~TomitaResultIterator()
     def->Release();
 }
 
-int compareStartPtr(CInterface * * pLeft, CInterface * * pRight)
+int compareStartPtr(CInterface * const * pLeft, CInterface * const * pRight)
 {
     //try and make it different to improve sort performance, and so results are reproducible between windows and linux, but it can't be guaranteed.
     GrammarSymbol * left = static_cast<GrammarSymbol *>(*pLeft);

+ 2 - 2
common/thorhelper/thorxmlread.cpp

@@ -1620,7 +1620,7 @@ class CXMLParse : public CInterface, implements IXMLParse
     {
         CXPath xpath;
         IXMLSelect *iXMLSelect;   // NOTE - not linked - creates circular links
-        CopyCIArrayOf<CParseStackInfo> stack, freeParseInfo;
+        CICopyArrayOf<CParseStackInfo> stack, freeParseInfo;
         IPTreeMaker *maker;
         Linked<CMarkReadBase> marking;
         Owned<COffsetNodeCreator> nodeCreator;
@@ -1679,7 +1679,7 @@ class CXMLParse : public CInterface, implements IXMLParse
             CParseStackInfo *stackInfo;
             if (freeParseInfo.ordinality())
             {
-                stackInfo = &freeParseInfo.pop();
+                stackInfo = &freeParseInfo.popGet();
                 stackInfo->reset();
             }
             else

+ 1 - 1
common/workunit/pkgimpl.hpp

@@ -500,7 +500,7 @@ public:
                 StringArray libnames, unresolvedLibs;
                 gatherLibraryNames(libnames, unresolvedLibs, *wufactory, *cw, qs);
 
-                PointerIArrayOf<IHpccPackage> libraries;
+                IPointerArrayOf<IHpccPackage> libraries;
                 ForEachItemIn(libitem, libnames)
                 {
                     const char *libname = libnames.item(libitem);

+ 2 - 2
common/workunit/workflow.cpp

@@ -945,8 +945,8 @@ void WorkflowMachine::performItem(unsigned wfid, unsigned scheduledWfid)
     currentWfid = wfid;
     currentScheduledWfid = scheduledWfid;
     process->perform(ctx, wfid);
-    scheduledWfid = wfidStack.pop();
-    currentWfid = wfidStack.pop();
+    scheduledWfid = wfidStack.popGet();
+    currentWfid = wfidStack.popGet();
     if(currentWfid)
     {
 #ifdef TRACE_WORKFLOW

+ 2 - 2
common/workunit/workunit.cpp

@@ -4907,7 +4907,7 @@ void CLocalWorkUnit::setSnapshot(const char * val)
     p->setProp("SNAPSHOT", val);
 }
 
-static int comparePropTrees(IInterface **ll, IInterface **rr)
+static int comparePropTrees(IInterface * const *ll, IInterface * const *rr)
 {
     IPropertyTree *l = (IPropertyTree *) *ll;
     IPropertyTree *r = (IPropertyTree *) *rr;
@@ -5940,7 +5940,7 @@ IWURoxieQueryInfo* CLocalWorkUnit::updateRoxieQueryInfo(const char *wuid, const
     return roxieQueryInfo.getLink();
 }
 
-static int compareResults(IInterface **ll, IInterface **rr)
+static int compareResults(IInterface * const *ll, IInterface * const *rr)
 {
     CLocalWUResult *l = (CLocalWUResult *) *ll;
     CLocalWUResult *r = (CLocalWUResult *) *rr;

+ 1 - 1
dali/base/daaudit.cpp

@@ -61,7 +61,7 @@ class CDaliAuditServer: public IDaliServer, public Thread
     CriticalSection handlemessagesect;
     StringAttr auditdir;
 
-    static int compfile(IInterface **v1, IInterface **v2) // for bAdd only
+    static int compfile(IInterface * const *v1, IInterface * const *v2) // for bAdd only
     {
         IFile *e1 = (IFile *)*v1;
         IFile *e2 = (IFile *)*v2;

+ 3 - 3
dali/base/dadfs.cpp

@@ -9287,7 +9287,7 @@ public:
                         }
                         // add remaining
                         ForEachItemIn(e, *eps) {
-                            SocketEndpoint &ep = eps->item(e);
+                            const SocketEndpoint &ep = eps->item(e);
                             StringBuffer ipStr;
                             ep.getIpText(ipStr);
                             IPropertyTree *node = createPTree();
@@ -9306,7 +9306,7 @@ public:
                         IPropertyTree *existing = root->queryPropTree(xpath.str());
                         if (existing) {
                             ForEachItemIn(e, *eps) {
-                                SocketEndpoint &ep = eps->item(e);
+                                const SocketEndpoint &ep = eps->item(e);
                                 StringBuffer ipStr;
                                 ep.getIpText(ipStr);
                                 VStringBuffer xpath("Node[@ip=\"%s\"]", ipStr.str());
@@ -11646,7 +11646,7 @@ bool CDistributedFileDirectory::publishMetaFileXML(const CDfsLogicalFileName &lo
         void Do(unsigned i)
         {
             UnsignedArray parts;
-            SocketEndpoint &ep = ips.item(i);
+            const SocketEndpoint &ep = ips.item(i);
             if (ep.isNull())
                 return;
             ForEachItemIn(j,ips) {

+ 1 - 1
dali/base/dafdesc.cpp

@@ -1583,7 +1583,7 @@ public:
         if (idx>=pending->ordinality())
             ERRLOG("IFileDescriptor setPart called after cluster finished");
         else {
-            SocketEndpoint &pep = pending->item(idx);
+            SocketEndpoint &pep = pending->element(idx);
             if (pep.isNull())
                 pep=ep;
             else

+ 5 - 5
dali/base/dasds.cpp

@@ -681,7 +681,7 @@ public:
 class CSubscriberContainer : public CSubscriberContainerBase
 {
     StringAttr xpath, fullXpath;
-    PointerIArrayOf<CQualifiers> qualifierStack;
+    IPointerArrayOf<CQualifiers> qualifierStack;
     bool sub, sendValue;
     unsigned depth;
 public:
@@ -5922,7 +5922,7 @@ void CCovenSDSManager::validateBackup()
         WARNLOG("Store backup file doesn't exist or differs, filename=%s", storeFilename.str());
 }
 
-static int uint64compare(unsigned __int64 *i1, unsigned __int64 *i2)
+static int uint64compare(unsigned __int64 const *i1, unsigned __int64 const *i2)
 {
     if (*i1==*i2) return 0;
     if (*i1<*i2) return -1;
@@ -5937,10 +5937,10 @@ public:
     unsigned __int64 num;
 };
 
-static int extNcompareFunc(CInterface **_itm1, CInterface **_itm2)
+static int extNcompareFunc(CInterface * const *_itm1, CInterface * const *_itm2)
 {
-    CLegacyFmtItem *itm1 = *(CLegacyFmtItem **)_itm1;
-    CLegacyFmtItem *itm2 = *(CLegacyFmtItem **)_itm2;
+    CLegacyFmtItem *itm1 = (CLegacyFmtItem *)*_itm1;
+    CLegacyFmtItem *itm2 = (CLegacyFmtItem *)*_itm2;
     if (itm1->num==itm2->num) return 0;
     if (itm1->num<itm2->num) return -1;
     return 1;

+ 1 - 1
dali/base/dasess.cpp

@@ -287,7 +287,7 @@ public:
     {
         if (!previousSessionIds.ordinality())
             return 0;
-        return previousSessionIds.pop();
+        return previousSessionIds.popGet();
     }
     unsigned previousSessionIdCount() const
     {

+ 3 - 3
dali/dafilesrv/dafscontrol.cpp

@@ -115,7 +115,7 @@ unsigned applyNodes(const char *grpip, ApplyMode mode, unsigned ver, bool isdali
             ep.port = getDaliServixPort();
         eps.append(ep);
     }
-    PointerIArrayOf<ISocket> sockets;
+    IPointerArrayOf<ISocket> sockets;
     unsigned to=10*1000;
     unsigned n=eps.ordinality();    // use approx log scale (timeout is long but only for failure situation)
     while (n>1) {
@@ -129,14 +129,14 @@ unsigned applyNodes(const char *grpip, ApplyMode mode, unsigned ver, bool isdali
     class casyncfor: public CAsyncFor
     {
         SocketEndpointArray &eps;
-        PointerIArrayOf<ISocket> &sockets;
+        IPointerArrayOf<ISocket> &sockets;
         ApplyMode mode;
         unsigned ver;
         SocketEndpointArray &result;
         StringAttrArray &resultstr;
         CriticalSection &sect;
     public:
-        casyncfor(ApplyMode _mode, unsigned _ver,SocketEndpointArray &_eps,PointerIArrayOf<ISocket> &_sockets,SocketEndpointArray &_result, StringAttrArray &_resultstr,CriticalSection &_sect) 
+        casyncfor(ApplyMode _mode, unsigned _ver,SocketEndpointArray &_eps,IPointerArrayOf<ISocket> &_sockets,SocketEndpointArray &_result, StringAttrArray &_resultstr,CriticalSection &_sect) 
             : eps(_eps), sockets(_sockets), result(_result), resultstr(_resultstr), sect(_sect)
         { 
             mode = _mode;

+ 1 - 1
dali/daliadmin/daliadmin.cpp

@@ -2098,7 +2098,7 @@ class CXMLSizesParser : public CInterface
         unsigned limit;
         __int64 totalSize;
 
-        static int _sortF(CInterface **_left, CInterface **_right)
+        static int _sortF(CInterface * const *_left, CInterface * const *_right)
         {
             CTreeItem **left = (CTreeItem **)_left;
             CTreeItem **right = (CTreeItem **)_right;

+ 3 - 3
dali/datest/datest.cpp

@@ -666,7 +666,7 @@ void Test_MultiFile()
             unsigned nc = rmfn.ordinality();
             StringBuffer rfns;
             for (unsigned j=0;j<nc;j++) {
-                RemoteFilename &rfn = rmfn.item(j);
+                const RemoteFilename &rfn = rmfn.item(j);
                 printf("  Component %d %s%s\n",j,rfn.getRemotePath(rfns.clear()).str(),
                                               rmfn.isWild(j)?", WILD":"");
             }
@@ -675,7 +675,7 @@ void Test_MultiFile()
                     rmfn.expandWild();
                     nc = rmfn.ordinality();
                     for (unsigned k=0;k<nc;k++) {
-                        RemoteFilename &rfn = rmfn.item(k);
+                        const RemoteFilename &rfn = rmfn.item(k);
                         printf("  Resolved %d %s\n",k,rfn.getRemotePath(rfns.clear()).str());
                         assertex(!rmfn.isWild(k));
                     }
@@ -2860,7 +2860,7 @@ void testMultiConnect()
         }
     } notify;
     unsigned t = msTick();
-    PointerIArrayOf<ISocket> out;
+    IPointerArrayOf<ISocket> out;
     multiConnect(eps,notify,5000);
     printf("connect took %d\n",msTick()-t);
 }

+ 2 - 2
dali/dfu/dfuwu.cpp

@@ -1226,7 +1226,7 @@ public:
         StringBuffer path;
         StringBuffer dir;
         ForEachItemIn(i1,rmfn) {
-            RemoteFilename &rfn = rmfn.item(i1);
+            const RemoteFilename &rfn = rmfn.item(i1);
             rfn.getLocalPath(path.clear());
             const char *s=path.str();
             size32_t dirlen = 0;
@@ -1265,7 +1265,7 @@ public:
         setDirectory(dir.str());
         StringBuffer mask;
         ForEachItemIn(i2,rmfn) {                    // now set mask
-            RemoteFilename &rfn = rmfn.item(i2);
+            const RemoteFilename &rfn = rmfn.item(i2);
             rfn.getLocalPath(path.clear());
             const char *s=path.str()+dir.length();
             if (isPathSepChar(*s)&&dir.length())

+ 3 - 3
dali/dfuXRefLib/dfuxreflib.cpp

@@ -1094,7 +1094,7 @@ public:
         ForEachItemIn(i2,epa) {
             if (i2)
                 out.append(", ");
-            SocketEndpoint &item = epa.item(sorted[i2]);
+            const SocketEndpoint &item = epa.item(sorted[i2]);
             StringBuffer cur;
             item.getUrlStr(cur);
             const char *s1 = prefix.str();
@@ -1512,7 +1512,7 @@ void loadFromDFS(CXRefManagerBase &manager,IGroup *grp,unsigned numdirs,const ch
                     SocketEndpoint nullep;
                     while (partno>=epa.ordinality())
                         epa.append(nullep);
-                    epa.item(partno) = ep;
+                    epa.element(partno) = ep;
                 }
             }
             else {
@@ -2469,7 +2469,7 @@ class CXRefManager: public CXRefManagerBase
         }
     }
 
-    static int compareDirectory(CInterface **le, CInterface **re)
+    static int compareDirectory(CInterface * const *le, CInterface * const *re)
     {
         const CDfuDirEntry *l = (const CDfuDirEntry *)*le;
         const CDfuDirEntry *r = (const CDfuDirEntry *)*re;

+ 1 - 1
dali/ft/daftdir.cpp

@@ -159,7 +159,7 @@ bool DirectoryBuilder::walkDirectory(const char * path, IPropertyTree * director
         fullname.append(PATHSEPCHAR);
     search.append(fullname).append(wildcard);
 
-    Array pending;
+    IArray pending;
     bool empty = true;
 
     checkForRemoteAbort(masterSocket);

+ 1 - 1
dali/ft/filecopy.cpp

@@ -2381,7 +2381,7 @@ void FileSprayer::setSource(IFileDescriptor * source, unsigned copy, unsigned mi
 
             ForEachItemIn(i, multi)
             {
-                RemoteFilename &rfn = multi.item(i);
+                const RemoteFilename &rfn = multi.item(i);
                 FilePartInfo & next = * new FilePartInfo(rfn);
                 Owned<IPartDescriptor> part = source->getPart(idx);
                 next.extractExtra(*part);

+ 1 - 1
dali/sasha/saarch.cpp

@@ -432,7 +432,7 @@ public:
 
     virtual IBranchItem *createBranchItem(IPropertyTree &e) = 0;
 
-    static int compareBranch(IInterface **v1, IInterface **v2) // for bAdd only
+    static int compareBranch(IInterface * const *v1, IInterface * const *v2) // for bAdd only
     {
         IBranchItem *e1 = (IBranchItem *)*v1;
         IBranchItem *e2 = (IBranchItem *)*v2;

+ 3 - 3
dali/sasha/saverify.cpp

@@ -498,19 +498,19 @@ public:
     {
         if (eps.ordinality()==0)
             return;
-        PointerIArrayOf<ISocket> sockets;
+        IPointerArrayOf<ISocket> sockets;
         multiConnect(eps,sockets,60*1000);
         CriticalSection sect;
         unsigned failurelimit = 10;             // only report 10 from each cluster
         class casyncfor: public CAsyncFor
         {
             SocketEndpointArray &eps;
-            PointerIArrayOf<ISocket> &sockets;
+            IPointerArrayOf<ISocket> &sockets;
             CriticalSection &sect;
             unsigned &failurelimit;
             const char *clustername;
         public:
-            casyncfor(SocketEndpointArray &_eps,PointerIArrayOf<ISocket> &_sockets, CriticalSection &_sect, unsigned &_failurelimit,const char *_clustername) 
+            casyncfor(SocketEndpointArray &_eps,IPointerArrayOf<ISocket> &_sockets, CriticalSection &_sect, unsigned &_failurelimit,const char *_clustername) 
                 : eps(_eps), sockets(_sockets), sect(_sect), failurelimit(_failurelimit)
             { 
                 clustername = _clustername;

+ 1 - 1
dali/sasha/saxref.cpp

@@ -1455,7 +1455,7 @@ public:
         basedir.setLength(bds);
     }
 
-    static int compareDirs(IInterface **t1,IInterface **t2)
+    static int compareDirs(IInterface * const *t1,IInterface * const *t2)
     {
         IPropertyTree *pt1 = *(IPropertyTree **)t1;
         IPropertyTree *pt2 = *(IPropertyTree **)t2;

+ 1 - 1
ecl/ecl-bundle/ecl-bundle.cpp

@@ -863,7 +863,7 @@ public:
     }
 
 private:
-    static int compareBundleSets(IInterface **a, IInterface **b)
+    static int compareBundleSets(IInterface * const *a, IInterface * const *b)
     {
         IBundleInfoSet *aa = (IBundleInfoSet *) *a;
         IBundleInfoSet *bb = (IBundleInfoSet *) *b;

+ 1 - 1
ecl/eclagent/eclagent.cpp

@@ -2677,7 +2677,7 @@ void EclAgent::checkPersistMatches(const char * logicalName, unsigned eclCRC)
     logException(ExceptionSeverityInformation, 0, msg.str(), false);
 }
 
-static int comparePersistAccess(IInterface **_a, IInterface **_b)
+static int comparePersistAccess(IInterface * const *_a, IInterface * const *_b)
 {
     IPropertyTree *a = *(IPropertyTree **)_a;
     IPropertyTree *b = *(IPropertyTree **)_b;

+ 3 - 3
ecl/eclagent/eclagent.ipp

@@ -355,7 +355,7 @@ private:
     mutable CriticalSection wusect;
     StringArray tempFiles;
     CriticalSection tfsect;
-    Array persistReadLocks;
+    IArray persistReadLocks;
     StringArray processedPersists;
 
     Owned<ILoadedDllEntry> dll;
@@ -728,8 +728,8 @@ public:
     CIArrayOf<EclGraphElement> branches;
     UnsignedArray branchIndexes;
     EclGraphElement * conditionalLink;
-    CopyCIArrayOf<EclSubGraph> dependentOn;
-    CopyCIArrayOf<EclGraphElement> dependentOnActivity;
+    CICopyArrayOf<EclSubGraph> dependentOn;
+    CICopyArrayOf<EclGraphElement> dependentOnActivity;
     IntArray dependentControlId;
     IProbeManager * probeManager;
 

+ 1 - 1
ecl/eclcc/eclcc.cpp

@@ -2223,7 +2223,7 @@ protected:
     Semaphore & fileReady;
 };
 
-int compareFilenames(IInterface * * pleft, IInterface * * pright)
+int compareFilenames(IInterface * const * pleft, IInterface * const * pright)
 {
     IFile * left = static_cast<IFile *>(*pleft);
     IFile * right = static_cast<IFile *>(*pright);

+ 1 - 1
ecl/eclplus/ListHelper.cpp

@@ -29,7 +29,7 @@ ListHelper::~ListHelper()
 {
 }
 
-static int compareWUs(IInterface **ll, IInterface **rr)
+static int compareWUs(IInterface * const *ll, IInterface * const *rr)
 {
     IConstECLWorkunit *l = (IConstECLWorkunit *) *ll;
     IConstECLWorkunit *r = (IConstECLWorkunit *) *rr;

+ 1 - 1
ecl/hql/hqldesc.cpp

@@ -57,7 +57,7 @@ void setFullNameProp(IPropertyTree * tree, const char * prop, IHqlExpression * e
         setFullNameProp(tree, prop, expr->queryFullContainerId()->lower()->str(), expr->queryName()->str());
 }
 
-static int compareSymbolsByPosition(IInterface * * pleft, IInterface * * pright)
+static int compareSymbolsByPosition(IInterface * const * pleft, IInterface * const * pright)
 {
     IHqlExpression * left = static_cast<IHqlExpression *>(*pleft);
     IHqlExpression * right = static_cast<IHqlExpression *>(*pright);

+ 2 - 2
ecl/hql/hqldsparam.cpp

@@ -166,11 +166,11 @@ IIdAtom * HqlGram::fieldMapFrom(IHqlExpression* mapping, IIdAtom * id)
 }
 
 // either a abstract dataset 
-bool HqlGram::requireLateBind(IHqlExpression* funcdef, Array& actuals)
+bool HqlGram::requireLateBind(IHqlExpression* funcdef, const HqlExprArray& actuals)
 {
     ForEachItemIn(idx, actuals)
     {
-        IHqlExpression *actual = (IHqlExpression *) &actuals.item(idx);
+        IHqlExpression *actual = &actuals.item(idx);
         if (isAbstractDataset(actual))
             return true;
     }

+ 1 - 1
ecl/hql/hqlerror.cpp

@@ -395,7 +395,7 @@ public:
     }
 
 private:
-    Array errors;
+    IArray errors;
 };
 
 IErrorReceiver * createDedupingErrorReceiver(IErrorReceiver & prev)

+ 1 - 1
ecl/hql/hqlesp.cpp

@@ -175,7 +175,7 @@ protected:
     HqlLookupContext & lookupCtx;
     Owned<IPropertyTree> root;
     Linked<IPropertyTree> archive;
-    CopyArray visited;
+    ICopyArray visited;
     StringPairArray results;
 };
 

+ 12 - 23
ecl/hql/hqlexpr.cpp

@@ -10367,15 +10367,6 @@ extern IHqlExpression *createValueF(node_operator op, ITypeInfo *type, ...)
     return CHqlExpressionWithType::makeExpression(op, type, children);
 }
 
-extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, unsigned num, IHqlExpression * * args)
-{
-    IHqlExpression * expr = createOpenValue(op, type);
-    unsigned index;
-    for (index = 0; index < num; index++)
-        expr->addOperand(args[index]);
-    return expr->closeExpr();
-}
-
 extern HQL_API IHqlExpression * createValueFromCommaList(node_operator op, ITypeInfo * type, IHqlExpression * argsExpr)
 {
     HqlExprArray args;
@@ -10389,21 +10380,20 @@ extern HQL_API IHqlExpression * createValueFromCommaList(node_operator op, IType
 
 extern HQL_API IHqlExpression * createValueSafe(node_operator op, ITypeInfo * type, const HqlExprArray & args)
 {
-    ForEachItemIn(idx, args)
-        args.item(idx).Link();
-    HqlExprArray & castArgs = const_cast<HqlExprArray &>(args);
-    IHqlExpression * * exprList = static_cast<IHqlExpression * *>(castArgs.getArray());
-    return createValue(op, type, args.ordinality(), exprList);
+    return createValueSafe(op, type, args, 0, args.ordinality());
 }
 
 extern HQL_API IHqlExpression * createValueSafe(node_operator op, ITypeInfo * type, const HqlExprArray & args, unsigned from, unsigned max)
 {
     assertex(from <= args.ordinality() && max <= args.ordinality() && from <= max);
+    IHqlExpression * expr = createOpenValue(op, type);
     for (unsigned idx=from; idx < max; idx++)
-        args.item(idx).Link();
-    HqlExprArray & castArgs = const_cast<HqlExprArray &>(args);
-    IHqlExpression * * exprList = static_cast<IHqlExpression * *>(castArgs.getArray());
-    return createValue(op, type, max-from, exprList + from);
+    {
+        IHqlExpression & cur = args.item(idx);
+        cur.Link();
+        expr->addOperand(&cur);
+    }
+    return expr->closeExpr();
 }
 
 extern IHqlExpression *createBoolExpr(node_operator op, IHqlExpression *p1)
@@ -13308,7 +13298,6 @@ extern HQL_API IHqlExpression *doInstantEclTransformations(IHqlExpression *qquer
 
 //==============================================================================================================
 
-//MAKEValueArray(byte, ByteArray);
 typedef UnsignedArray DepthArray;
 
 struct TransformTrackingInfo
@@ -13495,19 +13484,19 @@ void TransformTrackingInfo::lock()
 
 void TransformTrackingInfo::unlock()
 {
-    unsigned transformStackLevel = transformStackMark.pop();
+    unsigned transformStackLevel = transformStackMark.popGet();
     while (transformStack.ordinality() > transformStackLevel)
     {
-        CHqlExpression * expr = (CHqlExpression *)transformStack.pop();
+        CHqlExpression * expr = (CHqlExpression *)transformStack.popGet();
         unsigned oldDepth = 0;
         IInterface * extra = NULL;
         if (curTransformDepth > 1)
         {
-            oldDepth = depthStack.pop();
+            oldDepth = depthStack.popGet();
             if (oldDepth & TRANSFORM_DEPTH_SAVE_MATCH_EXPR)
                 extra = expr;
             else if (oldDepth)
-                extra = (IInterface *)transformStack.pop();
+                extra = (IInterface *)transformStack.popGet();
         }
         expr->resetTransformExtra(extra, oldDepth);
         expr->Release();

+ 0 - 1
ecl/hql/hqlexpr.hpp

@@ -1224,7 +1224,6 @@ extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, I
 extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, IHqlExpression *p1, IHqlExpression *p2, IHqlExpression *p3);
 extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, IHqlExpression *p1, IHqlExpression *p2, IHqlExpression *p3, IHqlExpression *p4);
 extern HQL_API IHqlExpression *createValueF(node_operator op, ITypeInfo * type, ...);
-extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, unsigned num, IHqlExpression * * args);
 extern HQL_API IHqlExpression *createValue(node_operator op, ITypeInfo * type, HqlExprArray & args);        //NB: This deletes the array that is passed
 extern HQL_API IHqlExpression *createValueSafe(node_operator op, ITypeInfo * type, const HqlExprArray & args);
 extern HQL_API IHqlExpression *createValueSafe(node_operator op, ITypeInfo * type, const HqlExprArray & args, unsigned from, unsigned max);

+ 1 - 1
ecl/hql/hqlexpr.ipp

@@ -1224,7 +1224,7 @@ protected:
 class CHqlMultiParentScope : public CHqlScope
 {
 protected:
-    CopyArray parents;
+    ICopyArray parents;
 
 public:
     CHqlMultiParentScope(IIdAtom *, ...);

+ 1 - 1
ecl/hql/hqlfold.cpp

@@ -2966,7 +2966,7 @@ IHqlExpression * foldConstantOperator(IHqlExpression * expr, unsigned foldOption
             {
                 //Transform this map to a case - it will be much more efficient.
                 HqlExprArray args2;
-                CopyArray alreadyDone;
+                ICopyArray alreadyDone;
                 args2.append(*LINK(allTestField));
                 ForEachItemIn(i, args)
                 {

+ 1 - 1
ecl/hql/hqlgram.hpp

@@ -762,7 +762,7 @@ protected:
     bool isAborting() { return errorDisabled; }
     IIdAtom * fieldMapTo(IHqlExpression* expr, IIdAtom * name);
     IIdAtom * fieldMapFrom(IHqlExpression* expr, IIdAtom * name);
-    bool requireLateBind(IHqlExpression* funcdef, Array& actuals);
+    bool requireLateBind(IHqlExpression* funcdef, const HqlExprArray & actuals);
     IHqlExpression* createDefJoinTransform(IHqlExpression* left,IHqlExpression* right,attribute& errpos, IHqlExpression * seq, IHqlExpression * flags);
     IHqlExpression * createRowAssignTransform(const attribute & srcAttr, const attribute & tgtAttr, const attribute & seqAttr);
     IHqlExpression * createClearTransform(IHqlExpression * record, const attribute & errpos);

+ 1 - 1
ecl/hql/hqlgram.y

@@ -12061,7 +12061,7 @@ beginPatternParameters
 
 endPatternParameters
     :                   {   
-                            parser->current_type = (ITypeInfo *)parser->savedType.pop();
+                            parser->current_type = (ITypeInfo *)parser->savedType.popGet();
                             $$.clear();
                         }
     ;

+ 4 - 4
ecl/hql/hqlgram2.cpp

@@ -505,7 +505,7 @@ void HqlGram::popTopScope()
     if(topScopes.length() > 0)
     {
         topScopes.pop();
-        insideEvaluate = wasInEvaluate.pop();
+        insideEvaluate = wasInEvaluate.popGet();
     }
 }                                       
 
@@ -578,7 +578,7 @@ void HqlGram::pushRecord(IHqlExpression *newRecord)
 
 IHqlExpression* HqlGram::popRecord()
 {
-    return &activeRecords.pop();
+    return &activeRecords.popGet();
 }                                       
 
 IHqlExpression* HqlGram::endRecordDef()
@@ -2600,8 +2600,8 @@ void HqlGram::enterCompoundObject()
 
 void HqlGram::leaveCompoundObject()
 {
-    current_id = (IIdAtom *)savedIds.pop();
-    lastpos = savedLastpos.pop();
+    current_id = (IIdAtom *)savedIds.popGet();
+    lastpos = savedLastpos.popGet();
 }
 
 void HqlGram::leaveType(const YYSTYPE & errpos)

+ 2 - 2
ecl/hql/hqlir.cpp

@@ -1745,7 +1745,7 @@ protected:
     }
 
 protected:
-    Array values;
+    IArray values;
     HqlExprArray results;
 };
 
@@ -1785,7 +1785,7 @@ protected:
     id_t doProcessAnnotation(IHqlExpression * expr);
 
 protected:
-    CopyArray types;
+    ICopyArray types;
     UnsignedArray typeIds;
     unsigned seq;
 };

+ 3 - 3
ecl/hql/hqlthql.cpp

@@ -57,7 +57,7 @@ bool endsWithDotDotDot(const StringBuffer & s)
     return (memcmp(s.str() + s.length() -3, "...", 3) == 0);
 }
 
-MAKEPointerArray(HqlExprArray, HqlExprArrayArray);
+typedef CopyReferenceArrayOf<HqlExprArray> HqlExprArrayArray;
 
 class HqltHql
 {
@@ -163,7 +163,7 @@ private:
     int           curDatasetDepth;
     StringBuffer  m_definitions;
     StringBuffer  m_services;
-    Array         m_visitedAlienTypes;
+    IArray         m_visitedAlienTypes;
     bool          m_isTop;
     int           m_export_level;
     unsigned      indent;
@@ -180,7 +180,7 @@ private:
     HqlExprArrayArray m_visited_array;
     PointerArray        scope;
     HqlExprArray    mapped;
-    PointerIArray   mapSaved;
+    IPointerArray   mapSaved;
     unsigned        clashCounter;
 };
 

+ 4 - 4
ecl/hql/hqltrans.cpp

@@ -2483,12 +2483,12 @@ void NestedHqlTransformer::beginNestedScope()
 
 void NestedHqlTransformer::endNestedScope()
 {
-    unsigned prevTransforms = depthStack.pop();
-    unsigned prevSelectors = depthStack.pop();
+    unsigned prevTransforms = depthStack.popGet();
+    unsigned prevSelectors = depthStack.popGet();
 
     while (savedSelectors.ordinality() != prevSelectors)
     {
-        IHqlExpression & cur = savedSelectors.pop();
+        IHqlExpression & cur = savedSelectors.popGet();
         NewHqlTransformer::setTransformedSelector(&cur, NULL);
     }
 
@@ -2497,7 +2497,7 @@ void NestedHqlTransformer::endNestedScope()
         OwnedHqlExpr prev = &savedTransformedValue.popGet();
         if (prev == savedNull)
             prev.clear();
-        IHqlExpression & cur = savedTransformed.pop();
+        IHqlExpression & cur = savedTransformed.popGet();
         NewHqlTransformer::setTransformed(&cur, prev);
     }
 }

+ 1 - 49
ecl/hql/hqltrans.ipp

@@ -876,54 +876,6 @@ public:
     MapOwnedToOwned<IHqlExpression, IHqlExpression> map;
 };
 
-class SlowScopeMapping
-{
-public:
-    inline IHqlExpression * getValue(IHqlExpression * key)
-    {
-        if (!key)
-            return nullValue;
-        unsigned match = find(key);
-        if (match != NotFound)
-            return &values.item(match);
-        return NULL;
-    }
-    inline void setValue(IHqlExpression * key, IHqlExpression * value)
-    {
-        if (!key)
-        {
-            nullValue.set(value);
-            return;
-        }
-        unsigned match = find(key);
-        if (match == NotFound)
-        {
-            keys.append(OLINK(*key));
-            values.append(OLINK(*value));
-        }
-        else
-            values.replace(OLINK(*value), match);
-    }
-    inline unsigned find(IHqlExpression * key)
-    {
-        IHqlExpression * * head = keys.getArray();
-        unsigned max = keys.ordinality();
-        for (unsigned i=0; i < max; i++)
-            if (head[i] == key)
-                return i;
-        return NotFound;
-        for (unsigned i=0; i < max; i++)
-            if (&keys.item(i) == key)
-                return i;
-        return NotFound;
-    }
-
-public:
-    HqlExprAttr nullValue;
-    HqlExprArray keys;
-    HqlExprArray values;
-};
-
 class HQL_API MergingTransformInfo : public AMergingTransformInfo
 {
     typedef FastScopeMapping MAPPINGCLASS;
@@ -1085,7 +1037,7 @@ struct ScopeSuspendInfo
 {
     CIArrayOf<ScopeInfo> scope;
     CIArrayOf<ScopeInfo> saved;
-    PointerIArrayOf<IHqlExpression> savedI;
+    IPointerArrayOf<IHqlExpression> savedI;
 };
 
 class HQL_API ScopedTransformer : public NewHqlTransformer

+ 37 - 22
ecl/hql/hqlutil.cpp

@@ -4177,7 +4177,7 @@ IHqlExpression * getFailMessage(IHqlExpression * failExpr, bool nullIfOmitted)
     return createConstant("");
 }
 
-int compareAtoms(IInterface * * pleft, IInterface * * pright)
+int compareAtoms(IInterface * const * pleft, IInterface * const * pright)
 {
     IAtom * left = static_cast<IAtom *>(*pleft);
     IAtom * right = static_cast<IAtom *>(*pright);
@@ -4185,8 +4185,25 @@ int compareAtoms(IInterface * * pleft, IInterface * * pright)
     return stricmp(left->str(), right->str());
 }
 
+int compareScopesByName(IHqlScope * left, IHqlScope * right)
+{
+    const char * leftName = left->queryName()->str();
+    const char * rightName = right->queryName()->str();
+    if (leftName && rightName)
+        return stricmp(leftName, rightName);
+    if (leftName)
+        return +1;
+    if (rightName)
+        return -1;
+    return 0;
+}
+
+int compareSymbolsByName(IHqlExpression * left, IHqlExpression * right)
+{
+    return stricmp(left->queryName()->str(), right->queryName()->str());
+}
 
-int compareSymbolsByName(IInterface * * pleft, IInterface * * pright)
+int compareSymbolsByName(IInterface * const * pleft, IInterface * const * pright)
 {
     IHqlExpression * left = static_cast<IHqlExpression *>(*pleft);
     IHqlExpression * right = static_cast<IHqlExpression *>(*pright);
@@ -4194,20 +4211,11 @@ int compareSymbolsByName(IInterface * * pleft, IInterface * * pright)
     return stricmp(left->queryName()->str(), right->queryName()->str());
 }
 
-int compareScopesByName(IInterface * * pleft, IInterface * * pright)
+int compareScopesByName(IInterface * const * pleft, IInterface * const * pright)
 {
     IHqlScope * left = static_cast<IHqlScope *>(*pleft);
     IHqlScope * right = static_cast<IHqlScope *>(*pright);
-
-    const char * leftName = left->queryName()->str();
-    const char * rightName = right->queryName()->str();
-    if (leftName && rightName)
-        return stricmp(leftName, rightName);
-    if (leftName)
-        return +1;
-    if (rightName)
-        return -1;
-    return 0;
+    return compareScopesByName(left, right);
 }
 
 class ModuleExpander
@@ -6156,11 +6164,8 @@ void gatherIndexBuildSortOrder(HqlExprArray & sorts, IHqlExpression * expr, bool
 //------------------------- Library processing -------------------------------------
 
 
-int compareLibraryParameterOrder(IInterface * * pleft, IInterface * * pright)
+int compareLibraryParameterOrder(IHqlExpression * left, IHqlExpression * right)
 {
-    IHqlExpression * left = static_cast<IHqlExpression *>(*pleft);
-    IHqlExpression * right = static_cast<IHqlExpression *>(*pright);
-
     //datasets come first - even if not streamed
     if (left->isDataset())
     {
@@ -6190,6 +6195,12 @@ int compareLibraryParameterOrder(IInterface * * pleft, IInterface * * pright)
 }
 
 
+static int compareLibraryParameterOrder(IInterface * const * pleft, IInterface * const * pright)
+{
+    IHqlExpression * left = static_cast<IHqlExpression *>(*pleft);
+    IHqlExpression * right = static_cast<IHqlExpression *>(*pright);
+    return compareLibraryParameterOrder(left, right);
+}
 
 LibraryInputMapper::LibraryInputMapper(IHqlExpression * _libraryInterface)
 : libraryInterface(_libraryInterface)
@@ -6772,18 +6783,22 @@ StringBuffer & convertToValidLabel(StringBuffer &out, const char * in, unsigned
     return out;
 }
 
-bool arraysSame(CIArray & left, CIArray & right)
+template <class ARRAY>
+bool doArraysSame(ARRAY & left, ARRAY & right)
 {
     if (left.ordinality() != right.ordinality())
         return false;
     return memcmp(left.getArray(), right.getArray(), left.ordinality() * sizeof(CInterface*)) == 0;
 }
 
-bool arraysSame(Array & left, Array & right)
+bool arraysSame(HqlExprArray & left, HqlExprArray & right)
 {
-    if (left.ordinality() != right.ordinality())
-        return false;
-    return memcmp(left.getArray(), right.getArray(), left.ordinality() * sizeof(CInterface*)) == 0;
+    return doArraysSame(left, right);
+}
+
+bool arraysSame(HqlExprCopyArray & left, HqlExprCopyArray & right)
+{
+    return doArraysSame(left, right);
 }
 
 bool isFailAction(IHqlExpression * expr)

+ 6 - 5
ecl/hql/hqlutil.hpp

@@ -57,9 +57,9 @@ extern HQL_API IHqlExpression * queryLastNonAttribute(IHqlExpression * expr);
 extern HQL_API IHqlExpression * queryNextRecordField(IHqlExpression * recorhqlutid, unsigned & idx);
 extern HQL_API void expandRecord(HqlExprArray & selects, IHqlExpression * selector, IHqlExpression * expr);
 
-extern HQL_API int compareSymbolsByName(IInterface * * pleft, IInterface * * pright);
-extern HQL_API int compareScopesByName(IInterface * * pleft, IInterface * * pright);
-extern HQL_API int compareAtoms(IInterface * * pleft, IInterface * * pright);
+extern HQL_API int compareSymbolsByName(IInterface * const * pleft, IInterface * const * pright);
+extern HQL_API int compareScopesByName(IInterface * const * pleft, IInterface * const * pright);
+extern HQL_API int compareAtoms(IInterface * const * pleft, IInterface * const * pright);
 extern HQL_API IHqlExpression * getSizetConstant(unsigned size);
 extern HQL_API IHqlExpression * createIntConstant(__int64 val);
 extern HQL_API IHqlExpression * createUIntConstant(unsigned __int64 val);
@@ -624,8 +624,9 @@ extern HQL_API bool debugFindFirstDifference(IHqlExpression * left, IHqlExpressi
 extern HQL_API void debugTrackDifference(IHqlExpression * expr);
 
 extern HQL_API StringBuffer & convertToValidLabel(StringBuffer &out, const char * in, unsigned inlen);
-extern HQL_API bool arraysSame(CIArray & left, CIArray & right);
-extern HQL_API bool arraysSame(Array & left, Array & right);
+
+extern HQL_API bool arraysSame(HqlExprArray & left, HqlExprArray & right);
+extern HQL_API bool arraysSame(HqlExprCopyArray & left, HqlExprCopyArray & right);
 extern HQL_API bool isFailAction(IHqlExpression * expr);
 extern HQL_API bool isFailureGuard(IHqlExpression * expr);
 

+ 1 - 1
ecl/hql/hqlxmldb.cpp

@@ -62,7 +62,7 @@ public:
 class CXmlScopeIterator : public IIterator, public CInterface
 {
 protected:
-    Array subscopes;
+    IArray subscopes;
     unsigned index;
 public:
     IMPLEMENT_IINTERFACE;

+ 1 - 1
ecl/hqlcpp/hqlcpp.ipp

@@ -153,7 +153,7 @@ private:
 
 public:
     CIArray             sections;
-    Array               helpers;
+    IArray               helpers;
     StringAttrArray     modules;
     StringAttrArray     includes;
     CIArray             extra;

+ 7 - 4
ecl/hqlcpp/hqlcppcase.cpp

@@ -115,14 +115,17 @@ IHqlExpression * createNotFoundValue()
 
 //===========================================================================
 
-static int comparePair(IInterface * * left, IInterface * * right)
+static int comparePair(IHqlExpression * lexpr, IHqlExpression * rexpr)
 {
-    IHqlExpression * lexpr = (IHqlExpression *)*left;
-    IHqlExpression * rexpr = (IHqlExpression *)*right;
-
     return lexpr->queryChild(0)->queryValue()->compare(rexpr->queryChild(0)->queryValue());
 }
 
+static int comparePair(IInterface * const * left, IInterface * const * right)
+{
+    IHqlExpression * lexpr = (IHqlExpression *)*left;
+    IHqlExpression * rexpr = (IHqlExpression *)*right;
+    return comparePair(lexpr, rexpr);
+}
 
 HqlCppCaseInfo::HqlCppCaseInfo(HqlCppTranslator & _translator) : translator(_translator)
 {

+ 2 - 2
ecl/hqlcpp/hqlgraph.cpp

@@ -451,7 +451,7 @@ void LogicalGraphCreator::endActivity()
 void LogicalGraphCreator::endSubGraph(bool nested)
 {
     subGraphs.pop();
-    subGraphId = savedGraphId.pop();
+    subGraphId = savedGraphId.popGet();
     if (!nested)
         restoreSubGraphs();
 }
@@ -790,7 +790,7 @@ LogicalGraphInfo * LogicalGraphCreator::queryExtra(IHqlExpression * expr)
 void LogicalGraphCreator::restoreSubGraphs()
 {
     subGraphs.kill();
-    unsigned level = savedLevels.pop();
+    unsigned level = savedLevels.popGet();
     while (saved.ordinality() != level)
         subGraphs.append(saved.popGet());
 }

+ 1 - 1
ecl/hqlcpp/hqlhoist.hpp

@@ -185,7 +185,7 @@ protected:
     IArrayOf<ConditionalContextInfo> candidates;
     ConditionalContextInfo * activeParent;
     OwnedHqlExpr rootExpr;
-    CopyCIArrayOf<CHqlExprMultiGuard> childGuards;
+    CICopyArrayOf<CHqlExprMultiGuard> childGuards;
     ICopyArrayOf<ConditionalContextInfo> insertLocations;
     unsigned seq;
     bool alwaysEvaluateGuardedTogether;

+ 2 - 2
ecl/hqlcpp/hqlhtcpp.cpp

@@ -6022,7 +6022,7 @@ double HqlCppTranslator::getComplexity(HqlExprArray & exprs)
 
 //---------------------------------------------------------------------------------------------------------------------
 
-static int compareTrackedSourceByName(CInterface * * _left, CInterface * * _right)
+static int compareTrackedSourceByName(CInterface * const * _left, CInterface * const * _right)
 {
     SourceFieldUsage & left = static_cast<SourceFieldUsage &>(**_left);
     SourceFieldUsage & right = static_cast<SourceFieldUsage &>(**_right);
@@ -16023,7 +16023,7 @@ ABoundActivity * HqlCppTranslator::doBuildActivityIf(BuildCtx & ctx, IHqlExpress
 
 ABoundActivity * HqlCppTranslator::doBuildActivitySequentialParallel(BuildCtx & ctx, IHqlExpression * expr, bool isRoot)
 {
-    Array boundActivities;
+    IArray boundActivities;
     ForEachChild(i, expr)
     {
         IHqlExpression * cur = expr->queryChild(i);

+ 3 - 3
ecl/hqlcpp/hqlregex.cpp

@@ -189,7 +189,7 @@ regexid_t RegexIdAllocator::queryID(IHqlExpression * expr, IAtom * name)
 }
 
 
-int compareUnsigned(unsigned * left, unsigned * right) 
+int compareUnsigned(unsigned const * left, unsigned const * right)
 { 
     return (*left < *right) ? -1 : (*left > *right) ? +1 : 0; 
 }
@@ -2119,7 +2119,7 @@ inline int compareHqlRegexExpr(HqlRegexExpr * left, HqlRegexExpr * right)
     return (idl < idr) ? -1 : (idl > idr) ? +1 : 0; 
 }
 
-int compareHqlRegexExpr(CInterface * * left, CInterface * * right) 
+static int compareHqlRegexExpr(CInterface * const * left, CInterface * const * right)
 { 
     return compareHqlRegexExpr((HqlRegexExpr *)*left, (HqlRegexExpr *)*right);
 }
@@ -2184,7 +2184,7 @@ static inline int compareState(HqlDfaState * left, HqlDfaState * right)
     return left->position.compare(right->position);
 }
 
-static int compareState(CInterface * * left, CInterface * * right) 
+static int compareState(CInterface * const * left, CInterface * const * right)
 { 
     return compareState((HqlDfaState *)*left, (HqlDfaState *)*right);
 }

+ 1 - 1
ecl/hqlcpp/hqlregex.ipp

@@ -265,7 +265,7 @@ public:
     inline HqlRegexExpr & item(unsigned i)                  { return values.item(i); }
 
 private:
-    CopyCIArrayOf<HqlRegexExpr> values;
+    CICopyArrayOf<HqlRegexExpr> values;
 };
 
 class HqlDfaState;

+ 2 - 2
ecl/hqlcpp/hqlresource.cpp

@@ -5480,14 +5480,14 @@ void EclResourcer::createResourced(HqlExprArray & transformed)
         createResourced(&graphs.item(idx3), transformed);
 }
 
-static int compareGraphDepth(CInterface * * _l, CInterface * * _r)
+static int compareGraphDepth(CInterface * const * _l, CInterface * const * _r)
 {
     ResourceGraphInfo * l = (ResourceGraphInfo *)*_l;
     ResourceGraphInfo * r = (ResourceGraphInfo *)*_r;
     return l->getDepth() - r->getDepth();
 }
 
-static int compareLinkDepth(CInterface * * _l, CInterface * * _r)
+static int compareLinkDepth(CInterface * const * _l, CInterface * const * _r)
 {
     ResourceGraphLink * l = (ResourceGraphLink *)*_l;
     ResourceGraphLink * r = (ResourceGraphLink *)*_r;

+ 1 - 1
ecl/hqlcpp/hqlresource.ipp

@@ -150,7 +150,7 @@ public:
 };
 
 typedef CIArrayOf<ResourceGraphInfo> ResourceGraphArray;
-typedef CopyCIArrayOf<ResourceGraphLink> GraphLinkArray;
+typedef CICopyArrayOf<ResourceGraphLink> GraphLinkArray;
 
 class ResourceGraphInfo : public CInterface
 {

+ 2 - 2
ecl/hqlcpp/hqltomita.cpp

@@ -1454,7 +1454,7 @@ inline int compareLRItem(HqlLRItem * left, HqlLRItem * right)
     return 0;
 }
 
-int compareLRItem(CInterface * * left, CInterface * * right) 
+int compareLRItem(CInterface * const * left, CInterface * const * right)
 { 
     return compareLRItem((HqlLRItem *)*left, (HqlLRItem *)*right);
 }
@@ -1630,7 +1630,7 @@ static inline int compareState(HqlLRState * left, HqlLRState * right)
     return left->items.compare(right->items);
 }
 
-static int compareState(CInterface * * left, CInterface * * right) 
+static int compareState(CInterface * const * left, CInterface * const * right)
 { 
     return compareState((HqlLRState *)*left, (HqlLRState *)*right);
 }

+ 1 - 1
ecl/hqlcpp/hqltomita.ipp

@@ -462,7 +462,7 @@ protected:
     CIArrayOf<TomRule> rules;
     CIArrayOf<TomToken> tokens;
     CIArrayOf<TomFeature> features;
-    CopyCIArrayOf<TomRule> activeRules;
+    CICopyArrayOf<TomRule> activeRules;
     unsigned numTerminals;
     unsigned numSymbols;
     unsigned numProductions;

+ 2 - 2
ecl/hqlcpp/hqlttcpp.cpp

@@ -6806,7 +6806,7 @@ void groupThorGraphs(HqlExprArray & in)
 
     //Need to work out the best order to generate the statements in.  We want
     //to move non thor queries to the front, so we do a insertion sort on them
-    CopyCIArrayOf<StatementInfo> sorted;
+    CICopyArrayOf<StatementInfo> sorted;
     ForEachItemIn(idx1, stmts)
     {
         StatementInfo & cur = stmts.item(idx1);
@@ -6900,7 +6900,7 @@ bool moveUnconditionalEarlier(HqlExprArray & in)
 
     //For each block of unconditional statements which follow a conditional statement, see if they can be moved over the conditional statements.
     //(copies with no overhead if couldImprove is false)
-    CopyCIArrayOf<StatementInfo> sorted;
+    CICopyArrayOf<StatementInfo> sorted;
     unsigned max = stmts.ordinality();
     for (unsigned idx1 = 0; idx1 < max;)
     {

+ 1 - 1
ecl/hqlcpp/hqlwcpp.cpp

@@ -142,7 +142,7 @@ void CppWriterTemplate::generate(ISectionWriter & writer, unsigned pass, IProper
                 output = (properties && properties->hasProp(cur.id->str()));
             break;
         case TplEndCondition:
-            output = outputStack.pop();
+            output = outputStack.popGet();
             break;
         }
 

+ 1 - 1
ecl/hthor/hthorkey.cpp

@@ -372,7 +372,7 @@ protected:
 
 //for layout translation
     Owned<IRecordLayoutTranslator> layoutTrans;
-    PointerIArrayOf<IRecordLayoutTranslator> layoutTransArray;
+    IPointerArrayOf<IRecordLayoutTranslator> layoutTransArray;
     bool gotLayoutTrans;
 };
 

+ 2 - 2
esp/bindings/SOAP/Platform/soaptype.hpp

@@ -66,7 +66,7 @@ union FieldValue
     bool   boolV;
     ISoapField* structV;
     StringArray* stringarrayV;
-    Array*       arrayV;
+    IArray*       arrayV;
 
     FieldValue() { }
     FieldValue(int v) { intV = v; }
@@ -78,7 +78,7 @@ union FieldValue
     FieldValue(bool v) { boolV = v; }
     FieldValue(ISoapField* v) {  structV = v; }
     FieldValue(StringArray* v) {  stringarrayV = v; }
-    FieldValue(Array* v) { arrayV = v; }
+    FieldValue(IArray* v) { arrayV = v; }
 };
 
 interface ISoapField : public IInterface

+ 1 - 1
esp/platform/espp.hpp

@@ -25,7 +25,7 @@ typedef ISocket * isockp;
 
 
 typedef MapBetween<int, int, isockp, isockp> SocketPortMap;
-MAKEPointerArray(ISocket, SocketPortArray);
+typedef CopyReferenceArrayOf<ISocket> SocketPortArray;
 
 class CEspTerminator : public Thread
 {

+ 1 - 1
esp/scm/roxiecommlibscm.ecm

@@ -59,7 +59,7 @@ SCMinterface IRoxieCommunicationClient(IInterface)
 };
 
 
-extern "C" ROXIECOMMLIB_API IRoxieCommunicationClient *createRoxieCommunicationClient(SocketEndpoint &roxieEP, unsigned roxieTimeout);
+extern "C" ROXIECOMMLIB_API IRoxieCommunicationClient *createRoxieCommunicationClient(const SocketEndpoint &roxieEP, unsigned roxieTimeout);
 
 
 

+ 4 - 4
esp/services/ws_smc/ws_smcService.cpp

@@ -91,28 +91,28 @@ struct QueueLock
     Linked<IJobQueue> queue;
 };
 
-static int sortTargetClustersByNameDescending(IInterface **L, IInterface **R)
+static int sortTargetClustersByNameDescending(IInterface * const *L, IInterface * const *R)
 {
     IEspTargetCluster *left = (IEspTargetCluster *) *L;
     IEspTargetCluster *right = (IEspTargetCluster *) *R;
     return strcmp(right->getClusterName(), left->getClusterName());
 }
 
-static int sortTargetClustersByNameAscending(IInterface **L, IInterface **R)
+static int sortTargetClustersByNameAscending(IInterface * const *L, IInterface * const *R)
 {
     IEspTargetCluster *left = (IEspTargetCluster *) *L;
     IEspTargetCluster *right = (IEspTargetCluster *) *R;
     return strcmp(left->getClusterName(), right->getClusterName());
 }
 
-static int sortTargetClustersBySizeDescending(IInterface **L, IInterface **R)
+static int sortTargetClustersBySizeDescending(IInterface * const *L, IInterface * const *R)
 {
     IEspTargetCluster *left = (IEspTargetCluster *) *L;
     IEspTargetCluster *right = (IEspTargetCluster *) *R;
     return right->getClusterSize() - left->getClusterSize();
 }
 
-static int sortTargetClustersBySizeAscending(IInterface **L, IInterface **R)
+static int sortTargetClustersBySizeAscending(IInterface * const *L, IInterface * const *R)
 {
     IEspTargetCluster *left = (IEspTargetCluster *) *L;
     IEspTargetCluster *right = (IEspTargetCluster *) *R;

+ 1 - 1
esp/services/ws_workunits/ws_workunitsQuerySets.cpp

@@ -1609,7 +1609,7 @@ bool CWsWorkunitsEx::onWUQueryDetails(IEspContext &context, IEspWUQueryDetailsRe
     return true;
 }
 
-int EspQuerySuperFileCompareFunc(IInterface **i1, IInterface **i2)
+int EspQuerySuperFileCompareFunc(IInterface * const *i1, IInterface * const *i2)
 {
     if (!i1 || !*i1 || !i2 || !*i2)
         return 0;

+ 1 - 1
esp/services/ws_workunits/ws_workunitsService.cpp

@@ -2074,7 +2074,7 @@ void doWUQueryFromArchive(IEspContext &context, const char* sashaServerIP, unsig
             }
             return info.getClear();
         }
-        static int compareWuids(IInterface **_a, IInterface **_b)
+        static int compareWuids(IInterface * const *_a, IInterface * const *_b)
         {
             IEspECLWorkunit *a = *(IEspECLWorkunit **)_a;
             IEspECLWorkunit *b = *(IEspECLWorkunit **)_b;

+ 4 - 4
plugins/javaembed/javaembed.cpp

@@ -270,8 +270,8 @@ protected:
     }
     void pop()
     {
-        row = (jobject) stack.pop();
-        Class = (jclass) stack.pop();
+        row = (jobject) stack.popGet();
+        Class = (jclass) stack.popGet();
     }
     jfieldID getFieldId(const RtlFieldInfo * field, const char *sig, const char *expected)
     {
@@ -989,14 +989,14 @@ public:
     virtual void processEndDataset(const RtlFieldInfo * field)
     {
         inDataSet = false;
-        idx = idxStack.pop();
+        idx = idxStack.popGet();
         pop();
     }
     virtual void processEndRow(const RtlFieldInfo * field)
     {
         if (field != outerRow)
         {
-            constructor = (jmethodID) stack.pop();
+            constructor = (jmethodID) stack.popGet();
             JNIenv->DeleteLocalRef(row);
             pop();
         }

+ 4 - 4
plugins/pyembed/pyembed.cpp

@@ -771,9 +771,9 @@ public:
 protected:
     void pop()
     {
-        iter.setown((PyObject *) iterStack.pop());
-        parent.setown((PyObject *) parentStack.pop());
-        named = namedStack.pop();
+        iter.setown((PyObject *) iterStack.popGet());
+        parent.setown((PyObject *) parentStack.popGet());
+        named = namedStack.popGet();
         elem.clear();
     }
     void push()
@@ -941,7 +941,7 @@ protected:
     void pop()
     {
         addArg(args.getClear());
-        args.setown((PyObject *) stack.pop());
+        args.setown((PyObject *) stack.popGet());
     }
     void addArg(PyObject *arg)
     {

+ 4 - 4
plugins/v8embed/v8embed.cpp

@@ -189,8 +189,8 @@ public:
 protected:
     void pop()
     {
-        named = namedStack.pop();
-        idx = idxStack.pop();
+        named = namedStack.popGet();
+        idx = idxStack.popGet();
         row = stack.back();
         stack.pop_back();
     }
@@ -356,8 +356,8 @@ protected:
     }
     void pop(const RtlFieldInfo * field)
     {
-        inDataset = dsStack.pop();
-        idx = idxStack.pop();
+        inDataset = dsStack.popGet();
+        idx = idxStack.popGet();
         v8::Local<v8::Object> row = obj;
         obj = stack.back();
         stack.pop_back();

+ 4 - 4
roxie/ccd/ccdcontext.cpp

@@ -545,7 +545,7 @@ private:
         logctx.CTXLOG("%s", msg.str());
     }
 
-    static int comparePersistAccess(IInterface **_a, IInterface **_b)
+    static int comparePersistAccess(IInterface * const *_a, IInterface * const *_b)
     {
         IPropertyTree *a = *(IPropertyTree **)_a;
         IPropertyTree *b = *(IPropertyTree **)_b;
@@ -629,7 +629,7 @@ private:
     IConstWorkUnit *workunit;
     IPropertyTree *workflowInfo;
     Owned<PersistVersion> persist;
-    Array persistReadLocks;
+    IArray persistReadLocks;
     bool doOnce;
 };
 
@@ -680,7 +680,7 @@ class CDeserializedResultStore : public CInterface, implements IDeserializedResu
 {
     PointerArrayOf<row_t> stored;
     UnsignedArray counts;
-    PointerIArrayOf<IOutputMetaData> metas;
+    IPointerArrayOf<IOutputMetaData> metas;
     mutable SpinLock lock;
 public:
     IMPLEMENT_IINTERFACE;
@@ -1040,7 +1040,7 @@ protected:
 
 protected:
     CriticalSection resultsCrit;
-    PointerIArrayOf<FlushingStringBuffer> resultMap;
+    IPointerArrayOf<FlushingStringBuffer> resultMap;
     bool exceptionLogged;
     bool aborted;
     CriticalSection abortLock; // NOTE: we don't bother to get lock when just reading to see whether to abort

+ 8 - 8
roxie/ccd/ccdfile.cpp

@@ -467,7 +467,7 @@ public:
     virtual offset_t getSize() { return fileSize; }
     virtual CDateTime *queryDateTime() { return &fileDate; }
 
-    static int compareAccess(IInterface **L, IInterface **R)
+    static int compareAccess(IInterface * const *L, IInterface * const *R)
     {
         ILazyFileIO *LL = (ILazyFileIO *) *L;
         ILazyFileIO *RR = (ILazyFileIO *) *R;
@@ -989,7 +989,7 @@ public:
                         break;
                     if (todo.ordinality())
                     {
-                        ILazyFileIO *popped = &todo.pop();
+                        ILazyFileIO *popped = &todo.popGet();
                         if (popped->isAlive())
                         {
                             next.set(popped);
@@ -1565,7 +1565,7 @@ public:
     }
 
     virtual bool IsShared() const { return CInterface::IsShared(); };
-    PointerIArrayOf<IFileIO> files;
+    IPointerArrayOf<IFileIO> files;
     StringArray filenames;
     Int64Array bases;
     unsigned valid;
@@ -1655,7 +1655,7 @@ public:
 
 template <class X> class PerChannelCacheOf
 {
-    PointerIArrayOf<X> cache;
+    IPointerArrayOf<X> cache;
     IntArray channels;
 public:
     void set(X *value, unsigned channel)
@@ -1691,9 +1691,9 @@ protected:
     bool isSuper;
 
     StringArray subNames;
-    PointerIArrayOf<IFileDescriptor> subFiles; // note - on slaves, the file descriptors may have incomplete info. On originating server is always complete
-    PointerIArrayOf<IFileDescriptor> remoteSubFiles; // note - on slaves, the file descriptors may have incomplete info. On originating server is always complete
-    PointerIArrayOf<IDefRecordMeta> diskMeta;
+    IPointerArrayOf<IFileDescriptor> subFiles; // note - on slaves, the file descriptors may have incomplete info. On originating server is always complete
+    IPointerArrayOf<IFileDescriptor> remoteSubFiles; // note - on slaves, the file descriptors may have incomplete info. On originating server is always complete
+    IPointerArrayOf<IDefRecordMeta> diskMeta;
     IArrayOf<IDistributedFile> subDFiles;  // To make sure subfiles get locked too
     IArrayOf<IResolvedFile> subRFiles;  // To make sure subfiles get locked too
 
@@ -2371,7 +2371,7 @@ public:
         ROQ->removePendingCallback(callback);
     }
 private:
-    void deserializeFilePart(MemoryBuffer &serverData, PointerIArrayOf<IFileDescriptor> &files, unsigned fileNo, bool remote)
+    void deserializeFilePart(MemoryBuffer &serverData, IPointerArrayOf<IFileDescriptor> &files, unsigned fileNo, bool remote)
     {
         IArrayOf<IPartDescriptor> parts;
         deserializePartFileDescriptors(serverData, parts);

+ 1 - 1
roxie/ccd/ccdkey.cpp

@@ -1498,7 +1498,7 @@ class InMemoryIndexCursor : public CInterface, implements IInMemoryIndexCursor
         return NULL;
     }
 
-    static int compareSegments(IInterface **v1, IInterface **v2)
+    static int compareSegments(IInterface * const *v1, IInterface * const *v2)
     {
         // MORE - just assuming an offset match is not really enough. Use the same code as we did in tracking
 

+ 2 - 2
roxie/ccd/ccdquery.hpp

@@ -34,7 +34,7 @@
 
 class TranslatorArray : public CInterface, implements IInterface
 {
-    PointerIArrayOf<IRecordLayoutTranslator> a;
+    IPointerArrayOf<IRecordLayoutTranslator> a;
 public:
     IMPLEMENT_IINTERFACE;
     inline IRecordLayoutTranslator *item(unsigned idx) const { return a.item(idx); }
@@ -203,7 +203,7 @@ public:
     inline bool isSequential() const { return sequential; }
     inline unsigned getLibraryGraphId() const { return libraryGraphId; }
 };
-MAKEPointerArray(ActivityArray, ActivityArrayArray);
+typedef CopyReferenceArrayOf<ActivityArray> ActivityArrayArray;
 
 typedef ActivityArray *ActivityArrayPtr;
 typedef MapStringTo<ActivityArrayPtr> MapStringToActivityArray;

+ 2 - 2
roxie/ccd/ccdserver.cpp

@@ -3073,7 +3073,7 @@ class CRemoteResultAdaptor :public CInterface, implements IRoxieInput, implement
                 {
                     if (!doContinuation(topEntry, stepExtra.returnMismatches()))
                     {
-                        unsigned last = heap.pop();
+                        unsigned last = heap.popGet();
                         if (heap.length())
                             heap.replace(last, 0);
                         removeHeap(top);
@@ -12434,7 +12434,7 @@ protected:
     bool grouped;
 };
 
-MAKEPointerArray(CRoxieThreadedConcatReader, ReaderArray);
+typedef CopyReferenceArrayOf<CRoxieThreadedConcatReader> ReaderArray;
 
 class CRoxieServerThreadedConcatActivity : public CRoxieServerActivity
 {

+ 3 - 3
roxie/ccd/ccdsnmp.cpp

@@ -657,10 +657,10 @@ class CQueryStatsAggregator : public CInterface, implements IQueryStatsAggregato
             return difftime(startTime, otherTime) < 0;
         }
 
-        static int compareTime(CInterface **_l, CInterface**_r)
+        static int compareTime(CInterface * const *_l, CInterface* const *_r)
         {
-            QueryStatsRecord *l = *(QueryStatsRecord **) _l;
-            QueryStatsRecord *r = *(QueryStatsRecord **) _r;
+            QueryStatsRecord *l = (QueryStatsRecord *)*_l;
+            QueryStatsRecord *r = (QueryStatsRecord *)*_r;
             return l->elapsedTimeMs - r->elapsedTimeMs;
         }
 

+ 1 - 1
roxie/roxiemem/roxiemem.cpp

@@ -2624,7 +2624,7 @@ class CChunkingRowManager : public CInterface, implements IRowManager
     BufferedRowCallbackManager callbacks;
     Owned<IActivityMemoryUsageMap> peakUsageMap;
     CIArrayOf<CHeap> fixedHeaps;
-    CopyCIArrayOf<CRoxieFixedRowHeapBase> fixedRowHeaps;  // These are observed, NOT linked
+    CICopyArrayOf<CRoxieFixedRowHeapBase> fixedRowHeaps;  // These are observed, NOT linked
     const IRowAllocatorCache *allocatorCache;
     unsigned __int64 cyclesChecked;       // When we last checked timelimit
     unsigned __int64 cyclesCheckInterval; // How often we need to check timelimit

+ 1 - 1
system/hrpc/hrpcutil.cpp

@@ -119,7 +119,7 @@ static CriticalSection mcsect;
 bool FastMultipleConnect(unsigned n,HRPCmodule **modules,bool *done,int timeout)
 {
     CriticalSection sect;
-    PointerIArrayOf<ISocket> sockets;
+    IPointerArrayOf<ISocket> sockets;
     SocketEndpointArray eps;
     unsigned i;
     for (i=0;i<n;i++) {

+ 2 - 2
system/jhtree/jhtree.cpp

@@ -2006,7 +2006,7 @@ extern jhtree_decl IKeyIndex *createKeyIndex(const char *keyfile, unsigned crc,
 extern jhtree_decl IKeyIndex *createKeyIndex(IReplicatedFile &part, unsigned crc, bool isTLK, bool preloadAllowed)
 {
     StringBuffer filePath;
-    RemoteFilename &rfn = part.queryCopies().item(0);
+    const RemoteFilename &rfn = part.queryCopies().item(0);
     rfn.getPath(filePath);
     return queryKeyStore()->load(filePath.str(), crc, part, isTLK, preloadAllowed);
 }
@@ -2902,7 +2902,7 @@ class CKeyArray : public CInterface, implements IKeyArray
 public:
     IMPLEMENT_IINTERFACE;
     virtual bool IsShared() const { return CInterface::IsShared(); }
-    PointerIArrayOf<IKeyIndexBase> keys;
+    IPointerArrayOf<IKeyIndexBase> keys;
     virtual IKeyIndexBase *queryKeyPart(unsigned partNo)
     {
         if (!keys.isItem(partNo))

+ 1 - 1
system/jhtree/keybuild.cpp

@@ -507,7 +507,7 @@ public:
     NodeInfoArray nodes;
 };
 
-int compareParts(CInterface * * _left, CInterface * * _right)
+int compareParts(CInterface * const * _left, CInterface * const * _right)
 {
     PartNodeInfo * left = (PartNodeInfo *)*_left;
     PartNodeInfo * right = (PartNodeInfo *)*_right;

+ 1 - 1
system/jhtree/keybuild.hpp

@@ -77,7 +77,7 @@ public:
         else
             value = NULL;
     }
-    static int compare(IInterface **ll, IInterface **rr)
+    static int compare(IInterface * const *ll, IInterface * const *rr)
     {
         CNodeInfo *l = (CNodeInfo *) *ll;
         CNodeInfo *r = (CNodeInfo *) *rr;

+ 1 - 1
system/jhtree/keydiff.cpp

@@ -1264,7 +1264,7 @@ private:
             WARNLOG("Patch did not include TLK info in header, TLK has been generated but its CRC has not been verified");
     }
 
-    static int rowCompare(IInterface ** ll, IInterface ** rr)
+    static int rowCompare(IInterface * const * ll, IInterface * const * rr)
     {
         CNodeInfo * l = static_cast<CNodeInfo *>(*ll);
         CNodeInfo * r = static_cast<CNodeInfo *>(*rr);

+ 0 - 1
system/jlib/CMakeLists.txt

@@ -83,7 +83,6 @@ set (    SRCS
 set (    INCLUDES
         jaio.hpp
         jarray.hpp
-        jarray.tpp
         jatomic.hpp
         javahash.hpp
         javahash.tpp

+ 0 - 1
system/jlib/jarray.cpp

@@ -18,7 +18,6 @@
 
 #include "jiface.hpp"
 #include "jarray.hpp"
-#include "jarray.tpp"
 #include "jsort.hpp"
 #include "jmisc.hpp"
 #include "jlib.hpp"

+ 374 - 108
system/jlib/jarray.hpp

@@ -20,7 +20,7 @@
 #ifndef JARRAY_HPP
 #define JARRAY_HPP
 
-
+#include <new>
 
 #include "platform.h"
 #include "jiface.hpp"
@@ -45,6 +45,7 @@ typedef int (* StdCompare)(const void *_e1, const void *_e2);
 class jlib_decl Allocator
 {
 public:
+    Allocator() { _init(); }
     void  kill();
     inline bool isItem(aindex_t pos = 0) const    { return pos < used; }      /* Is there an item at pos */
     inline aindex_t length() const                 { return used; } /* Return number of items  */
@@ -88,117 +89,384 @@ protected:
     inline void _move(aindex_t pos1, aindex_t pos2, aindex_t num) { memmove((char *)_head + pos1 * SIZE, (char *)_head + pos2 * SIZE, num * SIZE); }
 };
 
-/* inheritance structure:
-
-  BaseArrayOf inherits from AllocatorOf
-  CopyArrayOf (non-owning ref array) inherits from BaseArrayOf
-  OwningArrayOf inherits from BaseArrayOf
-  ArrayOf (owning ref array) inherits from OwningArrayOf
-  PtrArrayOf (owning ptr array) inherits from OwningArrayOf
+//--------------------------------------------------------------------------------------------------------------------
 
-  the difference between the latter two is that they call different functions to convert MEMBER to PARAM (Array__Member2Param vs Array__Member2ParamPtr)
-  this is necessary because of the use of global functions, to allow two arrays with the
-  same MEMBER but different PARAMs (otherwise these functions would have the same prototype, because their arguments only involve MEMBER and not PARAM)
+//Ugly - avoid problems with new being #defined in windows debug mode
+#undef new
 
- */
+template <class MEMBER, class PARAM = MEMBER>
+class SimpleArrayMapper
+{
+public:
+    static void construct(MEMBER & member, PARAM newValue)
+    {
+        ::new (&member) MEMBER(newValue);
+    }
+    static inline void destruct(MEMBER & member)
+    {
+        member.~MEMBER();
+    }
+    static inline bool matches(const MEMBER & member, PARAM param)
+    {
+        return member == param;
+    }
+    static inline PARAM getParameter(const MEMBER & member)
+    {
+        return (PARAM)member;
+    }
+};
 
-template <class MEMBER, class PARAM>
-class BaseArrayOf : public AllocatorOf<sizeof(MEMBER)>
+// An array which stores elements MEMBER, is passed and returns PARAMs
+// The MAPPER class is used to map between these two different classes.
+template <typename MEMBER, typename PARAM = MEMBER, class MAPPER = SimpleArrayMapper<MEMBER, PARAM> >
+class ArrayOf : public AllocatorOf<sizeof(MEMBER)>
 {
     typedef AllocatorOf<sizeof(MEMBER)> PARENT;
-    typedef BaseArrayOf<MEMBER,PARAM> SELF;
+    typedef ArrayOf<MEMBER,PARAM,MAPPER> SELF;
 
 protected:
-    typedef int (*CompareFunc)(MEMBER *, MEMBER *);
+    typedef int (*CompareFunc)(const MEMBER *, const MEMBER *);   // Should really be const, as should the original array functions
 
 public:
+    ~ArrayOf<MEMBER,PARAM,MAPPER>() { kill(); }
+
+    MEMBER & operator[](size_t pos) { return element((aindex_t)pos); }
+    const MEMBER & operator[](size_t pos) const { return element((aindex_t)pos); }
+
     inline bool contains(PARAM search) const          { return find(search) != NotFound; }
 
-    void add(PARAM, aindex_t pos);              /* Adds at pos             */
-    void append(PARAM);                         /* Adds to end of array    */
-    bool appendUniq(PARAM);                     /* Adds to end of array if not already in array - returns true if added*/
-    aindex_t bAdd(MEMBER & newItem, CompareFunc, bool & isNew);
-    aindex_t bSearch(const MEMBER & key, CompareFunc) const;
-    aindex_t find(PARAM) const;
-    MEMBER *getArray(aindex_t = 0) const;
-    void sort(CompareFunc);
-    void swap(aindex_t pos1, aindex_t pos2);
-    void swapWith(SELF & other) { this->doSwapWith(other); }
+    void add(PARAM newValue, aindex_t pos)
+    {
+        aindex_t valid_above = SELF::used - pos;
+        SELF::_space();
+        SELF::_move(pos + 1, pos, valid_above);
+        SELF::construct(newValue, pos);
+    }
+    void append(PARAM newValue)
+    {
+        SELF::_space();
+        SELF::construct(newValue, SELF::used-1);
+    }
+    bool appendUniq(PARAM newValue)
+    {
+        if (contains(newValue))
+            return false;
+        append(newValue);
+        return true;
+    }
+    aindex_t bAdd(MEMBER & newItem, CompareFunc cf, bool & isNew)
+    {
+        SELF::_space();
+
+        //MORE: This should have a callback function/method that is used to transfer the new element instead of memcpy
+        MEMBER * match = (MEMBER *) SELF::_doBAdd(&newItem, sizeof(MEMBER), (StdCompare)cf, isNew);
+        if (!isNew)
+            SELF::used--;
+
+        MEMBER * head= (MEMBER *)SELF::_head;
+        return (aindex_t)(match - head);
+    }
+    aindex_t bSearch(const MEMBER & key, CompareFunc cf) const
+    {
+        MEMBER * head= (MEMBER *)SELF::_head;
+        MEMBER * match = (MEMBER *) SELF::_doBSearch(&key, sizeof(MEMBER), (StdCompare)cf);
+        if (match)
+            return (aindex_t)(match - (MEMBER *)head);
+        return NotFound;
+    }
+    aindex_t find(PARAM searchValue) const
+    {
+        MEMBER * head= (MEMBER *)SELF::_head;
+        for (aindex_t pos = 0; pos < SELF::used; ++pos)
+        {
+            if (MAPPER::matches(head[pos], searchValue))
+                return pos;
+        }
+        return NotFound;
+    }
+    MEMBER * getArray(aindex_t pos = 0) const
+    {
+        MEMBER * head= (MEMBER *)SELF::_head;
+        assertex(pos <= SELF::used);
+        return &head[pos];
+    }
+    void sort(CompareFunc cf)
+    {
+        SELF::_doSort(sizeof(MEMBER), (StdCompare)cf);
+    }
+    void swap(aindex_t pos1, aindex_t pos2)
+    {
+        if (pos1 != pos2)
+        {
+            MEMBER * head= (MEMBER *)SELF::_head;
+            byte temp[sizeof(MEMBER)];
+            memcpy(temp, head + pos1, sizeof(MEMBER));
+            memcpy(head + pos1, head + pos2, sizeof(MEMBER));
+            memcpy(head + pos2, temp, sizeof(MEMBER));
+        }
+    }
+    void swapWith(SELF & other)
+    {
+        SELF::doSwapWith(other);
+    }
+    void clear()
+    {
+        SELF::used = 0;
+    }
+    void kill(bool nodestruct = false)
+    {
+        aindex_t count = SELF::used;
+        SELF::used = 0;
+        if (!nodestruct)
+        {
+            for (aindex_t i=0; i<count; i++)
+                 SELF::destruct(i);
+        }
+        PARENT::kill();
+    }
+    MEMBER & element(aindex_t pos)
+    {
+        assertex(SELF::isItem(pos));
+        MEMBER * head = (MEMBER *)SELF::_head;
+        return head[pos];
+    }
+    const MEMBER & element(aindex_t pos) const
+    {
+        assertex(SELF::isItem(pos));
+        MEMBER * head = (MEMBER *)SELF::_head;
+        return head[pos];
+    }
+    inline PARAM item(aindex_t pos) const
+    {
+        assertex(SELF::isItem(pos));
+        MEMBER * head= (MEMBER *)SELF::_head;
+        return MAPPER::getParameter(head[pos]);
+    }
+    void remove(aindex_t pos, bool nodestruct = false)
+    {
+        assertex(pos < SELF::used);
+        SELF::used --;
+        if (!nodestruct) SELF::destruct(pos);
+        SELF::_move( pos, pos + 1, ( SELF::used - pos ) );
+    }
+    void removen(aindex_t pos, aindex_t num, bool nodestruct = false)
+    {
+        assertex(pos + num <= SELF::used);
+        SELF::used -= num;
+        if (!nodestruct)
+        {
+            unsigned idx = 0;
+            for (;idx < num; idx++)
+                SELF::destruct(pos+idx);
+        }
+        SELF::_move( pos, pos + num, ( SELF::used - pos ) );
+    }
+    void pop(bool nodestruct = false)
+    {
+        assertex(SELF::used);
+        --SELF::used;
+        if (!nodestruct)
+            SELF::destruct(SELF::used);
+    }
+    PARAM popGet()
+    {
+        assertex(SELF::used);
+        --SELF::used;
+        MEMBER * head= (MEMBER *)SELF::_head;
+        return MAPPER::getParameter(head[SELF::used]); // used already decremented so element() would assert
+    }
+    void popn(aindex_t n, bool nodestruct = false)
+    {
+        assertex(SELF::used>=n);
+        MEMBER * head= (MEMBER *)SELF::_head;
+        while (n--)
+        {
+            --SELF::used;
+            if (!nodestruct)
+                SELF::destruct(SELF::used);
+        }
+    }
+    void popAll(bool nodestruct = false)
+    {
+        if (!nodestruct)
+        {
+            while (SELF::used)
+                SELF::destruct(--SELF::used);
+        }
+        else
+            SELF::used = 0;
+    }
+    void replace(PARAM newValue, aindex_t pos, bool nodestruct = false)
+    {
+        if (!nodestruct)
+            SELF::destruct(pos);
+        SELF::construct(newValue, pos);
+    }
+    const MEMBER & last(void) const
+    {
+        return element(SELF::used-1);
+    }
+    const MEMBER & last(aindex_t n) const
+    {
+        return element(SELF::used-n-1);
+    }
+    MEMBER & last(void)
+    {
+        return element(SELF::used-1);
+    }
+    MEMBER & last(aindex_t n)
+    {
+        return element(SELF::used-n-1);
+    }
+    PARAM tos(void) const
+    {
+        return MAPPER::getParameter(element(SELF::used-1));
+    }
+    PARAM tos(aindex_t n) const
+    {
+        return MAPPER::getParameter(element(SELF::used-n-1));
+    }
+    void trunc(aindex_t limit, bool nodestruct = false)
+    {
+        while (limit < SELF::used)
+            SELF::pop(nodestruct);
+    }
+    bool zap(PARAM searchValue, bool nodestruct = false)
+    {
+        MEMBER * head= (MEMBER *)SELF::_head;
+        for (aindex_t pos= 0; pos < SELF::used; ++pos)
+        {
+            if (MAPPER::matches(head[pos], searchValue))
+            {
+                remove(pos, nodestruct);
+                return true;
+            }
+        }
+        return false;
+    }
+
+protected:
+    inline void construct(PARAM newValue, unsigned pos)
+    {
+        MEMBER * head= (MEMBER *)SELF::_head;
+        MAPPER::construct(head[pos], newValue);
+    }
+    inline void destruct(unsigned pos)
+    {
+        MEMBER * head= (MEMBER *)SELF::_head;
+        MAPPER::destruct(head[pos]);
+    }
 };
 
-template <class MEMBER, class PARAM>
-class CopyArrayOf : public BaseArrayOf<MEMBER, PARAM>
+//--------------------------------------------------------------------------------------------------------------------
+
+template <typename ITEM>
+class OwnedReferenceArrayMapper
 {
-    typedef BaseArrayOf<MEMBER, PARAM> PARENT;
-    typedef CopyArrayOf<MEMBER, PARAM> SELF;
-    
+    typedef ITEM * MEMBER;
+    typedef ITEM & PARAM;
 public:
-    CopyArrayOf() { SELF::_init(); }
-    ~CopyArrayOf();
-    
-    void clear();
-    inline PARAM item(aindex_t pos) const;
-    PARAM tos(void) const;
-    PARAM tos(aindex_t) const;
-
-    PARAM pop(void);
-    void popn(aindex_t);
-    void popAll(void);
-    void remove(aindex_t pos);                  /* Remove (delete) item at pos */
-    void removen(aindex_t pos, aindex_t num);   /* Remove (delete) item at pos */
-    void replace(PARAM, aindex_t pos);          /* Replace an item at pos */
-    void trunc(aindex_t);
-    bool zap(PARAM);
+    static void construct(MEMBER & member, PARAM newValue)
+    {
+        member = &newValue;
+    }
+    static void destruct(MEMBER & member)
+    {
+        member->Release();
+    }
+    static inline bool matches(const MEMBER & member, PARAM param)
+    {
+        return member == &param;
+    }
+    static inline PARAM getParameter(const MEMBER & member)
+    {
+        return *member;
+    }
 };
 
-template <class MEMBER, class PARAM>
-class OwningArrayOf : public BaseArrayOf<MEMBER, PARAM>
+// An array which stores owned references to elements of type INTERFACE
+template <class INTERFACE>
+class OwnedReferenceArrayOf : public ArrayOf<INTERFACE *, INTERFACE &, OwnedReferenceArrayMapper<INTERFACE> >
 {
-    typedef BaseArrayOf<MEMBER, PARAM> PARENT;
-    typedef OwningArrayOf<MEMBER,PARAM> SELF;
-    
+};
+
+//--------------------------------------------------------------------------------------------------------------------
+
+template <typename ITEM>
+class OwnedPointerArrayMapper : public SimpleArrayMapper<ITEM*>
+{
+    typedef ITEM * MEMBER;
+    typedef ITEM * PARAM;
 public:
-    OwningArrayOf() { SELF::_init(); }
-    ~OwningArrayOf();
-    
-    void clear(bool nodel = false);                  /* Remove all items, don't free array */
-    void kill(bool nodel = false);                   /* Remove all items        */
-    void pop(bool nodel = false);
-    void popn(aindex_t,bool nodel = false);
-    void popAll(bool nodel = false);
-    void replace(PARAM, aindex_t pos, bool nodel = false); /* Replace an item at pos */
-    void remove(aindex_t pos, bool nodel = false);    /* Remove (delete) item at pos */
-    void removen(aindex_t pos, aindex_t num, bool nodel = false);    /* Remove N items (delete) item at pos */
-    void trunc(aindex_t pos, bool nodel = false);
-    bool zap(PARAM, bool nodel = false);
+    static void destruct(MEMBER & member)
+    {
+        ::Release(member);
+    }
 };
 
-template <class MEMBER, class PARAM>
-class ArrayOf : public OwningArrayOf<MEMBER, PARAM>
+// An array which stores owned pointers to elements of type INTERFACE
+template <typename INTERFACE>
+class OwnedPointerArrayOf : public ArrayOf<INTERFACE *, INTERFACE *, OwnedPointerArrayMapper<INTERFACE> >
 {
-    typedef OwningArrayOf<MEMBER, PARAM> PARENT;
-    typedef ArrayOf<MEMBER,PARAM> SELF;
+};
 
+//--------------------------------------------------------------------------------------------------------------------
+
+template <typename ITEM>
+class SafePointerArrayMapper : public SimpleArrayMapper<ITEM*>
+{
+    typedef ITEM * MEMBER;
+    typedef ITEM * PARAM;
 public:
-    inline PARAM item(aindex_t pos) const; 
-    PARAM popGet();
-    PARAM tos(void) const;
-    PARAM tos(aindex_t) const;
+    static void destruct(MEMBER & member)
+    {
+        delete member;
+    }
 };
 
-template <class MEMBER, class PARAM>
-class PtrArrayOf : public OwningArrayOf<MEMBER, PARAM>
+// An array which stores owned pointers to elements of type INTERFACE, and calls delete when they are released.
+template <typename INTERFACE>
+class SafePointerArrayOf : public ArrayOf<INTERFACE *, INTERFACE *, SafePointerArrayMapper<INTERFACE> >
+{
+};
+
+//--------------------------------------------------------------------------------------------------------------------
+
+template <class ITEM>
+class ReferenceArrayMapper
 {
-    typedef OwningArrayOf<MEMBER, PARAM> PARENT;
-    typedef PtrArrayOf<MEMBER,PARAM> SELF;
-    
 public:
-    inline PARAM item(aindex_t pos) const             { assertex(SELF::isItem(pos)); return Array__Member2ParamPtr(((MEMBER *)AllocatorOf<sizeof(MEMBER)>::_head)[pos]);}
-    PARAM popGet();
-    PARAM tos(void) const;
-    PARAM tos(aindex_t) const;
+    static void construct(ITEM * & member, ITEM & newValue)
+    {
+        member = &newValue;
+    }
+    static inline void destruct(ITEM * & member)
+    {
+    }
+    static inline bool matches(ITEM * const & member, ITEM & param)
+    {
+        return member == &param;
+    }
+    static inline ITEM & getParameter(ITEM * const & member)
+    {
+        return *member;
+    }
 };
 
+// An array which stores pointers to INTERFACE, but passes and returns references.
+template <class INTERFACE>
+class CopyReferenceArrayOf : public ArrayOf<INTERFACE *, INTERFACE &, ReferenceArrayMapper<INTERFACE> >
+{
+};
+
+//--------------------------------------------------------------------------------------------------------------------
+
+template <typename CLASS>
+class StructArrayOf : public ArrayOf<CLASS, const CLASS &> { };
+
+//--------------------------------------------------------------------------------------------------------------------
+
+
 template <class ARRAY, class PARAM> class ArrayIteratorOf
 {
 public:
@@ -237,32 +505,30 @@ private:
   { ForEachItemIn(idx##__LINE__, SRC)                        \
       (TGT).append((SRC).item(idx##__LINE__)); }
 
-#define MAKEArrayOf(member, param, array)       class array : public ArrayOf<member, param> {};
-#define MAKECopyArrayOf(member, param, array)   class array : public CopyArrayOf<member, param> {};
-#define MAKEPtrArrayOf(member, param, array)    class array : public PtrArrayOf<member, param> {};
-
-#define MAKEValueArray(simple, array)                                       \
-inline simple Array__Member2Param(simple &src)              { return src; }  \
-inline void Array__Assign(simple & dest, simple const & src){ dest = src; }  \
-inline bool Array__Equal(simple const & m, simple const p)  { return m==p; } \
-MAKECopyArrayOf(simple, simple, array)
-
-#define MAKEPointerArray(simple, array)                                     \
-inline simple & Array__Member2Param(simple *&src)              { return *src; }  \
-inline void Array__Assign(simple * & dest, simple & src)       { dest = &src; }  \
-inline bool Array__Equal(simple * const & m, simple const & p) { return m==&p; } \
-MAKECopyArrayOf(simple *, simple &, array)
-
-/* Documentation on the macros:
-
- MAKEValueArray(simple-type, array-name)
-   Declare an array of a built in, or simple type.  It takes care of defining
-   all the inline functions required. e.g. MAKEValueArray(unsigned, unsignedArray)
-
- MAKE[Copy]ArrayOf(member, param, array-name) 
-   Declares an array class of members, where param is used as the parameter
-   that is passed into and returned from the access functions.  Including Copy
-   in the name means that no action is taken when the items are destroyed.
+/*
+    Documentation on the template classes:
+
+    CopyReferenceArrayOf<X>
+        An array of references to objects/interfaces of type X.  This array doesn't link count.
+    OwnedReferenceArrayOf<X> {};
+        An array of references to link counted objects/interfaces of type X.  The array takes ownership of the items
+        that are added to it, and will be released when they are removed.
+    OwnedPointerArrayOf<X> {};
+        An array of pointers to link counted objects/interfaces of type X (which may be NULL).  The array takes
+        ownership of the items that are added to it, and will be released when they are removed.
+    SafePointerArrayOf<IInterface> {};
+        An array of pointers to objects/interfaces of type X (may include NULL).  The array takes ownership of the
+        items that are added to it, and will be deleted when they are removed.
+    ArrayOf<X> {}
+        An array of objects of type X.  This is normally used for simple types e.g., unsigned or pointers
+    StructArrayOf<X> {}
+        An array of objects of type X.  This is used where X is a class type because items are passed.
+        Copy constructors are called when items are added, and destructors when they are removed.
+
+    ArrayOf<MEMBER, PARAM, MAPPING> {}
+        The base array implementation which stores elements of type MEMBER, and elements of type PARAM are added.
+        The MAPPING class configures how MEMBERs are mapped to PARAMs, and the operations performed when items
+        are added or removed from the array.
 
 */
 

+ 0 - 0
system/jlib/jarray.tpp


Some files were not shown because too many files changed in this diff