1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: ut_Foreach.h
4
5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 $Revision: 13145 $
14 *---------------------------------------------------------------------------*/
15
16 #ifndef NW_UT_FOREACH_H_
17 #define NW_UT_FOREACH_H_
18
19 namespace nw
20 {
21 namespace ut
22 {
23 namespace internal
24 {
25
26 struct static_any_base
27 {
28 operator bool() const
29 {
30 return false;
31 }
32 };
33
34 template <typename Type>
35 struct static_any : public static_any_base
36 {
static_anystatic_any37 static_any(const Type& item) : m_Item(item) {}
38 mutable Type m_Item;
39 };
40
41 typedef const static_any_base& static_any_t;
42
43
44 template <typename Type>
static_any_cast(static_any_t value)45 NW_INLINE Type& static_any_cast(static_any_t value)
46 {
47 return static_cast<const static_any<Type>&>(value).m_Item;
48 }
49
50 //----------------------------------------
51 // typeof
52 //----------------------------------------
53 template <typename Type>
54 struct contain_type
55 {
56 typedef Type type;
57 };
58
59 template <typename Type>
encode_type(Type &)60 NW_INLINE contain_type<Type>* encode_type(Type&)
61 {
62 return 0;
63 }
64
65 template <typename Type>
encode_type(const Type &)66 NW_INLINE contain_type<const Type>* encode_type(const Type&)
67 {
68 return 0;
69 }
70
71 #define NW_FOREACH_TYPEOF(COL) \
72 (true ? 0 : nw::ut::internal::encode_type(COL))
73
74
75 //----------------------------------------
76 // contain
77 //----------------------------------------
78 template <typename Type>
contain(const Type & col)79 NW_INLINE static_any<Type> contain(const Type& col)
80 {
81 return col;
82 }
83
84 template <typename Type>
contain(Type & col)85 NW_INLINE static_any<Type*> contain(Type& col)
86 {
87 return &col;
88 }
89
90 template <typename Type, int Size>
contain(Type (& col)[Size])91 NW_INLINE static_any<Type*> contain(Type (&col)[Size])
92 {
93 return col;
94 }
95
96 //----------------------------------------
97 // Array
98 //----------------------------------------
99 template <typename Type, int Size>
begin(static_any_t cur,contain_type<Type[Size]> *)100 NW_INLINE static_any<Type*> begin(static_any_t cur, contain_type<Type[Size]>*)
101 {
102 return static_any_cast<Type*>(cur);
103 }
104
105 template <typename Type, int Size>
end(static_any_t cur,contain_type<Type[Size]> *)106 NW_INLINE static_any<Type*> end(static_any_t cur, contain_type<Type[Size]>*)
107 {
108 return static_any_cast<Type*>(cur) + Size;
109 }
110
111 template <typename Type, int Size>
next(static_any_t cur,contain_type<Type[Size]> *)112 NW_INLINE void next(static_any_t cur, contain_type<Type[Size]>*)
113 {
114 ++static_any_cast<Type*>(cur);
115 }
116
117 template <typename Type, int Size>
extract(static_any_t cur,contain_type<Type[Size]> *)118 NW_INLINE Type& extract(static_any_t cur, contain_type<Type[Size]>*)
119 {
120 return *static_any_cast<Type*>(cur);
121 }
122
123
124 template <typename Type, int Size>
done(static_any_t cur,static_any_t end,contain_type<Type[Size]> *)125 NW_INLINE bool done(static_any_t cur, static_any_t end, contain_type<Type[Size]>*)
126 {
127 return static_any_cast<Type*>(cur) == static_any_cast<Type*>(end);
128 }
129
130 //----------------------------------------
131 // Container
132 //----------------------------------------
133 template <typename Type>
begin(static_any_t cur,contain_type<Type> *)134 NW_INLINE static_any<typename Type::iterator> begin(static_any_t cur, contain_type<Type>*)
135 {
136 return static_any_cast<Type*>(cur)->begin();
137 }
138
139 template <typename Type>
begin(static_any_t cur,contain_type<const Type> *)140 NW_INLINE static_any<typename Type::const_iterator> begin(static_any_t cur, contain_type<const Type>*)
141 {
142 return static_any_cast<Type>(cur).begin();
143 }
144
145 template <typename Type>
end(static_any_t cur,contain_type<Type> *)146 NW_INLINE static_any<typename Type::iterator> end(static_any_t cur, contain_type<Type>*)
147 {
148 return static_any_cast<Type*>(cur)->end();
149 }
150
151 template <typename Type>
end(static_any_t cur,contain_type<const Type> *)152 NW_INLINE static_any<typename Type::const_iterator> end(static_any_t cur, contain_type<const Type>*)
153 {
154 return static_any_cast<Type>(cur).end();
155 }
156
157 template <typename Type>
next(static_any_t cur,contain_type<Type> *)158 NW_INLINE void next(static_any_t cur, contain_type<Type>*)
159 {
160 ++static_any_cast<typename Type::iterator>(cur);
161 }
162
163 template <typename Type>
extract(static_any_t cur,contain_type<Type> *)164 NW_INLINE typename Type::reference extract(static_any_t cur, contain_type<Type>*)
165 {
166 return *static_any_cast<typename Type::iterator>(cur);
167 }
168
169 template <typename Type>
done(static_any_t cur,static_any_t end,contain_type<Type> *)170 NW_INLINE bool done(static_any_t cur, static_any_t end, contain_type<Type>*)
171 {
172 typedef typename Type::iterator Iter;
173 return static_any_cast<Iter>(cur) == static_any_cast<Iter>(end);
174 }
175
176 //----------------------------------------
177 // pair
178 //----------------------------------------
179 template <typename Type>
begin(static_any_t cur,contain_type<std::pair<Type,Type>> *)180 NW_INLINE static_any<Type> begin(static_any_t cur, contain_type<std::pair<Type, Type> >*)
181 {
182 return static_any_cast<std::pair<Type, Type> >(cur).first;
183 }
184
185 template <typename Type>
end(static_any_t cur,contain_type<std::pair<Type,Type>> *)186 NW_INLINE static_any<Type> end(static_any_t cur, contain_type<std::pair<Type, Type> >*)
187 {
188 return static_any_cast<std::pair<Type, Type> >(cur).second;
189 }
190
191 template <typename Type>
next(static_any_t cur,contain_type<std::pair<Type,Type>> *)192 NW_INLINE void next(static_any_t cur, contain_type<std::pair<Type, Type> >*)
193 {
194 ++static_any_cast<Type>(cur);
195 }
196
197 template <typename Type>
extract(static_any_t cur,contain_type<std::pair<Type,Type>> *)198 NW_INLINE typename Type::reference extract(static_any_t cur, contain_type<std::pair<Type, Type> >*)
199 {
200 return *static_any_cast<Type>(cur);
201 }
202
203 template <typename Type>
done(static_any_t cur,static_any_t end,contain_type<std::pair<Type,Type>> *)204 NW_INLINE bool done(static_any_t cur, static_any_t end, contain_type<std::pair<Type, Type> >*)
205 {
206 return static_any_cast<Type>(cur) == static_any_cast<Type>(end);
207 }
208
209 //----------------------------------------
210 // pair
211 //----------------------------------------
212 template <typename Type>
begin(static_any_t cur,contain_type<std::pair<Type *,Type * >> *)213 NW_INLINE static_any<Type*> begin(static_any_t cur, contain_type<std::pair<Type*, Type*> >*)
214 {
215 return static_any_cast<std::pair<Type*, Type*> >(cur).first;
216 }
217
218 template <typename Type>
end(static_any_t cur,contain_type<std::pair<Type *,Type * >> *)219 NW_INLINE static_any<Type*> end(static_any_t cur, contain_type<std::pair<Type*, Type*> >*)
220 {
221 return static_any_cast<std::pair<Type*, Type*> >(cur).second;
222 }
223
224 template <typename Type>
next(static_any_t cur,contain_type<std::pair<Type *,Type * >> *)225 NW_INLINE void next(static_any_t cur, contain_type<std::pair<Type*, Type*> >*)
226 {
227 ++static_any_cast<Type*>(cur);
228 }
229
230 template <typename Type>
extract(static_any_t cur,contain_type<std::pair<Type *,Type * >> *)231 NW_INLINE Type& extract(static_any_t cur, contain_type<std::pair<Type*, Type*> >*)
232 {
233 return *static_any_cast<Type*>(cur);
234 }
235
236 template <typename Type>
done(static_any_t cur,static_any_t end,contain_type<std::pair<Type *,Type * >> *)237 NW_INLINE bool done(static_any_t cur, static_any_t end, contain_type<std::pair<Type*, Type*> >*)
238 {
239 return static_any_cast<Type*>(cur) == static_any_cast<Type*>(end);
240 }
241
242 } // namespace internal
243 } // namespace ut
244 } // namespace nw
245
246 #define NW_FOREACH_CONTAIN(COL) \
247 nw::ut::internal::contain(COL)
248
249 #define NW_FOREACH_BEGIN(COL) \
250 nw::ut::internal::begin(_contain, NW_FOREACH_TYPEOF(COL))
251
252 #define NW_FOREACH_END(COL) \
253 nw::ut::internal::end(_contain, NW_FOREACH_TYPEOF(COL))
254
255 #define NW_FOREACH_DONE(COL) \
256 nw::ut::internal::done(_cur, _end, NW_FOREACH_TYPEOF(COL))
257
258 #define NW_FOREACH_NEXT(COL) \
259 nw::ut::internal::next(_cur, NW_FOREACH_TYPEOF(COL))
260
261 #define NW_FOREACH_EXTRACT(COL) \
262 nw::ut::internal::extract(_cur, NW_FOREACH_TYPEOF(COL))
263
264 //! foreach のマクロです。
265 #define NW_FOREACH(VAR, COL) \
266 if (nw::ut::internal::static_any_t _contain = NW_FOREACH_CONTAIN(COL)) {} \
267 else if (nw::ut::internal::static_any_t _cur = NW_FOREACH_BEGIN(COL)) {} \
268 else if (nw::ut::internal::static_any_t _end = NW_FOREACH_END(COL)) {} \
269 else for (bool _continue = true; \
270 _continue && !NW_FOREACH_DONE(COL); \
271 _continue ? NW_FOREACH_NEXT(COL) : (void)0) \
272 if ((_continue = false) == true) {} \
273 else for (VAR = NW_FOREACH_EXTRACT(COL); !_continue; _continue = true)
274
275 #endif // NW_UT_FOREACH_H_
276