language/duchain
appendedlist_static.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef APPENDEDLIST_H
00020 #define APPENDEDLIST_H
00021
00022 #include <util/kdevvarlengtharray.h>
00023 #include "referencecounting.h"
00024
00025 namespace KDevelop {
00026
00044
00045
00046 #define FOREACH_FUNCTION(item, container) for(uint a = 0, mustDo = 1; a < container ## Size(); ++a) if((mustDo == 0 || mustDo == 1) && (mustDo = 2)) for(item(container()[a]); mustDo; mustDo = 0)
00047
00048 #define START_APPENDED_LISTS(selftype) typedef selftype SelfType;
00049
00050 #define APPENDED_LIST_COMMON(type, name) \
00051 KDevelop::AppendedList<dynamic, type> name ## List; \
00052 unsigned int name ## Size() const { return name ## List.size(); } \
00053 template<class T> bool name ## Equals(const T& rhs) const { unsigned int size = name ## Size(); if(size != rhs.name ## Size()) return false; for(uint a = 0; a < size; ++a) {if(!(name()[a] == rhs.name()[a])) return false;} return true; }
00054
00056
00057 #define APPENDED_LIST_FIRST(type, name) APPENDED_LIST_COMMON(type, name) \
00058 const type* name() const { return name ## List.data( ((char*)this) + sizeof(SelfType) ); } \
00059 unsigned int name ## OffsetBehind() const { return name ## List.dynamicDataSize(); } \
00060 template<class T> bool name ## ListChainEquals( const T& rhs ) const { return name ## Equals(rhs); } \
00061 template<class T> void name ## CopyAllFrom( const T& rhs ) { name ## List.copy(const_cast<type*>(name()), rhs.name(), rhs.name ## Size()); }
00062
00063 #define APPENDED_LIST(type, name, predecessor) APPENDED_LIST_COMMON(type, name) \
00064 const type* name() const { return name ## List.data( ((char*)this) + sizeof(SelfType) + predecessor ## OffsetBehind() ); } \
00065 unsigned int name ## OffsetBehind() const { return name ## List.dynamicDataSize() + predecessor ## OffsetBehind(); } \
00066 template<class T> bool name ## ListChainEquals( const T& rhs ) const { return name ## Equals(rhs) && predecessor ## ListChainEquals(rhs); } \
00067 template<class T> void name ## CopyAllFrom( const T& rhs ) { name ## List.copy(const_cast<type*>(name()), rhs.name(), rhs.name ## Size()); predecessor ## CopyAllFrom(); }
00068
00069 #define END_APPENDED_LISTS(predecessor) \
00070 unsigned int completeSize() const { return sizeof(SelfType) + predecessor ## OffsetBehind(); } \
00071 unsigned int lastOffsetBehind() const { return predecessor ## OffsetBehind(); } \
00072 \
00073 template<class T> bool listsEqual(const T& rhs) const { return predecessor ## ListChainEquals(rhs); } \
00074 template<class T> void copyListsFrom(const T& rhs) { return predecessor ## CopyAllFrom(rhs); }
00075
00076 template<bool dynamic, class T>
00077 class AppendedList : public KDevVarLengthArray<T, 10> {
00078 public:
00079 unsigned int dynamicDataSize() const {
00080 return this->size() * sizeof(T);
00081 }
00082 const T* data(char* ) const {
00083 return KDevVarLengthArray<T, 10>::data();
00084 }
00085 void copy(T* , const T* data, uint size) {
00086 Q_ASSERT(!shouldDoDUChainReferenceCountingInternal(KDevVarLengthArray<T, 10>::data()));
00087 bool empty = KDevVarLengthArray<T, 10>::isEmpty();
00088 Q_ASSERT(empty);
00089 for(uint a = 0; a < size; ++a)
00090 append(data[a]);
00091 }
00092
00093 void free(T*) {
00094 Q_ASSERT(!shouldDoDUChainReferenceCountingInternal(KDevVarLengthArray<T, 10>::data()));
00095 }
00096 };
00097
00098 template<class T>
00099 class AppendedList<false, T> {
00100 public:
00101 AppendedList() : listSize(0) {
00102 }
00103 unsigned int listSize;
00104 unsigned int size() const {
00105 return listSize;
00106 }
00107
00108 void free(T* position) {
00109 if(listSize)
00110 Q_ASSERT(shouldDoDUChainReferenceCountingInternal(position));
00111 for(unsigned int a = 0; a < listSize; ++a)
00112 (position+a)->~T();
00113 }
00114
00115
00116 const T* data(char* position) const {
00117 return (T*)position;
00118 }
00119
00120 unsigned int dynamicDataSize() const {
00121 return listSize * sizeof(T);
00122 }
00123 void copy(T* target, const T* data, uint size) {
00124 if(size)
00125 Q_ASSERT(shouldDoDUChainReferenceCountingInternal(target));
00126 for(uint a = 0; a < size; ++a)
00127 new (target+a) T(data[a]);
00128 listSize = size;
00129 }
00130 };
00131 }
00132
00133 #endif