aboutsummaryrefslogtreecommitdiff
path: root/contrib/native/client/src/include/drill/collections.hpp
blob: 9fbfcc5e2588bfdca258a4d7f5a8ef259c26271c (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
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _DRILL_COLLECTIONS_H
#define _DRILL_COLLECTIONS_H

#include <iterator>

#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>

namespace Drill {
namespace impl {

/**
 * Interface for internal iterators
 */
template<typename T>
class DrillIteratorImpl: private boost::noncopyable {
public:
	typedef DrillIteratorImpl<T> iterator;
	typedef boost::shared_ptr<iterator> iterator_ptr;

	typedef T value_type;
	typedef value_type& reference;
	typedef value_type* pointer;

	virtual ~DrillIteratorImpl() {};

	// To allow conversion from non-const to const types
	virtual operator typename DrillIteratorImpl<const T>::iterator_ptr() const = 0;

	virtual reference operator*() const = 0;
	virtual pointer   operator->() const = 0;

	virtual iterator& operator++() = 0;

	virtual bool operator==(const iterator& x) const = 0;
	virtual bool operator!=(const iterator& x) const = 0;
};

/**
 * Interface for internal collections
 */
template<typename T>
class DrillCollectionImpl: private boost::noncopyable {
public:
	// STL-like iterator typedef
	typedef DrillIteratorImpl<T> iterator;
	typedef boost::shared_ptr<iterator> iterator_ptr;
	typedef DrillIteratorImpl<const T> const_iterator;
	typedef boost::shared_ptr<const_iterator> const_iterator_ptr;

	typedef T value_type;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef value_type* pointer;
	typedef const value_type* const_pointer;
	typedef int size_type;

	virtual ~DrillCollectionImpl() {}

	virtual iterator_ptr begin() = 0;
	virtual const_iterator_ptr begin() const = 0;
	virtual iterator_ptr end() = 0;
	virtual const_iterator_ptr end() const = 0;
};
} // namespace internal

template<typename T>
class DrillCollection;

template<typename T>
class DrillIterator: public std::iterator<std::input_iterator_tag, T> {
public:
	typedef impl::DrillIteratorImpl<T> Impl;
	typedef boost::shared_ptr<Impl> ImplPtr;

	typedef DrillIterator<T> iterator;
	typedef std::iterator<std::input_iterator_tag, T> superclass;
	typedef typename superclass::reference reference;
	typedef typename superclass::pointer pointer;

	// Default constructor
	DrillIterator(): m_pImpl() {};
	~DrillIterator() {}

	// Iterators are CopyConstructible and CopyAssignable
	DrillIterator(const iterator& it): m_pImpl(it.m_pImpl) {}
	iterator& operator=(const iterator& it) {
		m_pImpl = it.m_pImpl;
		return *this;
	}

	template<typename U>
	DrillIterator(const DrillIterator<U>& it): m_pImpl(*it.m_pImpl) {}

	reference operator*() const { return m_pImpl->operator*(); }
	pointer   operator->() const { return m_pImpl->operator->(); }

	iterator& operator++() { m_pImpl->operator++(); return *this; }

	bool operator==(const iterator& x) const { 
		if (m_pImpl == x.m_pImpl) {
			return true;
		}
		return m_pImpl && m_pImpl->operator==(*x.m_pImpl);
	}

	bool operator!=(const iterator& x) const { 
		if (m_pImpl == x.m_pImpl) {
			return false;
		}
		return !m_pImpl ||  m_pImpl->operator!=(*x.m_pImpl);
	}

private:
	template<typename U>
	friend class DrillCollection;
	template<typename U>
	friend class DrillIterator;

	ImplPtr m_pImpl;

	template<typename U>
	DrillIterator(const boost::shared_ptr<impl::DrillIteratorImpl<U> >& pImpl): m_pImpl(pImpl) {}
};

template<typename T>
class DrillCollection {
public:
	typedef impl::DrillCollectionImpl<T> Impl;
	typedef boost::shared_ptr<Impl> ImplPtr;

	// STL-like iterator typedef
	typedef DrillIterator<T> iterator;
	typedef DrillIterator<const T> const_iterator;
	typedef T value_type;
	typedef value_type& reference;
	typedef const value_type& const_reference;
	typedef value_type* pointer;
	typedef const value_type* const_pointer;
	typedef int size_type;

	iterator       begin()       { return iterator(m_pImpl->begin()); }
	const_iterator begin() const { return const_iterator(boost::const_pointer_cast<const Impl>(m_pImpl)->begin()); }
	iterator       end()         { return iterator(m_pImpl->end()); }
	const_iterator end() const   { return const_iterator(boost::const_pointer_cast<const Impl>(m_pImpl)->end()); }

protected:
	DrillCollection(const ImplPtr& impl): m_pImpl(impl) {}

	Impl& operator*() { return *m_pImpl; }
	const Impl& operator*() const { return *m_pImpl; }
	Impl* operator->() { return m_pImpl.get(); }
	const Impl* operator->() const { return m_pImpl.get(); }

private:
	ImplPtr m_pImpl;
};


} /* namespace Drill */
#endif /* _DRILL_COLLECTIONS_H */