Multiple generators working and factored out a bit better

This commit is contained in:
Phil Nash
2011-01-27 22:29:36 +00:00
parent c2b96d7ddb
commit 5cad9d5a86
10 changed files with 340 additions and 25 deletions

View File

@@ -0,0 +1,298 @@
/*
* catch_generators.hpp
* Catch
*
* Created by Phil on 27/01/2011.
* Copyright 2011 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*
*/
#ifndef TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED
#include "catch_hub.h"
#include <vector>
#include <string>
namespace Catch
{
template<typename T>
struct IGenerator
{
virtual ~IGenerator
()
{}
virtual T getValue
( std::size_t index
) const = 0;
virtual std::size_t size
() const = 0;
};
template<typename T>
class BetweenGenerator : public IGenerator<T>
{
public:
///////////////////////////////////////////////////////////////////////////
BetweenGenerator
(
T from,
T to
)
: m_from( from ),
m_to( to )
{
}
///////////////////////////////////////////////////////////////////////////
virtual T getValue
(
std::size_t index
)
const
{
return m_from+index;
}
///////////////////////////////////////////////////////////////////////////
virtual std::size_t size
()
const
{
return 1+m_to-m_from;
}
private:
T m_from;
T m_to;
};
template<typename T>
class ValuesGenerator : public IGenerator<T>
{
public:
///////////////////////////////////////////////////////////////////////////
ValuesGenerator
()
{
}
///////////////////////////////////////////////////////////////////////////
void add
(
T value
)
{
m_values.push_back( value );
}
///////////////////////////////////////////////////////////////////////////
virtual T getValue
(
std::size_t index
)
const
{
return m_values[index];
}
///////////////////////////////////////////////////////////////////////////
virtual std::size_t size
()
const
{
return m_values.size();
}
private:
std::vector<T> m_values;
};
template<typename T>
class CompositeGenerator
{
public:
///////////////////////////////////////////////////////////////////////////
CompositeGenerator()
: m_totalSize( 0 )
{
}
///////////////////////////////////////////////////////////////////////////
CompositeGenerator& setFileInfo
(
const char* fileInfo
)
{
m_fileInfo = fileInfo;
return *this;
}
///////////////////////////////////////////////////////////////////////////
~CompositeGenerator
()
{
deleteAll( m_composed );
}
///////////////////////////////////////////////////////////////////////////
operator T
()
const
{
size_t overallIndex = Hub::getGeneratorIndex( m_fileInfo, m_totalSize );
typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin();
typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end();
for( size_t index = 0; it != itEnd; ++it )
{
const IGenerator<T>* generator = *it;
if( overallIndex >= index && overallIndex < index + generator->size() )
{
return generator->getValue( overallIndex-index );
}
index += generator->size();
}
throw "this should never happen!";
}
///////////////////////////////////////////////////////////////////////////
void add
(
const IGenerator<T>* generator
)
{
m_totalSize += generator->size();
m_composed.push_back( generator );
}
///////////////////////////////////////////////////////////////////////////
CompositeGenerator& then
(
CompositeGenerator& other
)
{
move( other );
return *this;
}
///////////////////////////////////////////////////////////////////////////
CompositeGenerator& then
(
T value
)
{
ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
valuesGen->add( value );
add( valuesGen );
return *this;
}
private:
///////////////////////////////////////////////////////////////////////////
void move
(
CompositeGenerator& other
)
{
std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) );
m_totalSize += other.m_totalSize;
other.m_composed.clear();
}
std::vector<const IGenerator<T>*> m_composed;
std::string m_fileInfo;
size_t m_totalSize;
};
namespace Generators
{
///////////////////////////////////////////////////////////////////////////
template<typename T>
CompositeGenerator<T> between
(
T from,
T to
)
{
CompositeGenerator<T> generators;
generators.add( new BetweenGenerator<T>( from, to ) );
return generators;
}
///////////////////////////////////////////////////////////////////////////
template<typename T>
CompositeGenerator<T> values
(
T val1,
T val2
)
{
CompositeGenerator<T> generators;
ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
valuesGen->add( val1 );
valuesGen->add( val2 );
generators.add( valuesGen );
return generators;
}
///////////////////////////////////////////////////////////////////////////
template<typename T>
CompositeGenerator<T> values
(
T val1,
T val2,
T val3
)
{
CompositeGenerator<T> generators;
ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
valuesGen->add( val1 );
valuesGen->add( val2 );
valuesGen->add( val3 );
generators.add( valuesGen );
return generators;
}
///////////////////////////////////////////////////////////////////////////
template<typename T>
CompositeGenerator<T> values
(
T val1,
T val2,
T val3,
T val4
)
{
CompositeGenerator<T> generators;
ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>();
valuesGen->add( val1 );
valuesGen->add( val2 );
valuesGen->add( val3 );
valuesGen->add( val4 );
generators.add( valuesGen );
return generators;
}
} // end namespace Generators
using namespace Generators;
} // end namespace Catch
#define INTERNAL_CATCH_LINESTR2( line ) #line
#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line )
#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" )
#endif // TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED

View File

@@ -96,18 +96,12 @@ namespace Catch
{
}
void reset
()
{
m_currentIndex = 0;
}
bool moveNext
()
{
if( ++m_currentIndex == m_size )
{
reset();
m_currentIndex = 0;
return false;
}
return true;
@@ -157,20 +151,19 @@ namespace Catch
return *it->second;
}
void reset
()
{
std::vector<GeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
std::vector<GeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.begin();
for(; it != itEnd; ++it )
{
(*it)->reset();
}
}
bool moveNext
()
{
std::vector<GeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin();
std::vector<GeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end();
for(; it != itEnd; ++it )
{
if( (*it)->moveNext() )
return true;
}
return false;
/*
if( !m_generatorsInOrder[m_currentGenerator]->moveNext() )
{
if( ++m_currentGenerator == m_generatorsInOrder.size() )
@@ -180,6 +173,7 @@ namespace Catch
}
}
return true;
*/
}
private:

View File

@@ -52,7 +52,7 @@ namespace Catch
};
}
#define CATCH_REGISTER_REPORTER( name, reporterType ) \
#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \
Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name );
#endif // TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED

View File

@@ -49,6 +49,6 @@ namespace Catch
} // end namespace Catch
#define CATCH_SECTION( name, desc ) if( Catch::Section catch_internal_Section = Catch::Section( name, desc ) )
#define INTERNAL_CATCH_SECTION( name, desc ) if( Catch::Section catch_internal_Section = Catch::Section( name, desc ) )
#endif // TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED