From 017258c983c18f86641788e840526a7f82af6370 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 4 Oct 2015 02:21:53 +0300 Subject: [PATCH] Fix rvalue forwarding to support auto_ptr/unique_ptr parameters --- include/boost/bind/bind.hpp | 483 ++++++++++++++++++++++++--------- test/Jamfile.v2 | 3 + test/bind_function_ap_test.cpp | 224 +++++++++++++++ test/bind_type_test.cpp | 75 +++++ test/bind_unique_ptr_test.cpp | 207 ++++++++++++++ 5 files changed, 858 insertions(+), 134 deletions(-) create mode 100644 test/bind_function_ap_test.cpp create mode 100644 test/bind_type_test.cpp create mode 100644 test/bind_unique_ptr_test.cpp diff --git a/include/boost/bind/bind.hpp b/include/boost/bind/bind.hpp index fd05131..f793551 100644 --- a/include/boost/bind/bind.hpp +++ b/include/boost/bind/bind.hpp @@ -32,6 +32,10 @@ #include #include +#if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) +#include // std::forward +#endif + // Borland-specific bug, visit_each() silently fails to produce code #if defined(__BORLANDC__) @@ -863,14 +867,337 @@ public: #if !defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) -template< class A > struct list_add_cref +template< class A1 > class rrlist1 { - typedef A const & type; +private: + + A1 & a1_; // not A1&& because of msvc-10.0 + +public: + + explicit rrlist1( A1 & a1 ): a1_( a1 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } // not static_cast because of g++ 4.9 + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } }; -template< class A > struct list_add_cref< A& > +template< class A1, class A2 > class rrlist2 { - typedef A & type; +private: + + A1 & a1_; + A2 & a2_; + +public: + + rrlist2( A1 & a1, A2 & a2 ): a1_( a1 ), a2_( a2 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } +}; + +template< class A1, class A2, class A3 > class rrlist3 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + +public: + + rrlist3( A1 & a1, A2 & a2, A3 & a3 ): a1_( a1 ), a2_( a2 ), a3_( a3 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } +}; + +template< class A1, class A2, class A3, class A4 > class rrlist4 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + +public: + + rrlist4( A1 & a1, A2 & a2, A3 & a3, A4 & a4 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } +}; + +template< class A1, class A2, class A3, class A4, class A5 > class rrlist5 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + +public: + + rrlist5( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6 > class rrlist6 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + +public: + + rrlist6( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7 > class rrlist7 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + +public: + + rrlist7( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8 > class rrlist8 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + A8 & a8_; + +public: + + rrlist8( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ), a8_( a8 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8>) const { return std::forward( a8_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8> (*) ()) const { return std::forward( a8_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } +}; + +template< class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9 > class rrlist9 +{ +private: + + A1 & a1_; + A2 & a2_; + A3 & a3_; + A4 & a4_; + A5 & a5_; + A6 & a6_; + A7 & a7_; + A8 & a8_; + A9 & a9_; + +public: + + rrlist9( A1 & a1, A2 & a2, A3 & a3, A4 & a4, A5 & a5, A6 & a6, A7 & a7, A8 & a8, A9 & a9 ): a1_( a1 ), a2_( a2 ), a3_( a3 ), a4_( a4 ), a5_( a5 ), a6_( a6 ), a7_( a7 ), a8_( a8 ), a9_( a9 ) {} + + A1 && operator[] (boost::arg<1>) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2>) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3>) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4>) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5>) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6>) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7>) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8>) const { return std::forward( a8_ ); } + A9 && operator[] (boost::arg<9>) const { return std::forward( a9_ ); } + + A1 && operator[] (boost::arg<1> (*) ()) const { return std::forward( a1_ ); } + A2 && operator[] (boost::arg<2> (*) ()) const { return std::forward( a2_ ); } + A3 && operator[] (boost::arg<3> (*) ()) const { return std::forward( a3_ ); } + A4 && operator[] (boost::arg<4> (*) ()) const { return std::forward( a4_ ); } + A5 && operator[] (boost::arg<5> (*) ()) const { return std::forward( a5_ ); } + A6 && operator[] (boost::arg<6> (*) ()) const { return std::forward( a6_ ); } + A7 && operator[] (boost::arg<7> (*) ()) const { return std::forward( a7_ ); } + A8 && operator[] (boost::arg<8> (*) ()) const { return std::forward( a8_ ); } + A9 && operator[] (boost::arg<9> (*) ()) const { return std::forward( a9_ ); } + + template T & operator[] ( _bi::value & v ) const { return v.get(); } + + template T const & operator[] ( _bi::value const & v ) const { return v.get(); } + + template T & operator[] (reference_wrapper const & v) const { return v.get(); } + + template typename result_traits::type operator[] (bind_t & b) const { return b.eval(*this); } + + template typename result_traits::type operator[] (bind_t const & b) const { return b.eval(*this); } }; template class bind_t @@ -903,221 +1230,109 @@ public: template result_type operator()( A1 && a1 ) { - list1< typename list_add_cref::type > a( a1 ); + rrlist1< A1 > a( a1 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1 ) const { - list1< typename list_add_cref::type > a( a1 ); + rrlist1< A1 > a( a1 ); return l_(type(), f_, a, 0); } template result_type operator()( A1 && a1, A2 && a2 ) { - list2< typename list_add_cref::type, typename list_add_cref::type > a( a1, a2 ); + rrlist2< A1, A2 > a( a1, a2 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2 ) const { - list2< typename list_add_cref::type, typename list_add_cref::type > a( a1, a2 ); + rrlist2< A1, A2 > a( a1, a2 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3 ) { - list3< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3 ); - + rrlist3< A1, A2, A3 > a( a1, a2, a3 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3 ) const { - list3< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3 ); - + rrlist3< A1, A2, A3 > a( a1, a2, a3 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) { - list4< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4 ); - + rrlist4< A1, A2, A3, A4 > a( a1, a2, a3, a4 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4 ) const { - list4< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4 ); - + rrlist4< A1, A2, A3, A4 > a( a1, a2, a3, a4 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) { - list5< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5 ); - + rrlist5< A1, A2, A3, A4, A5 > a( a1, a2, a3, a4, a5 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5 ) const { - list5< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5 ); - + rrlist5< A1, A2, A3, A4, A5 > a( a1, a2, a3, a4, a5 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) { - list6< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5, a6 ); - + rrlist6< A1, A2, A3, A4, A5, A6 > a( a1, a2, a3, a4, a5, a6 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6 ) const { - list6< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5, a6 ); - + rrlist6< A1, A2, A3, A4, A5, A6 > a( a1, a2, a3, a4, a5, a6 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) { - list7< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5, a6, a7 ); - + rrlist7< A1, A2, A3, A4, A5, A6, A7 > a( a1, a2, a3, a4, a5, a6, a7 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7 ) const { - list7< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5, a6, a7 ); - + rrlist7< A1, A2, A3, A4, A5, A6, A7 > a( a1, a2, a3, a4, a5, a6, a7 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) { - list8< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5, a6, a7, a8 ); - + rrlist8< A1, A2, A3, A4, A5, A6, A7, A8 > a( a1, a2, a3, a4, a5, a6, a7, a8 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8 ) const { - list8< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5, a6, a7, a8 ); - + rrlist8< A1, A2, A3, A4, A5, A6, A7, A8 > a( a1, a2, a3, a4, a5, a6, a7, a8 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) { - list9< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); - + rrlist9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); return l_( type(), f_, a, 0 ); } template result_type operator()( A1 && a1, A2 && a2, A3 && a3, A4 && a4, A5 && a5, A6 && a6, A7 && a7, A8 && a8, A9 && a9 ) const { - list9< - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type, - typename list_add_cref::type - > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); - + rrlist9< A1, A2, A3, A4, A5, A6, A7, A8, A9 > a( a1, a2, a3, a4, a5, a6, a7, a8, a9 ); return l_( type(), f_, a, 0 ); } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f1f2ab3..ce68da4 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -52,4 +52,7 @@ test-suite "bind" [ run bind_fwd2_test.cpp ] [ run bind_no_placeholders_test.cpp ] [ run placeholder_const_ref_test.cpp ] + [ run bind_function_ap_test.cpp ] + [ run bind_type_test.cpp ] + [ run bind_unique_ptr_test.cpp ] ; diff --git a/test/bind_function_ap_test.cpp b/test/bind_function_ap_test.cpp new file mode 100644 index 0000000..900a131 --- /dev/null +++ b/test/bind_function_ap_test.cpp @@ -0,0 +1,224 @@ +#include + +// +// bind_function_ap_test.cpp - regression test +// +// Copyright (c) 2015 Peter Dimov +// +// 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 +// + +#if defined( __GNUC__ ) && ( __GNUC__ * 100 + __GNUC_MINOR__ >= 406 ) +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined( __clang__ ) && defined( __has_warning ) +# if __has_warning( "-Wdeprecated-declarations" ) +# pragma GCC diagnostic ignored "-Wdeprecated-declarations" +# endif +#endif + +#include +#include +#include +#include + +// + +void fv1( std::auto_ptr p1 ) +{ + BOOST_TEST( *p1 == 1 ); +} + +void fv2( std::auto_ptr p1, std::auto_ptr p2 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); +} + +void fv3( std::auto_ptr p1, std::auto_ptr p2, std::auto_ptr p3 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); +} + +void fv4( std::auto_ptr p1, std::auto_ptr p2, std::auto_ptr p3, std::auto_ptr p4 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); +} + +void fv5( std::auto_ptr p1, std::auto_ptr p2, std::auto_ptr p3, std::auto_ptr p4, std::auto_ptr p5 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); +} + +void fv6( std::auto_ptr p1, std::auto_ptr p2, std::auto_ptr p3, std::auto_ptr p4, std::auto_ptr p5, std::auto_ptr p6 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); + BOOST_TEST( *p6 == 6 ); +} + +void fv7( std::auto_ptr p1, std::auto_ptr p2, std::auto_ptr p3, std::auto_ptr p4, std::auto_ptr p5, std::auto_ptr p6, std::auto_ptr p7 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); + BOOST_TEST( *p6 == 6 ); + BOOST_TEST( *p7 == 7 ); +} + +void fv8( std::auto_ptr p1, std::auto_ptr p2, std::auto_ptr p3, std::auto_ptr p4, std::auto_ptr p5, std::auto_ptr p6, std::auto_ptr p7, std::auto_ptr p8 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); + BOOST_TEST( *p6 == 6 ); + BOOST_TEST( *p7 == 7 ); + BOOST_TEST( *p8 == 8 ); +} + +void fv9( std::auto_ptr p1, std::auto_ptr p2, std::auto_ptr p3, std::auto_ptr p4, std::auto_ptr p5, std::auto_ptr p6, std::auto_ptr p7, std::auto_ptr p8, std::auto_ptr p9 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); + BOOST_TEST( *p6 == 6 ); + BOOST_TEST( *p7 == 7 ); + BOOST_TEST( *p8 == 8 ); + BOOST_TEST( *p9 == 9 ); +} + +void test() +{ + { + boost::function)> fw1 = boost::bind( fv1, _1 ); + + std::auto_ptr p1( new int(1) ); + + fw1( p1 ); + } + + { + boost::function, std::auto_ptr)> fw2 = boost::bind( fv2, _1, _2 ); + + std::auto_ptr p1( new int(1) ); + std::auto_ptr p2( new int(2) ); + + fw2( p1, p2 ); + } + + { + boost::function, std::auto_ptr, std::auto_ptr)> fw3 = boost::bind( fv3, _1, _2, _3 ); + + std::auto_ptr p1( new int(1) ); + std::auto_ptr p2( new int(2) ); + std::auto_ptr p3( new int(3) ); + + fw3( p1, p2, p3 ); + } + + { + boost::function, std::auto_ptr, std::auto_ptr, std::auto_ptr)> fw4 = boost::bind( fv4, _1, _2, _3, _4 ); + + std::auto_ptr p1( new int(1) ); + std::auto_ptr p2( new int(2) ); + std::auto_ptr p3( new int(3) ); + std::auto_ptr p4( new int(4) ); + + fw4( p1, p2, p3, p4 ); + } + + { + boost::function, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr)> fw5 = boost::bind( fv5, _1, _2, _3, _4, _5 ); + + std::auto_ptr p1( new int(1) ); + std::auto_ptr p2( new int(2) ); + std::auto_ptr p3( new int(3) ); + std::auto_ptr p4( new int(4) ); + std::auto_ptr p5( new int(5) ); + + fw5( p1, p2, p3, p4, p5 ); + } + + { + boost::function, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr)> fw6 = boost::bind( fv6, _1, _2, _3, _4, _5, _6 ); + + std::auto_ptr p1( new int(1) ); + std::auto_ptr p2( new int(2) ); + std::auto_ptr p3( new int(3) ); + std::auto_ptr p4( new int(4) ); + std::auto_ptr p5( new int(5) ); + std::auto_ptr p6( new int(6) ); + + fw6( p1, p2, p3, p4, p5, p6 ); + } + + { + boost::function, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr)> fw7 = boost::bind( fv7, _1, _2, _3, _4, _5, _6, _7 ); + + std::auto_ptr p1( new int(1) ); + std::auto_ptr p2( new int(2) ); + std::auto_ptr p3( new int(3) ); + std::auto_ptr p4( new int(4) ); + std::auto_ptr p5( new int(5) ); + std::auto_ptr p6( new int(6) ); + std::auto_ptr p7( new int(7) ); + + fw7( p1, p2, p3, p4, p5, p6, p7 ); + } + + { + boost::function, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr)> fw8 = boost::bind( fv8, _1, _2, _3, _4, _5, _6, _7, _8 ); + + std::auto_ptr p1( new int(1) ); + std::auto_ptr p2( new int(2) ); + std::auto_ptr p3( new int(3) ); + std::auto_ptr p4( new int(4) ); + std::auto_ptr p5( new int(5) ); + std::auto_ptr p6( new int(6) ); + std::auto_ptr p7( new int(7) ); + std::auto_ptr p8( new int(8) ); + + fw8( p1, p2, p3, p4, p5, p6, p7, p8 ); + } + + { + boost::function, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr, std::auto_ptr)> fw9 = boost::bind( fv9, _1, _2, _3, _4, _5, _6, _7, _8, _9 ); + + std::auto_ptr p1( new int(1) ); + std::auto_ptr p2( new int(2) ); + std::auto_ptr p3( new int(3) ); + std::auto_ptr p4( new int(4) ); + std::auto_ptr p5( new int(5) ); + std::auto_ptr p6( new int(6) ); + std::auto_ptr p7( new int(7) ); + std::auto_ptr p8( new int(8) ); + std::auto_ptr p9( new int(9) ); + + fw9( p1, p2, p3, p4, p5, p6, p7, p8, p9 ); + } +} + +int main() +{ + test(); + return boost::report_errors(); +} diff --git a/test/bind_type_test.cpp b/test/bind_type_test.cpp new file mode 100644 index 0000000..fc58bad --- /dev/null +++ b/test/bind_type_test.cpp @@ -0,0 +1,75 @@ +#include + +// +// bind_type_test.cpp +// +// Copyright (c) 2015 Peter Dimov +// +// 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 +// + +#include +#include + +// + +template struct X +{ +}; + +void fv1( X<1> ) +{ +} + +void fv2( X<1>, X<2> ) +{ +} + +void fv3( X<1>, X<2>, X<3> ) +{ +} + +void fv4( X<1>, X<2>, X<3>, X<4> ) +{ +} + +void fv5( X<1>, X<2>, X<3>, X<4>, X<5> ) +{ +} + +void fv6( X<1>, X<2>, X<3>, X<4>, X<5>, X<6> ) +{ +} + +void fv7( X<1>, X<2>, X<3>, X<4>, X<5>, X<6>, X<7> ) +{ +} + +void fv8( X<1>, X<2>, X<3>, X<4>, X<5>, X<6>, X<7>, X<8> ) +{ +} + +void fv9( X<1>, X<2>, X<3>, X<4>, X<5>, X<6>, X<7>, X<8>, X<9> ) +{ +} + +void test() +{ + boost::bind( fv1, _1 )( X<1>() ); + boost::bind( fv2, _1, _2 )( X<1>(), X<2>() ); + boost::bind( fv3, _1, _2, _3 )( X<1>(), X<2>(), X<3>() ); + boost::bind( fv4, _1, _2, _3, _4 )( X<1>(), X<2>(), X<3>(), X<4>() ); + boost::bind( fv5, _1, _2, _3, _4, _5 )( X<1>(), X<2>(), X<3>(), X<4>(), X<5>() ); + boost::bind( fv6, _1, _2, _3, _4, _5, _6 )( X<1>(), X<2>(), X<3>(), X<4>(), X<5>(), X<6>() ); + boost::bind( fv7, _1, _2, _3, _4, _5, _6, _7 )( X<1>(), X<2>(), X<3>(), X<4>(), X<5>(), X<6>(), X<7>() ); + boost::bind( fv8, _1, _2, _3, _4, _5, _6, _7, _8 )( X<1>(), X<2>(), X<3>(), X<4>(), X<5>(), X<6>(), X<7>(), X<8>() ); + boost::bind( fv9, _1, _2, _3, _4, _5, _6, _7, _8, _9 )( X<1>(), X<2>(), X<3>(), X<4>(), X<5>(), X<6>(), X<7>(), X<8>(), X<9>() ); +} + +int main() +{ + test(); + return boost::report_errors(); +} diff --git a/test/bind_unique_ptr_test.cpp b/test/bind_unique_ptr_test.cpp new file mode 100644 index 0000000..4e648f5 --- /dev/null +++ b/test/bind_unique_ptr_test.cpp @@ -0,0 +1,207 @@ +#include + +#if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_SMART_PTR ) + +int main() +{ +} + +#else + +// +// bind_unique_ptr_test.cpp +// +// Copyright (c) 2015 Peter Dimov +// +// 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 +// + +#include +#include +#include + +// + +void fv1( std::unique_ptr p1 ) +{ + BOOST_TEST( *p1 == 1 ); +} + +void fv2( std::unique_ptr p1, std::unique_ptr p2 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); +} + +void fv3( std::unique_ptr p1, std::unique_ptr p2, std::unique_ptr p3 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); +} + +void fv4( std::unique_ptr p1, std::unique_ptr p2, std::unique_ptr p3, std::unique_ptr p4 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); +} + +void fv5( std::unique_ptr p1, std::unique_ptr p2, std::unique_ptr p3, std::unique_ptr p4, std::unique_ptr p5 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); +} + +void fv6( std::unique_ptr p1, std::unique_ptr p2, std::unique_ptr p3, std::unique_ptr p4, std::unique_ptr p5, std::unique_ptr p6 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); + BOOST_TEST( *p6 == 6 ); +} + +void fv7( std::unique_ptr p1, std::unique_ptr p2, std::unique_ptr p3, std::unique_ptr p4, std::unique_ptr p5, std::unique_ptr p6, std::unique_ptr p7 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); + BOOST_TEST( *p6 == 6 ); + BOOST_TEST( *p7 == 7 ); +} + +void fv8( std::unique_ptr p1, std::unique_ptr p2, std::unique_ptr p3, std::unique_ptr p4, std::unique_ptr p5, std::unique_ptr p6, std::unique_ptr p7, std::unique_ptr p8 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); + BOOST_TEST( *p6 == 6 ); + BOOST_TEST( *p7 == 7 ); + BOOST_TEST( *p8 == 8 ); +} + +void fv9( std::unique_ptr p1, std::unique_ptr p2, std::unique_ptr p3, std::unique_ptr p4, std::unique_ptr p5, std::unique_ptr p6, std::unique_ptr p7, std::unique_ptr p8, std::unique_ptr p9 ) +{ + BOOST_TEST( *p1 == 1 ); + BOOST_TEST( *p2 == 2 ); + BOOST_TEST( *p3 == 3 ); + BOOST_TEST( *p4 == 4 ); + BOOST_TEST( *p5 == 5 ); + BOOST_TEST( *p6 == 6 ); + BOOST_TEST( *p7 == 7 ); + BOOST_TEST( *p8 == 8 ); + BOOST_TEST( *p9 == 9 ); +} + +void test() +{ + { + std::unique_ptr p1( new int(1) ); + + boost::bind( fv1, _1 )( std::move( p1 ) ); + } + + { + std::unique_ptr p1( new int(1) ); + std::unique_ptr p2( new int(2) ); + + boost::bind( fv2, _1, _2 )( std::move( p1 ), std::move( p2 ) ); + } + + { + std::unique_ptr p1( new int(1) ); + std::unique_ptr p2( new int(2) ); + std::unique_ptr p3( new int(3) ); + + boost::bind( fv3, _1, _2, _3 )( std::move( p1 ), std::move( p2 ), std::move( p3 ) ); + } + + { + std::unique_ptr p1( new int(1) ); + std::unique_ptr p2( new int(2) ); + std::unique_ptr p3( new int(3) ); + std::unique_ptr p4( new int(4) ); + + boost::bind( fv4, _1, _2, _3, _4 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ) ); + } + + { + std::unique_ptr p1( new int(1) ); + std::unique_ptr p2( new int(2) ); + std::unique_ptr p3( new int(3) ); + std::unique_ptr p4( new int(4) ); + std::unique_ptr p5( new int(5) ); + + boost::bind( fv5, _1, _2, _3, _4, _5 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ) ); + } + + { + std::unique_ptr p1( new int(1) ); + std::unique_ptr p2( new int(2) ); + std::unique_ptr p3( new int(3) ); + std::unique_ptr p4( new int(4) ); + std::unique_ptr p5( new int(5) ); + std::unique_ptr p6( new int(6) ); + + boost::bind( fv6, _1, _2, _3, _4, _5, _6 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ) ); + } + + { + std::unique_ptr p1( new int(1) ); + std::unique_ptr p2( new int(2) ); + std::unique_ptr p3( new int(3) ); + std::unique_ptr p4( new int(4) ); + std::unique_ptr p5( new int(5) ); + std::unique_ptr p6( new int(6) ); + std::unique_ptr p7( new int(7) ); + + boost::bind( fv7, _1, _2, _3, _4, _5, _6, _7 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ) ); + } + + { + std::unique_ptr p1( new int(1) ); + std::unique_ptr p2( new int(2) ); + std::unique_ptr p3( new int(3) ); + std::unique_ptr p4( new int(4) ); + std::unique_ptr p5( new int(5) ); + std::unique_ptr p6( new int(6) ); + std::unique_ptr p7( new int(7) ); + std::unique_ptr p8( new int(8) ); + + boost::bind( fv8, _1, _2, _3, _4, _5, _6, _7, _8 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ), std::move( p8 ) ); + } + + { + std::unique_ptr p1( new int(1) ); + std::unique_ptr p2( new int(2) ); + std::unique_ptr p3( new int(3) ); + std::unique_ptr p4( new int(4) ); + std::unique_ptr p5( new int(5) ); + std::unique_ptr p6( new int(6) ); + std::unique_ptr p7( new int(7) ); + std::unique_ptr p8( new int(8) ); + std::unique_ptr p9( new int(9) ); + + boost::bind( fv9, _1, _2, _3, _4, _5, _6, _7, _8, _9 )( std::move( p1 ), std::move( p2 ), std::move( p3 ), std::move( p4 ), std::move( p5 ), std::move( p6 ), std::move( p7 ), std::move( p8 ), std::move( p9 ) ); + } +} + +int main() +{ + test(); + return boost::report_errors(); +} + +#endif // #if defined( BOOST_NO_CXX11_RVALUE_REFERENCES ) || defined( BOOST_NO_CXX11_SMART_PTR )