From: <ro...@us...> - 2013-07-08 20:21:03
|
Revision: 2106 http://sourceforge.net/p/nsclspectcl/code/2106 Author: ron-fox Date: 2013-07-08 20:20:59 +0000 (Mon, 08 Jul 2013) Log Message: ----------- Test/develop the parameter array class. y Modified Paths: -------------- branches/spectcl-5.0/SpecTclPackage/CParameter.h branches/spectcl-5.0/SpecTclPackage/CParameterArray.cpp branches/spectcl-5.0/SpecTclPackage/CParameterArray.h branches/spectcl-5.0/SpecTclPackage/ParameterArrayTests.cpp branches/spectcl-5.0/SpecTclPackage/ParameterTests.cpp Modified: branches/spectcl-5.0/SpecTclPackage/CParameter.h =================================================================== --- branches/spectcl-5.0/SpecTclPackage/CParameter.h 2013-07-05 19:49:44 UTC (rev 2105) +++ branches/spectcl-5.0/SpecTclPackage/CParameter.h 2013-07-08 20:20:59 UTC (rev 2106) @@ -123,7 +123,7 @@ // Object operations: public: bool isvalid(); - bool checkLimits() {return false;} + bool checkLimits() {return m_checkLimits;} void registerParameter(); void reset(); Modified: branches/spectcl-5.0/SpecTclPackage/CParameterArray.cpp =================================================================== --- branches/spectcl-5.0/SpecTclPackage/CParameterArray.cpp 2013-07-05 19:49:44 UTC (rev 2105) +++ branches/spectcl-5.0/SpecTclPackage/CParameterArray.cpp 2013-07-08 20:20:59 UTC (rev 2106) @@ -21,3 +21,289 @@ #include "CParameterArray.h" #include "CParameter.h" +#include <math.h> +#include <string.h> +#include <stdio.h> +#include <stdexcept> + + + +class SimpleMaker : public CParameterArray::CConstructor +{ +public: + virtual CParameter* operator()(const char* pName) { + return new CParameter(pName); + } +}; + +class LowHiMaker : public CParameterArray::CConstructor +{ + double m_low; + double m_high; +public: + LowHiMaker(double low, double hi) : m_low(low), m_high(hi) {} + + virtual CParameter* operator()(const char* pName) { + return new CParameter(pName, m_low, m_high); + } +}; +class UnitsMaker : public CParameterArray::CConstructor +{ + double m_low; + double m_high; + std::string m_units; +public: + UnitsMaker(double low, double high, const char* pUnits) : + m_low(low), m_high(high), m_units(pUnits) {} + virtual CParameter* operator()(const char* pName) { + return new CParameter(pName, m_low, m_high, m_units.c_str()); + } +}; +class BinsMaker : public CParameterArray::CConstructor +{ + double m_low; + double m_high; + unsigned m_bins; + std::string m_units; +public: + BinsMaker(double low, double high, unsigned bins, const char* pUnits) : + m_low(low), m_high(high), m_bins(bins), m_units(pUnits) {} + virtual CParameter* operator()(const char* pName) { + return new CParameter(pName, m_low, m_high, m_bins, m_units.c_str()); + } +}; + +/** + * constructor + * + * @param pBaseName - Base name of the array being created. + * @param num - Size of the array. + * @param indexLow - Smallest index (largest is indexLow + num - 1). + */ +CParameterArray::CParameterArray(const char* pBaseName, unsigned num, unsigned indexLow) : + m_indexLow(indexLow), m_elementCount(num), m_rangeCheck(false) +{ + SimpleMaker m; + makeParameters(m, pBaseName, num, indexLow); + +} +/** + * constructor + * + * @param pBaseName - Base name of the array being created. + * @param low - Low value of the parameter. + * @param high - High value of the parameter. + * @param num - Size of the array. + * @param indexLow - Smallest index (largest is indexLow + num - 1). + */ +CParameterArray::CParameterArray(const char* pBaseName, double low, double high, + unsigned num, unsigned indexLow) : + m_indexLow(indexLow), m_elementCount(num), m_rangeCheck(false) +{ + + LowHiMaker m(low, high); + makeParameters(m, pBaseName, num, indexLow); + +} +/** + * constructor + * + * @param pBaseName - Base name of the array. + * @param low - Axis low limit on the parameter. + * @param high - High limit on the parameter. + * @param pUnits - Units of measure associated with the parameter. + * @param num - Number of parameters to create. + * @param indexLow - Index of the first parameter + */ + +CParameterArray::CParameterArray(const char* pBaseName, double low, double high, + const char* pUnits, + unsigned num, unsigned indexLow) : + m_indexLow(indexLow), m_elementCount(num), m_rangeCheck(false) +{ + UnitsMaker m(low, high, pUnits); + makeParameters(m, pBaseName, num, indexLow); +} +/** + * Constructor + * + * @param pBaseName - Base name of the array. + * @param low - Axis low limit on the parameter. + * @param high - High limit on the parameter. + * @param bins - Suggested axis binnint + * @param pUnits - Units of measure associated with the parameter. + * @param num - Number of parameters to create. + * @param indexLow - Index of the first parameter + */ + +CParameterArray::CParameterArray(const char* pBaseName, + double low, double high, unsigned bins, const char* pUnits, + unsigned num, unsigned indexLow) : + m_indexLow(indexLow), m_elementCount(num), m_rangeCheck(false) +{ + BinsMaker m(low, high, bins, pUnits); + makeParameters(m, pBaseName, num, indexLow); +} +/** + * destructor + * Delete all the parameters we created. The vector can take care of itself. + */ +CParameterArray::~CParameterArray() +{ + for (int i = 0; i < m_array.size(); i++) { + delete m_array[i]; + } +} + +/** + * enableRangeCheck + * Turns on index range checking. + */ +void +CParameterArray::enableRangeCheck() +{ + m_rangeCheck = true; +} +/** + * disableRangeCheck + * Disables array index range checking. + */ +void +CParameterArray::disableRangeCheck() +{ + m_rangeCheck = false; +} +/** + * operator[] + * Return a reference to an element of the array. + * + * @param i - Element to return. + * @return CParameter& reference to the parameter indexed. + * + * @throw std::range_error - if range checking is enabled and + * the index is out of range of the array. + */ +CParameter& +CParameterArray::operator[](unsigned i) +{ + if (m_rangeCheck) { + if ((i < m_indexLow) || ((i - m_indexLow) >= m_elementCount)) { + throw std::range_error("CParameterArray index is out of bounds"); + } + } + unsigned index = i - m_indexLow; + + return *(m_array[i - m_indexLow]); +} +/** + * changeLow + * Change the low value for all array elements. + * + * @param newLow - New low value. + */ +void +CParameterArray::changeLow(double newLow) { + for (int i = 0; i < m_array.size(); i++) { + m_array[i]->changeLow(newLow); + } +} +/** + * changeHigh + * Change the high value for all array elements. + * + * @param newHigh - new high limit value. + */ +void +CParameterArray::changeHigh(double newHigh) +{ + for (int i =0; i < m_array.size(); i++) { + m_array[i]->changeHigh(newHigh); + } +} +/** + * changeBins + * + * Change the recommended binning for all members of the array. + * + * @param newBins New suggested binning + */ +void +CParameterArray::changeBins(unsigned newBins) +{ + for (int i =0; i < m_array.size(); i++) { + m_array[i]->changeBins(newBins); + } +} +/** + * changeUnits + * Changes the units of measure fro all elements of the array. + * + * @param newUnits - The new units of measure. + */ +void +CParameterArray::changeUnits(const char* newUnits) +{ + for (int i = 0; i < m_array.size(); i++) { + m_array[i]->changeUnits(newUnits); + } +} +/** + * enableLimitCheck + * + * Turns on value limit checking for all array elements. + */ +void +CParameterArray::enableLimitCheck() +{ + for (int i = 0; i < m_array.size(); i++) { + m_array[i]->enableLimitCheck(); + } +} +/** + * disableLimitCheck + * + * Turns off value limit checking for all array elements. + */ +void +CParameterArray::disableLimitCheck() +{ + for (int i = 0; i < m_array.size(); i++) { + m_array[i]->disableLimitCheck(); + } +} +/*---------------------------------------------------------------------------- + * private utilities. + */ + +/** + * makeParameters + * + * Used the passed in constructor object to create the set of parameters + * demanded by n and lowIndex. + * + * @param pBaseName - base name for the array. + * @param maker - Functor object that can create on CParameter. + * @param n - Number of parameters to create. + * @param lowIndex- Index of the first parameter. + */ +void +CParameterArray::makeParameters(CParameterArray::CConstructor& maker, + const char* pBaseName, unsigned n, + unsigned lowIndex) +{ + + // how many digits in the biggest index: + + unsigned lastIndex = lowIndex + n - 1; + unsigned digits = (int)(log10((double)(lastIndex))) + 1; + + // . \0 + unsigned namesize = strlen(pBaseName) + 1 + digits + 1; + char* name = new char[namesize]; + for (int i = lowIndex; i <= lastIndex; i++) { + sprintf(name, "%s.%0*d", pBaseName, digits, i); + CParameter* pParam = maker(name); + m_array.push_back(pParam); + } + delete []name; +} Modified: branches/spectcl-5.0/SpecTclPackage/CParameterArray.h =================================================================== --- branches/spectcl-5.0/SpecTclPackage/CParameterArray.h 2013-07-05 19:49:44 UTC (rev 2105) +++ branches/spectcl-5.0/SpecTclPackage/CParameterArray.h 2013-07-08 20:20:59 UTC (rev 2106) @@ -42,38 +42,52 @@ * - index range checking can be optionally enabled/disabled. */ class CParameterArray { +private: unsigned m_indexLow; unsigned m_elementCount; bool m_rangeCheck; std::vector<CParameter*> m_array; + public: + class CConstructor { + public: + virtual CParameter* operator()(const char* pName) = 0; + }; +public: // Construction: CParameterArray(const char* pBaseName, - unsigned num, unsigned m_indexLow = 0) {} + unsigned num, unsigned indexLow = 0); CParameterArray(const char* pBaseName, double low, double high, - unsigned num, unsigned m_indexLow = 0) {} - CParameterArray(const char* pBaseName, double low, double high, const char* pUnits, - unsigned num, unsigned m_indexLow = 0) {} + unsigned num, unsigned indexLow = 0); + CParameterArray(const char* pBaseName, double low, double high, + const char* pUnits, + unsigned num, unsigned indexLow = 0); CParameterArray(const char* pBaseName, double low, double high, unsigned bins, const char* pUnits, - unsigned num, unsigned m_indexLow = 0) {} - virtual ~CParameterArray() {} + unsigned num, unsigned indexLow = 0); + virtual ~CParameterArray(); // Methods for the array. public: - void enableRangeCheck() {} - void disableRangeCheck() {} + void enableRangeCheck(); + void disableRangeCheck(); // Delegational methods public: - CParameter& operator[](unsigned int) {return *(reinterpret_cast<CParameter*>(0)); } - void changeLow(double newLow) {} - void changeHigh(double newHigh) {} - void changeBins(unsigned newBins) {} - void changeUnits(const char* newUnits) {} - void enableLimitCheck() {}; - void disableLimitCheck() {}; + CParameter& operator[](unsigned int); + void changeLow(double newLow); + void changeHigh(double newHigh); + void changeBins(unsigned newBins); + void changeUnits(const char* newUnits); + void enableLimitCheck(); + void disableLimitCheck(); + + // Private utilities: + + void makeParameters(CConstructor& maker, const char* pBaseName, + unsigned n, unsigned lowIndex); + }; #endif Modified: branches/spectcl-5.0/SpecTclPackage/ParameterArrayTests.cpp =================================================================== --- branches/spectcl-5.0/SpecTclPackage/ParameterArrayTests.cpp 2013-07-05 19:49:44 UTC (rev 2105) +++ branches/spectcl-5.0/SpecTclPackage/ParameterArrayTests.cpp 2013-07-08 20:20:59 UTC (rev 2106) @@ -4,31 +4,40 @@ #include <cppunit/Asserter.h> #include "Asserts.h" +#define private public +#include "CParameterArray.h" +#include "CParameterDictionary.h" +#undef private +#include "CParameter.h" +#include <stdio.h> +#include <stdexcept> + + class PArrayTests : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(PArrayTests); // Tests for construction in the first constructor defined. CPPUNIT_TEST(construct1); // simplest case - // CPPUNIT_TEST(destruct); // Destructor destroys elements. - // CPPUNIT_TEST(construct2); // index offset. - // CPPUNIT_TEST(construct3); // Right number of index digits in name. - // CPPUNIT_TEST(construct4); // Second constructor. - // CPPUNIT_TEST(construct5); // 3'd constructor - // CPPUNIT_TEST(construct6); // 4'th constructor. + CPPUNIT_TEST(destruct); // Destructor destroys elements. + CPPUNIT_TEST(construct2); // index offset. + CPPUNIT_TEST(construct3); // Second constructor. + CPPUNIT_TEST(construct4); // 3'd constructor + CPPUNIT_TEST(construct5); // 4'th constructor. - // CPPUNIT_TEST(rangecheck1); // Turn on/off range checking. + CPPUNIT_TEST(rangecheck1); // Turn on/off range checking. - // CPPUNIT_TEST(index1); - // CPPUNIT_TEST(rangecheck2); // Range checking works when on. std::range_error. + CPPUNIT_TEST(index1); + CPPUNIT_TEST(index2); // Biased indexing. + CPPUNIT_TEST(rangecheck2); // Range checking works when on. std::range_error. - // CPPUNIT_TEST(changelow); - // CPPUNIT_TEST(changehigh); - // CPPUNIT_TEST(changebins); - // CPPUNIT_TEST(changeunits); - // CPPUNIT_TEST(enablelimcheck); - // CPPUNIT_TEST(disablelimcheck); + CPPUNIT_TEST(changelow); + CPPUNIT_TEST(changehigh); + CPPUNIT_TEST(changebins); + CPPUNIT_TEST(changeunits); + CPPUNIT_TEST(enablelimcheck); + CPPUNIT_TEST(disablelimcheck); @@ -36,17 +45,317 @@ private: + CParameterDictionary* m_pDict; public: void setUp() { + m_pDict = CParameterDictionary::instance(); + CParameter::enableAutoRegistration(); } void tearDown() { + delete CParameterDictionary::m_pInstance; + CParameterDictionary::m_pInstance = 0; + m_pDict = 0; } protected: - void aTest(); + void construct1(); + void destruct(); + void construct2(); + void construct3(); + void construct4(); + void construct5(); + + void rangecheck1(); + void index1(); + void index2(); + void rangecheck2(); + + void changelow(); + void changehigh(); + void changebins(); + void changeunits(); + + void enablelimcheck(); + void disablelimcheck(); }; CPPUNIT_TEST_SUITE_REGISTRATION(PArrayTests); -void PArrayTests::aTest() { +/** + * construct1 + * without a base offset, constructing should produce a + * number of parameters in the dictionary e.g. 16 of them + * produces basename.00 .. basename.15 + */ +void PArrayTests::construct1() { + CParameterArray* pArray = new CParameterArray("test", 16); + + for (int i =0; i < 16; i++) { + char name[100]; + sprintf(name, "%s.%02d", "test", i); + + // Should be able to find name in the dictionary: + + + CParameterDictionary::DictionaryIterator p = m_pDict->find(name); + ASSERT(p != m_pDict->end()); + } } +/** + * destruct + * Destroying a parameter array should also destry the parameter.l + */ +void PArrayTests::destruct() +{ + CParameterArray* pArray = new CParameterArray("test", 16); + delete pArray; + for (int i =0; i < 16; i++) { + char name[100]; + sprintf(name, "%s.%02d", "test", i); + + // Should be able to find name in the dictionary: + + + CParameterDictionary::DictionaryIterator p = m_pDict->find(name); + ASSERT(p == m_pDict->end()); + } + +} +/** + * construct2 - a non zero indexLow should bias the index/name + * of the first element. + */ +void +PArrayTests::construct2() +{ + CParameterArray* pArray = new CParameterArray("test", 16, 100); + + EQ(100U, pArray->m_indexLow); + EQ(std::string("test.100"), pArray->m_array[0]->getName()); +} +/** + * Construction that specifies the low/and high limit of the parameter. + */ +void +PArrayTests::construct3() +{ + CParameterArray* pArray = new CParameterArray("test", -1.0, 1.0, 16); + for (int i =0; i < 16; i++) { + char name[1000]; + sprintf(name, "%s.%02d", "test", i); + ASSERT(m_pDict->find(name) != m_pDict->end()); + + CParameter* p = pArray->m_array[i]; + EQ(-1.0, p->getLow()); + EQ(1.0, p->getHigh()); + } +} +/** + * construct4 - constructor for low, high ,units. + */ +void PArrayTests::construct4() +{ + CParameterArray* pArray = new CParameterArray("test", -1.0, 1.0,"furlongs", 16); + for (int i =0; i < 16; i++) { + char name[1000]; + sprintf(name, "%s.%02d", "test", i); + ASSERT(m_pDict->find(name) != m_pDict->end()); + + CParameter* p = pArray->m_array[i]; + EQ(-1.0, p->getLow()); + EQ(1.0, p->getHigh()); + EQ(std::string("furlongs"), p->getUnits()); + } +} +/** + * construct5 - constructor with low, high , binnning and units. + */ +void +PArrayTests::construct5() +{ + CParameterArray* pArray = new CParameterArray("test", -1.0, 1.0, 100, + "furlongs", 16); + for (int i =0; i < 16; i++) { + char name[1000]; + sprintf(name, "%s.%02d", "test", i); + ASSERT(m_pDict->find(name) != m_pDict->end()); + + CParameter* p = pArray->m_array[i]; + EQ(-1.0, p->getLow()); + EQ(1.0, p->getHigh()); + EQ(100U, p->getBins()); + EQ(std::string("furlongs"), p->getUnits()); + } +} + +/** + * rangecheck1 - should be able to turn on-off range checking flag. + */ +void +PArrayTests::rangecheck1() +{ + CParameterArray* pArray = new CParameterArray("test", 16); + ASSERT(! pArray->m_rangeCheck); + pArray->enableRangeCheck(); + ASSERT(pArray->m_rangeCheck); + pArray->disableRangeCheck(); + ASSERT(!pArray->m_rangeCheck); +} +/** + * index1 + * The index operator should work too + */ +void +PArrayTests::index1() +{ + CParameterArray array("test", 16); + for (int i =0; i < 16; i++) { + char name[1000]; + sprintf(name, "%s.%02d", "test", i); + EQ(std::string(name), array[i].getName()); + } +} +/** + * index2 + * Ensure indexing works when we use offsets as well: + */ +void +PArrayTests::index2() +{ + CParameterArray array("test", 16, 5); + for (int i = 5; i < 5+16; i++) { + char name[1000]; + sprintf(name, "%s.%02d", "test", i); + EQ(std::string(name), array[i].getName()); + } +} +/** + * rangecheck2 + * When range checks are enabled indexing out of bounds should + * throw std:range_error. + */ +void +PArrayTests::rangecheck2() +{ + CParameterArray array("test", 16, 5); + array.enableRangeCheck(); + + bool threw = false; + bool rthrew= false; + std::string msg; + std::string correctms("CParameterArray index is out of bounds"); + + try { + array[0].getName(); + } + catch(std::range_error e) { + threw = true; + rthrew= true; + msg = e.what(); + } + catch (...) { + threw = true; + } + ASSERT(threw); + ASSERT(rthrew); + EQ(correctms, msg); + + threw = false; + rthrew = false; + msg = ""; + try { + array[100].getName(); + } + catch(std::range_error e) { + threw = true; + rthrew= true; + msg = e.what(); + } + catch (...) { + threw = true; + } + ASSERT(threw); + ASSERT(rthrew); + EQ(correctms, msg); +} +/** + * changelow + * changeLow - should change the low limit of all the members of the + * array. + */ +void +PArrayTests::changelow() +{ + CParameterArray array("test", 0, 1, 16); + array.changeLow(-1); + for(int i =0; i < 15; i++) { + EQ(-1.0, array[i].getLow()); + } +} +/** + * changehigh + * should change the high limit of all members of the array. + */ +void +PArrayTests::changehigh() +{ + CParameterArray array("test", -1.0, 0.0, 16); + array.changeHigh(1); + for (int i =0; i < 15; i++) { + EQ(1.0, array[i].getHigh()); + } +} +/** + * changebins + * changeBins should do all elements of the array. + */ +void +PArrayTests::changebins() +{ + CParameterArray array("test", -1.0, 1.0, 100, "units", 16); + array.changeBins(200); + for (int i =0;i < 15; i++) { + EQ(200U, array[i].getBins()); + } +} +/** + * changeunits + * changeUnits on the array should do all elements. + */ +void +PArrayTests::changeunits() +{ + CParameterArray array("test", -1.0, 1.0, 100, "units", 16); + array.changeUnits("furlongs"); + for (int i = 0; i < 15; i++) { + EQ(std::string("furlongs"), array[i].getUnits()); + } +} +/** + * enablelimcheck + * + * enableLimitCheck should do that for all array elements. + */ +void +PArrayTests::enablelimcheck() +{ + CParameterArray array("test", -1.0, 1.0, 100, "units", 16); + array.enableLimitCheck(); + for (int i =0; i < 15; i++) { + ASSERT(array[i].checkLimits()); + } +} +/** + * disablelimcheck + * disableLimitcheck should do that for all elements. + */ +void +PArrayTests::disablelimcheck() +{ + CParameterArray array("test", -1.0, 1.0, 100, "units", 16); + array.enableLimitCheck(); + array.disableLimitCheck(); + for (int i =0; i < 15; i++) { + ASSERT(!array[i].checkLimits()); + } +} Modified: branches/spectcl-5.0/SpecTclPackage/ParameterTests.cpp =================================================================== --- branches/spectcl-5.0/SpecTclPackage/ParameterTests.cpp 2013-07-05 19:49:44 UTC (rev 2105) +++ branches/spectcl-5.0/SpecTclPackage/ParameterTests.cpp 2013-07-08 20:20:59 UTC (rev 2106) @@ -52,11 +52,10 @@ CPPUNIT_TEST(checklimits); CPPUNIT_TEST(invalidate); CPPUNIT_TEST(resetall); - //CPPUNIT_TEST(enableautoreg); - //CPPUNIT_TEST(disableautoreg); + CPPUNIT_TEST_SUITE_END(); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |