/*---------------------------------------------------------------------------* Project: NintendoWare File: ut_Foreach.h Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo and/or its licensed developers and are protected by national and international copyright laws. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. The content herein is highly confidential and should be handled accordingly. $Revision: 31311 $ *---------------------------------------------------------------------------*/ #ifndef NW_UT_FOREACH_H_ #define NW_UT_FOREACH_H_ namespace nw { namespace ut { namespace internal { struct static_any_base { operator bool() const { return false; } }; template struct static_any : public static_any_base { static_any(const Type& item) : m_Item(item) {} mutable Type m_Item; }; typedef const static_any_base& static_any_t; template NW_INLINE Type& static_any_cast(static_any_t value) { return static_cast&>(value).m_Item; } //---------------------------------------- // typeof //---------------------------------------- template struct contain_type { typedef Type type; }; template NW_INLINE contain_type* encode_type(Type&) { return 0; } template NW_INLINE contain_type* encode_type(const Type&) { return 0; } #define NW_FOREACH_TYPEOF(COL) \ (true ? 0 : nw::ut::internal::encode_type(COL)) //---------------------------------------- // contain //---------------------------------------- template NW_INLINE static_any contain(const Type& col) { return col; } template NW_INLINE static_any contain(Type& col) { return &col; } template NW_INLINE static_any contain(Type (&col)[Size]) { return col; } //---------------------------------------- // Array //---------------------------------------- template NW_INLINE static_any begin(static_any_t cur, contain_type*) { return static_any_cast(cur); } template NW_INLINE static_any end(static_any_t cur, contain_type*) { return static_any_cast(cur) + Size; } template NW_INLINE void next(static_any_t cur, contain_type*) { ++static_any_cast(cur); } template NW_INLINE Type& extract(static_any_t cur, contain_type*) { return *static_any_cast(cur); } template NW_INLINE bool done(static_any_t cur, static_any_t end, contain_type*) { return static_any_cast(cur) == static_any_cast(end); } //---------------------------------------- // Container //---------------------------------------- template NW_INLINE static_any begin(static_any_t cur, contain_type*) { return static_any_cast(cur)->begin(); } template NW_INLINE static_any begin(static_any_t cur, contain_type*) { return static_any_cast(cur).begin(); } template NW_INLINE static_any end(static_any_t cur, contain_type*) { return static_any_cast(cur)->end(); } template NW_INLINE static_any end(static_any_t cur, contain_type*) { return static_any_cast(cur).end(); } template NW_INLINE void next(static_any_t cur, contain_type*) { ++static_any_cast(cur); } template NW_INLINE typename Type::reference extract(static_any_t cur, contain_type*) { return *static_any_cast(cur); } template NW_INLINE bool done(static_any_t cur, static_any_t end, contain_type*) { typedef typename Type::iterator Iter; return static_any_cast(cur) == static_any_cast(end); } //---------------------------------------- // pair //---------------------------------------- template NW_INLINE static_any begin(static_any_t cur, contain_type >*) { return static_any_cast >(cur).first; } template NW_INLINE static_any end(static_any_t cur, contain_type >*) { return static_any_cast >(cur).second; } template NW_INLINE void next(static_any_t cur, contain_type >*) { ++static_any_cast(cur); } template NW_INLINE typename Type::reference extract(static_any_t cur, contain_type >*) { return *static_any_cast(cur); } template NW_INLINE bool done(static_any_t cur, static_any_t end, contain_type >*) { return static_any_cast(cur) == static_any_cast(end); } //---------------------------------------- // pair //---------------------------------------- template NW_INLINE static_any begin(static_any_t cur, contain_type >*) { return static_any_cast >(cur).first; } template NW_INLINE static_any end(static_any_t cur, contain_type >*) { return static_any_cast >(cur).second; } template NW_INLINE void next(static_any_t cur, contain_type >*) { ++static_any_cast(cur); } template NW_INLINE Type& extract(static_any_t cur, contain_type >*) { return *static_any_cast(cur); } template NW_INLINE bool done(static_any_t cur, static_any_t end, contain_type >*) { return static_any_cast(cur) == static_any_cast(end); } } // namespace internal } // namespace ut } // namespace nw #define NW_FOREACH_CONTAIN(COL) \ nw::ut::internal::contain(COL) #define NW_FOREACH_BEGIN(COL) \ nw::ut::internal::begin(_contain, NW_FOREACH_TYPEOF(COL)) #define NW_FOREACH_END(COL) \ nw::ut::internal::end(_contain, NW_FOREACH_TYPEOF(COL)) #define NW_FOREACH_DONE(COL) \ nw::ut::internal::done(_cur, _end, NW_FOREACH_TYPEOF(COL)) #define NW_FOREACH_NEXT(COL) \ nw::ut::internal::next(_cur, NW_FOREACH_TYPEOF(COL)) #define NW_FOREACH_EXTRACT(COL) \ nw::ut::internal::extract(_cur, NW_FOREACH_TYPEOF(COL)) //! foreach のマクロです。 #define NW_FOREACH(VAR, COL) \ if (nw::ut::internal::static_any_t _contain = NW_FOREACH_CONTAIN(COL)) {} \ else if (nw::ut::internal::static_any_t _cur = NW_FOREACH_BEGIN(COL)) {} \ else if (nw::ut::internal::static_any_t _end = NW_FOREACH_END(COL)) {} \ else for (bool _continue = true; \ _continue && !NW_FOREACH_DONE(COL); \ _continue ? NW_FOREACH_NEXT(COL) : (void)0) \ if ((_continue = false) == true) {} \ else for (VAR = NW_FOREACH_EXTRACT(COL); !_continue; _continue = true) #endif // NW_UT_FOREACH_H_