From ab06f0a9999c23ae039a7c2b4bd4e62af599cbc6 Mon Sep 17 00:00:00 2001 From: Shan Jiang Date: Sat, 6 Sep 2008 04:11:11 +0000 Subject: [PATCH] [trunk] Add Poco::Array utility class and test cases. * add Array.h to Poco::Foundation. * add ArrayTest to testsuite. * update build solution/makefile. --- Foundation/Foundation_vs71.vcproj | 3 + Foundation/Foundation_vs80.vcproj | 4 + Foundation/Foundation_vs90.vcproj | 4 + Foundation/include/Poco/Array.h | 271 +++++++++++++++++++++ Foundation/testsuite/Makefile-Driver | 2 +- Foundation/testsuite/TestSuite_vs71.vcproj | 6 + Foundation/testsuite/TestSuite_vs80.vcproj | 8 + Foundation/testsuite/TestSuite_vs90.vcproj | 8 + Foundation/testsuite/src/ArrayTest.cpp | 253 +++++++++++++++++++ Foundation/testsuite/src/ArrayTest.h | 66 +++++ Foundation/testsuite/src/CoreTestSuite.cpp | 4 +- Foundation/testsuite/testsuite.vmsbuild | 1 + 12 files changed, 628 insertions(+), 2 deletions(-) create mode 100644 Foundation/include/Poco/Array.h create mode 100644 Foundation/testsuite/src/ArrayTest.cpp create mode 100644 Foundation/testsuite/src/ArrayTest.h diff --git a/Foundation/Foundation_vs71.vcproj b/Foundation/Foundation_vs71.vcproj index def11054e..25a9df1b7 100644 --- a/Foundation/Foundation_vs71.vcproj +++ b/Foundation/Foundation_vs71.vcproj @@ -554,6 +554,9 @@ + + diff --git a/Foundation/Foundation_vs80.vcproj b/Foundation/Foundation_vs80.vcproj index fcd3fc15d..2355fa208 100644 --- a/Foundation/Foundation_vs80.vcproj +++ b/Foundation/Foundation_vs80.vcproj @@ -763,6 +763,10 @@ RelativePath=".\include\Poco\Any.h" > + + diff --git a/Foundation/Foundation_vs90.vcproj b/Foundation/Foundation_vs90.vcproj index b9751f425..8dfa44349 100644 --- a/Foundation/Foundation_vs90.vcproj +++ b/Foundation/Foundation_vs90.vcproj @@ -754,6 +754,10 @@ RelativePath=".\include\Poco\Any.h" > + + diff --git a/Foundation/include/Poco/Array.h b/Foundation/include/Poco/Array.h new file mode 100644 index 000000000..cb19c541d --- /dev/null +++ b/Foundation/include/Poco/Array.h @@ -0,0 +1,271 @@ +// +// Array.h +// +// $Id: //poco/svn/Foundation/include/Poco/Array.h#2 $ +// +// Library: Foundation +// Package: Core +// Module: Array +// +// Definition of the Array class +// +// Copyright (c) 2004-2008, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// ------------------------------------------------------------------------------ +// (C) Copyright Nicolai M. Josuttis 2001. +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// ------------------------------------------------------------------------------ + + +#ifndef Foundation_Array_INCLUDED +#define Foundation_Array_INCLUDED + +#include "Poco/Exception.h" +#include "Poco/Bugcheck.h" +#include + +namespace Poco { + +template +class Array + /// STL container like C-style array replacement class. + /// + /// This implementation is based on the idea of Nicolai Josuttis. + /// His original implementation can be found at http://www.josuttis.com/cppcode/array.html . +{ + +public: + + typedef T value_type; + typedef T* iterator; + typedef const T* const_iterator; + typedef T& reference; + typedef const T& const_reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + iterator begin() + { + return elems; + } + + const_iterator begin() const + { + return elems; + } + + iterator end() + { + return elems+N; + } + + const_iterator end() const + { + return elems+N; + } + + typedef std::reverse_iterator reverse_iterator; + typedef std::reverse_iterator const_reverse_iterator; + + reverse_iterator rbegin() + { + return reverse_iterator(end()); + } + + const_reverse_iterator rbegin() const + { + return const_reverse_iterator(end()); + } + + reverse_iterator rend() + { + return reverse_iterator(begin()); + } + + const_reverse_iterator rend() const + { + return const_reverse_iterator(begin()); + } + + reference operator[](size_type i) + /// element access without range check. If the index is not small than the given size, the behavior is undefined. + { + poco_assert( i < N && "out of range" ); + return elems[i]; + } + + const_reference operator[](size_type i) const + /// element access without range check. If the index is not small than the given size, the behavior is undefined. + { + poco_assert( i < N && "out of range" ); + return elems[i]; + } + + reference at(size_type i) + /// element access with range check. Throws Poco::InvalidArgumentException if the index is over range. + { + if(i>=size()) + throw Poco::InvalidArgumentException("Array::at() range check failed: index is over range"); + return elems[i]; + } + + const_reference at(size_type i) const + /// element access with range check. Throws Poco::InvalidArgumentException if the index is over range. + { + if(i>=size()) + throw Poco::InvalidArgumentException("Array::at() range check failed: index is over range"); + return elems[i]; + } + + // front() and back() + reference front() + { + return elems[0]; + } + + const_reference front() const + { + return elems[0]; + } + + reference back() + { + return elems[N-1]; + } + + const_reference back() const + { + return elems[N-1]; + } + + static size_type size() + { + return N; + } + + static bool empty() + { + return false; + } + + static size_type max_size() + { + return N; + } + + enum { static_size = N }; + + void swap (Array& y) { + std::swap_ranges(begin(),end(),y.begin()); + } + + const T* data() const + /// direct access to data (read-only) + { + return elems; + } + + T* data() + { + return elems; + } + + T* c_array(){ + /// use array as C array (direct read/write access to data) + return elems; + } + + template + Array& operator= (const Array& rhs) + /// assignment with type conversion + { + std::copy(rhs.begin(),rhs.end(), begin()); + return *this; + } + + void assign (const T& value) + /// assign one value to all elements + { + std::fill_n(begin(),size(),value); + } + +public: + + T elems[N]; // fixed-size array of elements of type T, public specifier used to make this class a aggregate. + +}; + +// comparisons +template +bool operator== (const Array& x, const Array& y) +{ + return std::equal(x.begin(), x.end(), y.begin()); +} + +template +bool operator< (const Array& x, const Array& y) +{ + return std::lexicographical_compare(x.begin(),x.end(),y.begin(),y.end()); +} + +template +bool operator!= (const Array& x, const Array& y) +{ + return !(x==y); +} + +template +bool operator> (const Array& x, const Array& y) +{ + return y +bool operator<= (const Array& x, const Array& y) +{ + return !(y +bool operator>= (const Array& x, const Array& y) +{ + return !(x +inline void swap (Array& x, Array& y) + /// global swap() +{ + x.swap(y); +} + +}// namespace Poco + +#endif // Foundation_Array_INCLUDED + diff --git a/Foundation/testsuite/Makefile-Driver b/Foundation/testsuite/Makefile-Driver index dcdab634a..397072457 100644 --- a/Foundation/testsuite/Makefile-Driver +++ b/Foundation/testsuite/Makefile-Driver @@ -9,7 +9,7 @@ include $(POCO_BASE)/build/rules/global objects = ActiveMethodTest ActivityTest ActiveDispatcherTest \ - AutoPtrTest SharedPtrTest AutoReleasePoolTest Base64Test \ + AutoPtrTest ArrayTest SharedPtrTest AutoReleasePoolTest Base64Test \ BinaryReaderWriterTest LineEndingConverterTest \ ByteOrderTest ChannelTest ClassLoaderTest CoreTest CoreTestSuite \ CountingStreamTest CryptTestSuite DateTimeFormatterTest \ diff --git a/Foundation/testsuite/TestSuite_vs71.vcproj b/Foundation/testsuite/TestSuite_vs71.vcproj index 0631d8f9f..3b4d3b4cd 100644 --- a/Foundation/testsuite/TestSuite_vs71.vcproj +++ b/Foundation/testsuite/TestSuite_vs71.vcproj @@ -259,6 +259,9 @@ + + @@ -326,6 +329,9 @@ + + diff --git a/Foundation/testsuite/TestSuite_vs80.vcproj b/Foundation/testsuite/TestSuite_vs80.vcproj index a308df9ce..38791eb04 100644 --- a/Foundation/testsuite/TestSuite_vs80.vcproj +++ b/Foundation/testsuite/TestSuite_vs80.vcproj @@ -382,6 +382,10 @@ RelativePath=".\src\AnyTest.cpp" > + + @@ -470,6 +474,10 @@ RelativePath=".\src\AnyTest.h" > + + diff --git a/Foundation/testsuite/TestSuite_vs90.vcproj b/Foundation/testsuite/TestSuite_vs90.vcproj index dcc5c8b1d..0a302077e 100644 --- a/Foundation/testsuite/TestSuite_vs90.vcproj +++ b/Foundation/testsuite/TestSuite_vs90.vcproj @@ -371,6 +371,10 @@ RelativePath=".\src\AnyTest.cpp" > + + @@ -459,6 +463,10 @@ RelativePath=".\src\AnyTest.h" > + + diff --git a/Foundation/testsuite/src/ArrayTest.cpp b/Foundation/testsuite/src/ArrayTest.cpp new file mode 100644 index 000000000..5068e7e28 --- /dev/null +++ b/Foundation/testsuite/src/ArrayTest.cpp @@ -0,0 +1,253 @@ +// +// ArrayTest.cpp +// +// $Id: //poco/svn/Foundation/testsuite/src/ArrayTest.cpp#2 $ +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#include "ArrayTest.h" +#include "CppUnit/TestCaller.h" +#include "CppUnit/TestSuite.h" +#include "Poco/Array.h" +#include +#include +#include + +ArrayTest::ArrayTest(const std::string& name): CppUnit::TestCase(name) +{ +} + + +ArrayTest::~ArrayTest() +{ +} + +struct Element +{ + int _data; +}; + +void ArrayTest::testConstruction() +{ + + // fundamental type + typedef Poco::Array FloatArray; + FloatArray a = { { 42.f } }; + + for (unsigned i=1; i DArray; + typedef Poco::Array IArray; + IArray ia = { 1, 2, 3, 4, 5, 6 }; + DArray da; + da = ia; + da.assign(42); + + // user-defined type + typedef Poco::Array ElementArray; + ElementArray g; + + for (unsigned i=0; i Array; + Array a = { { 1 } }; + + // use some common STL container operations + assert(a.size() == SIZE); + assert(a.max_size() == SIZE); + assert(a.empty() == false); + assert(a.front() == a[0]); + assert(a.back() == a[a.size()-1]); + //assert(a.data() == &a[0]); + + // assign + a.assign(100); + for(int i = 0; i Array; + Array a = { 1, 2 }; + assert(a[0] == 1); + assert(a[1] == 2); + + typedef std::vector ArrayVec; + ArrayVec container; + container.push_back(a); + container.push_back(a); + + assert(container[0][0] == 1); + assert(container[0][1] == 2); + assert(container[1][0] == 1); + assert(container[1][1] == 2); +} + +void ArrayTest::testIterator() +{ + // create array of four seasons + Poco::Array seasons = { + { "spring", "summer", "autumn", "winter" } + }; + + // copy and change order + Poco::Array org = seasons; + for (size_t i=seasons.size()-1; i>0; --i) { + swap(seasons.at(i),seasons.at((i+1)%seasons.size())); + } + + // try swap() + swap(seasons,org); + + // try reverse iterators + for (Poco::Array::reverse_iterator pos + =seasons.rbegin(); pos IArray; + IArray a = { { 1, 2, 3, 4, 5 } }; + IArray b(a); + + // modify elements directly + for (unsigned i=0; i()); // operation + + for (unsigned i=0; i IArray; + typedef Poco::Array MultiArray; + + MultiArray a; + a[0][0] = 1; + a[0][1] = 2; + a[1][0] = 3; + a[1][1] = 4; + + MultiArray b = a; + assert(b[0][0] == 1); + assert(b[0][1] == 2); + assert(b[1][0] == 3); + assert(b[1][1] == 4); +} + +void ArrayTest::setUp() +{ +} + + +void ArrayTest::tearDown() +{ +} + + +CppUnit::Test* ArrayTest::suite() +{ + CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ArrayTest"); + + CppUnit_addTest(pSuite, ArrayTest, testConstruction); + CppUnit_addTest(pSuite, ArrayTest, testOperations); + CppUnit_addTest(pSuite, ArrayTest, testContainer); + CppUnit_addTest(pSuite, ArrayTest, testIterator); + CppUnit_addTest(pSuite, ArrayTest, testAlgorithm); + CppUnit_addTest(pSuite, ArrayTest, testMultiLevelArray); + + return pSuite; +} diff --git a/Foundation/testsuite/src/ArrayTest.h b/Foundation/testsuite/src/ArrayTest.h new file mode 100644 index 000000000..833d9e18a --- /dev/null +++ b/Foundation/testsuite/src/ArrayTest.h @@ -0,0 +1,66 @@ +// +// ArrayTest.h +// +// $Id: //poco/svn/Foundation/testsuite/src/ArrayTest.h#2 $ +// +// Definition of the ArrayTest class. +// +// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// and Contributors. +// +// Permission is hereby granted, free of charge, to any person or organization +// obtaining a copy of the software and accompanying documentation covered by +// this license (the "Software") to use, reproduce, display, distribute, +// execute, and transmit the Software, and to prepare derivative works of the +// Software, and to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire statement, including +// the above license grant, this restriction and the following disclaimer, +// must be included in all copies of the Software, in whole or in part, and +// all derivative works of the Software, unless such copies or derivative +// works are solely in the form of machine-executable object code generated by +// a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// + + +#ifndef ArrayTest_INCLUDED +#define ArrayTest_INCLUDED + + +#include "Poco/Foundation.h" +#include "CppUnit/TestCase.h" + + +class ArrayTest: public CppUnit::TestCase +{ +public: + ArrayTest(const std::string& name); + ~ArrayTest(); + + void testConstruction(); + void testOperations(); + void testContainer(); + void testIterator(); + void testAlgorithm(); + void testMultiLevelArray(); + + void setUp(); + void tearDown(); + + static CppUnit::Test* suite(); + +private: +}; + + +#endif // ArrayTest_INCLUDED + diff --git a/Foundation/testsuite/src/CoreTestSuite.cpp b/Foundation/testsuite/src/CoreTestSuite.cpp index 4f0a19196..0f82bb9da 100644 --- a/Foundation/testsuite/src/CoreTestSuite.cpp +++ b/Foundation/testsuite/src/CoreTestSuite.cpp @@ -33,6 +33,7 @@ #include "CoreTestSuite.h" #include "CoreTest.h" #include "AutoPtrTest.h" +#include "ArrayTest.h" #include "SharedPtrTest.h" #include "AutoReleasePoolTest.h" #include "ByteOrderTest.h" @@ -58,7 +59,8 @@ CppUnit::Test* CoreTestSuite::suite() CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("CoreTestSuite"); pSuite->addTest(CoreTest::suite()); - pSuite->addTest(AutoPtrTest::suite()); + pSuite->addTest(ArrayTest::suite()); + pSuite->addTest(AutoPtrTest::suite()); pSuite->addTest(SharedPtrTest::suite()); pSuite->addTest(AutoReleasePoolTest::suite()); pSuite->addTest(ByteOrderTest::suite()); diff --git a/Foundation/testsuite/testsuite.vmsbuild b/Foundation/testsuite/testsuite.vmsbuild index c86f52a1f..e61ad353e 100644 --- a/Foundation/testsuite/testsuite.vmsbuild +++ b/Foundation/testsuite/testsuite.vmsbuild @@ -7,6 +7,7 @@ EXE=TestRunner ActiveMethodTest ActivityTest AutoPtrTest +ArrayTest SmartPtrTest Base64Test AutoReleasePoolTest