1 //  (C) Copyright Gennadiy Rozental 2003-2005.
2 //  Distributed under the Boost Software License, Version 1.0.
3 //  (See accompanying file LICENSE_1_0.txt or copy at
4 //  http://www.boost.org/LICENSE_1_0.txt)
5 
6 //  See http://www.boost.org/libs/test for the library home page.
7 //
8 //  File        : $RCSfile: test_case_template.hpp,v $
9 //
10 //  Version     : $Revision: 1.1.1.1 $
11 //
12 //  Description : implements support for test cases templates instantiated with
13 //                sequence of test types
14 // ***************************************************************************
15 
16 #ifndef BOOST_TEST_TEST_CASE_TEMPLATE_HPP_071894GER
17 #define BOOST_TEST_TEST_CASE_TEMPLATE_HPP_071894GER
18 
19 // Boost.Test
20 #include <boost/test/unit_test_suite.hpp>
21 
22 // Boost
23 #include <boost/mpl/for_each.hpp>
24 #include <boost/mpl/identity.hpp>
25 #include <boost/type.hpp>
26 #include <boost/type_traits/is_const.hpp>
27 
28 // STL
29 #include <typeinfo>
30 
31 #include <boost/test/detail/suppress_warnings.hpp>
32 
33 //____________________________________________________________________________//
34 
35 #define BOOST_TEST_CASE_TEMPLATE( name, typelist )                          \
36     boost::unit_test::ut_detail::template_test_case_gen<name,typelist >(    \
37         BOOST_TEST_STRINGIZE( name ) )                                      \
38 /**/
39 
40 //____________________________________________________________________________//
41 
42 #define BOOST_TEST_CASE_TEMPLATE_FUNCTION( name, type_name )    \
43 template<typename type_name>                                    \
44 void BOOST_JOIN( name, _impl )( boost::type<type_name>* );      \
45                                                                 \
46 struct name {                                                   \
47     template<typename TestType>                                 \
48     static void run( boost::type<TestType>* frwrd = 0 )         \
49     {                                                           \
50        BOOST_JOIN( name, _impl )( frwrd );                      \
51     }                                                           \
52 };                                                              \
53                                                                 \
54 template<typename type_name>                                    \
55 void BOOST_JOIN( name, _impl )( boost::type<type_name>* )       \
56 /**/
57 
58 //____________________________________________________________________________//
59 
60 namespace boost {
61 
62 namespace unit_test {
63 
64 namespace ut_detail {
65 
66 // ************************************************************************** //
67 // **************          test_case_template_invoker          ************** //
68 // ************************************************************************** //
69 
70 template<typename TestCaseTemplate,typename TestType>
71 class test_case_template_invoker {
72 public:
operator ()()73     void    operator()()    { TestCaseTemplate::run( (boost::type<TestType>*)0 ); }
74 };
75 
76 //____________________________________________________________________________//
77 
78 // ************************************************************************** //
79 // **************           generate_test_case_4_type          ************** //
80 // ************************************************************************** //
81 
82 template<typename Generator,typename TestCaseTemplate>
83 struct generate_test_case_4_type {
generate_test_case_4_typeboost::unit_test::ut_detail::generate_test_case_4_type84     explicit    generate_test_case_4_type( const_string tc_name, Generator& G )
85     : m_test_case_name( tc_name )
86     , m_holder( G )
87     {}
88 
89     template<typename TestType>
operator ()boost::unit_test::ut_detail::generate_test_case_4_type90     void        operator()( mpl::identity<TestType> )
91     {
92         std::string full_name;
93         assign_op( full_name, m_test_case_name, 0 );
94         full_name += '<';
95         full_name += typeid(TestType).name();
96         if( boost::is_const<TestType>::value )
97             full_name += " const";
98         full_name += '>';
99 
100         m_holder.m_test_cases.push_back(
101             new test_case( full_name, test_case_template_invoker<TestCaseTemplate,TestType>() ) );
102     }
103 
104 private:
105     // Data members
106     const_string    m_test_case_name;
107     Generator&      m_holder;
108 };
109 
110 // ************************************************************************** //
111 // **************              test_case_template              ************** //
112 // ************************************************************************** //
113 
114 template<typename TestCaseTemplate,typename TestTypesList>
115 class template_test_case_gen : public test_unit_generator {
116 public:
117     // Constructor
template_test_case_gen(const_string tc_name)118     template_test_case_gen( const_string tc_name )
119     {
120         typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,
121                                           TestCaseTemplate
122         > single_test_gen;
123         mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, *this ) );
124     }
125 
next() const126     test_unit* next() const
127     {
128         if( m_test_cases.empty() )
129             return 0;
130 
131         test_unit* res = m_test_cases.front();
132         m_test_cases.pop_front();
133 
134         return res;
135     }
136 
137     // Data members
138     mutable std::list<test_unit*> m_test_cases;
139 };
140 
141 //____________________________________________________________________________//
142 
143 } // namespace ut_detail
144 
145 } // unit_test
146 
147 } // namespace boost
148 
149 //____________________________________________________________________________//
150 
151 #include <boost/test/detail/enable_warnings.hpp>
152 
153 // ***************************************************************************
154 //  Revision History :
155 //
156 //  $Log: test_case_template.hpp,v $
157 //  Revision 1.1.1.1  2006/03/20 20:15:27  ewalkup
158 //  boost libraries
159 //
160 //  Revision 1.15  2005/04/17 15:50:37  rogeeff
161 //  portability fixes
162 //
163 //  Revision 1.14  2005/04/13 04:35:18  rogeeff
164 //  forgot zero
165 //
166 //  Revision 1.13  2005/04/12 06:50:46  rogeeff
167 //  assign_to -> assign_op
168 //
169 //  Revision 1.12  2005/03/22 06:58:47  rogeeff
170 //  assign_to made free function
171 //
172 //  Revision 1.11  2005/02/20 08:27:06  rogeeff
173 //  This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
174 //
175 //  Revision 1.10  2005/02/01 06:40:06  rogeeff
176 //  copyright update
177 //  old log entries removed
178 //  minor stilistic changes
179 //  depricated tools removed
180 //
181 //  Revision 1.9  2005/01/30 03:20:38  rogeeff
182 //  use BOOST_JOIN and BOOST_TEST_STRINGIZE
183 //
184 // ***************************************************************************
185 
186 #endif // BOOST_TEST_TEST_CASE_TEMPLATE_HPP_071894GER
187 
188