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