summaryrefslogtreecommitdiff
path: root/app/wm2/listmacro2.h
blob: fa822836cc3d2009e9abfa5deebc68db9da9bc55 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

#ifndef _LISTMACRO_H_
#define _LISTMACRO_H_

#include <assert.h>

// assumes efficient realloc()

#define declarePList(List, T) \
  typedef T *T##_pointer; \
  declareList(List, T##_pointer);

#define implementPList(List, T) \
  typedef T *T##_pointer; \
  implementList(List, T##_pointer);

#define declareList(List, T) \
class List { \
public: \
    List(); \
    ~List(); \
\
    long count() const { return m_count; } \
    T &item(long index) const { \
	assert(index >= 0 && index < m_count); \
	return m_items[index]; \
    } \
    T *array(long index, long count) { \
	return m_items + index; \
    } \
\
    void append(const T &); \
    void remove(long index); \
    void remove_all(); \
    void move_to_start(long index); \
\
private: \
    T *m_items; \
    long m_count; \
};

#define implementList(List, T) \
\
List::List() : m_count(0), m_items(0) { } \
\
List::~List() { remove_all(); } \
\
void List::append(const T &item) { \
    if (m_items) { \
        m_items = (T *)realloc(m_items, (m_count + 1) * sizeof(T)); \
    } else { \
	m_items = (T *)malloc(sizeof(T)); \
    } \
    assert(m_items); \
    m_items[m_count++] = (T)item; \
} \
\
void List::remove(long index) { \
    assert(index >= 0 && index < m_count); \
    memcpy(m_items+index, m_items+index+1, (m_count-index-1) * sizeof(T)); \
    m_items = (T *)realloc(m_items, (m_count - 1) * sizeof(T)); \
    --m_count; \
} \
\
void List::remove_all() { \
    while (m_count > 0) remove(0); \
} \
\
void List::move_to_start(long index) { \
    assert(index >= 0 && index < m_count); \
    T temp = item(index); \
    if (index > 0) memcpy(m_items+1, m_items, index * sizeof(T)); \
    m_items[0] = temp; \
}

#endif