EventBlockArray.h 3.69 KB
Newer Older
legoc's avatar
legoc committed
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
/*
 * Nomad Instrument Control Software
 *
 * Copyright 2011 Institut Laue-Langevin
 *
 * Licensed under the EUPL, Version 1.1 only (the "License");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 *
 * http://www.osor.eu/eupl
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the Licence is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Licence for the specific language governing permissions and
 * limitations under the Licence.
 */

#ifndef LSTDPP_EVENTBLOCKARRAY_H
#define LSTDPP_EVENTBLOCKARRAY_H

#include <list>

#include "Event.h"

namespace lstdpp128 {

class EventBlockArrayIterator;

/**
 * The EventBlockArray is an array of EventBlock.
 */
class EventBlockArray {

public:
	typedef std::list<EventBlock *> array_type;

	/**
	 * The maxBlockSize is the maximum number of elements of a block and maxBlocks is the maximum number of blocks.
	 */
	EventBlockArray(int32_t maxBlockSize, int32_t maxBlocks = -1) :
		_maxBlockSize(maxBlockSize), _maxBlocks(maxBlocks), _reduced(false) {

		addEventBlock();
	}

	~EventBlockArray() {
		for (array_type::iterator b = _array.begin(); b != _array.end(); ++b) {
			delete *b;
		}
	}

	/**
	 * Returns the removed block or the null pointer.
	 */
	EventBlock * updateBlocks();
	void addEventBlock();
	bool isInsertable(time_type time) const;

	inline array_type & array() {
		return _array;
	}

	inline array_type const & array() const {
		return _array;
	}

	EventBlockArrayIterator begin() const;
	EventBlockArrayIterator end() const;

	time_type maxPreviousBlockTime(EventBlockArray::array_type::reverse_iterator const & b) const;
	EventBlockArrayIterator insertEvent(Event const & event);

private:
	int32_t _maxBlockSize;
	int32_t _maxBlocks;
	bool _reduced;
	array_type _array;
};

class EventBlockArrayIterator {

public:
	EventBlockArrayIterator(EventBlockArray::array_type const & EventBlocks, EventBlockArray::array_type::const_iterator const & b, std::multiset<Event, CompareEvents>::iterator const & e) :
		_EventBlocks(EventBlocks), _b(b), _e(e) {
	}

	inline bool first() const {
		return (_b == _EventBlocks.begin() && _e == (*_b)->events.begin());
	}

	inline bool end() const {
		return (_b == _EventBlocks.end());
	}

	inline Event & operator* () const {
		// why do we need a const_cast?
		return const_cast<Event &>(*_e);
	}

	inline bool operator== (EventBlockArrayIterator const & i) const {
		if (_b == _EventBlocks.end()) {
			return _b == i._b;
		}
		return _b == i._b && _e == i._e;
	}

	inline bool operator!= (EventBlockArrayIterator const & i) const {
		return !(*this == i);
	}

	inline EventBlockArrayIterator & operator++ () {

		if (!end()) {
			++_e;
			if (_e == (*_b)->events.end()) {
				++_b;
				if (end()) {
					return *this;
				}
				_e = (*_b)->events.begin();
			}
		}

		return *this;
	}

	inline EventBlockArrayIterator & operator-- () {

		if (!first()) {
			if (!end() && _e != (*_b)->events.begin()) {
				--_e;
				return *this;
			}

			--_b;
			std::multiset<Event, CompareEvents>::const_reverse_iterator ec = (*_b)->events.rbegin();
			// needing to advance before calling base to convert from reverse to forward iterator
			++ec;
			_e = ec.base();
		}

		return *this;
	}

private:
	EventBlockArray::array_type const & _EventBlocks;
	EventBlockArray::array_type::const_iterator _b;
	std::multiset<Event, CompareEvents>::iterator _e;
};

void testIterator(EventBlockArray const & EventBlocks);
void testSplitBlocks(EventBlockArray const & EventBlocks);
void printBlocks(EventBlockArray const & EventBlocks, bool printEvents);
void checkEvents(EventBlockArray const & EventBlocks);

}

#endif