diff --git a/src/epics/seq/CMakeLists.txt b/src/epics/seq/CMakeLists.txt
index 536c25de35f433f12bc9ed1a494fce5a6fde83b3..b737c73d695781f486adff7d52bf8aa5437fca13 100644
--- a/src/epics/seq/CMakeLists.txt
+++ b/src/epics/seq/CMakeLists.txt
@@ -1,5 +1,6 @@
 add_executable(test_sequencer_unit_tests
         test/test_main.cc
+        test/test_simple_range.cc
         test/test_fixed_size_string.cc
         test/test_fixed_size_vector.cc
         )
diff --git a/src/epics/seq/fixed_size_vector.hh b/src/epics/seq/fixed_size_vector.hh
index 66d13e376ad6cb82a6e9100cd04fd498e8ab20a8..6c060a5eff4ee7e80b63ccb7b81ba71cafab4fda 100644
--- a/src/epics/seq/fixed_size_vector.hh
+++ b/src/epics/seq/fixed_size_vector.hh
@@ -168,7 +168,7 @@ namespace embedded
 
         const T& operator[]( size_type index ) const noexcept
         {
-            return *reinterpret_cast< T* >( &storage_[ index ] );
+            return *reinterpret_cast< const T* >( &storage_[ index ] );
         }
 
         void
@@ -206,6 +206,30 @@ namespace embedded
             }
         }
 
+        T&
+        front() noexcept
+        {
+            return operator[](0);
+        }
+
+        T&
+        back() noexcept
+        {
+            return operator[](entries_-1);
+        }
+
+        const T&
+        front() const noexcept
+        {
+            return operator[](0);
+        }
+
+        const T&
+        back() const noexcept
+        {
+            return operator[](entries_-1);
+        }
+
     private:
         storage_type storage_[ max_size ]{};
         size_type    entries_{ 0 };
diff --git a/src/epics/seq/main.cc b/src/epics/seq/main.cc
index 956b83e61baa7e2a8a782d7c800b0a741d847052..8ecf5d66a02ee4835504f0a523b8788219413a41 100644
--- a/src/epics/seq/main.cc
+++ b/src/epics/seq/main.cc
@@ -28,6 +28,8 @@ of this distribution.
 #include <sys/stat.h>
 #include <errno.h>
 #include <ctype.h>
+#include <algorithm>
+#include <iterator>
 
 #ifdef USE_SYSTEM_TIME
 #include <time.h>
@@ -54,9 +56,11 @@ extern "C" {
 #include "asDbLib.h"
 
 #include "fixed_size_string.hh"
+#include "fixed_size_vector.hh"
+#include "simple_range.hh"
 
 using embedded::fixed_string;
-//template <std::size_t Size> using fixed_string = embedded::fixed_string<Size>;
+using embedded::fixed_size_vector;
 
 #ifdef CA_SDF
 #include <mutex>
@@ -182,7 +186,7 @@ typedef struct SET_ERR_TABLE {
 	double liveval;
 	int sigNum;
 	int chFlag;
-	int filtNum;
+	int filtNum{-1};
 	unsigned int sw[2];
 } SET_ERR_TABLE;
 
@@ -205,6 +209,15 @@ typedef struct CA_STARTUP_INFO {
 
 #endif
 
+using table_range = embedded::range<SET_ERR_TABLE*>;
+
+template <std::size_t entry_count>
+table_range
+make_range(fixed_size_vector<SET_ERR_TABLE, entry_count>& cont)
+{
+    return embedded::make_range(&cont[0], &cont[0] + cont.size());
+}
+
 // Gloabl variables		****************************************************************************************
 int chNum = 0;			///< Total number of channels held in the local lookup table.
 int chNotMon = 0;		///< Total number of channels not being monitored.
@@ -222,24 +235,24 @@ char reloadtimechannel[256];	///< Name of EPICS channel which contains the BURT
 struct timespec t;
 char logfilename[128];
 
-CDS_CD_TABLE cdTable[SDF_MAX_TSIZE];		///< Table used to hold EPICS database info for monitoring settings.
-CDS_CD_TABLE cdTableP[SDF_MAX_CHANS];		///< Temp table filled on BURT read and set to EPICS channels.
-FILTER_TABLE filterTable[SDF_MAX_FMSIZE];			///< Table for holding filter module switch settings for comparisons.
-SET_ERR_TABLE setErrTable[SDF_ERR_TSIZE];	///< Table used to report settings diffs.
-SET_ERR_TABLE unknownChans[SDF_ERR_TSIZE];	///< Table used to report channels not found in local database.
-SET_ERR_TABLE uninitChans[SDF_ERR_TSIZE];	///< Table used to report channels not initialized by BURT safe.snap.
-SET_ERR_TABLE unMonChans[SDF_MAX_TSIZE];	///< Table used to report channels not being monitored.
-SET_ERR_TABLE readErrTable[SDF_ERR_TSIZE];	///< Table used to report file read errors..
-SET_ERR_TABLE cdTableList[SDF_MAX_TSIZE];	///< Table used to report file read errors..
-time_t timeTable[SDF_MAX_CHANS];		///< Holds timestamps for cdTableP
+fixed_size_vector<CDS_CD_TABLE, SDF_MAX_TSIZE> cdTable;       ///< Table used to hold EPICS database info for monitoring settings.
+fixed_size_vector<CDS_CD_TABLE, SDF_MAX_CHANS> cdTableP;      ///< Temp table filled on BURT read and set to EPICS channels.
+fixed_size_vector<FILTER_TABLE, SDF_MAX_FMSIZE> filterTable;  ///< Table for holding filter module switch settings for comparisons.
+fixed_size_vector<SET_ERR_TABLE, SDF_ERR_TSIZE> setErrTable;  ///< Table used to report settings diffs.
+fixed_size_vector<SET_ERR_TABLE, SDF_ERR_TSIZE> unknownChans; ///< Table used to report channels not found in local database.
+fixed_size_vector<SET_ERR_TABLE, SDF_ERR_TSIZE> uninitChans;  ///< Table used to report channels not initialized by BURT safe.snap.
+fixed_size_vector<SET_ERR_TABLE, SDF_MAX_TSIZE> unMonChans;	  ///< Table used to report channels not being monitored.
+fixed_size_vector<SET_ERR_TABLE, SDF_ERR_TSIZE> readErrTable; ///< Table used to report file read errors..
+fixed_size_vector<SET_ERR_TABLE, SDF_MAX_TSIZE> cdTableList;  ///< Table used to report file read errors..
+fixed_size_vector<time_t, SDF_MAX_CHANS> timeTable;           ///< Holds timestamps for cdTableP
 
-int filterMasks[SDF_MAX_FMSIZE];		///< Filter monitor masks, as manipulated by the user
+fixed_size_vector<int, SDF_MAX_FMSIZE> filterMasks;		///< Filter monitor masks, as manipulated by the user
 
-dbAddr fmMaskChan[SDF_MAX_FMSIZE];		///< We reflect the mask value into these channels
-dbAddr fmMaskChanCtrl[SDF_MAX_FMSIZE];		///< We signal bit changes to the masks on these channels
+fixed_size_vector<dbAddr, SDF_MAX_FMSIZE> fmMaskChan;		///< We reflect the mask value into these channels
+fixed_size_vector<dbAddr, SDF_MAX_FMSIZE> fmMaskChanCtrl;		///< We signal bit changes to the masks on these channels
 
 #ifdef CA_SDF
-SET_ERR_TABLE disconnectChans[SDF_MAX_TSIZE];
+fixed_size_vector<SET_ERR_TABLE, SDF_MAX_TSIZE> disconnectChans;
 
 // caTable, caConnTAble, chConnNum, chEnumDetermined are protected by the caTableMutex
 EPICS_CA_TABLE caTable[SDF_MAX_TSIZE];		    ///< Table used to hold the data returned by channel access
@@ -286,27 +299,41 @@ int checkFileMod( char* , time_t* , int );
 unsigned int filtCtrlBitConvert(unsigned int);
 void getSdfTime(char *, int size);
 void logFileEntry(const char *);
-void getEpicsSettings(int, time_t *);
-bool writeTable2File(char *burtdir, char *filename, int ftype, CDS_CD_TABLE *myTable);
+void getEpicsSettings();
+
+template <std::size_t entry_count>
+bool writeTable2File(char *burtdir, char *filename, int ftype, fixed_size_vector<CDS_CD_TABLE, entry_count>& myTable);
+
 int savesdffile(int,int,char *,char *,char *,char *,char *,dbAddr,dbAddr,dbAddr);
 int createSortTableEntries(int,int,const char *,int *,time_t*);
-int reportSetErrors(char *,int,SET_ERR_TABLE *,int,int);
-int spChecker(int,SET_ERR_TABLE *,int,char *,int,int *);
-void newfilterstats(int);
-int writeEpicsDb(int,CDS_CD_TABLE *,int);
+template <std::size_t entry_count>
+int reportSetErrors(char *,fixed_size_vector<SET_ERR_TABLE, entry_count>&,int,int);
+template <std::size_t entry_count>
+int spChecker(int,fixed_size_vector<SET_ERR_TABLE, entry_count>&,int,char *,int,int *);
+void newfilterstats();
+
+template <std::size_t entry_count>
+int writeEpicsDb(fixed_size_vector<CDS_CD_TABLE, entry_count>&,int);
 int readConfig( char *,char *,int,char *);
 int parseLine(char *, int,char *,char *,char *,char *,char *,char *);
-int modifyTable(int,SET_ERR_TABLE *);
-int resetSelectedValues(int,SET_ERR_TABLE *);
-void clearTableSelections(int,SET_ERR_TABLE *, int *);
-void setAllTableSelections(int,SET_ERR_TABLE *, int *,int);
-void changeSelectCB_uninit(int, SET_ERR_TABLE *, int *);
-void decodeChangeSelect(int, int, int, SET_ERR_TABLE *, int *, void (*)(int, SET_ERR_TABLE *, int *));
+int modifyTable(table_range);
+template <std::size_t entry_count>
+int resetSelectedValues(fixed_size_vector<SET_ERR_TABLE, entry_count>&);
+template <std::size_t entry_count>
+void clearTableSelections(fixed_size_vector<SET_ERR_TABLE, entry_count>& dcsErrTable, int sc[]);
+void setAllTableSelections(table_range, int *,int);
+void changeSelectCB_uninit(SET_ERR_TABLE&, int *);
+void decodeChangeSelect(int, int, table_range, int *, void (*)(SET_ERR_TABLE&, int *));
 int appendAlarms2File(char *,char *,char *);
 void registerFilters();
-void setupFMArrays(char *,int*,dbAddr*,dbAddr*);
-void resyncFMArrays(int *,dbAddr*);
-void processFMChanCommands(int*,dbAddr*,dbAddr*,int*,int,SET_ERR_TABLE*);
+void setupFMArrays(char *,fixed_size_vector<int, SDF_MAX_FMSIZE>&,
+        fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>&,
+        fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>&);
+void resyncFMArrays(fixed_size_vector<int, SDF_MAX_FMSIZE>&,fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>&);
+void processFMChanCommands(fixed_size_vector<int, SDF_MAX_FMSIZE>&,
+        fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>&,
+        fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>&,
+        int*,table_range);
 void countDisconnectedChannels(int);
 void saveStrSetPoint(int, const char*);
 void updateStrVarSetPoint(int);
@@ -318,8 +345,8 @@ void nullCACallback(struct event_handler_args);
 bool getCAIndex(const char *, ADDRESS *);
 
 int canFindCAChannel(char *entry);
-bool setCAValue(ADDRESS, SDF_TYPE, void *);
-bool setCAValueLong(ADDRESS, PV_INT_TYPE *);
+bool setCAValue(ADDRESS, SDF_TYPE, const void *);
+bool setCAValueLong(ADDRESS, const PV_INT_TYPE *);
 
 bool syncEpicsDoubleValue(ADDRESS, double *, time_t *, int *);
 bool syncEpicsIntValue(ADDRESS, PV_INT_TYPE *, time_t *, int *);
@@ -357,11 +384,11 @@ bool GET_ADDRESS(const char* name, ADDRESS* addr)
 {
     return getCAIndex(name, addr);
 }
-bool PUT_VALUE(ADDRESS addr, SDF_TYPE type, void* pval)
+bool PUT_VALUE(ADDRESS addr, SDF_TYPE type, const void* pval)
 {
     return setCAValue(addr, type, pval);
 }
-bool PUT_VALUE_INT(ADDRESS addr, PV_INT_TYPE* val)
+bool PUT_VALUE_INT(ADDRESS addr, const PV_INT_TYPE* val)
 {
     return setCAValueLong(addr, val);
 }
@@ -393,11 +420,11 @@ bool GET_ADDRESS(const char* name, ADDRESS* addr)
     return dbNameToAddr(name, addr) == 0;
 }
 
-bool PUT_VALUE(ADDRESS addr, SDF_TYPE type, void* pval)
+bool PUT_VALUE(ADDRESS addr, SDF_TYPE type, const void* pval)
 {
     return dbPutField(&addr,(type==SDF_NUM ? DBR_DOUBLE : DBR_STRING),pval,1) == 0;
 }
-bool PUT_VALUE_INT(ADDRESS addr, PV_INT_TYPE *val)
+bool PUT_VALUE_INT(ADDRESS addr, const PV_INT_TYPE *val)
 {
     return dbPutField(&addr, DBR_LONG, val, 1) == 0;
 }
@@ -584,12 +611,16 @@ int parseLine(char *s, int bufSize, char *str1, char *str2, char *str3, char *st
 ///	@param[in] numEntries		Number of entries in the table.	
 ///	@param[in] dcsErrtable 		Pointer to table
 ///	@param[out] sc 			Pointer to change counters.
-void clearTableSelections(int numEntries,SET_ERR_TABLE *dcsErrTable, int sc[])
+template <std::size_t entry_count>
+void clearTableSelections(fixed_size_vector<SET_ERR_TABLE, entry_count>& dcsErrTable, int sc[])
 {
-int ii;
+    int ii;
 	for(ii=0;ii<3;ii++) sc[ii] = 0;
-	for(ii=0;ii<numEntries;ii++) dcsErrTable[ii].chFlag = 0;
-	for(ii=0;ii<numEntries;ii++) dcsErrTable[ii].filtNum = -1;
+	for (auto& entry:dcsErrTable)
+    {
+	    entry.chFlag = 0;
+	    entry.filtNum = -1;
+    }
 }
 
 
@@ -598,40 +629,43 @@ int ii;
 ///	@param[in] dcsErrtable 		Pointer to table
 ///	@param[out] sc 			Pointer to change counters.
 ///	@param[in] selectOp 		Present selection.
-void setAllTableSelections(int numEntries,SET_ERR_TABLE *dcsErrTable, int sc[],int selectOpt)
+void setAllTableSelections(table_range dcsErrTable, int sc[],int selectOpt)
 {
-int ii;
-int filtNum = -1;
-long status = 0;
+    int filtNum = -1;
+    long status = 0;
+
 	switch(selectOpt) {
 		case 1:
 			sc[0] = 0;
-			for(ii=0;ii<numEntries;ii++) {
-				dcsErrTable[ii].chFlag |= 2;
+			for (auto& entry:dcsErrTable)
+			{
+				entry.chFlag |= 2;
 				sc[0] ++;
-				if(dcsErrTable[ii].chFlag & 4) {
-					dcsErrTable[ii].chFlag &= ~(4);
+				if(entry.chFlag & 4) {
+					entry.chFlag &= ~(4);
 					sc[1] --;
 				}
 			}
 			break;
 		case 2:
 			sc[1] = 0;
-			for(ii=0;ii<numEntries;ii++) {
-				dcsErrTable[ii].chFlag |= 4;
+            for (auto& entry:dcsErrTable)
+			{
+				entry.chFlag |= 4;
 				sc[1] ++;
-				if(dcsErrTable[ii].chFlag & 2) {
-					dcsErrTable[ii].chFlag &= ~(2);
+				if(entry.chFlag & 2) {
+					entry.chFlag &= ~(2);
 					sc[0] --;
 				}
 			}
 			break;
 		case 3:
-			sc[2] = numEntries;
-			for(ii=0;ii<numEntries;ii++) {
-				dcsErrTable[ii].chFlag |= 8;
+			sc[2] = std::distance(dcsErrTable.begin(), dcsErrTable.end());
+            for (auto& entry:dcsErrTable)
+			{
+				entry.chFlag |= 8;
 				
-				filtNum = dcsErrTable[ii].filtNum;
+				filtNum = entry.filtNum;
 				if (filtNum >= 0) {
 					if (filterMasks[filtNum] == filterTable[filtNum].mask) {
 						filterMasks[filtNum] = ((ALL_SWSTAT_BITS & filterMasks[filtNum]) > 0 ? 0 : ~0);
@@ -649,12 +683,12 @@ long status = 0;
 ///	@param[in] index		Number providing the index into the dcsErrTable
 ///	@param[in] dcsErrTable		Pointer to table
 ///	@param[out] selectCounter	Pointer to change counters
-void changeSelectCB_uninit(int index, SET_ERR_TABLE *dcsErrTable, int selectCounter[])
+void changeSelectCB_uninit(SET_ERR_TABLE &errTableEntry, int selectCounter[])
 {
-	int revertBit = dcsErrTable[index].chFlag & 2;
-	int acceptBit = dcsErrTable[index].chFlag & 4;
-	int monBit = dcsErrTable[index].chFlag & 8;
-	int otherBits = 0; //dcsErrTable[index].chFlag | ~(2 | 4 | 8);
+	int revertBit = errTableEntry.chFlag & 2;
+	int acceptBit = errTableEntry.chFlag & 4;
+	int monBit = errTableEntry.chFlag & 8;
+	int otherBits = 0; //errTableEntry.chFlag | ~(2 | 4 | 8);
 
 	// revert is not defined on this table
 	if (revertBit) {
@@ -666,7 +700,7 @@ void changeSelectCB_uninit(int index, SET_ERR_TABLE *dcsErrTable, int selectCoun
 		acceptBit = 4;
 		selectCounter[1] ++;
 	} 
-	dcsErrTable[index].chFlag = revertBit | acceptBit | monBit | otherBits;
+	errTableEntry.chFlag = revertBit | acceptBit | monBit | otherBits;
 }
 
 /// Common routine to set/unset individual entries for table changes..
@@ -675,40 +709,42 @@ void changeSelectCB_uninit(int index, SET_ERR_TABLE *dcsErrTable, int selectCoun
 ///	@param[in] totalItems		Number items selected for change.
 ///	@param[in] dcsErrtable 		Pointer to table
 ///	@param[out] selectCounter 	Pointer to change counters.
-void decodeChangeSelect(int selNum, int page, int totalItems, SET_ERR_TABLE *dcsErrTable, int selectCounter[], void (*cb)(int, SET_ERR_TABLE*, int*))
+void decodeChangeSelect(int selNum, int page, table_range dcsErrTable, int selectCounter[], void (*cb)(SET_ERR_TABLE&, int*))
 {
-int selectBit;
-int selectLine;
+    int selectBit;
+    int selectLine;
 
 	selectBit = selNum / 100;
 	selectLine = selNum % 100 - 1;
 	selNum += page * SDF_ERR_DSIZE;
 	selectLine += page * SDF_ERR_DSIZE;
-	if(selectLine < totalItems) {
+
+	auto selection = dcsErrTable.begin() + selectLine;
+	if(selection < dcsErrTable.end()) {
 		switch (selectBit) {
 			case 0:
-				dcsErrTable[selectLine].chFlag ^= 2;
-				if(dcsErrTable[selectLine].chFlag & 2) selectCounter[0] ++;
+				selection->chFlag ^= 2;
+				if(selection->chFlag & 2) selectCounter[0] ++;
 				else selectCounter[0] --;
-				if(dcsErrTable[selectLine].chFlag & 4) {
-					dcsErrTable[selectLine].chFlag &= ~(4);
+				if(selection->chFlag & 4) {
+					selection->chFlag &= ~(4);
 					selectCounter[1] --;
 				}
 				break;
 			case 1:
-				dcsErrTable[selectLine].chFlag ^= 4;
-				if(dcsErrTable[selectLine].chFlag & 4) selectCounter[1] ++;
+				selection->chFlag ^= 4;
+				if(selection->chFlag & 4) selectCounter[1] ++;
 				else selectCounter[1] --;
-				if(dcsErrTable[selectLine].chFlag & 2) {
-					dcsErrTable[selectLine].chFlag &= ~(2);
+				if(selection->chFlag & 2) {
+					selection->chFlag &= ~(2);
 					selectCounter[0] --;
 				}
 				break;
 			case 2:
 				/* we only handle non-filter bank entries here */
-				if (dcsErrTable[selectLine].filtNum < 0) {
-					dcsErrTable[selectLine].chFlag ^= 8;
-					if(dcsErrTable[selectLine].chFlag & 8) selectCounter[2] ++;
+				if (selection->filtNum < 0) {
+					selection->chFlag ^= 8;
+					if(selection->chFlag & 8) selectCounter[2] ++;
 					else selectCounter[2] --;
 				}
 				break;
@@ -716,7 +752,7 @@ int selectLine;
 				break;
 		}
 		if (cb)
-			cb(selectLine, dcsErrTable, selectCounter);
+			cb(*selection, selectCounter);
 	}
 }
 
@@ -852,10 +888,10 @@ void createSwitchText(FILTER_TABLE *filter, StringLike& dest) {
 }
 
 /// Routine to check filter switch settings and provide info on switches not set as requested.
-/// @param[in] fcount	Number of filters in the control model.
 /// @param[in] monitorAll	Global monitoring flag.
 /// @return	Number of errant switch settings found.
-int checkFilterSwitches(int fcount, SET_ERR_TABLE setErrTable[], int monitorAll, int displayall, int wcflag, char *wcstr, int *diffcntr)
+template <std::size_t entry_count>
+int checkFilterSwitches(fixed_size_vector<SET_ERR_TABLE, entry_count>& setErrTable, int monitorAll, int displayall, int wcflag, char *wcstr, int *diffcntr)
 {
 unsigned int refVal=0;
 unsigned int presentVal=0;
@@ -863,7 +899,7 @@ unsigned int x=0,y=0;
 unsigned int mask = 0;
 unsigned int maskedRefVal = 0;
 unsigned int maskedSwReqVal = 0;
-int ii=0,jj=0;
+int jj=0;
 int errCnt = 0;
 fixed_string<64>swname[3];
 fixed_string<64> tmpname;
@@ -880,15 +916,17 @@ ADDRESS paddr1;
 ADDRESS paddr2;
 long status=0;
 
-	for(ii=0;ii<fcount;ii++)
-	{
+    auto filtNum = -1;
+    for (const auto& curFilt:filterTable)
+    {
+        ++filtNum;
 		bzero(buffer, sizeof(struct buffer)*2);
 
-		swname[0] = filterTable[ii].fname;
+		swname[0] = curFilt.fname;
 		swname[0] += "SW1S";
-		swname[1] = filterTable[ii].fname;
+		swname[1] = curFilt.fname;
 		swname[1] += "SW2S";
-		swname[2] = filterTable[ii].fname;
+		swname[2] = curFilt.fname;
 		swname[2] += "SWSTR";
 		GET_ADDRESS(swname[0],&paddr);
 		GET_VALUE_INT(paddr,&(buffer[0].rval),&(buffer[0].t), 0);
@@ -897,15 +935,17 @@ long status=0;
 		for(jj=0;jj<2;jj++) {
 			if(buffer[jj].rval > 0xffff || buffer[jj].rval < 0)	// Switch setting overrange
 			{
-				setErrTable[errCnt].chname = swname[jj];
-				setErrTable[errCnt].burtset = " ";
-				setErrTable[errCnt].liveset.printf("0x%x", buffer[jj].rval);
-				setErrTable[errCnt].diff = "OVERRANGE";
-				setErrTable[errCnt].liveval = 0.0;
-				setErrTable[errCnt].sigNum = filterTable[ii].sw[jj];
+			    setErrTable.emplace_back();
+			    auto& curErr = setErrTable.back();
+				curErr.chname = swname[jj];
+				curErr.burtset = " ";
+				curErr.liveset.printf("0x%x", buffer[jj].rval);
+				curErr.diff = "OVERRANGE";
+				curErr.liveval = 0.0;
+				curErr.sigNum = curFilt.sw[jj];
 				// take the latest change time between the SW1S & SW2S channels
 				mtime = (buffer[0].t >= buffer[1].t ? buffer[0].t : buffer[1].t);
-				setErrTable[errCnt].timeset = ctime(&mtime);
+				curErr.timeset = ctime(&mtime);
 				buffer[jj].rval &= 0xffff;
 				errCnt ++;
 			}
@@ -916,39 +956,41 @@ long status=0;
 		x = refVal;
 		GET_ADDRESS(swname[2],&paddr2);
 		PUT_VALUE_STR(paddr2,swstrE);
-		setErrTable[errCnt].filtNum = -1;
+		//setErrTable[errCnt].filtNum = -1;
 
-		mask = (unsigned int)filterTable[ii].mask;
+		mask = (unsigned int)curFilt.mask;
 		maskedRefVal = refVal & mask;
-		maskedSwReqVal = filterTable[ii].swreq & mask;
-		if(( maskedRefVal != maskedSwReqVal && errCnt < SDF_ERR_TSIZE && (mask || monitorAll) && filterTable[ii].init) )
+		maskedSwReqVal = curFilt.swreq & mask;
+		if(( maskedRefVal != maskedSwReqVal && errCnt < SDF_ERR_TSIZE && (mask || monitorAll) && curFilt.init) )
 			*diffcntr += 1;
-		if(( maskedRefVal != maskedSwReqVal && errCnt < SDF_ERR_TSIZE && (mask || monitorAll) && filterTable[ii].init) || displayall)
+		if(( maskedRefVal != maskedSwReqVal && errCnt < SDF_ERR_TSIZE && (mask || monitorAll) && curFilt.init) || displayall)
 		{
 			filtStrBitConvert(1,refVal,swstrE);
-			filtStrBitConvert(1,filterTable[ii].swreq,swstrB);
+			filtStrBitConvert(1,curFilt.swreq,swstrB);
 			x = maskedRefVal ^ maskedSwReqVal;
 			filtStrBitConvert(1,x,swstrD);
-			tmpname = filterTable[ii].fname;
+			tmpname = curFilt.fname;
 
 			if(!wcflag || (wcflag && (strstr(tmpname.c_str(),wcstr) != NULL))) {
-			setErrTable[errCnt].chname = tmpname;
-			setErrTable[errCnt].burtset = swstrB;
-			setErrTable[errCnt].liveset = swstrE;
-			setErrTable[errCnt].diff = swstrD;
-			
-			setErrTable[errCnt].liveval = 0.0;
-			setErrTable[errCnt].sigNum = filterTable[ii].sw[0] + (filterTable[ii].sw[1] * SDF_MAX_TSIZE);
-			setErrTable[errCnt].filtNum = ii;
-			setErrTable[errCnt].sw[0] = buffer[0].rval;
-			setErrTable[errCnt].sw[1] = buffer[1].rval;
-			if(filterTable[ii].mask & ALL_SWSTAT_BITS) setErrTable[errCnt].chFlag |= 0x1;
-			else setErrTable[errCnt].chFlag &= 0xe;
-
-			// take the latest change time between the SW1S & SW2S channels
-			mtime = (buffer[0].t >= buffer[1].t ? buffer[0].t : buffer[1].t);
-			setErrTable[errCnt].timeset = ctime(&mtime);
-			errCnt ++;
+			    setErrTable.emplace_back();
+			    auto& curErr = setErrTable.back();
+                curErr.chname = tmpname;
+                curErr.burtset = swstrB;
+                curErr.liveset = swstrE;
+                curErr.diff = swstrD;
+
+                curErr.liveval = 0.0;
+                curErr.sigNum = curFilt.sw[0] + (curFilt.sw[1] * SDF_MAX_TSIZE);
+                curErr.filtNum = filtNum;
+                curErr.sw[0] = buffer[0].rval;
+                curErr.sw[1] = buffer[1].rval;
+                if(curFilt.mask & ALL_SWSTAT_BITS) curErr.chFlag |= 0x1;
+                else curErr.chFlag &= 0xe;
+
+                // take the latest change time between the SW1S & SW2S channels
+                mtime = (buffer[0].t >= buffer[1].t ? buffer[0].t : buffer[1].t);
+                curErr.timeset = ctime(&mtime);
+                errCnt ++;
 			}
 		}
 	}
@@ -1008,42 +1050,36 @@ void logFileEntry(const char *message)
 /// Function to read all settings, listed in main table, from the EPICS database.
 ///	@param[in] numchans The number of channels listed in the main table.
 ///	@param[out] times (Optional) An array of at least numchans time_t values to put change times in
-void getEpicsSettings(int numchans, time_t *times)
+void getEpicsSettings()
 {
-int ii;
-long status;
-int chcount = 0;
-double dval = 0;
-ADDRESS geaddr;
-bool statusR = false;
-char sval[64];
-time_t *change_t = 0;
-
-	for(ii=0;ii<numchans;ii++)
-	{
-		// Load main table settings into temp (cdTableP)
-		cdTableP[ii].chname = cdTable[ii].chname;
-		cdTableP[ii].datatype = cdTable[ii].datatype;
-		cdTableP[ii].mask = cdTable[ii].mask;
-		cdTableP[ii].initialized = cdTable[ii].initialized;
-		// Find address of channel
-		if(GET_ADDRESS(cdTableP[ii].chname,&geaddr)) {
-			change_t = ( times ? &times[ii] : 0 );
-			if(cdTableP[ii].datatype == SDF_NUM)
-			{
-				statusR = GET_VALUE_NUM(geaddr,&dval,change_t, NULL); //&(cdTableP[ii].connected));
-				if (statusR) cdTableP[ii].data.chval = (cdTable[ii].filterswitch ? (int)dval & 0xffff : dval);
-			} else {
-				statusR = GET_VALUE_STR(geaddr,sval,sizeof(sval),change_t, NULL); //&(cdTableP[ii].connected));
-				if(statusR) sprintf(cdTableP[ii].data.strval,"%s",sval);
-			}
-			chcount ++;
-		}
-	}
-}
-
-void encodeBURTString(char *src, char *dest, int dest_size) {
-	char *ch = 0;
+    cdTableP.clear();
+    std::transform(cdTable.begin(), cdTable.end(), std::back_inserter( cdTableP),
+                   [](const CDS_CD_TABLE& entry) -> CDS_CD_TABLE {
+        CDS_CD_TABLE result;
+        result.chname = entry.chname;
+        result.datatype = entry.datatype;
+        result.mask = entry.mask;
+        result.initialized = entry.initialized;
+
+        ADDRESS geaddr;
+        if(GET_ADDRESS(result.chname,&geaddr)) {
+            time_t* change_t = nullptr;
+           if(result.datatype == SDF_NUM)
+           {
+               double dval;
+               if (GET_VALUE_NUM(geaddr,&dval,change_t, NULL)) {
+                   result.data.chval = (entry.filterswitch ? (int) dval & 0xffff : dval);
+               }
+           } else {
+               GET_VALUE_STR(geaddr,result.data.strval, sizeof(result.data.strval),change_t, NULL);
+           }
+       }
+        return result;
+    });
+}
+
+void encodeBURTString(const char *src, char *dest, int dest_size) {
+	const char *ch = 0;
 	int expand = 0;
 
 	if (!src || !dest || dest_size < 1) return;
@@ -1073,10 +1109,11 @@ void encodeBURTString(char *src, char *dest, int dest_size) {
 #define SDF_FILE_PARAMS_ONLY	1
 #define SDF_FILE_BURT_ONLY	2
 /// Common routine for saving table data to BURT files.
+template <std::size_t entry_count>
 bool writeTable2File(char *burtdir,
                      char *filename, 		///< Name of file to write
 		    int ftype, 			///< Type of file to write
-		    CDS_CD_TABLE *myTable)	///< Table to be written.
+		    fixed_size_vector<CDS_CD_TABLE, entry_count>& myTable)	///< Table to be written.
 {
         int ii;
         FILE *csFile=0;
@@ -1113,18 +1150,18 @@ bool writeTable2File(char *burtdir,
 	fprintf(csFile,"%s\n","Req File: autoBurt.req ");
 	fprintf(csFile,"%s\n","--- End BURT header");
 
-	for(ii=0;ii<chNum;ii++)
+	for (const auto& entry:myTable)
 	{
-		if (myTable[ii].filterswitch) {
-			if ((myTable[ii].mask & ALL_SWSTAT_BITS)== ~0) {
+		if (entry.filterswitch) {
+			if ((entry.mask & ALL_SWSTAT_BITS)== ~0) {
 				strcpy(monitorstring, "1");
-			} else if ((myTable[ii].mask & ALL_SWSTAT_BITS) == 0) {
+			} else if ((entry.mask & ALL_SWSTAT_BITS) == 0) {
 				strcpy(monitorstring, "0");
 			} else {
-				snprintf(monitorstring, sizeof(monitorstring), "0x%x", myTable[ii].mask);
+				snprintf(monitorstring, sizeof(monitorstring), "0x%x", entry.mask);
 			}
 		} else {
-			if (myTable[ii].mask)
+			if (entry.mask)
 				strcpy(monitorstring,"1");
 			else
 				strcpy(monitorstring,"0");
@@ -1133,28 +1170,28 @@ bool writeTable2File(char *burtdir,
 		{
 		   case SDF_WITH_INIT_FLAG:
 			if(myTable[ii].datatype == SDF_NUM) {
-				fprintf(csFile,"%s %d %.*e %s %d\n",myTable[ii].chname,1,precision,myTable[ii].data.chval,monitorstring,myTable[ii].initialized);
+				fprintf(csFile,"%s %d %.*e %s %d\n",entry.chname,1,precision,entry.data.chval,monitorstring,entry.initialized);
 			} else {
-				encodeBURTString(myTable[ii].data.strval, burtString, sizeof(burtString));
-				fprintf(csFile,"%s %d %s %s %d\n",myTable[ii].chname,1,burtString,monitorstring,myTable[ii].initialized);
+				encodeBURTString(entry.data.strval, burtString, sizeof(burtString));
+				fprintf(csFile,"%s %d %s %s %d\n",entry.chname,1,burtString,monitorstring,entry.initialized);
 			}
 			break;
 		   case SDF_FILE_PARAMS_ONLY:
-			if(myTable[ii].initialized) {
-				if(myTable[ii].datatype == SDF_NUM) {
-					fprintf(csFile,"%s %d %.*e %s\n",myTable[ii].chname,1,precision,myTable[ii].data.chval,monitorstring);
+			if(entry.initialized) {
+				if(entry.datatype == SDF_NUM) {
+					fprintf(csFile,"%s %d %.*e %s\n",entry.chname,1,precision,entry.data.chval,monitorstring);
 				} else {
-					encodeBURTString(myTable[ii].data.strval, burtString, sizeof(burtString));
-					fprintf(csFile,"%s %d %s %s\n",myTable[ii].chname,1,burtString,monitorstring);
+					encodeBURTString(entry.data.strval, burtString, sizeof(burtString));
+					fprintf(csFile,"%s %d %s %s\n",entry.chname,1,burtString,monitorstring);
 				}
 			}
 			break;
 		   case SDF_FILE_BURT_ONLY:
-			if(myTable[ii].datatype == SDF_NUM) {
-				fprintf(csFile,"%s %d %.*e\n",myTable[ii].chname,1,precision,myTable[ii].data.chval);
+			if(entry.datatype == SDF_NUM) {
+				fprintf(csFile,"%s %d %.*e\n",entry.chname,1,precision,entry.data.chval);
 			} else {
-				encodeBURTString(myTable[ii].data.strval, burtString, sizeof(burtString));
-				fprintf(csFile,"%s %d %s \n",myTable[ii].chname,1,burtString);
+				encodeBURTString(entry.data.strval, burtString, sizeof(burtString));
+				fprintf(csFile,"%s %d %s \n",entry.chname,1,burtString);
 			}
 			break;
 		   default:
@@ -1288,7 +1325,7 @@ char shortfilename[64];
                         break;
 		case SAVE_EPICS_AS_SDF:
 			// printf("Save epics as sdf\n");
-			getEpicsSettings(chNum, NULL);
+			getEpicsSettings();
 			if(!writeTable2File(sdfdir,filename,SDF_FILE_PARAMS_ONLY,cdTableP)) {
                             sprintf(filemsg,"FAILED EPICS SAVE %s",filename);
 			    logFileEntry(filemsg);
@@ -1308,6 +1345,8 @@ char shortfilename[64];
 	status = dbPutField(&staddr,DBR_STRING,timestring,1);
 	status = dbPutField(&rladdr,DBR_STRING,timestring,1);
 	return(0);
+
+	// I can type above your caret
 }
 
 
@@ -1522,9 +1561,9 @@ double liveval = 0.0;
 }
 
 /// Common routine to load monitoring tables into EPICS channels for MEDM screen.
+template <std::size_t entry_count>
 int reportSetErrors(char *pref,			///< Channel name prefix from EPICS environment. 
-		     int numEntries, 			///< Number of entries in table to be reported.
-		     SET_ERR_TABLE setErrTable[],	///< Which table to report to EPICS channels.
+		     fixed_size_vector<SET_ERR_TABLE , entry_count>& setErrTable,	///< Which table to report to EPICS channels.
 		     int page,                      ///< Which page of 40 to display.
              int linkInFilters)				///< Should the SDF_FM_LINE values be set.
 {
@@ -1560,21 +1599,22 @@ int minusOne = -1;
 
 	// Get the page number to display
 	mypage = page;
-	// Calculat start index to the diff table.
+	// Calculate start index to the diff table.
 	myindex = page *  SDF_ERR_DSIZE;
+	int numEntries = setErrTable.size();
 	if(myindex == numEntries && numEntries > 0) {
 		mypage --;
 		myindex = mypage *  SDF_ERR_DSIZE;
 	}
 	// If index is > number of entries in the table, then page back.
-        if(myindex > numEntries) {
+    if(myindex > numEntries) {
 		mypage = numEntries / SDF_ERR_DSIZE;
 		myindex = mypage *  SDF_ERR_DSIZE;
-        }
+    }
 	// Set the stop index to the diff table.
 	rc = myindex + SDF_ERR_DSIZE;
 	// If stop index beyond last diff table entry, set it to last entry.
-        if(rc > numEntries) rc = numEntries;
+    if(rc > numEntries) rc = numEntries;
 	numDisp = rc - myindex;
 
 	// Fill in table entries.
@@ -1583,7 +1623,7 @@ int minusOne = -1;
 		sprintf(s, "%s_%s_STAT%d", pref,"SDF_SP", lineNum);
 		status = dbNameToAddr(s,&saddr);
 		//sprintf(stmp, "%s%s", (setErrTable[ii].filtNum >= 0 ? "* " : ""), setErrTable[ii].chname);
-		status = dbPutField(&saddr,DBR_UCHAR,&setErrTable[ii].chname,flength);
+		status = dbPutField(&saddr,DBR_UCHAR,setErrTable[ii].chname.c_str(),flength);
 
 		sprintf(s1, "%s_%s_STAT%d_BURT", pref,"SDF_SP", lineNum);
 		status = dbNameToAddr(s1,&baddr);
@@ -1618,7 +1658,7 @@ int minusOne = -1;
 	}
 
 	// Clear out empty table entries.
-	for(ii=numDisp;ii<40;ii++)
+	for(ii=numDisp;ii<SDF_ERR_DSIZE;ii++)
 	{
 		sprintf(s, "%s_%s_STAT%d", pref,"SDF_SP", ii);
 		status = dbNameToAddr(s,&saddr);
@@ -1667,12 +1707,13 @@ int minusOne = -1;
 //	- Present Value
 //	- Time the present setting was applied.
 /// Setpoint monitoring routine.
-int spChecker(int monitorAll, SET_ERR_TABLE setErrTable[],int wcVal, char *wcstring, int listAll, int *totalDiffs)
+template <std::size_t entry_count>
+int spChecker(int monitorAll, fixed_size_vector<SET_ERR_TABLE, entry_count>& setErrTable,int wcVal, char *wcstring, int listAll, int *totalDiffs)
 {
    	int errCntr = 0;
 	ADDRESS paddr;
 	long status=0;
-	int ii;
+	//int ii;
 	double rval;
 	fixed_string<128> sval;
 	time_t mtime;
@@ -1698,28 +1739,32 @@ int spChecker(int monitorAll, SET_ERR_TABLE setErrTable[],int wcVal, char *wcstr
 */
 #endif
 	// Check filter switch settings first
-	     errCntr = checkFilterSwitches(fmNum,setErrTable,monitorAll,listAll,wcVal,wcstring,&filtDiffs);
-	     *totalDiffs = filtDiffs;
-	     if(chNum) {
-		for(ii=0;ii<chNum;ii++) {
+        setErrTable.clear();
+	    errCntr = checkFilterSwitches(setErrTable,monitorAll,listAll,wcVal,wcstring,&filtDiffs);
+	    *totalDiffs = filtDiffs;
+
+	    int index = -1;
+	    for (auto& curSP: cdTable)
+        {
+	        ++index;
 			if((errCntr < SDF_ERR_TSIZE) && 		// Within table max size
-			  ((cdTable[ii].mask != 0) || (monitorAll)) && 	// Channel is to be monitored
-			   cdTable[ii].initialized && 			// Channel was set in BURT
-			   cdTable[ii].filterswitch == 0 ||		// Not a filter switch channel
-			   (listAll && cdTable[ii].filterswitch == 0))
+			  ((curSP.mask != 0) || (monitorAll)) && 	// Channel is to be monitored
+			   curSP.initialized && 			// Channel was set in BURT
+			   curSP.filterswitch == 0 ||		// Not a filter switch channel
+			   (listAll && curSP.filterswitch == 0))
 			{
 				localErr = 0;
 				mtime = 0;
 				// Find address of channel
-				GET_ADDRESS(cdTable[ii].chname,&paddr);
+				GET_ADDRESS(curSP.chname,&paddr);
 				// If this is a digital data type, then get as double.
-				if(cdTable[ii].datatype == SDF_NUM)
+				if(curSP.datatype == SDF_NUM)
 				{
-					GET_VALUE_NUM(paddr,&rval,&mtime, NULL); //&(cdTable[ii].connected));
-					if(cdTable[ii].data.chval != rval || listAll)
+					GET_VALUE_NUM(paddr,&rval,&mtime, NULL); //&(curSP.connected));
+					if(curSP.data.chval != rval || listAll)
 					{
-						sdfdiff = fabs(cdTable[ii].data.chval - rval);
-						burtset.printf("%.10lf",cdTable[ii].data.chval);
+						sdfdiff = fabs(curSP.data.chval - rval);
+						burtset.printf("%.10lf",curSP.data.chval);
 						liveset.printf("%.10lf",rval);
 						liveval = rval;
 						diffB2L.printf("%.8le",sdfdiff);
@@ -1727,11 +1772,11 @@ int spChecker(int monitorAll, SET_ERR_TABLE setErrTable[],int wcVal, char *wcstr
 					}
 				// If this is a string type, then get as string.
 				} else {
-                    updateStrVarSetPoint(ii);
-					GET_VALUE_STR(paddr,sval,&mtime, NULL); //&(cdTable[ii].connected));
-					if(sval != cdTable[ii].data.strval || listAll)
+                    updateStrVarSetPoint(index);
+					GET_VALUE_STR(paddr,sval,&mtime, NULL); //&(curSP.connected));
+					if(sval != curSP.data.strval || listAll)
 					{
-						burtset = cdTable[ii].data.strval;
+						burtset = curSP.data.strval;
 						liveset = sval;
 						liveval = 0.0;
 						diffB2L.printf("%s","                                   ");
@@ -1739,30 +1784,31 @@ int spChecker(int monitorAll, SET_ERR_TABLE setErrTable[],int wcVal, char *wcstr
 					}
 				}
 				if(localErr) *totalDiffs += 1;
-				if(localErr && wcVal  && (strstr(cdTable[ii].chname.c_str(),wcstring) == NULL))
+				if(localErr && wcVal  && (strstr(curSP.chname.c_str(),wcstring) == NULL))
 					localErr = 0;
 				// If a diff was found, then write info the EPICS setpoint diff table.
 				if(localErr)
 				{
-					setErrTable[errCntr].chname = cdTable[ii].chname;
+				    setErrTable.emplace_back();
+				    auto& curErr = setErrTable.back();
+					curErr.chname = curSP.chname;
 
-					setErrTable[errCntr].burtset = burtset;
+					curErr.burtset = burtset;
 
-					setErrTable[errCntr].liveset = liveset;
-					setErrTable[errCntr].liveval = liveval;
-					setErrTable[errCntr].diff = diffB2L;
-					setErrTable[errCntr].sigNum = ii;
-					setErrTable[errCntr].filtNum = -1;
+					curErr.liveset = liveset;
+					curErr.liveval = liveval;
+					curErr.diff = diffB2L;
+					curErr.sigNum = index;
+					curErr.filtNum = -1;
 
 					localtimestring = ctime(&mtime);
-					setErrTable[errCntr].timeset = localtimestring;
-					if(cdTable[ii].mask) setErrTable[errCntr].chFlag |= 1;
-					else setErrTable[errCntr].chFlag &= ~(1);
+					curErr.timeset = localtimestring;
+					if(curSP.mask) curErr.chFlag |= 1;
+					else curErr.chFlag &= ~(1);
 					errCntr ++;
 				}
 			}
 		}
-	     }
 	return(errCntr);
 }
 
@@ -1772,29 +1818,30 @@ int spChecker(int monitorAll, SET_ERR_TABLE setErrTable[],int wcVal, char *wcstr
 /// @param modTable[in] An array of SET_ERR_TABLE entries that hold the current views state to be merged with cdTable
 ///
 /// @remark modifies cdTable
-int modifyTable(int numEntries,SET_ERR_TABLE modTable[])
+int modifyTable(table_range modTable)
 {
-int ii,jj;
-int fmIndex = -1;
-unsigned int sn,sn1;
-int found = 0;
-	for(ii=0;ii<numEntries;ii++)
+    int jj;
+    int fmIndex = -1;
+    unsigned int sn,sn1;
+    int found = 0;
+
+	for (const auto& entry:modTable)
 	{
 		// if accept or monitor is set
-		if(modTable[ii].chFlag > 3) 
+		if(entry.chFlag > 3)
 		{
 			found = 0;
 			for(jj=0;jj<chNum;jj++)
 			{
-				if (cdTable[jj].chname == modTable[ii].chname) {
-					if ( CHFLAG_ACCEPT_BIT(modTable[ii].chFlag) ) {
-						if(cdTable[jj].datatype == SDF_NUM) cdTable[jj].data.chval = modTable[ii].liveval;/* atof(modTable[ii].liveset);*/
-						else sprintf(cdTable[jj].data.strval,"%s",modTable[ii].liveset);
+				if (cdTable[jj].chname == entry.chname) {
+					if ( CHFLAG_ACCEPT_BIT(entry.chFlag) ) {
+						if(cdTable[jj].datatype == SDF_NUM) cdTable[jj].data.chval = entry.liveval;/* atof(entry.liveset);*/
+						else sprintf(cdTable[jj].data.strval,"%s",entry.liveset);
 						cdTable[jj].initialized = 1;
 						found = 1;
 						fmIndex = cdTable[jj].filterNum;
 					}
-					if(CHFLAG_MONITOR_BIT(modTable[ii].chFlag)) {
+					if(CHFLAG_MONITOR_BIT(entry.chFlag)) {
 						fmIndex = cdTable[jj].filterNum;
 						if (fmIndex >= 0 && fmIndex < SDF_MAX_FMSIZE) {
 							// filter module use the manualy modified state, cannot just toggle
@@ -1807,21 +1854,21 @@ int found = 0;
 					}
 				}
 			}
-			if(modTable[ii].filtNum >= 0 && !found) { 
-				fmIndex = modTable[ii].filtNum;
+			if(entry.filtNum >= 0 && !found) {
+				fmIndex = entry.filtNum;
 				// printf("This is a filter from diffs = %s\n",filterTable[fmIndex].fname);
 				filterTable[fmIndex].newSet = 1;
-				sn = modTable[ii].sigNum;
+				sn = entry.sigNum;
 				sn1 = sn / SDF_MAX_TSIZE;
 				sn %= SDF_MAX_TSIZE;
-				if(CHFLAG_ACCEPT_BIT(modTable[ii].chFlag)) {
-					cdTable[sn].data.chval = modTable[ii].sw[0];
+				if(CHFLAG_ACCEPT_BIT(entry.chFlag)) {
+					cdTable[sn].data.chval = entry.sw[0];
 					cdTable[sn].initialized = 1;
-					cdTable[sn1].data.chval = modTable[ii].sw[1];
+					cdTable[sn1].data.chval = entry.sw[1];
 					cdTable[sn1].initialized = 1;
 					filterTable[fmIndex].init = 1;
 				}
-				if(CHFLAG_MONITOR_BIT(modTable[ii].chFlag)) {
+				if(CHFLAG_MONITOR_BIT(entry.chFlag)) {
 					filterTable[fmIndex].mask = filterMasks[fmIndex];
 				 	cdTable[sn].mask = filterMasks[fmIndex];
 				 	cdTable[sn1].mask = filterMasks[fmIndex];
@@ -1829,23 +1876,23 @@ int found = 0;
 			}
 		}
 	}
-	newfilterstats(fmNum);
+	newfilterstats();
 	return(0);
 }
 
-int resetSelectedValues(int errNum, SET_ERR_TABLE modTable[])
+template <std::size_t entry_count>
+int resetSelectedValues(fixed_size_vector<SET_ERR_TABLE, entry_count>& modTable)
 {
 long status;
-int ii;
 int sn;
 int sn1 = 0;
 ADDRESS saddr;
 
-	for(ii=0;ii<errNum;ii++)
+	for(const auto& entry:modTable)
 	{
-		if (modTable[ii].chFlag & 2)
+		if (entry.chFlag & 2)
 		{
-			sn = modTable[ii].sigNum;
+			sn = entry.sigNum;
 			if(sn > SDF_MAX_TSIZE) {
 				sn1 = sn / SDF_MAX_TSIZE;
 				sn %= SDF_MAX_TSIZE;
@@ -1863,10 +1910,10 @@ ADDRESS saddr;
 }
 
 /// This function sets filter module request fields to aid in decoding errant filter module switch settings.
-void newfilterstats(int numchans) {
+void newfilterstats() {
 	ADDRESS paddr;
 	long status;
-	int ii;
+
 	FILE *log=0;
 	fixed_string<128> chname;
 	unsigned int mask = 0x1ffff;
@@ -1876,28 +1923,28 @@ void newfilterstats(int numchans) {
 	unsigned int tmpL = 0;
 
 	printf("In newfilterstats\n");
-	for(ii=0;ii<numchans;ii++) {
-		if(filterTable[ii].newSet) {
+	for(auto& filterEntry:filterTable) {
+		if(filterEntry.newSet) {
 			counter ++;
-			filterTable[ii].newSet = 0;
-			filterTable[ii].init = 1;
-			rsw1 = filterTable[ii].sw[0];
-			rsw2 = filterTable[ii].sw[1];
-			filterTable[ii].mask =  cdTable[rsw1].mask | cdTable[rsw2].mask;;
-			cdTable[rsw1].mask = filterTable[ii].mask;
-			cdTable[rsw2].mask = filterTable[ii].mask;
+			filterEntry.newSet = 0;
+			filterEntry.init = 1;
+			rsw1 = filterEntry.sw[0];
+			rsw2 = filterEntry.sw[1];
+			filterEntry.mask =  cdTable[rsw1].mask | cdTable[rsw2].mask;;
+			cdTable[rsw1].mask = filterEntry.mask;
+			cdTable[rsw2].mask = filterEntry.mask;
 			tmpreq =  ((unsigned int)cdTable[rsw1].data.chval & 0xffff) + 
 				(((unsigned int)cdTable[rsw2].data.chval & 0xffff) << 16);
-			filterTable[ii].swreq = filtCtrlBitConvert(tmpreq);
+			filterEntry.swreq = filtCtrlBitConvert(tmpreq);
 			// Find address of channel
-			chname  = filterTable[ii].fname;
+			chname  = filterEntry.fname;
 			chname += "SWREQ";
 			if(GET_ADDRESS(chname,&paddr)) {
-				tmpL = (unsigned int)filterTable[ii].swreq;
+				tmpL = (unsigned int)filterEntry.swreq;
 				PUT_VALUE_INT(paddr,&tmpL);
 			}
 			// Find address of channel
-			chname = filterTable[ii].fname;
+			chname = filterEntry.fname;
 			chname += "SWMASK";
 			if(GET_ADDRESS(chname,&paddr)) {
 				PUT_VALUE_INT(paddr,&mask);
@@ -1909,54 +1956,43 @@ void newfilterstats(int numchans) {
 }
 
 /// This function writes BURT settings to EPICS records.
-int writeEpicsDb(int numchans,		///< Number of channels to write
-	         CDS_CD_TABLE myTable[],	///< Table with data to be written.
+template <std::size_t entry_count>
+int writeEpicsDb(fixed_size_vector<CDS_CD_TABLE, entry_count>& myTable,	///< Table with data to be written.
 	     	 int command) 		///< Write request.
 {
 	ADDRESS paddr;
 	long status;
 	int ii;
 
-	// chNotFound = 0;
 	switch (command)
 	{
 		case SDF_LOAD_DB_ONLY:
 		case SDF_LOAD_PARTIAL:
-			for(ii=0;ii<numchans;ii++) {
-				// Find address of channel
-				if (GET_ADDRESS(myTable[ii].chname,&paddr))
-				{
-					if (myTable[ii].datatype == SDF_NUM)
-					{
-						PUT_VALUE(paddr,SDF_NUM,&(myTable[ii].data.chval));
-					} else {
-						PUT_VALUE(paddr,SDF_STR,myTable[ii].data.strval);
-					}
-				}
-				else {				// Write errors to chan not found table.
-				printf("CNF for %s = %d\n",myTable[ii].chname,status);
-				#if 0
-					if(chNotFound < SDF_ERR_TSIZE) {
-						sprintf(unknownChans[chNotFound].chname,"%s",myTable[ii].chname);
-						sprintf(unknownChans[chNotFound].liveset,"%s"," ");
-						unknownChans[chNotFound].liveval = 0.0;
-						sprintf(unknownChans[chNotFound].timeset,"%s"," ");
-						sprintf(unknownChans[chNotFound].diff,"%s"," ");
-						unknownChans[chNotFound].chFlag = 0;
-					}
-					chNotFound ++;
-				#endif
-				}
-			}
-
-                        // Set the SDF_FILE_LOADED environment var to 1,
-                        // signalling to the epipcs sequencer to
-                        // trigger a BURT_RESTORE
 
+		    for (const auto& entry:myTable)
+		    {
+                        // Find address of channel
+                        if (GET_ADDRESS(entry.chname,&paddr))
                         {
-                            set_sdf_file_loaded(1);
+                            if (entry.datatype == SDF_NUM)
+                            {
+                                PUT_VALUE(paddr,SDF_NUM,&(entry.data.chval));
+                            } else {
+                                PUT_VALUE(paddr,SDF_STR,entry.data.strval);
+                            }
                         }
-			break;
+                        else {				// Write errors to chan not found table.
+                            printf("CNF for %s = %d\n",entry.chname,status);
+                        }
+                    }
+                    // Set the SDF_FILE_LOADED environment var to 1,
+                    // signalling to the epipcs sequencer to
+                    // trigger a BURT_RESTORE
+
+                    {
+                        set_sdf_file_loaded(1);
+                    }
+                    break;
 		case SDF_READ_ONLY:
 			// If request was only to re-read the BURT file, then don't want to apply new settings.
 			// This is typically the case where only mask fields were changed in the BURT file to
@@ -1965,23 +2001,24 @@ int writeEpicsDb(int numchans,		///< Number of channels to write
 			break;
 		case SDF_RESET:
 			// Only want to set those channels marked by a mask back to their original BURT setting.
-			for(ii=0;ii<numchans;ii++) {
-				// FIXME: check does this make sense w/ a bitmask in mask?
-				// can filter modules get here?  It seems that they will, so would we need
-				// to mask the value we set ?
-			    if(myTable[ii].mask) {
-			    	//Find address of channel
-			    	if (GET_ADDRESS(myTable[ii].chname,&paddr))
-			    	{
-			    		if (myTable[ii].datatype == SDF_NUM)
-						{
-							PUT_VALUE(paddr,SDF_NUM,&(myTable[ii].data.chval));
-						} else {
-							PUT_VALUE(paddr,SDF_STR,myTable[ii].data.strval);
-						}
-			    	}
-			    }
-			}
+			for (const auto& entry: myTable)
+			{
+                // FIXME: check does this make sense w/ a bitmask in mask?
+                // can filter modules get here?  It seems that they will, so would we need
+                // to mask the value we set ?
+                if(entry.mask) {
+                    //Find address of channel
+                    if (GET_ADDRESS(entry.chname,&paddr))
+                    {
+                        if (entry.datatype == SDF_NUM)
+                        {
+                            PUT_VALUE(paddr,SDF_NUM,&(entry.data.chval));
+                        } else {
+                            PUT_VALUE(paddr,SDF_STR,entry.data.strval);
+                        }
+                    }
+                }
+            }
 			break;
 		default:
 			printf("writeEpicsDb setting routine got unknown request \n");
@@ -2047,7 +2084,7 @@ int readConfig( char *pref,		///< EPICS channel prefix from EPICS environment.
 	getSdfTime(timestring, 256);
 
 	if(command == SDF_RESET) {
-		lderror = writeEpicsDb(chNum,cdTable,command);
+		lderror = writeEpicsDb(cdTable,command);
 	} else {
 		printf("PARTIAL %s\n",sdfile);
 		cdf = fopen(sdfile,"r");
@@ -2253,9 +2290,9 @@ int readConfig( char *pref,		///< EPICS channel prefix from EPICS environment.
 		fclose(cdf);
 		fclose(adf);
 		printf("Loading epics %d\n",chNumP);
-		lderror = writeEpicsDb(chNumP,cdTableP,command);
+		lderror = writeEpicsDb(cdTableP,command);
 		sleep(2);
-		newfilterstats(fmNum);
+		newfilterstats();
 		fmtInit = 1;
 	}
 
@@ -2307,40 +2344,50 @@ void registerFilters() {
 
 /// Provide initial values to the filterMasks arrray and the SDF_FM_MASK and SDF_FM_MASK_CTRL variables
 ///
-void setupFMArrays(char *pref, int *fmMasks, dbAddr *fmMaskAddr, dbAddr *fmCtrlAddr) {
+void setupFMArrays(char *pref,fixed_size_vector<int, SDF_MAX_FMSIZE>& fmMasks,
+                   fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>& fmMaskAddr,
+                   fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>& fmCtrlAddr) {
 	int ii = 0;
 	int sw1 = 0;
 	int sw2 = 0;
-	long status = 0;
-	char name[256];
-	char ctrl[256];
+	fixed_string<256> name;
+	fixed_string<256> ctrl;
 	int zero = 0;
 
-	for (ii = 0; ii < SDF_MAX_FMSIZE; ++ii) {
-		sw1 = filterTable[ii].sw[0];
-		sw2 = filterTable[ii].sw[1];
-		fmMasks[ii] = filterTable[ii].mask = cdTable[sw1].mask | cdTable[sw2].mask;
+	fmMasks.clear();
+	fmMaskAddr.clear();
+	fmCtrlAddr.clear();
+	for (ii = 0; ii < filterTable.size(); ++ii)
+	{
+        sw1 = filterTable[ii].sw[0];
+        sw2 = filterTable[ii].sw[1];
+        fmMasks[ii] = filterTable[ii].mask = cdTable[sw1].mask | cdTable[sw2].mask;
 
-		sprintf(name, "%s_SDF_FM_MASK_%d", pref, ii);
-		status = dbNameToAddr(name, &fmMaskAddr[ii]);
-		status = dbPutField(&fmMaskAddr[ii],DBR_LONG,&(fmMasks[ii]),1);
+        name.printf("%s_SDF_FM_MASK_%d", pref, ii);
+        fmMaskAddr.emplace_back();
+        dbNameToAddr(name.c_str(), &fmMaskAddr[ii]);
+        dbPutField(&fmMaskAddr[ii],DBR_LONG,&(fmMasks[ii]),1);
 
-		sprintf(ctrl, "%s_SDF_FM_MASK_CTRL_%d", pref, ii);
-		status = dbNameToAddr(ctrl, &fmCtrlAddr[ii]);
-		status = dbPutField(&fmCtrlAddr[ii],DBR_LONG,&zero,1);
+        ctrl.printf("%s_SDF_FM_MASK_CTRL_%d", pref, ii);
+        fmCtrlAddr.emplace_back();
+        dbNameToAddr(ctrl.c_str(), &fmCtrlAddr[ii]);
+        dbPutField(&fmCtrlAddr[ii],DBR_LONG,&zero,1);
 
-	} 
+    }
 }
 
 /// Copy the filter mask information from cdTable into fmMasks
 ///
-void resyncFMArrays(int *fmMasks, dbAddr *fmMaskAddr) {
+void resyncFMArrays(fixed_size_vector<int, SDF_MAX_FMSIZE>&fmMasks,
+                    fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>& fmMaskAddr)
+{
 	int ii = 0;
 	int sw1 = 0;
 	int sw2 = 0;
 	long status = 0;
 
-	for (ii = 0; ii < SDF_MAX_FMSIZE; ++ii) {
+
+	for (ii = 0; ii < filterTable.size(); ++ii) {
 		sw1 = filterTable[ii].sw[0];
 		sw2 = filterTable[ii].sw[1];
 		fmMasks[ii] = filterTable[ii].mask = (cdTable[sw1].mask | cdTable[sw2].mask) & ALL_SWSTAT_BITS;
@@ -2364,7 +2411,11 @@ void resyncFMArrays(int *fmMasks, dbAddr *fmMaskAddr) {
 ///
 /// @remark Each of the input arrays is expected to have a length of SDF_MAX_FMSIZE
 /// with fmNum in actual use.
-void processFMChanCommands(int *fMask, dbAddr *fmMaskAddr, dbAddr *fmCtrlAddr, int *selectCounter, int errCnt, SET_ERR_TABLE *setErrTable) {
+void processFMChanCommands(
+        fixed_size_vector<int, SDF_MAX_FMSIZE>& fMask,
+        fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>& fmMaskAddr,
+        fixed_size_vector<dbAddr, SDF_MAX_FMSIZE>& fmCtrlAddr,
+        int *selectCounter, table_range setErrTable) {
 	int ii = 0;
 	int jj = 0;
 	int refMask = 0;
@@ -2376,7 +2427,8 @@ void processFMChanCommands(int *fMask, dbAddr *fmMaskAddr, dbAddr *fmCtrlAddr, i
 	long nvals = 1;
 	int foundCh = 0;
 
-	for (ii = 0; ii < SDF_MAX_FMSIZE && ii < fmNum; ++ii) {
+	//std::distance(setErrTable.begin(), setErrTable.end());
+	for (ii = 0; ii < filterTable.size(); ++ii) {
 		status = dbGetField(&fmCtrlAddr[ii], DBR_LONG, &ctrl, &ropts, &nvals, NULL);
 
 		// only do work if there is a change
@@ -2393,10 +2445,17 @@ void processFMChanCommands(int *fMask, dbAddr *fmMaskAddr, dbAddr *fmCtrlAddr, i
 		foundCh = 0;
 		/* if there is a change, update4 the selection count) */
 		if (differsPre != differsPost) {
-			for (jj = 0; jj < errCnt && setErrTable[jj].filtNum >= 0 && setErrTable[jj].filtNum != ii; ++jj) {}
-			if (jj < errCnt && setErrTable[jj].filtNum == ii) {
-				setErrTable[jj].chFlag ^= CHFLAG_MONITOR_BIT_VAL;
-				foundCh = setErrTable[jj].chFlag;
+		    // search through setErrTable
+			//for (jj = 0; jj < errCnt && setErrTable[jj].filtNum >= 0 && setErrTable[jj].filtNum != ii; ++jj) {}
+			auto match = std::find_if(setErrTable.begin(), setErrTable.end(), [ii](const SET_ERR_TABLE& cur) -> bool {
+			    return cur.filtNum == ii;
+			});
+			// act on search
+			//if (jj < errCnt && setErrTable[jj].filtNum == ii)
+			if ( match != setErrTable.end())
+			{
+				match->chFlag ^= CHFLAG_MONITOR_BIT_VAL;
+				foundCh = match->chFlag;
 				selectCounter[2] += ( differsPre ? -1 : 1 );
 			}
 		}
@@ -2476,7 +2535,7 @@ bool getCAIndex(const char *entry, ADDRESS *addr) {
 	return false;
 }
 
-bool setCAValue(ADDRESS ii, SDF_TYPE type, void *data)
+bool setCAValue(ADDRESS ii, SDF_TYPE type, const void *data)
 {
 	bool result = false;
 	int status = ECA_NORMAL;
@@ -2492,12 +2551,12 @@ bool setCAValue(ADDRESS ii, SDF_TYPE type, void *data)
 	return result;
 }
 
-bool setCAValueLong(ADDRESS ii, PV_INT_TYPE *data) {
+bool setCAValueLong(ADDRESS ii, const PV_INT_TYPE *data) {
 	double tmp = 0.0;
 
 	if (!data) return false;
 	tmp = (double)*data;
-	return setCAValue(ii,SDF_NUM,(void*)&tmp);
+	return setCAValue(ii,SDF_NUM,(const void*)&tmp);
 }
 
 bool syncEpicsDoubleValue(ADDRESS index, double *dest, time_t *tp, int *connp) {
@@ -3282,8 +3341,8 @@ int main(int argc,char *argv[])
 	char *fotonDiffFile = getenv("FOTON_DIFF_FILE");
 	char *logdir = getenv("LOG_DIR");
 	char myDiffCmd[256];
-	SET_ERR_TABLE *currentTable = 0;
-	int currentTableCnt = 0;
+	table_range currentTable;
+
 
 	if(stat(logdir, &st) == -1) mkdir(logdir,0777);
 	// strcat(sdf,"_safe");
@@ -3509,7 +3568,7 @@ int main(int argc,char *argv[])
     status = checkFileMod( coeffFile, &coeffFileMt, 1 );
     status = checkFileMod( fotonFile, &fotonFileMt, 1 );
 
-	reportSetErrors(pref, 0,setErrTable,0,1);
+	reportSetErrors(pref,setErrTable,0,1);
 
 	sleep(1);       // Need to wait before first restore to allow sequencers time to do their initialization.
 	cdSort = spChecker(monFlag,cdTableList,wcVal,wcstring,1,&status);
@@ -3591,7 +3650,7 @@ int main(int argc,char *argv[])
 					setChans = chNum - fmNum;
 					status = dbPutField(&fulldbcntaddr,DBR_LONG,&setChans,1);
 					// Sort channels for data reporting via the MEDM table.
-					getEpicsSettings(chNum,NULL);
+					getEpicsSettings();
 					noMon = createSortTableEntries(chNum,0,"",&noInit,NULL);
 					// Calculate and report number of channels NOT being monitored.
 					status = dbPutField(&monchancntaddr,DBR_LONG,&chNotMon,1);
@@ -3667,23 +3726,23 @@ int main(int argc,char *argv[])
 			case SDF_TABLE_DIFFS:
 				// Need to clear selections when moving between tables.
 				if(lastTable !=  SDF_TABLE_DIFFS) {
-					clearTableSelections(sperror,setErrTable, selectCounter);
+					clearTableSelections(setErrTable, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 				}
-				pageDisp = reportSetErrors(pref, sperror,setErrTable,pageNum,1);
-				currentTable = setErrTable;
-				currentTableCnt = sperror;
+				pageDisp = reportSetErrors(pref, setErrTable,pageNum,1);
+				currentTable = make_range(setErrTable);
+
 				status = dbPutField(&sorttableentriesaddr,DBR_LONG,&sperror,1);
 				status = dbGetField(&resetoneaddr,DBR_LONG,&resetNum,&ropts,&nvals,NULL);
 				if(selectAll) {
-					setAllTableSelections(sperror,setErrTable, selectCounter,selectAll);
+					setAllTableSelections(make_range(setErrTable), selectCounter,selectAll);
 				}
 				if(resetNum) {
-					decodeChangeSelect(resetNum, pageDisp, sperror, setErrTable,selectCounter, NULL);
+					decodeChangeSelect(resetNum, pageDisp, make_range(setErrTable),selectCounter, NULL);
 				}
 				if(confirmVal) {
-					if(selectCounter[0] && (confirmVal & 2)) status = resetSelectedValues(sperror, setErrTable);
+					if(selectCounter[0] && (confirmVal & 2)) status = resetSelectedValues(setErrTable);
 					if((selectCounter[1] || selectCounter[2]) && (confirmVal & 2)) {
 						// Save present table as timenow.
 						status = dbGetField(&loadedfile_addr,DBR_STRING,backupName,&ropts,&nvals,NULL);
@@ -3691,7 +3750,7 @@ int main(int argc,char *argv[])
 						savesdffile(SAVE_TABLE_AS_SDF,SAVE_TIME_NOW,sdfDir,modelname,sdfile,saveasfilename,backupName,
 							    savefileaddr,savetimeaddr,reloadtimeaddr);
 						// Overwrite the table with new values
-						status = modifyTable(sperror,setErrTable);
+						status = modifyTable(make_range(setErrTable));
 						// Overwrite file
 						savesdffile(SAVE_TABLE_AS_SDF,SAVE_OVERWRITE,sdfDir,modelname,sdfile,saveasfilename,
 							    backupName,savefileaddr,savetimeaddr,reloadtimeaddr);
@@ -3699,7 +3758,7 @@ int main(int argc,char *argv[])
                         status = checkFileMod( sdffileloaded, &sdfFileMt, 1 );
 						writeTable2File(sdfDir,bufile,SDF_WITH_INIT_FLAG,cdTable);
 					}
-					clearTableSelections(sperror,setErrTable, selectCounter);
+					clearTableSelections(setErrTable, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 					status = dbPutField(&confirmwordaddr,DBR_LONG,&confirmVal,1);
@@ -3711,42 +3770,41 @@ int main(int argc,char *argv[])
 			case SDF_TABLE_NOT_FOUND:
 				// Need to clear selections when moving between tables.
 				if(lastTable != SDF_TABLE_NOT_FOUND) {
-					clearTableSelections(sperror,setErrTable, selectCounter);
+					clearTableSelections(setErrTable, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 				}
-				pageDisp = reportSetErrors(pref, chNotFound,unknownChans,pageNum,1);
-				currentTable = unknownChans;
-				currentTableCnt = chNotFound;
+				pageDisp = reportSetErrors(pref, unknownChans,pageNum,1);
+				currentTable = make_range(unknownChans);
+
 				status = dbPutField(&sorttableentriesaddr,DBR_LONG,&chNotFound,1);
 				/*if (resetNum > 200) {
-					decodeChangeSelect(resetNum, pageDisp, chNotFound, unknownChans,selectCounter, NULL);
+					decodeChangeSelect(resetNum, pageDisp, make_range(unknownChans),selectCounter, NULL);
 				}*/
 				lastTable =  SDF_TABLE_NOT_FOUND;
 				break;
 			case SDF_TABLE_NOT_INIT:
 				if(lastTable != SDF_TABLE_NOT_INIT) {
-					clearTableSelections(sperror,setErrTable, selectCounter);
+					clearTableSelections(setErrTable, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 				}
 				if (!freezeTable)
-					getEpicsSettings(chNum,NULL);
+					getEpicsSettings();
 				noMon = createSortTableEntries(chNum,wcVal,wcstring,&noInit,NULL);
-				pageDisp = reportSetErrors(pref, noInit, uninitChans,pageNum,1);
-				currentTable = uninitChans;
-				currentTableCnt = noInit;
+				pageDisp = reportSetErrors(pref, uninitChans,pageNum,1);
+				currentTable = make_range(uninitChans);
 				status = dbGetField(&resetoneaddr,DBR_LONG,&resetNum,&ropts,&nvals,NULL);
 				if(selectAll == 2 || selectAll == 3) {
-					setAllTableSelections(noInit,uninitChans,selectCounter,selectAll);
+					setAllTableSelections(make_range(uninitChans),selectCounter,selectAll);
 					if (selectAll == 3)
-						setAllTableSelections(noInit,uninitChans,selectCounter,2);
+						setAllTableSelections(make_range(uninitChans),selectCounter,2);
 				}
 				if(resetNum > 100) {
-					decodeChangeSelect(resetNum, pageDisp, noInit, uninitChans,selectCounter, changeSelectCB_uninit);
+					decodeChangeSelect(resetNum, pageDisp, make_range(uninitChans),selectCounter, changeSelectCB_uninit);
 				}
 				if(confirmVal) {
-					if(selectCounter[0] && (confirmVal & 2)) status = resetSelectedValues(noInit, uninitChans);
+					if(selectCounter[0] && (confirmVal & 2)) status = resetSelectedValues(uninitChans);
 					if(selectCounter[1] && (confirmVal & 2)) {
 						// Save present table as timenow.
 						status = dbGetField(&loadedfile_addr,DBR_STRING,backupName,&ropts,&nvals,NULL);
@@ -3754,7 +3812,7 @@ int main(int argc,char *argv[])
 						savesdffile(SAVE_TABLE_AS_SDF,SAVE_TIME_NOW,sdfDir,modelname,sdfile,saveasfilename,backupName,
 							    savefileaddr,savetimeaddr,reloadtimeaddr);
 						// Overwrite the table with new values
-						status = modifyTable(noInit,uninitChans);
+						status = modifyTable(make_range(uninitChans));
 						// Overwrite file
 						savesdffile(SAVE_TABLE_AS_SDF,SAVE_OVERWRITE,sdfDir,modelname,sdfile,saveasfilename,
 							    backupName,savefileaddr,savetimeaddr,reloadtimeaddr);
@@ -3762,7 +3820,7 @@ int main(int argc,char *argv[])
                         status = checkFileMod( sdffileloaded, &sdfFileMt, 1 );
 						writeTable2File(sdfDir,bufile,SDF_WITH_INIT_FLAG,cdTable);
 					}
-					clearTableSelections(chNotInit,uninitChans, selectCounter);
+					clearTableSelections(uninitChans, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 					status = dbPutField(&confirmwordaddr,DBR_LONG,&confirmVal,1);
@@ -3774,27 +3832,26 @@ int main(int argc,char *argv[])
 			case SDF_TABLE_NOT_MONITORED:
 				D("In not mon\n");
 				if(lastTable != SDF_TABLE_NOT_MONITORED) {
-					clearTableSelections(noMon,unMonChans, selectCounter);
+					clearTableSelections(unMonChans, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 					status = dbPutField(&confirmwordaddr,DBR_LONG,&confirmVal,1);
 				}
 				if (!freezeTable)
-					getEpicsSettings(chNum,NULL); //timeTable);
+					getEpicsSettings(); //timeTable);
 				noMon = createSortTableEntries(chNum,wcVal,wcstring,&noInit,NULL);//timeTable);
 				status = dbPutField(&monchancntaddr,DBR_LONG,&chNotMon,1);
-				pageDisp = reportSetErrors(pref, noMon, unMonChans,pageNum,1);
-				currentTable = unMonChans;
-				currentTableCnt = noMon;
+				pageDisp = reportSetErrors(pref, unMonChans,pageNum,1);
+				currentTable = make_range(unMonChans);
 				status = dbGetField(&resetoneaddr,DBR_LONG,&resetNum,&ropts,&nvals,NULL);
 				if(selectAll) {
-					setAllTableSelections(noMon,unMonChans,selectCounter,selectAll);
+					setAllTableSelections(make_range(unMonChans),selectCounter,selectAll);
 				}
 				if(resetNum) {
-					decodeChangeSelect(resetNum, pageDisp, noMon, unMonChans,selectCounter, NULL);
+					decodeChangeSelect(resetNum, pageDisp, make_range(unMonChans),selectCounter, NULL);
 				}
 				if(confirmVal) {
-					if(selectCounter[0] && (confirmVal & 2)) status = resetSelectedValues(noMon, unMonChans);
+					if(selectCounter[0] && (confirmVal & 2)) status = resetSelectedValues(unMonChans);
 					if((selectCounter[1] || selectCounter[2]) && (confirmVal & 2)) {
 						// Save present table as timenow.
 						status = dbGetField(&loadedfile_addr,DBR_STRING,backupName,&ropts,&nvals,NULL);
@@ -3802,7 +3859,7 @@ int main(int argc,char *argv[])
 						savesdffile(SAVE_TABLE_AS_SDF,SAVE_TIME_NOW,sdfDir,modelname,sdfile,saveasfilename,backupName,
 							    savefileaddr,savetimeaddr,reloadtimeaddr);
 						// Overwrite the table with new values
-						status = modifyTable(noMon,unMonChans);
+						status = modifyTable(make_range(unMonChans));
 						// Overwrite file
 						savesdffile(SAVE_TABLE_AS_SDF,SAVE_OVERWRITE,sdfDir,modelname,sdfile,saveasfilename,
 							    backupName,savefileaddr,savetimeaddr,reloadtimeaddr);
@@ -3811,7 +3868,7 @@ int main(int argc,char *argv[])
 						writeTable2File(sdfDir,bufile,SDF_WITH_INIT_FLAG,cdTable);
 					}
 					// noMon = createSortTableEntries(chNum,wcVal,wcstring);
-					clearTableSelections(noMon,unMonChans, selectCounter);
+					clearTableSelections(unMonChans, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 					status = dbPutField(&confirmwordaddr,DBR_LONG,&confirmVal,1);
@@ -3822,24 +3879,23 @@ int main(int argc,char *argv[])
 				break;
 			case SDF_TABLE_FULL:
 				if(lastTable != SDF_TABLE_FULL) {
-					clearTableSelections(cdSort,cdTableList, selectCounter);
+					clearTableSelections(cdTableList, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 				}
 				if (!freezeTable)
 					cdSort = spChecker(monFlag,cdTableList,wcVal,wcstring,1,&status);
-				pageDisp = reportSetErrors(pref, cdSort, cdTableList,pageNum,1);
-				currentTable = cdTableList;
-				currentTableCnt = cdSort;
+				pageDisp = reportSetErrors(pref, cdTableList,pageNum,1);
+				currentTable = make_range(cdTableList);
 				status = dbGetField(&resetoneaddr,DBR_LONG,&resetNum,&ropts,&nvals,NULL);
 				if(selectAll == 3) {
-					setAllTableSelections(cdSort,cdTableList,selectCounter,selectAll);
+					setAllTableSelections(make_range(cdTableList),selectCounter,selectAll);
 				}
 				if(resetNum) {
-					decodeChangeSelect(resetNum, pageDisp, cdSort, cdTableList,selectCounter, NULL);
+					decodeChangeSelect(resetNum, pageDisp, make_range(cdTableList),selectCounter, NULL);
 				}
 				if(confirmVal) {
-					if(selectCounter[0] && (confirmVal & 2)) status = resetSelectedValues(cdSort, cdTableList);
+					if(selectCounter[0] && (confirmVal & 2)) status = resetSelectedValues(cdTableList);
 					if((selectCounter[1] || selectCounter[2]) && (confirmVal & 2)) {
 						// Save present table as timenow.
 						status = dbGetField(&loadedfile_addr,DBR_STRING,backupName,&ropts,&nvals,NULL);
@@ -3847,7 +3903,7 @@ int main(int argc,char *argv[])
 						savesdffile(SAVE_TABLE_AS_SDF,SAVE_TIME_NOW,sdfDir,modelname,sdfile,saveasfilename,
 							    backupName,savefileaddr,savetimeaddr,reloadtimeaddr);
 						// Overwrite the table with new values
-						status = modifyTable(cdSort,cdTableList);
+						status = modifyTable(make_range(cdTableList));
 						// Overwrite file
 						savesdffile(SAVE_TABLE_AS_SDF,SAVE_OVERWRITE,sdfDir,modelname,sdfile,saveasfilename,
 							    backupName,savefileaddr,savetimeaddr,reloadtimeaddr);
@@ -3855,7 +3911,7 @@ int main(int argc,char *argv[])
                         status = checkFileMod( sdffileloaded, &sdfFileMt, 1 );
 						writeTable2File(sdfDir,bufile,SDF_WITH_INIT_FLAG,cdTable);
 					}
-					clearTableSelections(cdSort,cdTableList, selectCounter);
+					clearTableSelections(cdTableList, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 					status = dbPutField(&confirmwordaddr,DBR_LONG,&confirmVal,1);
@@ -3869,26 +3925,24 @@ int main(int argc,char *argv[])
 #ifdef CA_SDF
 			case SDF_TABLE_DISCONNECTED:
 				if(lastTable != SDF_TABLE_DISCONNECTED) {
-					clearTableSelections(cdSort,cdTableList, selectCounter);
+					clearTableSelections(cdTableList, selectCounter);
 					resyncFMArrays(filterMasks,fmMaskChan);
 					confirmVal = 0;
 				}
 				noMon = createSortTableEntries(chNum,wcVal,wcstring,&noInit,NULL);
-				pageDisp =  reportSetErrors(pref, chDisconnected, disconnectChans, pageNum,0);
+				pageDisp =  reportSetErrors(pref, disconnectChans, pageNum,0);
 				chDisconnectedCount = chDisconnected;
-				currentTable = disconnectChans;
-				currentTableCnt = chDisconnected;
+				currentTable = make_range(disconnectChans);
 				status = dbPutField(&sorttableentriesaddr,DBR_LONG,&chDisconnected, 1);
 				if (resetNum > 200) {
-					decodeChangeSelect(resetNum, pageDisp, chDisconnected, disconnectChans, selectCounter, NULL);
+					decodeChangeSelect(resetNum, pageDisp, make_range(disconnectChans), selectCounter, NULL);
 				}
 				break;
 #endif
 			default:
-				pageDisp = reportSetErrors(pref, sperror,setErrTable,pageNum,1);
+				pageDisp = reportSetErrors(pref, setErrTable,pageNum,1);
 				status = dbPutField(&sorttableentriesaddr,DBR_LONG,&sperror,1);
-				currentTable = setErrTable;
-				currentTableCnt = sperror;
+				currentTable = make_range(setErrTable);
 				break;
 		}
 		if (selectAll) {
@@ -3909,7 +3963,7 @@ int main(int argc,char *argv[])
 		}
 		status = dbPutField(&(pagelockaddr[0]),DBR_LONG,&freezeTable,1);
 
-		processFMChanCommands(filterMasks, fmMaskChan,fmMaskChanCtrl,selectCounter, currentTableCnt, currentTable);
+		processFMChanCommands(filterMasks, fmMaskChan,fmMaskChanCtrl,selectCounter, currentTable);
 
 		// Check file CRCs every 5 seconds.
 		// DAQ and COEFF file checking was moved from skeleton.st to here RCG V2.9.
diff --git a/src/epics/seq/simple_range.hh b/src/epics/seq/simple_range.hh
new file mode 100644
index 0000000000000000000000000000000000000000..36cbb0aefb8bc0e0af4e61b4d3db54a1d575fec6
--- /dev/null
+++ b/src/epics/seq/simple_range.hh
@@ -0,0 +1,78 @@
+//
+// Created by jonathan.hanks on 11/17/20.
+//
+
+#ifndef DAQD_TRUNK_SIMPLE_RANGE_HH
+#define DAQD_TRUNK_SIMPLE_RANGE_HH
+
+#include <type_traits>
+#include <utility>
+
+namespace embedded
+{
+    /*!
+     * @brief a very simple range class, just tracks two iterators in one unit, [start, end)
+     * @tparam It the iterator type, which must be noexcept on copy and move
+     */
+    template <typename It>
+    class range
+    {
+        static_assert(std::is_nothrow_copy_constructible<It>::value, "It must be no throw copy constructable");
+        static_assert(std::is_nothrow_copy_assignable<It>::value, "It must be no throw copyable");
+        static_assert(std::is_nothrow_move_constructible<It>::value, "It must be no throw move constructable");
+        static_assert(std::is_nothrow_move_assignable<It>::value, "It must be no throw movable");
+    public:
+        using iterator = It;
+
+        range() noexcept: start_{}, end_{} {}
+        range(const range&) noexcept = default;
+        range(range&&) noexcept = default;
+        range(It it1, It it2) noexcept: start_{std::move(it1)}, end_{std::move(it2)} {}
+        range& operator=(const range&) noexcept = default;
+        range& operator=(range&&) noexcept = default;
+
+        iterator
+        begin() noexcept
+        {
+            return start_;
+        }
+
+        iterator
+        end() noexcept
+        {
+            return end_;
+        }
+
+        const iterator
+        begin() const noexcept
+        {
+            return start_;
+        }
+
+        const iterator
+        end() const noexcept
+        {
+            return end_;
+        }
+
+    private:
+        It start_;
+        It end_;
+    };
+
+    /*!
+     * @brief Given two iterators of type It construct a range
+     * @tparam It
+     * @param start
+     * @param end
+     * @return the resulting range
+     */
+    template <typename It>
+    range<It>
+    make_range(It start, It end)
+    {
+        return range<It>(std::move(start), std::move(end));
+    }
+}
+
+#endif //DAQD_TRUNK_SIMPLE_RANGE_HH
diff --git a/src/epics/seq/test/test_fixed_size_vector.cc b/src/epics/seq/test/test_fixed_size_vector.cc
index 0b5bf44f5a974ae930cbf811c8b545adc4364c6f..602dd286a92e73c2d5bf9caec2478218905d5df4 100644
--- a/src/epics/seq/test/test_fixed_size_vector.cc
+++ b/src/epics/seq/test/test_fixed_size_vector.cc
@@ -188,6 +188,31 @@ TEST_CASE( "We have defined enough to make the this usable by std::algorithms" )
     REQUIRE( v0[ 4 ] == 5 );
 }
 
+TEST_CASE( "We can use front()/back() to reference the first/last elements when there are more than one.")
+{
+    embedded::fixed_size_vector<int, 20> v0;
+    v0.push_back(5);
+    REQUIRE( v0.front() == v0.back() );
+    v0.front() = 42;
+    REQUIRE( v0[0] == 42 );
+    v0.back() = 44;
+    REQUIRE( v0[0] == 44 );
+    v0.push_back(10);
+    REQUIRE( v0.front() == 44 );
+    REQUIRE( v0.back() == 10 );
+    REQUIRE( v0[0] == v0.front() );
+    REQUIRE( v0[1] == v0.back() );
+}
+
+TEST_CASE( "We can use front()/back() in a const setting as well")
+{
+    embedded::fixed_size_vector<int, 20> v0;
+    v0.push_back(5);
+
+    const auto& vconst = v0;
+    REQUIRE( vconst.front() == vconst.back() );
+}
+
 // static_assert(std::is_trivially_destructible<embedded::fixed_size_vector<int,
 // 20> >::value, "For trivial destructable types the fixed sized vector should
 // be trivially destructable");
diff --git a/src/epics/seq/test/test_simple_range.cc b/src/epics/seq/test/test_simple_range.cc
new file mode 100644
index 0000000000000000000000000000000000000000..efe9d32164013a1b4315294b7d56b8453dfff966
--- /dev/null
+++ b/src/epics/seq/test/test_simple_range.cc
@@ -0,0 +1,18 @@
+//
+// Created by jonathan.hanks on 11/17/20.
+//
+#include "catch.hpp"
+
+#include "simple_range.hh"
+
+#include <vector>
+
+TEST_CASE("You can create a simple range from two iterators")
+{
+    using it_type = typename std::vector<int>::iterator;
+    std::vector<int> backing_store{1,2,3,4,5,6,7,8,9,0};
+
+    embedded::range<it_type> rng = embedded::make_range(backing_store.begin() + 3, backing_store.begin() + 3 + 3);
+    REQUIRE( *rng.begin() == 4 );
+    REQUIRE( *rng.end() == 7 );
+}