Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:52:41

0001 //  (C) Copyright Gennadiy Rozental 2001.
0002 //  Distributed under the Boost Software License, Version 1.0.
0003 //  (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See http://www.boost.org/libs/test for the library home page.
0007 //
0008 ///@ file
0009 /// Defines template_test_case_gen
0010 // ***************************************************************************
0011 
0012 #ifndef BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
0013 #define BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
0014 
0015 // Boost.Test
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 // Boost
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 // STL
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 // **************          test_case_template_invoker          ************** //
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 // **************           generate_test_case_4_type          ************** //
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()); // same as execution_monitor.ipp
0094 #else
0095         full_name += BOOST_CURRENT_FUNCTION;
0096 #endif
0097 
0098         // replacing ',' by ', ' first, and then removing any double space
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     // Data members
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 // **************              test_case_template              ************** //
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     // Data members
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     // Constructor
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 // Describing template test cases with tuples
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; // silence warning
0185     }
0186 
0187 public:
0188     // Constructor
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 /* C++11 variadic, type alias */
0204 
0205 } // namespace ut_detail
0206 } // unit_test
0207 } // namespace boost
0208 
0209 #include <boost/test/detail/enable_warnings.hpp>
0210 
0211 #endif // BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER