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
85
86
87
88
89
90
91
|
// Copyright Joakim Karlsson & Kim Gräsman 2010-2012.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef IGLOO_CONSTRAINT_H
#define IGLOO_CONSTRAINT_H
namespace snowhouse {
struct ConstraintOperator;
typedef std::stack<bool> ResultStack;
typedef std::stack<ConstraintOperator*> OperatorStack;
template <typename HT, typename TT>
struct ConstraintList
{
typedef HT HeadType;
typedef TT TailType;
ConstraintList(const HeadType& head, const TailType& tail)
: m_head(head), m_tail(tail)
{
}
HeadType m_head;
TailType m_tail;
};
struct Nil
{
Nil() {}
Nil(const Nil&) {}
};
// ---- These structs defines the resulting types of list concatenation operations
template <typename L1, typename L2>
struct type_concat
{
typedef ConstraintList<typename L1::HeadType, typename type_concat<typename L1::TailType, L2>::t> t;
};
template <typename L2> struct type_concat<Nil, L2> { typedef L2 t; };
template <typename L3> inline L3 tr_concat(const Nil&, const Nil&) { return Nil(); }
// ---- These structs define the concatenation operations.
template <typename LeftList, typename RightList, typename ResultList>
struct ListConcat
{
static ResultList Concatenate(const LeftList& left, const RightList& right)
{
return ResultList(left.m_head, ListConcat<typename LeftList::TailType, RightList, typename type_concat< typename LeftList::TailType, RightList>::t>::Concatenate(left.m_tail, right));
}
};
// Concatenating an empty list with a second list yields the second list
template <typename RightList, typename ResultList>
struct ListConcat<Nil, RightList, ResultList>
{
static ResultList Concatenate(const Nil&, const RightList& right)
{
return right;
}
};
// Concatenating two empty lists yields an empty list
template <typename ResultList>
struct ListConcat<Nil, Nil, ResultList>
{
static ResultList Concatenate(const Nil&, const Nil&)
{
return Nil();
}
};
// ---- The concatenation operation
template <typename L1, typename L2>
inline typename type_concat<L1, L2>::t Concatenate(const L1& list1, const L2& list2)
{
return ListConcat<L1, L2, typename type_concat<L1, L2>::t>::Concatenate(list1, list2);
}
}
#endif
|