Tuesday, February 08, 2011

Generalized foreach with C++0x

從別的地方看來的(一時找不太到URL),然後自己加上其它std container的支援以及整數/陣列的支援...個人用了一陣子覺得蠻方便的XD

只能說C++0x的auto跟decltype實在是好物!!





/* foreach support for non-container type, the indexer iterates through 0 ~ (A-1) */
static inline int8_t beginof(int8_t a) { return 0; }
static inline int8_t endof(int8_t a) { return a; }
static inline uint8_t beginof(uint8_t a) { return 0; }
static inline uint8_t endof(uint8_t a) { return a; }

static inline int16_t beginof(int16_t a) { return 0; }
static inline int16_t endof(int16_t a) { return a; }
static inline uint16_t beginof(uint16_t a) { return 0; }
static inline uint16_t endof(uint16_t a) { return a; }

static inline int32_t beginof(int32_t a) { return 0; }
static inline int32_t endof(int32_t a) { return a; }
static inline uint32_t beginof(uint32_t a) { return 0; }
static inline uint32_t endof(uint32_t a) { return a; }

static inline int64_t beginof(int64_t a) { return 0; }
static inline int64_t endof(int64_t a) { return a; }
static inline uint64_t beginof(uint64_t a) { return 0; }
static inline uint64_t endof(uint64_t a) { return a; }

template static inline T* beginof (T (&a)[N]) { return a; }
template static inline T* endof (T (&a)[N]) { return a + N; }

// foreach support for std::vector
#include
template static inline typename std::vector::iterator beginof (std::vector& v) { return v.begin(); }
template static inline typename std::vector::iterator endof (std::vector& v) { return v.end(); }

template static inline typename std::vector::const_iterator beginof (const std::vector& v) { return v.begin(); }
template static inline typename std::vector::const_iterator endof (const std::vector& v) { return v.end(); }

// foreach support for std::list
#include
template static inline typename std::list::iterator beginof (std::list& v) { return v.begin(); }
template static inline typename std::list::iterator endof (std::list& v) { return v.end(); }

template static inline typename std::list::const_iterator beginof (const std::list& v) { return v.begin(); }
template static inline typename std::list::const_iterator endof (const std::list& v) { return v.end(); }

// foreach support for std::map
#include
template static inline typename std::map::iterator beginof (std::map& m) { return m.begin(); }
template static inline typename std::map::iterator endof (std::map& m) { return m.end(); }

template static inline typename std::map::const_iterator beginof (const std::map& m) { return m.begin(); }
template static inline typename std::map::const_iterator endof (const std::map& m) { return m.end(); }

// foreach support for std::tr1::unordered_set
#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include
template static inline typename std::unordered_set::iterator beginof (std::unordered_set& m) { return m.begin(); }
template static inline typename std::unordered_set::iterator endof (std::unordered_set& m) { return m.end(); }

template static inline typename std::unordered_set::const_iterator beginof (const std::unordered_set& m) { return m.begin(); }
template static inline typename std::unordered_set::const_iterator endof (const std::unordered_set& m) { return m.end(); }

#include
template static inline typename std::unordered_map::iterator beginof (std::unordered_map& m) { return m.begin(); }
template static inline typename std::unordered_map::iterator endof (std::unordered_map& m) { return m.end(); }

template static inline typename std::unordered_map::const_iterator beginof (const std::unordered_map& m) { return m.begin(); }
template static inline typename std::unordered_map::const_iterator endof (const std::unordered_map& m) { return m.end(); }
#else
#include
template static inline typename std::tr1::unordered_set::iterator beginof (std::tr1::unordered_set& m) { return m.begin(); }
template static inline typename std::tr1::unordered_set::iterator endof (std::tr1::unordered_set& m) { return m.end(); }

template static inline typename std::tr1::unordered_set::const_iterator beginof (const std::tr1::unordered_set& m) { return m.begin(); }
template static inline typename std::tr1::unordered_set::const_iterator endof (const std::tr1::unordered_set& m) { return m.end(); }

// foreach support for std::tr1::unordered_map
#include
template static inline typename std::tr1::unordered_map::iterator beginof (std::tr1::unordered_map& m) { return m.begin(); }
template static inline typename std::tr1::unordered_map::iterator endof (std::tr1::unordered_map& m) { return m.end(); }

template static inline typename std::tr1::unordered_map::const_iterator beginof (const std::tr1::unordered_map& m) { return m.begin(); }
template static inline typename std::tr1::unordered_map::const_iterator endof (const std::tr1::unordered_map& m) { return m.end(); }
#endif

// foreach support for __gnu_cxx::hash_map
#include
template static inline typename __gnu_cxx::hash_map::iterator beginof (__gnu_cxx::hash_map& m) { return m.begin(); }
template static inline typename __gnu_cxx::hash_map::iterator endof (__gnu_cxx::hash_map& m) { return m.end(); }

template static inline typename __gnu_cxx::hash_map::const_iterator beginof (const __gnu_cxx::hash_map& m) { return m.begin(); }
template static inline typename __gnu_cxx::hash_map::const_iterator endof (const __gnu_cxx::hash_map& m) { return m.end(); }

#define foreach(i, c) \
for(decltype(beginof(c)) i = beginof(c); i != endof(c); ++i)





0 Comments: