| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  *  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
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-10 07:58:48 +01:00
										 |  |  | #include "catch_context.h"
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-02-04 09:30:36 +00:00
										 |  |  | #include <iterator>
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | #include <vector>
 | 
					
						
							|  |  |  | #include <string>
 | 
					
						
							| 
									
										
										
										
											2011-02-04 09:30:36 +00:00
										 |  |  | #include <stdlib.h>
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  | namespace Catch { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | template<typename T> | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  | struct IGenerator { | 
					
						
							|  |  |  |     virtual ~IGenerator() {} | 
					
						
							|  |  |  |     virtual T getValue( std::size_t index ) const = 0; | 
					
						
							|  |  |  |     virtual std::size_t size () const = 0; | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename T> | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  | class BetweenGenerator : public IGenerator<T> { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     virtual T getValue( std::size_t index ) const { | 
					
						
							| 
									
										
										
										
											2013-01-09 19:32:50 +00:00
										 |  |  |         return m_from+static_cast<int>( index ); | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     virtual std::size_t size() const { | 
					
						
							| 
									
										
										
										
											2012-05-09 08:17:51 +01:00
										 |  |  |         return static_cast<std::size_t>( 1+m_to-m_from ); | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |     T m_from; | 
					
						
							|  |  |  |     T m_to; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename T> | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  | class ValuesGenerator : public IGenerator<T> { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     ValuesGenerator(){} | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     void add( T value ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         m_values.push_back( value ); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     virtual T getValue( std::size_t index ) const { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         return m_values[index]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     virtual std::size_t size() const { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         return m_values.size(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | private: | 
					
						
							|  |  |  |     std::vector<T> m_values; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename T> | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  | class CompositeGenerator { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | public: | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     CompositeGenerator() : m_totalSize( 0 ) {} | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-03-08 09:26:20 +00:00
										 |  |  |     // *** Move semantics, similar to auto_ptr ***
 | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  |     CompositeGenerator( CompositeGenerator& other ) | 
					
						
							|  |  |  |     :   m_fileInfo( other.m_fileInfo ), | 
					
						
							|  |  |  |         m_totalSize( 0 ) | 
					
						
							| 
									
										
										
										
											2011-02-23 09:06:05 +00:00
										 |  |  |     { | 
					
						
							| 
									
										
										
										
											2013-03-08 09:26:20 +00:00
										 |  |  |         move( other ); | 
					
						
							| 
									
										
										
										
											2011-02-23 09:06:05 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     CompositeGenerator& setFileInfo( const char* fileInfo ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         m_fileInfo = fileInfo; | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     ~CompositeGenerator() { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         deleteAll( m_composed ); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     operator T () const { | 
					
						
							| 
									
										
										
										
											2012-05-21 18:52:09 +01:00
										 |  |  |         size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         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(); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2011-02-23 09:06:05 +00:00
										 |  |  |         CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); | 
					
						
							| 
									
										
										
										
											2013-03-08 09:26:20 +00:00
										 |  |  |         return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     void add( const IGenerator<T>* generator ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         m_totalSize += generator->size(); | 
					
						
							|  |  |  |         m_composed.push_back( generator ); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     CompositeGenerator& then( CompositeGenerator& other ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         move( other ); | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     CompositeGenerator& then( T value ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); | 
					
						
							|  |  |  |         valuesGen->add( value ); | 
					
						
							|  |  |  |         add( valuesGen ); | 
					
						
							|  |  |  |         return *this; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | private: | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     void move( CompositeGenerator& other ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) ); | 
					
						
							|  |  |  |         m_totalSize += other.m_totalSize; | 
					
						
							|  |  |  |         other.m_composed.clear(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |     std::vector<const IGenerator<T>*> m_composed; | 
					
						
							|  |  |  |     std::string m_fileInfo; | 
					
						
							|  |  |  |     size_t m_totalSize; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | namespace Generators | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     template<typename T> | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     CompositeGenerator<T> between( T from, T to ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         CompositeGenerator<T> generators; | 
					
						
							|  |  |  |         generators.add( new BetweenGenerator<T>( from, to ) ); | 
					
						
							|  |  |  |         return generators; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<typename T> | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     CompositeGenerator<T> values( T val1, T val2 ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         CompositeGenerator<T> generators; | 
					
						
							|  |  |  |         ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); | 
					
						
							|  |  |  |         valuesGen->add( val1 ); | 
					
						
							|  |  |  |         valuesGen->add( val2 ); | 
					
						
							|  |  |  |         generators.add( valuesGen ); | 
					
						
							|  |  |  |         return generators; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     template<typename T> | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     CompositeGenerator<T> values( T val1, T val2, T val3 ){ | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         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> | 
					
						
							| 
									
										
										
										
											2012-05-15 07:42:26 +01:00
										 |  |  |     CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) { | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  |         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
 | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | using namespace Generators; | 
					
						
							| 
									
										
										
										
											2013-07-03 19:14:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-01-27 22:29:36 +00:00
										 |  |  | } // 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
 |