Comment detail

不動点演算子 (Nested Flatten)

折角なのでBoost.MPLでやりました。Boost 1.36.0使用。 VC++ 9 SP1, VC++ 8 SP1, gcc 4.3.1 (Cygwin), gcc 3.4.4 (Cygwin付属)で確認。

うまくいかずあれこれ悩んでいましたが、#5921を見たらあっというまに出来上がりました。ありがとうございます。参考ページは自分が理解するのに役立ちました。

coutではなくprintfを使っている理由は、コンパイル時計算されて定数展開されているのをアセンブリ出力を見て確かめるときに分かりやすいからです(さすがにprintfはインライン展開されないですから)。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <cstdio>
#include <boost/mpl/int.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/less_equal.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/bind.hpp>
#include <boost/mpl/less_equal.hpp>

namespace mpl = boost::mpl;

template<typename F>
struct Y
{
    struct G
    {
        template<typename P>
        struct apply
        {
            struct U
            {
                template<typename A>
                struct apply : P::template apply<P>::type::template apply<A>
                {};
            };
            typedef mpl::bind<F, U, mpl::_1> type;
        };
    };
    typedef typename G::template apply<G>::type type;
};

struct FactorialBase
{
    template<typename F, typename X>
    struct apply
    {
        struct X_Times_X_minus_1 :
            mpl::times
            <
                X,
                typename F::template apply<typename mpl::template prior<X>::type>::type
            >
        {};
        typedef typename mpl::eval_if
        <
            mpl::less_equal<X, mpl::int_<1> >,
            mpl::int_<1>,
            X_Times_X_minus_1
        >::type type;
    };
};

struct FibonacciBase
{
    template<typename F, typename X>
    struct apply
    {
        typedef typename mpl::template prior<X>::type PriorX;
        struct X_minus_2_Plus_X_minus_1 :
            mpl::plus
            <
                typename F::template apply<typename mpl::template prior<PriorX>::type>::type,
                typename F::template apply<PriorX>::type
            >
        {};
        typedef typename mpl::eval_if
        <
            mpl::less_equal<X, mpl::int_<1> >,
            X,
            X_minus_2_Plus_X_minus_1
        >::type type;
    };
};

int main()
{
    typedef Y<FactorialBase>::type Factorial;
    typedef Factorial::apply<mpl::int_<10> >::type result1;
    typedef Y<FibonacciBase>::type Fibonacci;
    typedef Fibonacci::apply<mpl::int_<10> >::type result2;
    std::printf("%d\n", result1::value);
    std::printf("%d\n", result2::value);
}

Index

Feed

Other

Link

Pathtraq

loading...