Skip to content

Instantly share code, notes, and snippets.

@sanyarnd
Last active September 1, 2019 00:08
Show Gist options
  • Select an option

  • Save sanyarnd/e300569aa6774da0e985632d9c74cd9b to your computer and use it in GitHub Desktop.

Select an option

Save sanyarnd/e300569aa6774da0e985632d9c74cd9b to your computer and use it in GitHub Desktop.
MPL Multiplication Table
#include <iostream>
#include "mult_table.hpp"
int main()
{
std::cout << std::setw(3*N) << "Multiplication Table " << N << "x" << N << ":" << std::endl;
print_table<mult_table>();
return 0;
}
#pragma once
#ifndef MULT_TABLE_HPP
#define MULT_TABLE_HPP
#define BOOST_MPL_LIMIT_VECTOR_SIZE 50
// N x N table
const int N = 24;
#include <iomanip>
#include <iostream>
#include <boost/mpl/back_inserter.hpp>
#include <boost/mpl/copy.hpp>
#include <boost/mpl/end.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/insert.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/range_c.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/transform.hpp>
#include <boost/mpl/vector.hpp>
namespace mpl = boost::mpl;
// scalar vector multiplication
template <int i>
struct multiply_scalar
{
template<typename T>
struct apply
{
typedef mpl::int_<(T::value * i)> type;
};
};
// vector of 1..N
typedef mpl::copy
<
mpl::range_c<int, 1, N + 1>::type, // range = [a..b) => N=N+1;
mpl::back_inserter< mpl::vector<> >
>::type nums;
// Recursive auxiliary function for table
template<class S, class T, int N>
struct mult_table_aux :
mpl::insert< S, typename mpl::end< S >::type, typename mpl::transform< T, multiply_scalar<N> >::type >
{};
// Multiplication table recursion class
template<class T, int N>
struct mult_table_ :
mult_table_aux<typename mult_table_<T, N - 1>::type, T, N>
{};
// Multiplication table recursion base case
template<class T>
struct mult_table_<T, 0>
{
typedef mpl::vector<> type;
};
// Multiplication table
typedef mult_table_<nums, N>::type mult_table;
// Printing
// no need of wrapper, actually
template <class T> struct wrap { };
// print int
struct print_table2
{
template <class T>
void operator() (wrap <T>) const
{
std::cout << std::setw(4) << T::value << " ";
}
};
// print vector of int
struct print_table1
{
template <class T>
void operator() (wrap <T>) const
{
mpl::for_each <T, wrap<mpl::_>>(print_table2());
std::cout << std::endl;
}
};
// print vector of vectors
template <class TSeq>
void print_table()
{
mpl::for_each <TSeq, wrap<mpl::_>> (print_table1());
}
#endif // MULT_TABLE_HPP
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment