changeset 14:ab9ed41eb455

higherorder: a few exercises
author Lewin Bormann <lbo@spheniscida.de>
date Fri, 27 Mar 2020 15:09:49 +0100
parents a5357921e566
children 4e12eb36caa8
files src/binary.cc src/higherorder.cc
diffstat 2 files changed, 73 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/src/binary.cc	Thu Mar 26 10:53:17 2020 +0100
+++ b/src/binary.cc	Fri Mar 27 15:09:49 2020 +0100
@@ -1,8 +1,10 @@
 #include <iostream>
+#include <boost/static_assert.hpp>
 
 template<unsigned long In>
 struct binary {
     static const unsigned long value = binary<In/10>::value * 2 + In%10;
+    BOOST_STATIC_ASSERT(In%10 < 2);
 };
 
 template<>
--- a/src/higherorder.cc	Thu Mar 26 10:53:17 2020 +0100
+++ b/src/higherorder.cc	Fri Mar 27 15:09:49 2020 +0100
@@ -1,12 +1,42 @@
 #include <iostream>
+#include <boost/static_assert.hpp>
 #include <boost/mpl/apply.hpp>
+#include <boost/mpl/at.hpp>
+#include <boost/mpl/equal.hpp>
 #include <boost/mpl/int.hpp>
 #include <boost/mpl/lambda.hpp>
+#include <boost/mpl/multiplies.hpp>
 #include <boost/mpl/placeholders.hpp>
 #include <boost/mpl/plus.hpp>
+#include <boost/mpl/transform.hpp>
+#include <boost/mpl/vector_c.hpp>
 
 namespace mpl = boost::mpl;
 
+template<typename A, typename B>
+struct equal {
+    typedef mpl::bool_<false> type;
+};
+template<typename A>
+struct equal<A, A> {
+    typedef mpl::bool_<true> type;
+};
+
+template<int N>
+struct arg {
+    template<typename A, typename ... As>
+    struct apply : arg<N-1>::template apply<As...> {
+    };
+};
+
+template<>
+struct arg<1> {
+    template<typename A, typename ... As>
+    struct apply {
+        typedef A type;
+    };
+};
+
 struct plus10 {
     template<typename X>
     struct apply {
@@ -15,15 +45,48 @@
 };
 
 template<typename F, typename X>
-struct apply_twice {
-    typedef typename F::template apply<X>::type once;
-    typedef typename F::template apply<once>::type type;
-};
+struct apply : public F::template apply<X> {};
+
+template<typename F, typename X>
+struct apply_twice : public F::template apply<typename F::template apply<X>::type> {};
+
+int exercises(void) {
+    // 3-1
+    {
+        typedef mpl::vector_c<int, 1, 2, 3> src;
+        typedef mpl::transform<src, mpl::plus<mpl::int_<1>, mpl::_>>::type dst;
+        BOOST_STATIC_ASSERT(3 == mpl::at<dst, mpl::int_<1>>::type::value);
+    }
+    // 3-3
+    {
+        typedef mpl::lambda<apply_twice<mpl::lambda<std::add_pointer<mpl::_>>::type, mpl::_>, mpl::_>::type ptrtwice;
+        typedef mpl::lambda<apply_twice<ptrtwice, mpl::_>>::type ptrquad;
+        BOOST_STATIC_ASSERT(equal<double****, mpl::apply<ptrquad, double>::type>::type::value);
+        std::cout << typeid(mpl::apply<ptrquad, double>::type).name();
+    }
+    return 0;
+}
+
+int arg_test(void) {
+    BOOST_STATIC_ASSERT(3 == arg<2>::template apply<mpl::int_<1>, mpl::int_<3>, mpl::int_<2>>::type::value);
+    std::cout << arg<2>::template apply<mpl::int_<1>, mpl::int_<3>, mpl::int_<2>>::type::value;
+    return 0;
+}
+
+int test(void) {
+    typedef mpl::int_<3> three;
+    // lambda<> takes a placeholder expression and returns a metafunction class.
+    typedef mpl::lambda<mpl::plus<mpl::int_<11>, mpl::_1>>::type plus11;
+    typedef mpl::lambda<plus10>::type plus10_2;
+
+    typedef mpl::vector_c<int, 1, 2, 3> seq1;
+    typedef mpl::transform<seq1, plus10>::type seq2;
+    std::cout << apply_twice<plus11, three>::type::value << " " << mpl::at<seq2, mpl::int_<2>>::type::value << std::endl;
+    return 0;
+}
 
 int main(void) {
-    typedef mpl::int_<3> three;
-    typedef mpl::lambda<mpl::plus<mpl::int_<11>, mpl::_1>>::type plus11;
-
-    std::cout << apply_twice<plus11, three>::type::value << std::endl;
+    exercises();
     return 0;
 }
+