diff options
Diffstat (limited to 'boost/test')
-rw-r--r-- | boost/test/data/for_each_sample.hpp | 54 | ||||
-rw-r--r-- | boost/test/data/index_sequence.hpp | 62 | ||||
-rw-r--r-- | boost/test/data/monomorphic/fwd.hpp | 3 | ||||
-rw-r--r-- | boost/test/data/monomorphic/grid.hpp | 71 | ||||
-rw-r--r-- | boost/test/data/monomorphic/sample_merge.hpp | 103 | ||||
-rw-r--r-- | boost/test/data/monomorphic/zip.hpp | 64 | ||||
-rw-r--r-- | boost/test/data/test_case.hpp | 114 | ||||
-rw-r--r-- | boost/test/data/traits.hpp | 87 | ||||
-rw-r--r-- | boost/test/impl/debug.ipp | 44 | ||||
-rw-r--r-- | boost/test/impl/execution_monitor.ipp | 12 | ||||
-rw-r--r-- | boost/test/impl/framework.ipp | 20 | ||||
-rw-r--r-- | boost/test/impl/xml_report_formatter.ipp | 2 | ||||
-rw-r--r-- | boost/test/tools/collection_comparison_op.hpp | 10 | ||||
-rw-r--r-- | boost/test/tools/detail/print_helper.hpp | 6 | ||||
-rw-r--r-- | boost/test/tools/interface.hpp | 21 | ||||
-rw-r--r-- | boost/test/utils/named_params.hpp | 2 |
16 files changed, 422 insertions, 253 deletions
diff --git a/boost/test/data/for_each_sample.hpp b/boost/test/data/for_each_sample.hpp index 8bc1964311..b3bc1ffc78 100644 --- a/boost/test/data/for_each_sample.hpp +++ b/boost/test/data/for_each_sample.hpp @@ -14,10 +14,14 @@ // Boost.Test #include <boost/test/data/config.hpp> -#include <boost/test/data/traits.hpp> #include <boost/test/data/size.hpp> +#include <boost/test/data/index_sequence.hpp> +#include <boost/test/data/monomorphic/sample_merge.hpp> #include <boost/test/data/monomorphic/fwd.hpp> +// STL +#include <tuple> + #include <boost/test/detail/suppress_warnings.hpp> // needed for std::min @@ -30,12 +34,48 @@ namespace unit_test { namespace data { // ************************************************************************** // +// ************** data::invoke_action ************** // +// ************************************************************************** // + +template<typename Action, typename T> +inline void +invoke_action( Action const& action, T && arg, std::false_type /* is_tuple */ ) +{ + action( std::forward<T>(arg) ); +} + +//____________________________________________________________________________// + +template<typename Action, typename T, std::size_t ...I> +inline void +invoke_action_impl( Action const& action, + T && args, + index_sequence<I...> const& ) +{ + action( std::get<I>(std::forward<T>(args))... ); +} + +//____________________________________________________________________________// + +template<typename Action, typename T> +inline void +invoke_action( Action const& action, T&& args, std::true_type /* is_tuple */ ) +{ + invoke_action_impl( action, + std::forward<T>(args), + typename make_index_sequence< 0, std::tuple_size<T>::value >::type{} ); + +} + +//____________________________________________________________________________// + +// ************************************************************************** // // ************** for_each_sample ************** // // ************************************************************************** // template<typename DataSet, typename Action> inline typename std::enable_if<monomorphic::is_dataset<DataSet>::value,void>::type -for_each_sample( DataSet const& samples, +for_each_sample( DataSet && samples, Action const& act, data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE ) { @@ -45,7 +85,9 @@ for_each_sample( DataSet const& samples, auto it = samples.begin(); while( size-- > 0 ) { - data::traits<typename DataSet::sample>::invoke_action( *it, act ); + invoke_action( act, + *it, + typename monomorphic::ds_detail::is_tuple<decltype(*it)>::type()); ++it; } } @@ -54,11 +96,13 @@ for_each_sample( DataSet const& samples, template<typename DataSet, typename Action> inline typename std::enable_if<!monomorphic::is_dataset<DataSet>::value,void>::type -for_each_sample( DataSet const& samples, +for_each_sample( DataSet && samples, Action const& act, data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE ) { - data::for_each_sample( data::make( samples ), act, number_of_samples ); + data::for_each_sample( data::make( std::forward<DataSet>(samples) ), + act, + number_of_samples ); } } // namespace data diff --git a/boost/test/data/index_sequence.hpp b/boost/test/data/index_sequence.hpp new file mode 100644 index 0000000000..21af7e504c --- /dev/null +++ b/boost/test/data/index_sequence.hpp @@ -0,0 +1,62 @@ +// (C) Copyright Gennadiy Rozental 2001. +// 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) + +// See http://www.boost.org/libs/test for the library home page. +// +/// @file +/// Defines c++14 index_sequence implementation +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_INDEX_SEQUENCE_HPP +#define BOOST_TEST_DATA_INDEX_SEQUENCE_HPP + +// Boost.Test +#include <boost/test/data/config.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +//____________________________________________________________________________// + +namespace boost { +namespace unit_test { +namespace data { + +// ************************************************************************** // +// ************** data::index_sequence ************** // +// ************************************************************************** // + +template <std::size_t... Ns> +struct index_sequence {}; + +template<typename IS1, typename IS2> +struct merge_index_sequence; + +template <std::size_t... Ns1, std::size_t... Ns2> +struct merge_index_sequence<index_sequence<Ns1...>, index_sequence<Ns2...>> { + typedef index_sequence<Ns1..., Ns2...> type; +}; + +template <std::size_t B, std::size_t E, typename Enabler = void> +struct make_index_sequence { + typedef typename merge_index_sequence<typename make_index_sequence<B,(B+E)/2>::type, + typename make_index_sequence<(B+E)/2,E>::type>::type type; +}; + +template <std::size_t B, std::size_t E> +struct make_index_sequence<B,E,typename std::enable_if<E==B+1,void>::type> { + typedef index_sequence<B> type; +}; + +template <typename... T> +using index_sequence_for = typename make_index_sequence<0, sizeof...(T)>::type; + +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_INDEX_SEQUENCE_HPP + diff --git a/boost/test/data/monomorphic/fwd.hpp b/boost/test/data/monomorphic/fwd.hpp index 26c36743df..cf6d3b0000 100644 --- a/boost/test/data/monomorphic/fwd.hpp +++ b/boost/test/data/monomorphic/fwd.hpp @@ -24,6 +24,9 @@ #include <boost/type_traits/is_array.hpp> #include <boost/mpl/bool.hpp> +// STL +#include <tuple> + #include <boost/test/detail/suppress_warnings.hpp> // STL diff --git a/boost/test/data/monomorphic/grid.hpp b/boost/test/data/monomorphic/grid.hpp index 6af906c62c..3e1b36abad 100644 --- a/boost/test/data/monomorphic/grid.hpp +++ b/boost/test/data/monomorphic/grid.hpp @@ -19,8 +19,8 @@ #if !defined(BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__) -#include <boost/test/data/traits.hpp> #include <boost/test/data/monomorphic/fwd.hpp> +#include <boost/test/data/monomorphic/sample_merge.hpp> #include <boost/test/detail/suppress_warnings.hpp> @@ -31,53 +31,6 @@ namespace unit_test { namespace data { namespace monomorphic { -namespace ds_detail { - -// !! ?? variadic template implementation; use forward_as_tuple? -template<typename T1, typename T2> -struct grid_traits { - typedef std::tuple<T1,T2> type; - typedef typename data::traits<type>::ref_type ref_type; - - static ref_type - tuple_merge(T1 const& a1, T2 const& a2) - { - return ref_type(a1,a2); - } -}; - -//____________________________________________________________________________// - -template<typename T1, typename T2,typename T3> -struct grid_traits<T1,std::tuple<T2,T3>> { - typedef std::tuple<T1,T2,T3> type; - typedef typename data::traits<type>::ref_type ref_type; - - static ref_type - tuple_merge(T1 const& a1, std::tuple<T2 const&,T3 const&> const& a2) - { - return ref_type(a1,get<0>(a2),get<1>(a2)); - } -}; - -//____________________________________________________________________________// - -template<typename T1, typename T2,typename T3> -struct grid_traits<std::tuple<T1,T2>,T3> { - typedef std::tuple<T1,T2,T3> type; - typedef typename data::traits<type>::ref_type ref_type; - - static ref_type - tuple_merge(std::tuple<T1 const&,T2 const&> const& a1, T3 const& a2) - { - return ref_type(get<0>(a1),get<1>(a1),a2); - } -}; - -//____________________________________________________________________________// - -} // namespace ds_detail - // ************************************************************************** // // ************** grid ************** // // ************************************************************************** // @@ -88,21 +41,15 @@ struct grid_traits<std::tuple<T1,T2>,T3> { //! The arity of the resulting dataset is the sum of the arity of its operands. template<typename DataSet1, typename DataSet2> class grid { - typedef typename boost::decay<DataSet1>::type dataset1_decay; - typedef typename boost::decay<DataSet2>::type dataset2_decay; - - typedef typename dataset1_decay::iterator dataset1_iter; - typedef typename dataset2_decay::iterator dataset2_iter; + typedef typename boost::decay<DataSet1>::type dataset1_decay; + typedef typename boost::decay<DataSet2>::type dataset2_decay; - typedef typename dataset1_decay::sample sample1; - typedef typename dataset2_decay::sample sample2; + typedef typename dataset1_decay::iterator dataset1_iter; + typedef typename dataset2_decay::iterator dataset2_iter; public: - typedef typename ds_detail::grid_traits<sample1,sample2>::type sample; struct iterator { - typedef typename data::traits<sample>::ref_type ref_type; - // Constructor explicit iterator( dataset1_iter iter1, DataSet2 const& ds2 ) : m_iter1( std::move( iter1 ) ) @@ -111,8 +58,14 @@ public: , m_ds2_pos( 0 ) {} + using iterator_sample = decltype( + sample_merge( *std::declval<dataset1_iter>(), + *std::declval<dataset2_iter>()) ); + // forward iterator interface - ref_type operator*() const { return ds_detail::grid_traits<sample1,sample2>::tuple_merge( *m_iter1, *m_iter2 ); } + auto operator*() const -> iterator_sample { + return sample_merge( *m_iter1, *m_iter2 ); + } void operator++() { ++m_ds2_pos; diff --git a/boost/test/data/monomorphic/sample_merge.hpp b/boost/test/data/monomorphic/sample_merge.hpp new file mode 100644 index 0000000000..d7535beff7 --- /dev/null +++ b/boost/test/data/monomorphic/sample_merge.hpp @@ -0,0 +1,103 @@ +// (C) Copyright Gennadiy Rozental 2001. +// 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) + +// See http://www.boost.org/libs/test for the library home page. +// +/// @file +/// Defines helper routines and types for merging monomorphic samples +// *************************************************************************** + +#ifndef BOOST_TEST_DATA_MONOMORPHIC_SAMPLE_MERGE_HPP +#define BOOST_TEST_DATA_MONOMORPHIC_SAMPLE_MERGE_HPP + +// Boost.Test +#include <boost/test/data/config.hpp> +#include <boost/test/data/index_sequence.hpp> + +#include <boost/test/data/monomorphic/fwd.hpp> + +#include <boost/test/detail/suppress_warnings.hpp> + +namespace boost { +namespace unit_test { +namespace data { +namespace monomorphic { + +//____________________________________________________________________________// + +namespace ds_detail { + +template <class T> +struct is_tuple : std::false_type {}; + +template <class ...T> +struct is_tuple<std::tuple<T...>> : std::true_type {}; + +template <class T> +struct is_tuple<T&&> : is_tuple<typename std::decay<T>::type> {}; + +template <class T> +struct is_tuple<T&> : is_tuple<typename std::decay<T>::type> {}; + +template<typename T> +inline auto as_tuple_impl_xvalues( T const & arg, std::false_type /* is_rvalue_ref */ ) + -> decltype(std::tuple<T const&>(arg)) { + //return std::tuple<T const&>(arg); + return std::forward_as_tuple(arg); +} + +template<typename T> +inline auto as_tuple_impl_xvalues( T && arg, std::true_type /* is_rvalue_ref */ ) + -> decltype(std::make_tuple(std::forward<T>(arg))) { + return std::make_tuple(std::forward<T>(arg)); +} + + +template<typename T> +inline auto as_tuple_impl( T && arg, std::false_type /* is_tuple = nullptr */ ) + -> decltype(as_tuple_impl_xvalues(std::forward<T>(arg), + typename std::is_rvalue_reference<T&&>::type())) { + return as_tuple_impl_xvalues(std::forward<T>(arg), + typename std::is_rvalue_reference<T&&>::type()); +} + +//____________________________________________________________________________// + +template<typename T> +inline T && +as_tuple_impl(T && arg, std::true_type /* is_tuple */ ) { + return std::forward<T>(arg); +} + +template<typename T> +inline auto as_tuple( T && arg ) + -> decltype( as_tuple_impl(std::forward<T>(arg), + typename ds_detail::is_tuple<T>::type()) ) { + return as_tuple_impl(std::forward<T>(arg), + typename ds_detail::is_tuple<T>::type()); +} + +//____________________________________________________________________________// + +} // namespace ds_detail + +template<typename T1, typename T2> +inline auto +sample_merge( T1 && a1, T2 && a2 ) + -> decltype( std::tuple_cat(ds_detail::as_tuple(std::forward<T1>(a1)), + ds_detail::as_tuple(std::forward<T2>(a2)) ) ) { + return std::tuple_cat(ds_detail::as_tuple(std::forward<T1>(a1)), + ds_detail::as_tuple(std::forward<T2>(a2))); +} + +} // namespace monomorphic +} // namespace data +} // namespace unit_test +} // namespace boost + +#include <boost/test/detail/enable_warnings.hpp> + +#endif // BOOST_TEST_DATA_MONOMORPHIC_SAMPLE_MERGE_HPP + diff --git a/boost/test/data/monomorphic/zip.hpp b/boost/test/data/monomorphic/zip.hpp index 1c7f46472c..5fc65d0e20 100644 --- a/boost/test/data/monomorphic/zip.hpp +++ b/boost/test/data/monomorphic/zip.hpp @@ -17,8 +17,8 @@ #if !defined(BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__) -#include <boost/test/data/traits.hpp> #include <boost/test/data/monomorphic/fwd.hpp> +#include <boost/test/data/monomorphic/sample_merge.hpp> #include <boost/test/detail/suppress_warnings.hpp> @@ -28,51 +28,6 @@ namespace unit_test { namespace data { namespace monomorphic { -namespace ds_detail { - -// !! ?? variadic template implementation; use forward_as_tuple? -template<typename T1, typename T2> -struct zip_traits { - typedef std::tuple<T1,T2> type; - typedef typename data::traits<type>::ref_type ref_type; - - static ref_type - tuple_merge(T1 const& a1, T2 const& a2) - { - return ref_type(a1,a2); - } -}; - -//____________________________________________________________________________// - -template<typename T1, typename T2,typename T3> -struct zip_traits<T1,std::tuple<T2,T3>> { - typedef std::tuple<T1,T2,T3> type; - typedef typename data::traits<type>::ref_type ref_type; - - static ref_type - tuple_merge(T1 const& a1, std::tuple<T2 const&,T3 const&> const& a2) - { - return ref_type(a1,std::get<0>(a2),std::get<1>(a2)); - } -}; - -//____________________________________________________________________________// - -template<typename T1, typename T2,typename T3> -struct zip_traits<std::tuple<T1,T2>,T3> { - typedef std::tuple<T1,T2,T3> type; - typedef typename data::traits<type>::ref_type ref_type; - - static ref_type - tuple_merge(std::tuple<T1 const&,T2 const&> const& a1, T3 const& a2) - { - return ref_type(std::get<0>(a1),std::get<1>(a1),a2); - } -}; - -} // namespace ds_detail - // ************************************************************************** // // ************** zip ************** // // ************************************************************************** // @@ -89,25 +44,24 @@ class zip { typedef typename dataset1_decay::iterator dataset1_iter; typedef typename dataset2_decay::iterator dataset2_iter; - typedef typename dataset1_decay::sample sample1; - typedef typename dataset2_decay::sample sample2; - public: - typedef typename ds_detail::zip_traits<sample1,sample2>::type sample; - enum { arity = dataset1_decay::arity + dataset2_decay::arity }; struct iterator { - typedef typename data::traits<sample>::ref_type ref_type; - // Constructor explicit iterator( dataset1_iter iter1, dataset2_iter iter2 ) : m_iter1( std::move( iter1 ) ) , m_iter2( std::move( iter2 ) ) {} + using iterator_sample = decltype( + sample_merge( *std::declval<dataset1_iter>(), + *std::declval<dataset2_iter>()) ); + // forward iterator interface - ref_type operator*() const { return ds_detail::zip_traits<sample1,sample2>::tuple_merge( *m_iter1, *m_iter2 ); } + auto operator*() const -> iterator_sample { + return sample_merge( *m_iter1, *m_iter2 ); + } void operator++() { ++m_iter1; ++m_iter2; } private: @@ -116,6 +70,8 @@ public: dataset2_iter m_iter2; }; + typedef typename iterator::iterator_sample sample; + //! Constructor //! //! The datasets are moved and not copied. diff --git a/boost/test/data/test_case.hpp b/boost/test/data/test_case.hpp index 112be06c54..9564816ee4 100644 --- a/boost/test/data/test_case.hpp +++ b/boost/test/data/test_case.hpp @@ -33,9 +33,16 @@ #include <boost/bind.hpp> +#include <boost/type_traits/is_copy_constructible.hpp> + #include <boost/test/detail/suppress_warnings.hpp> #include <boost/test/tools/detail/print_helper.hpp> +#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \ + && !defined(BOOST_TEST_DATASET_MAX_ARITY) +# define BOOST_TEST_DATASET_MAX_ARITY 10 +#endif + //____________________________________________________________________________// namespace boost { @@ -57,6 +64,53 @@ struct seed { } }; + +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \ + !defined(BOOST_NO_CXX11_DECLTYPE) && \ + !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && \ + !defined(BOOST_NO_CXX11_SMART_PTR) + +#define BOOST_TEST_DATASET_VARIADIC +template <class T> +struct parameter_holder { + std::shared_ptr<T> value; + + parameter_holder(T && value_) + : value(std::make_shared<T>(std::move(value_))) + {} + + operator T const&() const { + return *value; + } +}; + +template <class T> +parameter_holder<typename std::remove_reference<T>::type> +boost_bind_rvalue_holder_helper_impl(T&& value, boost::false_type /* is copy constructible */) { + return parameter_holder<typename std::remove_reference<T>::type>(std::forward<T>(value)); +} + +template <class T> +T&& boost_bind_rvalue_holder_helper_impl(T&& value, boost::true_type /* is copy constructible */) { + return std::forward<T>(value); +} + +template <class T> +auto boost_bind_rvalue_holder_helper(T&& value) + -> decltype(boost_bind_rvalue_holder_helper_impl( + std::forward<T>(value), + typename boost::is_copy_constructible<typename std::remove_reference<T>::type>::type())) +{ + // need to use boost::is_copy_constructible because std::is_copy_constructible is broken on MSVC12 + return boost_bind_rvalue_holder_helper_impl( + std::forward<T>(value), + typename boost::is_copy_constructible<typename std::remove_reference<T>::type>::type()); +} + +#endif + + // ************************************************************************** // // ************** test_case_gen ************** // // ************************************************************************** // @@ -94,7 +148,8 @@ public: return res; } - // !! ?? variadics based implementation +#if !defined(BOOST_TEST_DATASET_VARIADIC) + /// make this variadic #define TC_MAKE(z,arity,_) \ template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \ void operator()( BOOST_PP_ENUM_BINARY_PARAMS(arity, Arg, const& arg) ) const \ @@ -104,7 +159,20 @@ public: BOOST_PP_ENUM_PARAMS(arity, arg) ) ) ); \ } \ - BOOST_PP_REPEAT_FROM_TO(1, 4, TC_MAKE, _) + BOOST_PP_REPEAT_FROM_TO(1, BOOST_TEST_DATASET_MAX_ARITY, TC_MAKE, _) +#else + + template<typename ...Arg> + void operator()(Arg&& ... arg) const + { + m_test_cases.push_back( + new test_case( m_tc_name, + m_tc_file, + m_tc_line, + boost::bind( &TestCase::template test_method<Arg...>, + boost_bind_rvalue_holder_helper(std::forward<Arg>(arg))...))); + } +#endif private: // Data members @@ -148,18 +216,22 @@ make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_l BOOST_PP_SEQ_FOR_EACH_I(BOOST_DATA_TEST_CASE_PARAM, _, params)) \ /**/ -#define BOOST_DATA_TEST_CASE_IMPL( arity, test_name, dataset, params ) \ -struct test_name { \ +#define BOOST_DATA_TEST_CASE_IMPL(arity, F, test_name, dataset, params) \ +struct test_name : public F { \ template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \ static void test_method( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \ { \ + BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry.");\ + test_name t; \ + BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \ BOOST_TEST_CONTEXT( "" \ BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params)) \ - _impl(BOOST_PP_SEQ_ENUM(params)); \ + t._impl(BOOST_PP_SEQ_ENUM(params)); \ + BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \ } \ private: \ template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \ - static void _impl(BOOST_DATA_TEST_CASE_PARAMS( params )); \ + void _impl(BOOST_DATA_TEST_CASE_PARAMS( params )); \ }; \ \ BOOST_AUTO_TU_REGISTRAR( test_name )( \ @@ -173,13 +245,13 @@ BOOST_AUTO_TU_REGISTRAR( test_name )( \ void test_name::_impl( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \ /**/ -#define BOOST_DATA_TEST_CASE_WITH_PARAMS( test_name, dataset, ... ) \ +#define BOOST_DATA_TEST_CASE_WITH_PARAMS( F, test_name, dataset, ... ) \ BOOST_DATA_TEST_CASE_IMPL( BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \ - test_name, dataset, \ + F, test_name, dataset, \ BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \ /**/ -#define BOOST_DATA_TEST_CASE_NO_PARAMS( test_name, dataset ) \ - BOOST_DATA_TEST_CASE_WITH_PARAMS( test_name, dataset, sample ) \ +#define BOOST_DATA_TEST_CASE_NO_PARAMS( F, test_name, dataset ) \ + BOOST_DATA_TEST_CASE_WITH_PARAMS( F, test_name, dataset, sample ) \ /**/ #if BOOST_PP_VARIADICS_MSVC @@ -188,14 +260,32 @@ BOOST_AUTO_TU_REGISTRAR( test_name )( \ BOOST_PP_CAT( \ BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \ BOOST_DATA_TEST_CASE_NO_PARAMS, \ - BOOST_DATA_TEST_CASE_WITH_PARAMS) (__VA_ARGS__), ) \ + BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \ + BOOST_AUTO_TEST_CASE_FIXTURE, __VA_ARGS__), ) \ +/**/ + +#define BOOST_DATA_TEST_CASE_F( F, ... ) \ + BOOST_PP_CAT( \ + BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \ + BOOST_DATA_TEST_CASE_NO_PARAMS, \ + BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \ + F, __VA_ARGS__), ) \ /**/ + #else #define BOOST_DATA_TEST_CASE( ... ) \ BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \ BOOST_DATA_TEST_CASE_NO_PARAMS, \ - BOOST_DATA_TEST_CASE_WITH_PARAMS) (__VA_ARGS__) \ + BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \ + BOOST_AUTO_TEST_CASE_FIXTURE, __VA_ARGS__) \ +/**/ + +#define BOOST_DATA_TEST_CASE_F( F, ... ) \ + BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \ + BOOST_DATA_TEST_CASE_NO_PARAMS, \ + BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \ + F, __VA_ARGS__) \ /**/ #endif diff --git a/boost/test/data/traits.hpp b/boost/test/data/traits.hpp deleted file mode 100644 index eee52fdab5..0000000000 --- a/boost/test/data/traits.hpp +++ /dev/null @@ -1,87 +0,0 @@ -// (C) Copyright Gennadiy Rozental 2001. -// 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) - -// See http://www.boost.org/libs/test for the library home page. -// -/// @file -/// Defines helper traits -// *************************************************************************** - -#ifndef BOOST_TEST_DATA_TRAITS_HPP_102211GER -#define BOOST_TEST_DATA_TRAITS_HPP_102211GER - -// Boost.Test -#include <boost/test/data/config.hpp> -#include <boost/test/data/monomorphic/fwd.hpp> - -// STL -#include <tuple> - -#include <boost/test/detail/suppress_warnings.hpp> - -//____________________________________________________________________________// - -namespace boost { -namespace unit_test { -namespace data { - -// ************************************************************************** // -// ************** data::traits ************** // -// ************************************************************************** // - -template<typename T> -struct traits { - // type of the reference to sample returned by iterator - typedef T const& ref_type; - - template<typename Action> - static void - invoke_action( ref_type arg, Action const& action ) - { - action( arg ); - } -}; - -//____________________________________________________________________________// - -// !! ?? reimplement using variadics -template<typename T1, typename T2> -struct traits<std::tuple<T1,T2>> { - // type of the reference to sample returned by iterator - typedef std::tuple<T1 const&,T2 const&> ref_type; - - template<typename Action> - static void - invoke_action( ref_type arg, Action const& action ) - { - action( std::get<0>(arg), std::get<1>(arg) ); - } -}; - -//____________________________________________________________________________// - -template<typename T1, typename T2, typename T3> -struct traits<std::tuple<T1,T2,T3>> { - // type of the reference to sample returned by iterator - typedef std::tuple<T1 const&,T2 const&,T3 const&> ref_type; - - template<typename Action> - static void - invoke_action( ref_type arg, Action const& action ) - { - action( std::get<0>(arg), std::get<1>(arg), std::get<2>(arg) ); - } -}; - -//____________________________________________________________________________// - -} // namespace data -} // namespace unit_test -} // namespace boost - -#include <boost/test/detail/enable_warnings.hpp> - -#endif // BOOST_TEST_DATA_TRAITS_HPP_102211GER - diff --git a/boost/test/impl/debug.ipp b/boost/test/impl/debug.ipp index f4ee4971ce..f547052ded 100644 --- a/boost/test/impl/debug.ipp +++ b/boost/test/impl/debug.ipp @@ -752,6 +752,29 @@ set_debugger( unit_test::const_string, dbg_starter ) // ************** attach debugger to the current process ************** // // ************************************************************************** // +#if defined(BOOST_WIN32_BASED_DEBUG) + +struct safe_handle_helper +{ + HANDLE& handle; + safe_handle_helper(HANDLE &handle_) : handle(handle_) {} + + void close_handle() + { + if( handle != INVALID_HANDLE_VALUE ) + { + ::CloseHandle( handle ); + handle = INVALID_HANDLE_VALUE; + } + } + + ~safe_handle_helper() + { + close_handle(); + } +}; +#endif + bool attach_debugger( bool break_or_continue ) { @@ -781,6 +804,8 @@ attach_debugger( bool break_or_continue ) if( !dbg_init_done_ev ) return false; + + safe_handle_helper safe_handle_obj( dbg_init_done_ev ); // *************************************************** // // Debugger command line format @@ -797,17 +822,20 @@ attach_debugger( bool break_or_continue ) DWORD format_size = MAX_CMD_LINE; DWORD type = REG_SZ; - if( !s_info.m_reg_query_value || (*s_info.m_reg_query_value)( + bool b_read_key = s_info.m_reg_query_value && + ((*s_info.m_reg_query_value)( reg_key, // handle of open key "Debugger", // name of subkey to query 0, // reserved &type, // value type (LPBYTE)format, // buffer for returned string - &format_size ) != ERROR_SUCCESS ) // in: buffer size; out: actual size of returned string - return false; + &format_size ) == ERROR_SUCCESS ); // in: buffer size; out: actual size of returned string if( !s_info.m_reg_close_key || (*s_info.m_reg_close_key)( reg_key ) != ERROR_SUCCESS ) return false; + + if( !b_read_key ) + return false; // *************************************************** // // Debugger command line @@ -841,12 +869,16 @@ attach_debugger( bool break_or_continue ) &debugger_info // pointer to PROCESS_INFORMATION that will contain the new process identification ); + bool debugger_run_ok = false; if( created ) - ::WaitForSingleObject( dbg_init_done_ev, INFINITE ); + { + DWORD ret_code = ::WaitForSingleObject( dbg_init_done_ev, INFINITE ); + debugger_run_ok = ( ret_code == WAIT_OBJECT_0 ); + } - ::CloseHandle( dbg_init_done_ev ); + safe_handle_obj.close_handle(); - if( !created ) + if( !created || !debugger_run_ok ) return false; if( break_or_continue ) diff --git a/boost/test/impl/execution_monitor.ipp b/boost/test/impl/execution_monitor.ipp index b3e873efbe..f7fc8ea4e2 100644 --- a/boost/test/impl/execution_monitor.ipp +++ b/boost/test/impl/execution_monitor.ipp @@ -1137,6 +1137,8 @@ execution_monitor::catch_signals( boost::function<int ()> const& F ) detail::system_signal_exception SSE( this ); int ret_val = 0; + // clang windows workaround: this not available in __finally scope + bool l_catch_system_errors = p_catch_system_errors; __try { __try { @@ -1147,7 +1149,7 @@ execution_monitor::catch_signals( boost::function<int ()> const& F ) } } __finally { - if( p_catch_system_errors ) { + if( l_catch_system_errors ) { BOOST_TEST_CRT_SET_HOOK( old_crt_hook ); _set_invalid_parameter_handler( old_iph ); @@ -1380,8 +1382,8 @@ enable( unsigned mask ) return ~old_cw & BOOST_FPE_ALL; #elif defined(__GLIBC__) && defined(__USE_GNU) && !defined(BOOST_CLANG) && !defined(BOOST_NO_FENV_H) - ::feclearexcept(BOOST_FPE_ALL); - int res = ::feenableexcept( mask ); + feclearexcept(BOOST_FPE_ALL); + int res = feenableexcept( mask ); return res == -1 ? (unsigned)BOOST_FPE_INV : (unsigned)res; #else /* Not Implemented */ @@ -1417,8 +1419,8 @@ disable( unsigned mask ) return ~old_cw & BOOST_FPE_ALL; #elif defined(__GLIBC__) && defined(__USE_GNU) && !defined(BOOST_CLANG) && !defined(BOOST_NO_FENV_H) - ::feclearexcept(BOOST_FPE_ALL); - int res = ::fedisableexcept( mask ); + feclearexcept(BOOST_FPE_ALL); + int res = fedisableexcept( mask ); return res == -1 ? (unsigned)BOOST_FPE_INV : (unsigned)res; #else /* Not Implemented */ diff --git a/boost/test/impl/framework.ipp b/boost/test/impl/framework.ipp index f710828051..78459bac27 100644 --- a/boost/test/impl/framework.ipp +++ b/boost/test/impl/framework.ipp @@ -480,6 +480,7 @@ public: BOOST_TEST_FOREACH( test_unit_id, chld_id, ts.m_children ) deduce_siblings_order( chld_id, master_tu_id, tuoi ); + ts.m_ranked_children.clear(); BOOST_TEST_FOREACH( test_unit_id, chld_id, ts.m_children ) { counter_t rank = assign_sibling_rank( chld_id, tuoi ); ts.m_ranked_children.insert( std::make_pair( rank, chld_id ) ); @@ -581,8 +582,17 @@ public: typedef unit_test_monitor_t::error_level execution_result; + // Random generator using the std::rand function (seeded prior to the call) + struct random_generator_helper { + size_t operator()(size_t i) const { + return std::rand() % i; + } + }; + // Executed the test tree with the root at specified test unit - execution_result execute_test_tree( test_unit_id tu_id, unsigned timeout = 0 ) + execution_result execute_test_tree( test_unit_id tu_id, + unsigned timeout = 0, + random_generator_helper const * const p_random_generator = 0) { test_unit const& tu = framework::get( tu_id, TUT_ANY ); @@ -662,12 +672,14 @@ public: it++; } - std::random_shuffle( children_with_the_same_rank.begin(), children_with_the_same_rank.end() ); + const random_generator_helper& rand_gen = p_random_generator ? *p_random_generator : random_generator_helper(); + + std::random_shuffle( children_with_the_same_rank.begin(), children_with_the_same_rank.end(), rand_gen ); BOOST_TEST_FOREACH( test_unit_id, chld, children_with_the_same_rank ) { unsigned chld_timeout = child_timeout( timeout, tu_timer.elapsed() ); - result = (std::min)( result, execute_test_tree( chld, chld_timeout ) ); + result = (std::min)( result, execute_test_tree( chld, chld_timeout, &rand_gen ) ); if( unit_test_monitor.is_critical_error( result ) ) break; @@ -1221,7 +1233,7 @@ run( test_unit_id id, bool continue_test ) case 0: break; case 1: - seed = static_cast<unsigned>( std::time( 0 ) ); + seed = static_cast<unsigned>( std::rand() ^ std::time( 0 ) ); // better init using std::rand() ^ ... default: BOOST_TEST_MESSAGE( "Test cases order is shuffled using seed: " << seed ); std::srand( seed ); diff --git a/boost/test/impl/xml_report_formatter.ipp b/boost/test/impl/xml_report_formatter.ipp index 08af9a3427..424ef4ba44 100644 --- a/boost/test/impl/xml_report_formatter.ipp +++ b/boost/test/impl/xml_report_formatter.ipp @@ -65,7 +65,7 @@ xml_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream& descr = "failed"; ostr << '<' << ( tu.p_type == TUT_CASE ? "TestCase" : "TestSuite" ) - << " name" << utils::attr_value() << tu.p_name + << " name" << utils::attr_value() << tu.p_name.get() << " result" << utils::attr_value() << descr << " assertions_passed" << utils::attr_value() << tr.p_assertions_passed << " assertions_failed" << utils::attr_value() << tr.p_assertions_failed diff --git a/boost/test/tools/collection_comparison_op.hpp b/boost/test/tools/collection_comparison_op.hpp index e5c5ca3bb8..9d5a7d8f7b 100644 --- a/boost/test/tools/collection_comparison_op.hpp +++ b/boost/test/tools/collection_comparison_op.hpp @@ -278,7 +278,7 @@ lexicographic_compare( Lhs const& lhs, Rhs const& rhs ) template <typename Lhs, typename Rhs, typename OP> inline assertion_result -compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<OP>* tp, mpl::true_ ) +compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<OP>*, mpl::true_ ) { return lexicographic_compare<OP>( lhs, rhs ); } @@ -287,7 +287,7 @@ compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<OP>* tp, mpl::t template <typename Lhs, typename Rhs, typename L, typename R> inline assertion_result -compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LT<L, R> >* tp, mpl::false_ ) +compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LT<L, R> >*, mpl::false_ ) { return lhs < rhs; } @@ -296,7 +296,7 @@ compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LT<L, R> >* template <typename Lhs, typename Rhs, typename L, typename R> inline assertion_result -compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LE<L, R> >* tp, mpl::false_ ) +compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LE<L, R> >*, mpl::false_ ) { return lhs <= rhs; } @@ -305,7 +305,7 @@ compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LE<L, R> >* template <typename Lhs, typename Rhs, typename L, typename R> inline assertion_result -compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GT<L, R> >* tp, mpl::false_ ) +compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GT<L, R> >*, mpl::false_ ) { return lhs > rhs; } @@ -314,7 +314,7 @@ compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GT<L, R> >* template <typename Lhs, typename Rhs, typename L, typename R> inline assertion_result -compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GE<L, R> >* tp, mpl::false_ ) +compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GE<L, R> >*, mpl::false_ ) { return lhs >= rhs; } diff --git a/boost/test/tools/detail/print_helper.hpp b/boost/test/tools/detail/print_helper.hpp index 77b936c44b..39ab707f36 100644 --- a/boost/test/tools/detail/print_helper.hpp +++ b/boost/test/tools/detail/print_helper.hpp @@ -22,9 +22,12 @@ // Boost #include <boost/mpl/or.hpp> +#include <boost/static_assert.hpp> #include <boost/type_traits/is_array.hpp> #include <boost/type_traits/is_function.hpp> #include <boost/type_traits/is_abstract.hpp> +#include <boost/type_traits/has_left_shift.hpp> + #include <limits> #include <boost/test/detail/suppress_warnings.hpp> @@ -41,6 +44,9 @@ namespace tt_detail { template<typename T> struct print_log_value { + BOOST_STATIC_ASSERT_MSG( (boost::has_left_shift<std::ostream,T>::value), + "Type has to implement operator<< to be printable"); + void operator()( std::ostream& ostr, T const& t ) { typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type cant_use_nl; diff --git a/boost/test/tools/interface.hpp b/boost/test/tools/interface.hpp index 48d5affc4f..5e84f1c6d4 100644 --- a/boost/test/tools/interface.hpp +++ b/boost/test/tools/interface.hpp @@ -40,17 +40,9 @@ // ************** BOOST_TEST_<level> ************** // // ************************************************************************** // -#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS -#define BOOST_TEST_BUILD_ASSERTION( P ) \ - ::boost::test_tools::tt_detail::expression_holder const& E= \ - ::boost::test_tools::tt_detail::hold_expression( \ - ::boost::test_tools::assertion::seed() ->* P ) \ -/**/ -#else -#define BOOST_TEST_BUILD_ASSERTION( P ) \ - auto const& E = ::boost::test_tools::assertion::seed()->*P \ +#define BOOST_TEST_BUILD_ASSERTION( P ) \ + (::boost::test_tools::assertion::seed()->*P) \ /**/ -#endif //____________________________________________________________________________// @@ -75,10 +67,10 @@ do { \ #define BOOST_TEST_TOOL_ET_IMPL( P, level ) \ do { \ BOOST_TEST_PASSPOINT(); \ - BOOST_TEST_BUILD_ASSERTION( P ); \ + \ ::boost::test_tools::tt_detail:: \ report_assertion( \ - E.evaluate(), \ + BOOST_TEST_BUILD_ASSERTION( P ).evaluate(), \ BOOST_TEST_LAZY_MSG( BOOST_TEST_STRINGIZE( P ) ), \ BOOST_TEST_L(__FILE__), \ static_cast<std::size_t>(__LINE__), \ @@ -94,10 +86,11 @@ do { \ #define BOOST_TEST_TOOL_ET_IMPL_EX( P, level, arg ) \ do { \ BOOST_TEST_PASSPOINT(); \ - BOOST_TEST_BUILD_ASSERTION( P ); \ + \ ::boost::test_tools::tt_detail:: \ report_assertion( \ - ::boost::test_tools::tt_detail::assertion_evaluate(E) \ + ::boost::test_tools::tt_detail::assertion_evaluate( \ + BOOST_TEST_BUILD_ASSERTION( P ) ) \ << arg, \ ::boost::test_tools::tt_detail::assertion_text( \ BOOST_TEST_LAZY_MSG( BOOST_TEST_STRINGIZE(P) ), \ diff --git a/boost/test/utils/named_params.hpp b/boost/test/utils/named_params.hpp index ebd5a6a751..88b8a883fe 100644 --- a/boost/test/utils/named_params.hpp +++ b/boost/test/utils/named_params.hpp @@ -331,7 +331,7 @@ struct typed_keyword<bool,unique_id,required> template<typename T, typename Params, typename Keyword> inline typename enable_if_c<!has_param<Params,Keyword>::value,void>::type -opt_assign( T& target, Params const& p, Keyword k ) +opt_assign( T& /*target*/, Params const& /*p*/, Keyword /*k*/ ) { } |