diff --git a/include/boost/bind/bind.hpp b/include/boost/bind/bind.hpp index 5d0464d..3b3e0c0 100644 --- a/include/boost/bind/bind.hpp +++ b/include/boost/bind/bind.hpp @@ -20,17 +20,16 @@ // See http://www.boost.org/libs/bind for documentation. // -#include #include #include #include +#include +#include +#include #include #include #include #include -#include -#include -#include #include #include #include @@ -147,18 +146,15 @@ template struct accept_lambda } }; -template struct equal_lambda +struct equal_lambda { - Tp const& tp1_; - Tp const& tp2_; - bool result; - explicit equal_lambda( Tp const& tp1, Tp const& tp2 ): tp1_( tp1 ), tp2_( tp2 ), result( true ) {} + equal_lambda(): result( true ) {} - template void operator()( I ) + template void operator()( A1& a1, A2& a2 ) { - result = result && ref_compare( std::get( tp1_ ), std::get( tp2_ ) ); + result = result && ref_compare( a1, a2 ); } }; @@ -176,22 +172,22 @@ public: list( A... a ): data_( a... ) {} - template R call_impl( type, F & f, A2 & a2, mp11::index_sequence ) + template R call_impl( type, F & f, A2 & a2, _bi::index_sequence ) { return unwrapper::unwrap( f, 0 )( a2[ std::get( data_ ) ]... ); } - template R call_impl( type, F & f, A2 & a2, mp11::index_sequence ) const + template R call_impl( type, F & f, A2 & a2, _bi::index_sequence ) const { return unwrapper::unwrap( f, 0 )( a2[ std::get( data_ ) ]... ); } - template void call_impl( type, F & f, A2 & a2, mp11::index_sequence ) + template void call_impl( type, F & f, A2 & a2, _bi::index_sequence ) { unwrapper::unwrap( f, 0 )( a2[ std::get( data_ ) ]... ); } - template void call_impl( type, F & f, A2 & a2, mp11::index_sequence ) const + template void call_impl( type, F & f, A2 & a2, _bi::index_sequence ) const { unwrapper::unwrap( f, 0 )( a2[ std::get( data_ ) ]... ); } @@ -200,12 +196,12 @@ public: template R operator()( type, F & f, A2 & a2 ) { - return call_impl( type(), f, a2, mp11::index_sequence_for() ); + return call_impl( type(), f, a2, _bi::index_sequence_for() ); } template R operator()( type, F & f, A2 & a2 ) const { - return call_impl( type(), f, a2, mp11::index_sequence_for() ); + return call_impl( type(), f, a2, _bi::index_sequence_for() ); } // @@ -238,12 +234,12 @@ public: template void accept( V & v ) const { - mp11::tuple_for_each( data_, accept_lambda( v ) ); + _bi::tuple_for_each( accept_lambda( v ), data_ ); } bool operator==( list const & rhs ) const { - return mp11::mp_for_each< mp11::mp_iota_c< sizeof...(A) > >( equal_lambda( data_, rhs.data_ ) ).result; + return _bi::tuple_for_each( equal_lambda(), data_, rhs.data_ ).result; } }; diff --git a/include/boost/bind/detail/integer_sequence.hpp b/include/boost/bind/detail/integer_sequence.hpp new file mode 100644 index 0000000..ce2c2b0 --- /dev/null +++ b/include/boost/bind/detail/integer_sequence.hpp @@ -0,0 +1,111 @@ +#ifndef BOOST_BIND_DETAIL_INTEGER_SEQUENCE_HPP_INCLUDED +#define BOOST_BIND_DETAIL_INTEGER_SEQUENCE_HPP_INCLUDED + +// Copyright 2015, 2017, 2019 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 + +#if defined(__has_builtin) +# if __has_builtin(__make_integer_seq) +# define BOOST_BIND_DETAIL_HAS_MAKE_INTEGER_SEQ +# endif +#endif + +namespace boost +{ +namespace _bi +{ + +// integer_sequence +template struct integer_sequence +{ +}; + +#if defined(BOOST_BIND_DETAIL_HAS_MAKE_INTEGER_SEQ) + +template using make_integer_sequence = __make_integer_seq; + +#else + +// detail::make_integer_sequence_impl +namespace detail +{ + +// iseq_if_c +template struct iseq_if_c_impl; + +template struct iseq_if_c_impl +{ + using type = T; +}; + +template struct iseq_if_c_impl +{ + using type = E; +}; + +template using iseq_if_c = typename iseq_if_c_impl::type; + +// iseq_identity +template struct iseq_identity +{ + using type = T; +}; + +template struct append_integer_sequence; + +template struct append_integer_sequence, integer_sequence> +{ + using type = integer_sequence< T, I..., ( J + sizeof...(I) )... >; +}; + +template struct make_integer_sequence_impl; + +template struct make_integer_sequence_impl_ +{ +private: + + static_assert( N >= 0, "make_integer_sequence: N must not be negative" ); + + static T const M = N / 2; + static T const R = N % 2; + + using S1 = typename make_integer_sequence_impl::type; + using S2 = typename append_integer_sequence::type; + using S3 = typename make_integer_sequence_impl::type; + using S4 = typename append_integer_sequence::type; + +public: + + using type = S4; +}; + +template struct make_integer_sequence_impl: iseq_if_c>, iseq_if_c>, make_integer_sequence_impl_ > > +{ +}; + +} // namespace detail + +// make_integer_sequence +template using make_integer_sequence = typename detail::make_integer_sequence_impl::type; + +#endif // defined(BOOST_BIND_DETAIL_HAS_MAKE_INTEGER_SEQ) + +// index_sequence +template using index_sequence = integer_sequence; + +// make_index_sequence +template using make_index_sequence = make_integer_sequence; + +// index_sequence_for +template using index_sequence_for = make_integer_sequence; + +} // namespace _bi +} // namespace boost + +#endif // #ifndef BOOST_BIND_DETAIL_INTEGER_SEQUENCE_HPP_INCLUDED diff --git a/include/boost/bind/detail/tuple_for_each.hpp b/include/boost/bind/detail/tuple_for_each.hpp new file mode 100644 index 0000000..24a05b0 --- /dev/null +++ b/include/boost/bind/detail/tuple_for_each.hpp @@ -0,0 +1,63 @@ +#ifndef BOOST_BIND_DETAIL_TUPLE_FOR_EACH_HPP_INCLUDED +#define BOOST_BIND_DETAIL_TUPLE_FOR_EACH_HPP_INCLUDED + +// Copyright 2015-2020 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 +#include + +#if BOOST_MP11_MSVC +# pragma warning( push ) +# pragma warning( disable: 4100 ) // unreferenced formal parameter 'tp' +#endif + +namespace boost +{ +namespace _bi +{ + +// tuple_for_each( f, tp ) + +template F tuple_for_each_impl( F&& f, Tp&& tp, integer_sequence ) +{ + using A = int[ 1 + sizeof...(J) ]; + using std::get; + return (void)A{ 0, ((void)f(get(std::forward(tp))), 0)... }, std::forward(f); +} + +template F tuple_for_each( F&& f, Tp&& tp ) +{ + using seq = make_index_sequence::type>::value>; + return _bi::tuple_for_each_impl( std::forward(f), std::forward(tp), seq() ); +} + +// tuple_for_each( f, tp1, tp2 ) + +template F tuple_for_each_impl( F&& f, Tp1&& tp1, Tp2&& tp2, integer_sequence ) +{ + using A = int[ 1 + sizeof...(J) ]; + using std::get; + return (void)A{ 0, ((void)f( get(std::forward(tp1)), get(std::forward(tp2)) ), 0)... }, std::forward(f); +} + +template F tuple_for_each( F&& f, Tp1&& tp1, Tp2&& tp2 ) +{ + using seq = make_index_sequence::type>::value>; + return _bi::tuple_for_each_impl( std::forward(f), std::forward(tp1), std::forward(tp2), seq() ); +} + +} // namespace _bi +} // namespace boost + +#if BOOST_MP11_MSVC +# pragma warning( pop ) +#endif + +#endif // #ifndef BOOST_BIND_DETAIL_TUPLE_FOR_EACH_HPP_INCLUDED