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