Perfect Numbers CXX TMP

From base48
Jump to: navigation, search

Don't try to run that on your machine ;-)

#include <boost/mpl/long.hpp> 
#include <boost/mpl/range_c.hpp> 
#include <boost/mpl/vector_c.hpp> 
#include <boost/mpl/arithmetic.hpp> 
#include <boost/mpl/accumulate.hpp> 
#include <boost/mpl/back_inserter.hpp> 
#include <boost/mpl/equal.hpp> 
#include <boost/mpl/copy_if.hpp> 
#include <boost/mpl/at.hpp> 
#include <boost/mpl/size.hpp> 
#include <iostream> 
 
namespace mpl = boost::mpl; 
 
template < typename Sum , typename Div , typename Num > 
struct perf_num_plus_if : 
    mpl::if_< 
        mpl::equal_to< 
            mpl::modulus< Num,Div > , 
            mpl::long_<0> 
        >,         
        typename mpl::plus<Sum,Div>::type, 
        Sum 
    >::type                 
    {}; 
 
template< typename Num > 
    struct perf_num_impl : 
        mpl::accumulate< 
            mpl::range_c< 
                long, 
                1, 
                Num::value/2+1 
            >, 
            mpl::long_<0>, 
            perf_num_plus_if< 
                mpl::_, 
                mpl::_, 
                Num 
            > 
        >::type 
    {}; 
 
template< long Start , long End > 
    struct  perfect_number : 
        mpl::copy_if< 
            mpl::range_c<long,Start,End>, 
            mpl::equal_to< mpl::_1 , perf_num_impl<mpl::_1> >, 
            mpl::back_inserter< mpl::vector_c<long> > 
        >::type 
    {}; 
 
template< typename Seq , size_t Pos , size_t Max > 
    struct Output 
    { 
        Output() 
        { 
           std::cout << mpl::at_c<Seq, Pos >::type::value << std::endl;               
           Output< Seq , Pos+1 , Max >(); 
        } 
    }; 
template< typename Seq , size_t N > 
    struct Output< Seq , N , N > 
    { 
        Output(){} 
    }; 
 
int main() 
{ 
   typedef perfect_number< 1 , 500 > vec; 
   Output< vec , 0 , mpl::size< vec >::value >(); 
}