Move foreach to its own header.
This commit is contained in:
parent
b74cd8ec97
commit
609db2639e
@ -18,55 +18,15 @@ standard foreach as in Qt.
|
|||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
#include "Utils.h" // swap
|
#include "Utils.h" // swap
|
||||||
|
#include "ForEach.h" // swap
|
||||||
|
|
||||||
#include <string.h> // memmove
|
#include <string.h> // memmove
|
||||||
#include <new> // for placement new
|
#include <new> // for placement new
|
||||||
|
|
||||||
|
|
||||||
#if NV_CC_GNUC // If typeof is available:
|
|
||||||
|
|
||||||
#define NV_FOREACH(i, container) \
|
|
||||||
typedef typeof(container) NV_STRING_JOIN2(cont,__LINE__); \
|
|
||||||
for(NV_STRING_JOIN2(cont,__LINE__)::PseudoIndex i((container).start()); !(container).isDone(i); (container).advance(i))
|
|
||||||
/*
|
|
||||||
#define NV_FOREACH(i, container) \
|
|
||||||
for(typename typeof(container)::PseudoIndex i((container).start()); !(container).isDone(i); (container).advance(i))
|
|
||||||
*/
|
|
||||||
|
|
||||||
#else // If typeof not available:
|
|
||||||
|
|
||||||
struct PseudoIndexWrapper {
|
|
||||||
template <typename T>
|
|
||||||
PseudoIndexWrapper(const T & container) {
|
|
||||||
nvStaticCheck(sizeof(typename T::PseudoIndex) <= sizeof(memory));
|
|
||||||
new (memory) typename T::PseudoIndex(container.start());
|
|
||||||
}
|
|
||||||
// PseudoIndex cannot have a dtor!
|
|
||||||
|
|
||||||
template <typename T> typename T::PseudoIndex & operator()(const T * container) {
|
|
||||||
return *reinterpret_cast<typename T::PseudoIndex *>(memory);
|
|
||||||
}
|
|
||||||
template <typename T> const typename T::PseudoIndex & operator()(const T * container) const {
|
|
||||||
return *reinterpret_cast<const typename T::PseudoIndex *>(memory);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8 memory[4]; // Increase the size if we have bigger enumerators.
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NV_FOREACH(i, container) \
|
|
||||||
for(PseudoIndexWrapper i(container); !(container).isDone(i(&(container))); (container).advance(i(&(container))))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Declare foreach keyword.
|
|
||||||
#if !defined NV_NO_USE_KEYWORDS
|
|
||||||
# define foreach NV_FOREACH
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
namespace nv
|
namespace nv
|
||||||
{
|
{
|
||||||
|
// @@ Move this to utils?
|
||||||
/// Delete all the elements of a container.
|
/// Delete all the elements of a container.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void deleteAll(T & container)
|
void deleteAll(T & container)
|
||||||
|
@ -9,6 +9,7 @@ SET(CORE_SRCS
|
|||||||
DefsGnucWin32.h
|
DefsGnucWin32.h
|
||||||
DefsVcWin32.h
|
DefsVcWin32.h
|
||||||
FileSystem.h FileSystem.cpp
|
FileSystem.h FileSystem.cpp
|
||||||
|
ForEach.h
|
||||||
HashMap.h
|
HashMap.h
|
||||||
Library.h Library.cpp
|
Library.h Library.cpp
|
||||||
Memory.h Memory.cpp
|
Memory.h Memory.cpp
|
||||||
|
56
src/nvcore/ForEach.h
Normal file
56
src/nvcore/ForEach.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
// This code is in the public domain -- Ignacio Castaño <castano@gmail.com>
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef NV_CORE_FOREACH_H
|
||||||
|
#define NV_CORE_FOREACH_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
The foreach macros that I use are very non-standard and somewhat confusing, but I like them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "nvcore.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if NV_CC_GNUC // If typeof is available:
|
||||||
|
|
||||||
|
#define NV_FOREACH(i, container) \
|
||||||
|
typedef typeof(container) NV_STRING_JOIN2(cont,__LINE__); \
|
||||||
|
for(NV_STRING_JOIN2(cont,__LINE__)::PseudoIndex i((container).start()); !(container).isDone(i); (container).advance(i))
|
||||||
|
/*
|
||||||
|
#define NV_FOREACH(i, container) \
|
||||||
|
for(typename typeof(container)::PseudoIndex i((container).start()); !(container).isDone(i); (container).advance(i))
|
||||||
|
*/
|
||||||
|
|
||||||
|
#else // If typeof not available:
|
||||||
|
|
||||||
|
struct PseudoIndexWrapper {
|
||||||
|
template <typename T>
|
||||||
|
PseudoIndexWrapper(const T & container) {
|
||||||
|
nvStaticCheck(sizeof(typename T::PseudoIndex) <= sizeof(memory));
|
||||||
|
new (memory) typename T::PseudoIndex(container.start());
|
||||||
|
}
|
||||||
|
// PseudoIndex cannot have a dtor!
|
||||||
|
|
||||||
|
template <typename T> typename T::PseudoIndex & operator()(const T * container) {
|
||||||
|
return *reinterpret_cast<typename T::PseudoIndex *>(memory);
|
||||||
|
}
|
||||||
|
template <typename T> const typename T::PseudoIndex & operator()(const T * container) const {
|
||||||
|
return *reinterpret_cast<const typename T::PseudoIndex *>(memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8 memory[4]; // Increase the size if we have bigger enumerators.
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NV_FOREACH(i, container) \
|
||||||
|
for(PseudoIndexWrapper i(container); !(container).isDone(i(&(container))); (container).advance(i(&(container))))
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Declare foreach keyword.
|
||||||
|
#if !defined NV_NO_USE_KEYWORDS
|
||||||
|
# define foreach NV_FOREACH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // NV_CORE_FOREACH_H
|
@ -14,7 +14,7 @@ HashMap based on Thatcher Ulrich <tu@tulrich.com> container, donated to the Publ
|
|||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "Stream.h"
|
#include "Stream.h"
|
||||||
#include "Utils.h" // hash
|
#include "Utils.h" // hash
|
||||||
#include "Array.h" // foreach/pseudoindex
|
#include "ForEach.h"
|
||||||
|
|
||||||
#include <new> // for placement new
|
#include <new> // for placement new
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user