1 | #ifndef MYCPP_GC_TUPLE_H
|
2 | #define MYCPP_GC_TUPLE_H
|
3 |
|
4 | #include <type_traits>
|
5 |
|
6 | template <class A, class B>
|
7 | class Tuple2 {
|
8 | typedef Tuple2<A, B> this_type;
|
9 |
|
10 | public:
|
11 | Tuple2(A a, B b) : a_(a), b_(b) {
|
12 | }
|
13 |
|
14 | A at0() {
|
15 | return a_;
|
16 | }
|
17 | B at1() {
|
18 | return b_;
|
19 | }
|
20 |
|
21 | static constexpr ObjHeader obj_header() {
|
22 | return ObjHeader::Tuple(field_mask(), sizeof(this_type));
|
23 | }
|
24 |
|
25 | static constexpr uint32_t field_mask() {
|
26 | return (std::is_pointer<A>() ? maskbit(offsetof(this_type, a_)) : 0) |
|
27 | (std::is_pointer<B>() ? maskbit(offsetof(this_type, b_)) : 0);
|
28 | }
|
29 |
|
30 | private:
|
31 | A a_;
|
32 | B b_;
|
33 | };
|
34 |
|
35 | template <class A, class B, class C>
|
36 | class Tuple3 {
|
37 | typedef Tuple3<A, B, C> this_type;
|
38 |
|
39 | public:
|
40 | Tuple3(A a, B b, C c) : a_(a), b_(b), c_(c) {
|
41 | }
|
42 | A at0() {
|
43 | return a_;
|
44 | }
|
45 | B at1() {
|
46 | return b_;
|
47 | }
|
48 | C at2() {
|
49 | return c_;
|
50 | }
|
51 |
|
52 | static constexpr ObjHeader obj_header() {
|
53 | return ObjHeader::Tuple(field_mask(), sizeof(this_type));
|
54 | }
|
55 |
|
56 | static constexpr uint32_t field_mask() {
|
57 | return (std::is_pointer<A>() ? maskbit(offsetof(this_type, a_)) : 0) |
|
58 | (std::is_pointer<B>() ? maskbit(offsetof(this_type, b_)) : 0) |
|
59 | (std::is_pointer<C>() ? maskbit(offsetof(this_type, c_)) : 0);
|
60 | }
|
61 |
|
62 | private:
|
63 | A a_;
|
64 | B b_;
|
65 | C c_;
|
66 | };
|
67 |
|
68 | template <class A, class B, class C, class D>
|
69 | class Tuple4 {
|
70 | typedef Tuple4<A, B, C, D> this_type;
|
71 |
|
72 | public:
|
73 | Tuple4(A a, B b, C c, D d) : a_(a), b_(b), c_(c), d_(d) {
|
74 | }
|
75 | A at0() {
|
76 | return a_;
|
77 | }
|
78 | B at1() {
|
79 | return b_;
|
80 | }
|
81 | C at2() {
|
82 | return c_;
|
83 | }
|
84 | D at3() {
|
85 | return d_;
|
86 | }
|
87 |
|
88 | static constexpr ObjHeader obj_header() {
|
89 | return ObjHeader::Tuple(field_mask(), sizeof(this_type));
|
90 | }
|
91 |
|
92 | static constexpr uint32_t field_mask() {
|
93 | return (std::is_pointer<A>() ? maskbit(offsetof(this_type, a_)) : 0) |
|
94 | (std::is_pointer<B>() ? maskbit(offsetof(this_type, b_)) : 0) |
|
95 | (std::is_pointer<C>() ? maskbit(offsetof(this_type, c_)) : 0) |
|
96 | (std::is_pointer<D>() ? maskbit(offsetof(this_type, d_)) : 0);
|
97 | }
|
98 |
|
99 | private:
|
100 | A a_;
|
101 | B b_;
|
102 | C c_;
|
103 | D d_;
|
104 | };
|
105 |
|
106 | template <class A, class B, class C, class D, class E>
|
107 | class Tuple5 {
|
108 | typedef Tuple5<A, B, C, D, E> this_type;
|
109 |
|
110 | public:
|
111 | Tuple5(A a, B b, C c, D d, E e) : a_(a), b_(b), c_(c), d_(d), e_(e) {
|
112 | }
|
113 | A at0() {
|
114 | return a_;
|
115 | }
|
116 | B at1() {
|
117 | return b_;
|
118 | }
|
119 | C at2() {
|
120 | return c_;
|
121 | }
|
122 | D at3() {
|
123 | return d_;
|
124 | }
|
125 | E at4() {
|
126 | return e_;
|
127 | }
|
128 |
|
129 | static constexpr ObjHeader obj_header() {
|
130 | return ObjHeader::Tuple(field_mask(), sizeof(this_type));
|
131 | }
|
132 |
|
133 | static constexpr uint32_t field_mask() {
|
134 | return (std::is_pointer<A>() ? maskbit(offsetof(this_type, a_)) : 0) |
|
135 | (std::is_pointer<B>() ? maskbit(offsetof(this_type, b_)) : 0) |
|
136 | (std::is_pointer<C>() ? maskbit(offsetof(this_type, c_)) : 0) |
|
137 | (std::is_pointer<D>() ? maskbit(offsetof(this_type, d_)) : 0) |
|
138 | (std::is_pointer<E>() ? maskbit(offsetof(this_type, e_)) : 0);
|
139 | }
|
140 |
|
141 | private:
|
142 | A a_;
|
143 | B b_;
|
144 | C c_;
|
145 | D d_;
|
146 | E e_;
|
147 | };
|
148 |
|
149 | #endif // MYCPP_GC_TUPLE_H
|