File indexing completed on 2025-01-18 09:52:41
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #ifndef BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
0013 #define BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
0014
0015
0016 #include <boost/test/detail/config.hpp>
0017 #include <boost/test/detail/global_typedef.hpp>
0018 #include <boost/test/detail/fwd_decl.hpp>
0019 #include <boost/test/tree/test_unit.hpp>
0020
0021 #include <boost/test/utils/class_properties.hpp>
0022 #include <boost/test/tree/observer.hpp>
0023 #include <boost/test/utils/algorithm.hpp>
0024
0025
0026
0027 #include <boost/shared_ptr.hpp>
0028 #include <boost/mpl/for_each.hpp>
0029 #include <boost/mpl/identity.hpp>
0030 #include <boost/type.hpp>
0031 #include <boost/type_traits/is_const.hpp>
0032 #include <boost/type_traits/is_volatile.hpp>
0033 #include <boost/type_traits/is_lvalue_reference.hpp>
0034 #include <boost/type_traits/is_rvalue_reference.hpp>
0035 #include <boost/type_traits/remove_reference.hpp>
0036 #include <boost/function/function0.hpp>
0037
0038 #if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
0039 # include <boost/current_function.hpp>
0040 #else
0041 # include <boost/core/demangle.hpp>
0042 #endif
0043
0044
0045 #include <string> // for std::string
0046 #include <list> // for std::list
0047
0048 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
0049 !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
0050 #include <type_traits>
0051 #include <boost/mpl/is_sequence.hpp>
0052 #endif
0053
0054 #include <boost/test/detail/suppress_warnings.hpp>
0055
0056
0057
0058
0059 namespace boost {
0060 namespace unit_test {
0061 namespace ut_detail {
0062
0063
0064
0065
0066
0067 template<typename TestCaseTemplate,typename TestType>
0068 class test_case_template_invoker {
0069 public:
0070 void operator()() { TestCaseTemplate::run( (boost::type<TestType>*)0 ); }
0071 };
0072
0073
0074
0075
0076
0077 template<typename Generator, typename TestCaseTemplate>
0078 struct generate_test_case_4_type {
0079 explicit generate_test_case_4_type( const_string tc_name, const_string tc_file, std::size_t tc_line, Generator& G )
0080 : m_test_case_name( tc_name )
0081 , m_test_case_file( tc_file )
0082 , m_test_case_line( tc_line )
0083 , m_holder( G )
0084 {}
0085
0086 template<typename TestType>
0087 void operator()( mpl::identity<TestType> )
0088 {
0089 std::string full_name;
0090 assign_op( full_name, m_test_case_name, 0 );
0091 full_name += '<';
0092 #if !defined(BOOST_NO_TYPEID) && !defined(BOOST_NO_RTTI)
0093 full_name += boost::core::demangle(typeid(TestType).name());
0094 #else
0095 full_name += BOOST_CURRENT_FUNCTION;
0096 #endif
0097
0098
0099 static const std::string to_replace[] = { "class ", "struct ", ",", " ", " <", " >"};
0100 static const std::string replacement[] = { "", "" , ", ", " ", "<" , ">"};
0101
0102 full_name = unit_test::utils::replace_all_occurrences_of(
0103 full_name,
0104 to_replace, to_replace + sizeof(to_replace)/sizeof(to_replace[0]),
0105 replacement, replacement + sizeof(replacement)/sizeof(replacement[0]));
0106
0107 typedef typename boost::remove_reference<TestType>::type TestTypewoRef;
0108 if( boost::is_const<TestTypewoRef>::value )
0109 full_name += "_const";
0110 if( boost::is_volatile<TestTypewoRef>::value )
0111 full_name += "_volatile";
0112 if( boost::is_rvalue_reference<TestType>::value )
0113 full_name += "_refref";
0114 else if( boost::is_lvalue_reference<TestType>::value )
0115 full_name += "_ref";
0116
0117 full_name += '>';
0118
0119 m_holder.m_test_cases.push_back( new test_case( ut_detail::normalize_test_case_name( full_name ),
0120 m_test_case_file,
0121 m_test_case_line,
0122 test_case_template_invoker<TestCaseTemplate,TestType>() ) );
0123 }
0124
0125 private:
0126
0127 const_string m_test_case_name;
0128 const_string m_test_case_file;
0129 std::size_t m_test_case_line;
0130 Generator& m_holder;
0131 };
0132
0133
0134
0135
0136
0137 class template_test_case_gen_base : public test_unit_generator {
0138 public:
0139 test_unit* next() const BOOST_OVERRIDE
0140 {
0141 if( m_test_cases.empty() )
0142 return 0;
0143
0144 test_unit* res = m_test_cases.front();
0145 m_test_cases.pop_front();
0146
0147 return res;
0148 }
0149
0150
0151 mutable std::list<test_unit*> m_test_cases;
0152 };
0153
0154 template<typename TestCaseTemplate,typename TestTypesList, typename enabler = void>
0155 class template_test_case_gen : public template_test_case_gen_base {
0156 public:
0157
0158 template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
0159 {
0160 typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,TestCaseTemplate> single_test_gen;
0161
0162 mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, tc_file, tc_line, *this ) );
0163 }
0164 };
0165
0166
0167 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
0168 !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && \
0169 !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
0170
0171 template<typename TestCaseTemplate,
0172 template <class ...> class C,
0173 typename... parameter_pack>
0174 class template_test_case_gen<
0175 TestCaseTemplate,
0176 C<parameter_pack...>,
0177 typename std::enable_if<!boost::mpl::is_sequence<C<parameter_pack...>>::value>::type >
0178 : public template_test_case_gen_base {
0179
0180 template<typename F>
0181 void for_each(F &f)
0182 {
0183 auto l = { (f(mpl::identity<parameter_pack>()), 0)... };
0184 (void)l;
0185 }
0186
0187 public:
0188
0189 template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
0190 {
0191 using this_type = template_test_case_gen<
0192 TestCaseTemplate,
0193 C<parameter_pack...>,
0194 typename std::enable_if<!boost::mpl::is_sequence<C<parameter_pack...>>::value>::type>;
0195 using single_test_gen = generate_test_case_4_type<this_type, TestCaseTemplate>;
0196
0197 single_test_gen op( tc_name, tc_file, tc_line, *this );
0198
0199 this->for_each(op);
0200 }
0201 };
0202
0203 #endif
0204
0205 }
0206 }
0207 }
0208
0209 #include <boost/test/detail/enable_warnings.hpp>
0210
0211 #endif