Mercurial > lbo > hg > ctmp
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; } +