Add AbstractDeclarationNavigationContext, and move the html-method from
[kdevelopdvcssupport.git] / language / duchain / appendedlist_static.h
blob4682392bd66152098549687081ed3be7c516f097
1 /*
2 Copyright 2008 David Nolden <david.nolden.kdevelop@art-master.de>
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License version 2 as published by the Free Software Foundation.
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Library General Public License for more details.
13 You should have received a copy of the GNU Library General Public License
14 along with this library; see the file COPYING.LIB. If not, write to
15 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 Boston, MA 02110-1301, USA.
19 #ifndef APPENDEDLIST_H
20 #define APPENDEDLIST_H
22 #include <util/kdevvarlengtharray.h>
24 namespace KDevelop {
26 /**
27 * This file contains macros and classes that can be used to conveniently implement classes that store the data of an arbitrary count
28 * of additional lists within the same memory block directly behind the class data, in a way that one the whole data can be stored by one copy-operation
29 * to another place, like needed in ItemRepository. These macros simplify having two versions of a class: One that has its lists attached in memory,
30 * and one version that has them contained as a directly accessible KDevVarLengthArray. Both versions have their lists accessible through access-functions,
31 * have a completeSize() function that computes the size of the one-block version, and a copyListsFrom(..) function which can copy the lists from one
32 * version to the other. The class that contains these lists must have a boolean template parameter called "dynamic".
34 * See identifier.cpp for an example how to use these classes. @todo Document this a bit more
35 * */
37 //Foreach macro that takes a container and a function-name, and will iterate through the vector returned by that function, using the lenght returned by the function-name with "Size" appended.
38 //This might be a little slow
39 #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)
41 #define START_APPENDED_LISTS(selftype) typedef selftype SelfType;
43 #define APPENDED_LIST_COMMON(type, name) \
44 KDevelop::AppendedList<dynamic, type> name ## List; \
45 unsigned int name ## Size() const { return name ## List.size(); } \
46 template<class T> bool name ## Equals(const T& rhs) const { unsigned int size = name ## Size(); return size == rhs.name ## Size() && memcmp( name(), rhs.name(), size * sizeof(type) ) == 0; }
48 ///@todo Make these things a bit faster(less recursion)
50 #define APPENDED_LIST_FIRST(type, name) APPENDED_LIST_COMMON(type, name) \
51 const type* name() const { return name ## List.data( ((char*)this) + sizeof(SelfType) ); } \
52 unsigned int name ## OffsetBehind() const { return name ## List.dynamicDataSize(); } \
53 template<class T> bool name ## ListChainEquals( const T& rhs ) const { return name ## Equals(rhs); } \
54 template<class T> void name ## CopyAllFrom( const T& rhs ) { name ## List.copy(const_cast<type*>(name()), rhs.name(), rhs.name ## Size()); }
56 #define APPENDED_LIST(type, name, predecessor) APPENDED_LIST_COMMON(type, name) \
57 const type* name() const { return name ## List.data( ((char*)this) + sizeof(SelfType) + predecessor ## OffsetBehind() ); } \
58 unsigned int name ## OffsetBehind() const { return name ## List.dynamicDataSize() + predecessor ## OffsetBehind(); } \
59 template<class T> bool name ## ListChainEquals( const T& rhs ) const { return name ## Equals(rhs) && predecessor ## ListChainEquals(rhs); } \
60 template<class T> void name ## CopyAllFrom( const T& rhs ) { name ## List.copy(const_cast<type*>(name()), rhs.name(), rhs.name ## Size()); predecessor ## CopyAllFrom(); }
62 #define END_APPENDED_LISTS(predecessor) /* Returns the size of the object containing the appended lists, including them */ \
63 unsigned int completeSize() const { return sizeof(SelfType) + predecessor ## OffsetBehind(); } \
64 unsigned int lastOffsetBehind() const { return predecessor ## OffsetBehind(); } \
65 /* Compares all appended lists and returns true if they are equal */ \
66 template<class T> bool listsEqual(const T& rhs) const { return predecessor ## ListChainEquals(rhs); } \
67 template<class T> void copyListsFrom(const T& rhs) { return predecessor ## CopyAllFrom(rhs); }
69 template<bool dynamic, class T>
70 class AppendedList : public KDevVarLengthArray<T, 10> {
71 public:
72 unsigned int dynamicDataSize() const {
73 return this->size() * sizeof(T);
75 const T* data(char* /*position*/) const {
76 return KDevVarLengthArray<T, 10>::data();
78 void copy(T* /*target*/, const T* data, uint size) {
79 this->resize(size);
80 memcpy(KDevVarLengthArray<T, 10>::data(), data, size * sizeof(T));
84 template<class T>
85 class AppendedList<false, T> {
86 public:
87 unsigned int listSize;
88 unsigned int size() const {
89 return listSize;
92 //currentOffset should point to the position where the data of this item should be saved
93 const T* data(char* position) const {
94 return (unsigned int*)position;
96 //Count of bytes that were appeendd
97 unsigned int dynamicDataSize() const {
98 return listSize * sizeof(unsigned int);
100 void copy(T* target, const T* data, uint size) {
101 listSize = size;
102 memcpy(target, data, size * sizeof(T));
107 #endif