1 // (C) Copyright Gennadiy Rozental 2001.
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)
6 // See http://www.boost.org/libs/test for the library home page.
9 /// Defines template_test_case_gen
10 // ***************************************************************************
12 #ifndef BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
13 #define BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
16 #include <boost/test/detail/config.hpp>
17 #include <boost/test/detail/global_typedef.hpp>
18 #include <boost/test/detail/fwd_decl.hpp>
19 #include <boost/test/detail/workaround.hpp>
21 #include <boost/test/utils/class_properties.hpp>
23 #include <boost/test/tree/observer.hpp>
27 #include <boost/shared_ptr.hpp>
28 #include <boost/mpl/for_each.hpp>
29 #include <boost/mpl/identity.hpp>
30 #include <boost/type.hpp>
31 #include <boost/type_traits/is_const.hpp>
32 #include <boost/function/function0.hpp>
34 #if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
35 # include <boost/current_function.hpp>
37 # include <boost/core/demangle.hpp>
41 #include <string> // for std::string
42 #include <list> // for std::list
44 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
45 !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
46 !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
50 #include <boost/test/detail/suppress_warnings.hpp>
53 //____________________________________________________________________________//
59 // ************************************************************************** //
60 // ************** test_case_template_invoker ************** //
61 // ************************************************************************** //
63 template<typename TestCaseTemplate,typename TestType>
64 class test_case_template_invoker {
66 void operator()() { TestCaseTemplate::run( (boost::type<TestType>*)0 ); }
69 // ************************************************************************** //
70 // ************** generate_test_case_4_type ************** //
71 // ************************************************************************** //
73 template<typename Generator, typename TestCaseTemplate>
74 struct generate_test_case_4_type {
75 explicit generate_test_case_4_type( const_string tc_name, const_string tc_file, std::size_t tc_line, Generator& G )
76 : m_test_case_name( tc_name )
77 , m_test_case_file( tc_file )
78 , m_test_case_line( tc_line )
82 template<typename TestType>
83 void operator()( mpl::identity<TestType> )
85 std::string full_name;
86 assign_op( full_name, m_test_case_name, 0 );
88 #if !defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI)
89 full_name += boost::core::demangle(typeid(TestType).name()); // same as execution_monitor.ipp
91 full_name += BOOST_CURRENT_FUNCTION;
93 if( boost::is_const<TestType>::value )
94 full_name += "_const";
97 m_holder.m_test_cases.push_back( new test_case( ut_detail::normalize_test_case_name( full_name ),
100 test_case_template_invoker<TestCaseTemplate,TestType>() ) );
105 const_string m_test_case_name;
106 const_string m_test_case_file;
107 std::size_t m_test_case_line;
111 // ************************************************************************** //
112 // ************** test_case_template ************** //
113 // ************************************************************************** //
115 class template_test_case_gen_base : public test_unit_generator {
117 virtual test_unit* next() const
119 if( m_test_cases.empty() )
122 test_unit* res = m_test_cases.front();
123 m_test_cases.pop_front();
129 mutable std::list<test_unit*> m_test_cases;
132 template<typename TestCaseTemplate,typename TestTypesList>
133 class template_test_case_gen : public template_test_case_gen_base {
136 template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
138 typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,TestCaseTemplate> single_test_gen;
140 mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, tc_file, tc_line, *this ) );
144 // adding support for tuple
145 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
146 !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
147 !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
149 template<typename TestCaseTemplate, typename... tuple_parameter_pack>
150 class template_test_case_gen<TestCaseTemplate, std::tuple<tuple_parameter_pack...> > : public template_test_case_gen_base {
155 template<int N, int... Is>
156 struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
159 struct gen_seq<0, Is...> : seq<Is...> { };
161 template<typename tuple_t, typename F, int... Is>
162 void for_each(F &f, seq<Is...>)
164 auto l = { (f(mpl::identity<typename std::tuple_element<Is, tuple_t>::type>()), 0)... };
165 (void)l; // silence warning
170 template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
172 using tuple_t = std::tuple<tuple_parameter_pack...>;
173 using this_type = template_test_case_gen<TestCaseTemplate, tuple_t >;
174 using single_test_gen = generate_test_case_4_type<this_type, TestCaseTemplate>;
176 single_test_gen op( tc_name, tc_file, tc_line, *this );
178 this->for_each<tuple_t>(op, gen_seq<sizeof...(tuple_parameter_pack)>());
182 #endif /* C++11 variadic and tuples */
184 } // namespace ut_detail
188 #include <boost/test/detail/enable_warnings.hpp>
190 #endif // BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER