Skip to content
Snippets Groups Projects
Commit 6e2ff135 authored by Fons Rademakers's avatar Fons Rademakers
Browse files

From Anar:

- the SFind functor has been simplified and now become a fully copyable functor
- added  tests for  the following  cases:
   * TMap with std::for_each (Full iteration: from the Begin up to the End)
   * TMap with std::for_each (Partial iteration: from the Begin up to the
     3rd element)
   * TMap with std::find_if
   * TMap with std::count_if
- cosmetic changes


git-svn-id: http://root.cern.ch/svn/root/trunk@23329 27541ba8-7e3a-0410-8455-c3a389f83636
parent 28fffc2a
Branches
Tags
No related merge requests found
...@@ -636,7 +636,8 @@ distclean: clean ...@@ -636,7 +636,8 @@ distclean: clean
.SUFFIXES: .$(SrcSuf) .SUFFIXES: .$(SrcSuf)
### ###
stressIterators.$(ObjSuf): stressIterators.h
Event.$(ObjSuf): Event.h Event.$(ObjSuf): Event.h
MainEvent.$(ObjSuf): Event.h MainEvent.$(ObjSuf): Event.h
......
...@@ -4,12 +4,16 @@ ...@@ -4,12 +4,16 @@
//---------------------------------------------------------------- //----------------------------------------------------------------
// This is a tests ROOT Iterators and STL algorithms. // This is a tests ROOT Iterators and STL algorithms.
// The test project covers the following cases: // The test project covers the following cases:
// 1 - TList with std::for_each // 1 - TList with std::for_each (Full iteration: from the Begin up to the End)
// 2 - TList with std::find_if // 2 - TList with std::find_if
// 3 - TList with std::count_if // 3 - TList with std::count_if
// 4 - TObjArray with std::for_each // 4 - TObjArray with std::for_each (Full iteration: from the Begin up to the End)
// 5 - TObjArray with std::find_if // 5 - TObjArray with std::find_if
// 6 - TObjArray with std::count_if // 6 - TObjArray with std::count_if
// 7 - TMap with std::for_each (Full iteration: from the Begin up to the End)
// 8 - TMap with std::for_each (Partial iteration: from the Begin up to the 3rd element)
// 9 - TMap with std::find_if
// 10 - TMap with std::count_if
...@@ -22,104 +26,21 @@ ...@@ -22,104 +26,21 @@
#include "TList.h" #include "TList.h"
#include "TObjString.h" #include "TObjString.h"
#include "TObjArray.h" #include "TObjArray.h"
#include "TMap.h"
// Local
#include "stressIterators.h"
using namespace std; using namespace std;
static Int_t gCount = 0;
//______________________________________________________________________________
struct SEnumFunctor {
bool operator()(TObject *aObj) throw(exception) {
if (!aObj)
throw invalid_argument("SEnumFunctor: aObj is a NULL pointer");
TObjString *str(dynamic_cast<TObjString*>(aObj));
if (!str)
throw runtime_error("SEnumFunctor: Container's element is not a TObjString object.");
++gCount;
cout << str->String().Data() << endl;
return true;
}
};
//______________________________________________________________________________
struct SFind {
SFind(const TString &aStr): fToFind(aStr) {
}
bool operator()(TObject *aObj) {
TObjString *str(dynamic_cast<TObjString*>(aObj));
return !str->String().CompareTo(fToFind);
}
private:
const TString fToFind;
};
//______________________________________________________________________________
// Checking TList with for_each algorithm
template<class T>
void TestContainer_for_each(const T &container, Int_t aSize) throw(exception)
{
gCount = 0; // TODO: using gCount is a very bad method. Needs to be revised.
TIter iter(&container);
for_each(iter.Begin(), TIter::End(), SEnumFunctor());
if (aSize != gCount)
throw runtime_error("Test case <TestList_for_each> has failed.");
cout << "->> Ok." << endl;
}
//______________________________________________________________________________
// Checking a ROOT container with find_if algorithm
template<class T>
void TestContainer_find_if(const T &container, const TString &aToFind) throw(exception)
{
typedef TIterCategory<T> iterator_t;
SFind func(aToFind);
iterator_t iter(&container);
iterator_t found(
find_if(iter.Begin(), iterator_t::End(), func)
);
if (!(*found))
throw runtime_error("Test case <TestContainer_find_if> has failed.");
TObjString *str(dynamic_cast<TObjString*>(*found));
if (!str)
throw runtime_error("Test case <TestContainer_find_if> has failed.");
std::cout << "I found: " << str->String().Data() << std::endl;
cout << "->> Ok." << endl;
}
//______________________________________________________________________________
// Checking a ROOT container with count_if algorithm
template<class T>
void TestContainer_count_if(const T &container, const TString &aToFind) throw(exception)
{
typedef TIterCategory<T> iterator_t;
SFind func(aToFind);
iterator_t iter(&container);
typename iterator_t::difference_type cnt(
count_if(iter.Begin(), iterator_t::End(), func)
);
if (1 != cnt)
throw runtime_error("Test case <TestContainer_count_if> has failed.");
cout << "->> Ok." << endl;
}
//______________________________________________________________________________ //______________________________________________________________________________
void stressIterators() throw(exception) void stressIterators() throw(exception)
{ {
const Int_t size = 15; const Int_t size = 15;
ostringstream ss; ostringstream ss;
// TList // TList
TList list; TList list;
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
ss << "test string #" << i; ss << "test string #" << i;
TObjString *s(new TObjString(ss.str().c_str())); TObjString *s(new TObjString(ss.str().c_str()));
...@@ -127,17 +48,18 @@ void stressIterators() throw(exception) ...@@ -127,17 +48,18 @@ void stressIterators() throw(exception)
ss.str(""); ss.str("");
} }
cout << "====================================" << endl; cout << "#1 ====================================" << endl;
cout << "-----> " << "TestContainer_for_each<TList>(list, list.GetSize())" << endl; cout << "-----> " << "TestContainer_for_each<TList>(list, list.GetSize())" << endl;
TestContainer_for_each<TList>(list, list.GetSize()); TestContainer_for_each<TList>(list, list.GetSize());
cout << "====================================" << endl; cout << "\n#2 ====================================" << endl;
cout << "-----> " << "TestContainer_find_if<TList>(list, \"test string #3\")" << endl; cout << "-----> " << "TestContainer_find_if<TList>(list, \"test string #3\")" << endl;
TestContainer_find_if<TList>(list, "test string #3"); TestContainer_find_if<TList>(list, "test string #3");
cout << "====================================" << endl; cout << "\n#3 ====================================" << endl;
cout << "-----> " << "TestContainer_count_if<TList>(list, \"test string #3\")" << endl; cout << "-----> " << "TestContainer_count_if<TList>(list, \"test string #3\", 1)" << endl;
TestContainer_count_if<TList>(list, "test string #3"); // we suppose to find exactly one match
TestContainer_count_if<TList>(list, "test string #3", 1);
// TObjArray // TObjArray
...@@ -149,17 +71,41 @@ void stressIterators() throw(exception) ...@@ -149,17 +71,41 @@ void stressIterators() throw(exception)
ss.str(""); ss.str("");
} }
cout << "====================================" << endl; cout << "\n#4 ====================================" << endl;
cout << "-----> " << "TestContainer_for_each<TObjArray>(obj_array, obj_array.GetSize())" << endl; cout << "-----> " << "TestContainer_for_each<TObjArray>(obj_array, obj_array.GetSize())" << endl;
TestContainer_for_each<TObjArray>(obj_array, obj_array.GetEntriesFast()); TestContainer_for_each<TObjArray>(obj_array, obj_array.GetSize());
cout << "====================================" << endl; cout << "\n#5 ====================================" << endl;
cout << "-----> " << "TestContainer_find_if<TObjArray>(obj_array, \"test string #3\")" << endl; cout << "-----> " << "TestContainer_find_if<TObjArray>(obj_array, \"test string #3\")" << endl;
TestContainer_find_if<TObjArray>(obj_array, "test string #3"); TestContainer_find_if<TObjArray>(obj_array, "test string #3");
cout << "====================================" << endl; cout << "\n#6 ====================================" << endl;
cout << "-----> " << "TestContainer_count_if<TObjArray>(obj_array, \"test string #3\")" << endl; cout << "-----> " << "TestContainer_count_if<TObjArray>(obj_array, \"test string #3\", 1)" << endl;
TestContainer_count_if<TObjArray>(obj_array, "test string #3"); // we suppose to find exactly one match
TestContainer_count_if<TObjArray>(obj_array, "test string #3", 1);
// TMap
const char * const cszValue("value");
TMap map_container(size);
for (int i = 0; i < size; ++i) {
ss << "test string #" << i;
TObjString *s(new TObjString(ss.str().c_str()));
map_container.Add(s, new TObjString(cszValue));
ss.str("");
}
cout << "\n#7 ====================================" << endl;
cout << "-----> " << "TestContainer_for_each<TMap>(map_container, map_container.GetSize())" << endl;
TestContainer_for_each<TMap>(map_container, map_container.GetSize());
cout << "\n#8 ====================================" << endl;
cout << "-----> " << "TestContainer_for_each2<TMap>(map_container)" << endl;
TestContainer_for_each2<TMap>(map_container);
cout << "\n#9 ====================================" << endl;
cout << "-----> " << "TestContainer_find_if<TMap>(map_container, cszValue)" << endl;
TestContainer_find_if<TMap>(map_container, cszValue);
cout << "\n#10 ====================================" << endl;
cout << "-----> " << "TestContainer_count_if<TMap>(map_container, cszValue, map_container.GetSize());" << endl;
TestContainer_count_if<TMap>(map_container, cszValue, map_container.GetSize());
} }
//______________________________________________________________________________ //______________________________________________________________________________
......
// @(#)root/test:$Id$
// Author: Anar Manafov 18/04/2008
#ifndef ROOT_stressIterators
#define ROOT_stressIterators
static Int_t gCount = 0;
// Here we have a collection of functors and functions used by the test suit
//______________________________________________________________________________
template<class T>
struct SEnumFunctor {
bool operator()(TObject *aObj) const throw(std::exception) {
if (!aObj)
throw std::invalid_argument("SEnumFunctor: aObj is a NULL pointer");
if ((aObj->IsA() == TObjString::Class())) {
TObjString *str(dynamic_cast<TObjString*>(aObj));
if (!str)
throw std::runtime_error("SEnumFunctor: Container's element is not a TObjString object.");
++gCount;
std::cout << str->String().Data() << std::endl;
}
return true;
}
};
//______________________________________________________________________________
template<>
struct SEnumFunctor<TMap> {
bool operator()(TObject *aObj) const throw(std::exception) {
if (!aObj)
throw std::invalid_argument("SEnumFunctor: aObj is a NULL pointer");
if ((aObj->IsA() == TPair::Class())) {
TPair *pair(dynamic_cast<TPair*>(aObj));
if (!pair)
throw std::runtime_error("SEnumFunctor: Container's element is not a TPair object.");
TObjString *key(dynamic_cast<TObjString*>(pair->Key()));
TObjString *value(dynamic_cast<TObjString*>(pair->Value()));
if (!key || !value)
throw std::runtime_error("SEnumFunctor: Can't retriev key/value of a pair");
++gCount;
std::cout << key->String().Data() << " : " << value->String().Data() << std::endl;
}
return true;
}
};
//______________________________________________________________________________
template<class T>
struct SFind : std::binary_function<TObject*, TString, bool> {
bool operator()(TObject *_Obj, const TString &_ToFind) const {
TObjString *str(dynamic_cast<TObjString*>(_Obj));
if (!str)
throw std::runtime_error("SFind: Container's element is not a TObString object.");
return !str->String().CompareTo(_ToFind);
}
};
//______________________________________________________________________________
template<>
struct SFind<TMap> : std::binary_function<TObject*, TString, bool> {
bool operator()(TObject *_Obj, const TString &_ToFind) const {
TPair *pair(dynamic_cast<TPair*>(_Obj));
if (!pair)
throw std::runtime_error("SFind: Container's element is not a TPair object.");
// Checking the VALUE of the pair
TObjString *str(dynamic_cast<TObjString*>(pair->Value()));
return !str->String().CompareTo(_ToFind);
}
};
//______________________________________________________________________________
// Checking a given container with for_each algorithm
// Full iteration: from Begin to End
template<class T>
void TestContainer_for_each(const T &container, Int_t aSize) throw(std::exception)
{
gCount = 0; // TODO: a use of gCount is a very bad method. Needs to be revised.
TIter iter(&container);
std::for_each(iter.Begin(), TIter::End(), SEnumFunctor<T>());
if (aSize != gCount)
throw std::runtime_error("Test case <TestList_for_each> has failed.");
std::cout << "->> Ok." << std::endl;
}
//______________________________________________________________________________
// Checking a given container with for_each algorithm
// Partial iteration: from Begin to 3rd element
template<class T>
void TestContainer_for_each2(const T &container) throw(std::exception)
{
gCount = 0; // TODO: a use of gCount is a very bad method. Needs to be revised.
TIter iter(&container);
TIter iter_end(&container);
// Artificially shifting the iterator to the 4th potision - a new End iterator
iter_end();
iter_end();
iter_end();
iter_end();
std::for_each(iter.Begin(), iter_end, SEnumFunctor<T>());
if (3 != gCount)
throw std::runtime_error("Test case <TestList_for_each2> has failed.");
std::cout << "->> Ok." << std::endl;
}
//______________________________________________________________________________
// Checking a ROOT container with find_if algorithm
template<class T>
void TestContainer_find_if(const T &container, const TString &aToFind) throw(std::exception)
{
typedef TIterCategory<T> iterator_t;
iterator_t iter(&container);
iterator_t found(
std::find_if(iter.Begin(), iterator_t::End(), bind2nd(SFind<T>(), aToFind))
);
if (!(*found))
throw std::runtime_error("Test case <TestContainer_find_if> has failed. Can't find object.");
// Checking whether element is a Pair or not
if (((*found)->IsA() == TPair::Class())) {
TPair *pair(dynamic_cast<TPair*>(*found));
if (!pair)
throw std::runtime_error("TestContainer_find_if: Container's element is not a TPair object.");
TObjString *key(dynamic_cast<TObjString*>(pair->Key()));
TObjString *val(dynamic_cast<TObjString*>(pair->Value()));
std::cout << "I found: [" << key->String().Data() << " : " << val->String().Data() << "]" << std::endl;
std::cout << "->> Ok." << std::endl;
return;
}
TObjString *str(dynamic_cast<TObjString*>(*found));
if (!str)
throw std::runtime_error("Test case <TestContainer_find_if> has failed. String object is NULL");
std::cout << "I found: " << str->String().Data() << std::endl;
std::cout << "->> Ok." << std::endl;
}
//______________________________________________________________________________
// Checking a ROOT container with count_if algorithm
template<class T>
void TestContainer_count_if(const T &container, const TString &aToFind, Int_t Count) throw(std::exception)
{
typedef TIterCategory<T> iterator_t;
iterator_t iter(&container);
typename iterator_t::difference_type cnt(
std::count_if(iter.Begin(), iterator_t::End(), bind2nd(SFind<T>(), aToFind))
);
if (Count != cnt)
throw std::runtime_error("Test case <TestContainer_count_if> has failed.");
std::cout << "->> Ok." << std::endl;
}
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment