;
+
+ using type = mp_transform<_g, A2>;
+};
+
+} // namespace detail
+
// mp_transform_if
namespace detail
{
-/*
template class P, template class F, class... L> struct mp_transform_if_impl
{
- // error: pack expansion used as argument for non-pack parameter of alias template
- template using _f = mp_eval_if>, mp_first>, F, U...>;
+ // the stupid quote-unquote dance avoids "pack expansion used as argument for non-pack parameter of alias template"
+#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
+
+ template struct _f_ { using type = mp_eval_if, U...>>, mp_first>, mp_quote::template fn, U...>; };
+ template using _f = typename _f_::type;
+
+#else
+
+ template using _f = mp_eval_if, U...>>, mp_first>, mp_quote::template fn, U...>;
+
+#endif
+
using type = mp_transform<_f, L...>;
};
-*/
-
-template class P, template class F, class... L> struct mp_transform_if_impl;
-
-template class P, template class F, template class L, class... T> struct mp_transform_if_impl>
-{
-#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
-
- template struct _f { using type = mp_eval_if>, U, F, U>; };
- using type = L::type...>;
-
-#else
-
- template using _f = mp_eval_if>, U, F, U>;
- using type = L<_f...>;
-
-#endif
-};
-
-template class P, template class F, template class L1, class... T1, template class L2, class... T2> struct mp_transform_if_impl, L2>
-{
- static_assert( sizeof...(T1) == sizeof...(T2), "The arguments of mp_transform_if should be of the same size" );
-
-#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
-
- template struct _f { using type = mp_eval_if>, U1, F, U1, U2>; };
- using type = L1::type...>;
-
-#else
-
- template using _f = mp_eval_if>, U1, F, U1, U2>;
- using type = L1<_f...>;
-
-#endif
-};
-
-template class P, template class F, template class L1, class... T1, template class L2, class... T2, template class L3, class... T3> struct mp_transform_if_impl, L2, L3>
-{
- static_assert( sizeof...(T1) == sizeof...(T2) && sizeof...(T1) == sizeof...(T3), "The arguments of mp_transform_if should be of the same size" );
-
-#if defined( BOOST_MSVC ) && BOOST_WORKAROUND( BOOST_MSVC, <= 1910 )
-
- template struct _f { using type = mp_eval_if>, U1, F, U1, U2, U3>; };
- using type = L1::type...>;
-
-#else
-
- template using _f = mp_eval_if>, U1, F, U1, U2, U3>;
- using type = L1<_f...>;
-
-#endif
-};
} // namespace detail
@@ -753,8 +740,6 @@ template class L, class T1, class T2, class T3, class T4, cla
} // namespace detail
-template class F> using mp_fold = typename detail::mp_fold_impl::type;
-
// mp_reverse_fold
namespace detail
{
diff --git a/include/boost/mp11/bind.hpp b/include/boost/mp11/bind.hpp
new file mode 100644
index 0000000..f7febf5
--- /dev/null
+++ b/include/boost/mp11/bind.hpp
@@ -0,0 +1,64 @@
+#ifndef BOOST_MP11_BIND_HPP_INCLUDED
+#define BOOST_MP11_BIND_HPP_INCLUDED
+
+// Copyright 2017 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
+
+namespace boost
+{
+namespace mp11
+{
+
+template struct mp_arg
+{
+ template using fn = mp_at_c, I>;
+};
+
+using _1 = mp_arg<0>;
+using _2 = mp_arg<1>;
+using _3 = mp_arg<2>;
+using _4 = mp_arg<3>;
+using _5 = mp_arg<4>;
+using _6 = mp_arg<5>;
+using _7 = mp_arg<6>;
+using _8 = mp_arg<7>;
+using _9 = mp_arg<8>;
+
+template class F, class... T> struct mp_bind;
+
+namespace detail
+{
+
+template struct eval_bound_arg
+{
+ using type = V;
+};
+
+template struct eval_bound_arg, T...>
+{
+ using type = typename mp_arg::template fn;
+};
+
+template class F, class... U, class... T> struct eval_bound_arg, T...>
+{
+ using type = typename mp_bind::template fn;
+};
+
+} // namespace detail
+
+template class F, class... T> struct mp_bind
+{
+ template using fn = F::type...>;
+};
+
+} // namespace mp11
+} // namespace boost
+
+#endif // #ifndef BOOST_MP11_BIND_HPP_INCLUDED
diff --git a/include/boost/mp11/function.hpp b/include/boost/mp11/function.hpp
index e714aa0..571a24b 100644
--- a/include/boost/mp11/function.hpp
+++ b/include/boost/mp11/function.hpp
@@ -12,6 +12,7 @@
#include
#include
#include
+#include
namespace boost
{
@@ -84,6 +85,26 @@ template struct mp_or_impl
} // namespace detail
+// mp_same
+namespace detail
+{
+
+template struct mp_same_impl;
+
+template<> struct mp_same_impl<>
+{
+ using type = mp_true;
+};
+
+template struct mp_same_impl
+{
+ using type = mp_all...>;
+};
+
+} // namespace detail
+
+template using mp_same = typename detail::mp_same_impl::type;
+
} // namespace mp11
} // namespace boost
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index 4f68b59..3bfaec6 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -94,6 +94,7 @@ run mp_all.cpp : : : $(REQ) ;
run mp_and.cpp : : : $(REQ) ;
run mp_any.cpp : : : $(REQ) ;
run mp_or.cpp : : : $(REQ) ;
+run mp_same.cpp : : : $(REQ) ;
# map
run mp_map_find.cpp : : : $(REQ) ;
@@ -102,3 +103,6 @@ run mp_map_insert.cpp : : : $(REQ) ;
run mp_map_replace.cpp : : : $(REQ) ;
run mp_map_erase.cpp : : : $(REQ) ;
run mp_map_update.cpp : : : $(REQ) ;
+
+# bind
+run mp_bind.cpp : : : $(REQ) ;
diff --git a/test/mp_bind.cpp b/test/mp_bind.cpp
new file mode 100644
index 0000000..19edf31
--- /dev/null
+++ b/test/mp_bind.cpp
@@ -0,0 +1,106 @@
+
+// Copyright 2017 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
+#include
+#include
+#include
+
+struct X1 {};
+struct X2 {};
+struct X3 {};
+struct X4 {};
+struct X5 {};
+struct X6 {};
+struct X7 {};
+struct X8 {};
+struct X9 {};
+
+template using add_pointer = typename std::add_pointer::type;
+
+int main()
+{
+ using namespace boost::mp11;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_1::fn, X1>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_1::fn, X1>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_2::fn, X2>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_2::fn, X2>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_3::fn, X3>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_3::fn, X3>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_4::fn, X4>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_4::fn, X4>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_5::fn, X5>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_5::fn, X5>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_6::fn, X6>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_6::fn, X6>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_7::fn, X7>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_7::fn, X7>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_8::fn, X8>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_8::fn, X8>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<_9::fn, X9>));
+
+ //
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X1*>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X1*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X2*>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X2*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X3*>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X3*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X4*>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X4*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X5*>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X5*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X6*>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X6*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X7*>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X7*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X8*>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X8*>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same::fn, X9*>));
+
+ //
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same<
+ mp_bind,
+ mp_bind,
+ mp_bind,
+ mp_bind,
+ mp_bind,
+ mp_bind,
+ mp_bind,
+ mp_bind,
+ mp_bind
+ >::fn, std::tuple>));
+
+ //
+
+ return boost::report_errors();
+}
diff --git a/test/mp_same.cpp b/test/mp_same.cpp
new file mode 100644
index 0000000..5b642ae
--- /dev/null
+++ b/test/mp_same.cpp
@@ -0,0 +1,33 @@
+
+// Copyright 2017 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
+
+int main()
+{
+ using boost::mp11::mp_same;
+ using boost::mp11::mp_true;
+ using boost::mp11::mp_false;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_true>));
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_false>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_false>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_false>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, mp_false>));
+
+ return boost::report_errors();
+}
diff --git a/test/mp_transform.cpp b/test/mp_transform.cpp
index 6782278..ed6f1dd 100644
--- a/test/mp_transform.cpp
+++ b/test/mp_transform.cpp
@@ -29,6 +29,15 @@ struct Z2 {};
struct Z3 {};
struct Z4 {};
+struct U1 {};
+struct U2 {};
+
+struct V1 {};
+struct V2 {};
+
+struct W1 {};
+struct W2 {};
+
template using add_pointer = typename std::add_pointer::type;
template using is_same = typename std::is_same::type;
@@ -81,5 +90,16 @@ int main()
//
+ using L8 = std::pair;
+ using L9 = std::pair;
+ using L10 = std::pair;
+ using L11 = std::pair;
+
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, std::tuple>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, std::tuple>>));
+ BOOST_TEST_TRAIT_TRUE((std::is_same, std::pair, std::tuple>>));
+
+ //
+
return boost::report_errors();
}
diff --git a/test/mp_transform_if.cpp b/test/mp_transform_if.cpp
index 89292dd..048909a 100644
--- a/test/mp_transform_if.cpp
+++ b/test/mp_transform_if.cpp
@@ -26,6 +26,8 @@ template using add_pointer = T*;
template using is_not_ref = mp_not>;
template using second = T2;
template using third = T3;
+template using fourth = T4;
+template