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
//天干 
std::string HeavenlyStems[] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};
const static HeavenlyStemsCount = sizeof( HeavenlyStems ) / sizeof( HeavenlyStems[ 0 ] );

//地支
std::string EarthlyBranches[] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};
const static EarthlyBranchesCount = sizeof( EarthlyBranches ) / sizeof( EarthlyBranches[ 0 ] );

template< int HS >
struct HeavenlyStemIndex
{
    enum
    {
        Value = ( HS % HeavenlyStemsCount ),
        Next = HeavenlyStemIndex< Value + 1 >::Value
    };
};

template< int EB >
struct EarthlyBrancheIndex
{
    enum
    {
        Value = ( EB % EarthlyBranchesCount ),
        Next = EarthlyBrancheIndex< Value + 1 >::Value
    };
};

struct SexagenaryCycleBase
{
    virtual std::string ToString() = 0;
    virtual SexagenaryCycleBase* CreateNext() = 0;
};

template< int HS = 0, int EB = 0 >
struct SexagenaryCycle : public SexagenaryCycleBase
{
    typedef HeavenlyStemIndex< HS > HSIndex;
    typedef EarthlyBrancheIndex< EB > EBIndex;
    typedef SexagenaryCycle< HSIndex::Next, EBIndex::Next > Next;

    static bool created;
    static SexagenaryCycleBase* Create()
    {
        if ( created )
        {
            return NULL;
        }
        created = true;
        return new SexagenaryCycle();
    }

    SexagenaryCycleBase* CreateNext()
    {
        return Next::Create();
    }

    std::string ToString()
    {
        return HeavenlyStems[ HSIndex::Value ] + EarthlyBranches[ EBIndex::Value ];
    }
};

template< int HS, int EB >
bool SexagenaryCycle< HS, EB >::created = false;

void SexagenaryCycleGenerater()
{
    SexagenaryCycleBase* base = SexagenaryCycle<>::Create();
    while ( base )
    {
        std::cout << base->ToString() << " ";
        SexagenaryCycleBase* next = base->CreateNext();
        delete base;
        base = next;
        next = NULL;
    }
};