source: src/Common/VectorMap.h @ 35df560

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 35df560 was 97d246d, checked in by Aaron Moss <a3moss@…>, 5 years ago

Tweaks to DeclStats?

  • Property mode set to 100644
File size: 8.1 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// ScopedMap.h --
8//
9// Author           : Aaron B. Moss
10// Created On       : Wed Feb  1 16:55:00 2017
11// Last Modified By : Aaron B. Moss
12// Last Modified On : Wed Feb  1 16:55:00 2017
13// Update Count     : 1
14//
15
16#ifndef _VECTORMAP_H
17#define _VECTORMAP_H
18
19#include <iterator>
20#include <utility>
21#include <vector>
22
23/// Maps integers from a contiguous range to T's
24template<typename T>
25class VectorMap {
26        std::vector<T> data;
27
28public:
29        typedef typename std::vector<T>::size_type size_type;
30        typedef size_type key_type;
31        typedef T mapped_type;
32        typedef std::pair<size_type, T&> value_type;
33        typedef std::pair<size_type, const T&> const_value_type;
34        typedef typename std::vector<T>::difference_type difference_type;
35        typedef const value_type& reference;
36        typedef const const_value_type& const_reference;
37        typedef const value_type* pointer;
38        typedef const const_value_type* const_pointer;
39       
40        class iterator : public std::iterator< std::random_access_iterator_tag,
41                                               value_type,
42                                                                                   difference_type,
43                                                                                   pointer,
44                                                                                   reference > {
45        friend class VectorMap;
46        friend class const_iterator;
47       
48                value_type data;
49
50                iterator(size_type i, std::vector<T>& v) : data(i, v[i]) {}
51        public:
52                iterator(const iterator& that) : data(that.data) {}
53                iterator& operator= (const iterator& that) {
54                        new(&data) value_type{ that.data };
55                        return *this;
56                }
57
58                reference operator* () { return data; }
59                pointer operator-> () { return &data; }
60
61                iterator& operator++ () {
62                        // SHENANIGANS: relies on pair<unsigned, T&> having a trivial destructor and
63                        // vector<T> having contiguous layout
64                        new(&data) value_type{ (data.first + 1), *(&data.second + 1) };
65                        return *this;
66                }
67                iterator operator++ (int) { iterator tmp = *this; ++(*this); return tmp; }
68
69                iterator& operator-- () {
70                        // SHENANIGANS: same reasons as operator++
71                        new(&data) value_type{ (data.first - 1), *(&data.second - 1) };
72                        return *this;
73                }
74                iterator operator-- (int) { iterator tmp = *this; --(*this); return tmp; }
75
76                iterator& operator+= (difference_type i) {
77                        // SHENANIGANS: same reasons as operator++
78                        new(&data) value_type{ (data.first + i), *(&data.second + i) };
79                        return *this;
80                }
81
82                iterator operator+ (difference_type i) const { iterator tmp = *this; return tmp += i; }
83
84                iterator& operator-= (difference_type i) {
85                        // SHENANIGANS: same reasons as operator++
86                        new(&data) value_type{ (data.first - i), *(&data.second - i) };
87                        return *this;
88                }
89
90                iterator operator- (difference_type i) const { iterator tmp = *this; return tmp -= i; }
91
92                difference_type operator- (const iterator& o) const { return data.first - o.data.first; }
93
94                value_type operator[] (difference_type i) const {
95                        // SHENANIGANS: same reasons as operator++
96                        return value_type{ (data.first + i), *(&data.second + i) };
97                }
98
99                bool operator== (const iterator& o) const {
100                        return data.first == o.data.first && &data.second == &o.data.second;
101                }
102               
103                bool operator!= (const iterator& that) const { return !(*this == that); }
104
105                bool operator< (const iterator& o) const { return data.first < o.data.first; }
106
107                bool operator> (const iterator& o) const { return data.first > o.data.first; }
108
109                bool operator<= (const iterator& o) const { return data.first <= o.data.first; }
110
111                bool operator>= (const iterator& o) const { return data.first >= o.data.first; }
112        };
113
114        class const_iterator : public std::iterator< std::bidirectional_iterator_tag,
115                                                     const_value_type,
116                                                                                                  difference_type,
117                                                                                                  const_pointer,
118                                                                                                  const_reference  > {
119        friend class VectorMap;
120                const_value_type data;
121
122                const_iterator(size_type i, const std::vector<T>& v) : data(i, v[i]) {}
123        public:
124                const_iterator(const iterator& that) : data(that.data) {}
125                const_iterator(const const_iterator& that) : data(that.data) {}
126                const_iterator& operator= (const iterator& that) {
127                        new(&data) const_value_type{ that.data };
128                        return *this;
129                }
130                const_iterator& operator= (const const_iterator& that) {
131                        new(&data) const_value_type{ that.data };
132                        return *this;
133                }
134
135                const_reference operator* () { return data; }
136                const_pointer operator-> () { return &data; }
137
138                const_iterator& operator++ () {
139                        // SHENANIGANS: same reasons as iterator::operator++
140                        new(&data) const_value_type{ (data.first + 1), *(&data.second + 1) };
141                        return *this;
142                }
143                const_iterator operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; }
144
145                const_iterator& operator-- () {
146                        // SHENANIGANS: same reasons as iterator::operator++
147                        new(&data) const_value_type{ (data.first - 1), *(&data.second - 1) };
148                        return *this;
149                }
150                const_iterator operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; }
151
152                const_iterator& operator+= (difference_type i) {
153                        // SHENANIGANS: same reasons as iterator::operator++
154                        new(&data) const_value_type{ (data.first + i), *(&data.second + i) };
155                        return *this;
156                }
157
158                const_iterator operator+ (difference_type i) const {
159                        const_iterator tmp = *this; return tmp += i;
160                }
161
162                const_iterator& operator-= (difference_type i) {
163                        // SHENANIGANS: same reasons as iterator::operator++
164                        new(&data) const_value_type{ (data.first - i), *(&data.second - i) };
165                        return *this;
166                }
167
168                const_iterator operator- (difference_type i) const {
169                        const_iterator tmp = *this; return tmp -= i;
170                }
171
172                difference_type operator- (const const_iterator& o) const {
173                        return data.first - o.data.first;
174                }
175
176                const_value_type operator[] (difference_type i) const {
177                        // SHENANIGANS: same reasons as iterator::operator++
178                        return const_value_type{ (data.first + i), *(&data.second + i) };
179                }
180
181                bool operator== (const const_iterator& o) const {
182                        return data.first == o.data.first && &data.second == &o.data.second;
183                }
184               
185                bool operator!= (const const_iterator& that) const { return !(*this == that); }
186
187                bool operator< (const const_iterator& o) const { return data.first < o.data.first; }
188
189                bool operator> (const const_iterator& o) const { return data.first > o.data.first; }
190
191                bool operator<= (const const_iterator& o) const { return data.first <= o.data.first; }
192
193                bool operator>= (const const_iterator& o) const { return data.first >= o.data.first; }
194        };
195
196        /// Reserve space for n elements
197        void reserve(size_type n) {
198                if ( n > data.size() ) { data.insert( data.end(), n - data.size(), T{} ); }
199        }
200
201        /// Unsafe access; no bounds checking
202        T& operator[] (size_type i) { return data[i]; }
203        const T& operator[] (size_type i) const { return data[i]; }
204
205        /// Safe access; will insert new values if needed
206        T& at(size_type i) {
207                reserve(i+1);
208                return data[i];
209        }
210
211        /// Number of stored values
212        unsigned size() const { return data.size(); }
213
214        /// No stored values
215        bool empty() const { return data.empty(); }
216
217        /// Empties the map
218        void clear() { data.clear(); }
219
220        /// Returns 1 if element in map, 0 otherwise
221        size_type count( size_type i ) const { return i < size() ? 1 : 0; }
222
223        iterator begin() { return iterator{ 0, data }; }
224        const_iterator begin() const { return const_iterator{ 0, data }; }
225        const_iterator cbegin() const { return const_iterator{ 0, data }; }
226
227        iterator end() { return iterator{ data.size(), data }; }
228        const_iterator end() const { return const_iterator{ data.size(), data }; }
229        const_iterator cend() const { return const_iterator{ data.size(), data }; }
230
231        iterator find( size_type i ) { return i < size() ? iterator{ i, data } : end(); }
232        const_iterator find( size_type i ) const { return i < size() ? const_iterator{ i, data } : end(); }
233};
234
235template<typename T>
236typename VectorMap<T>::iterator operator+ (typename VectorMap<T>::difference_type i, 
237                                           const typename VectorMap<T>::iterator& it) {
238        return it + i;
239}
240
241template<typename T>
242typename VectorMap<T>::const_iterator operator+ (typename VectorMap<T>::difference_type i, 
243                                                 const typename VectorMap<T>::const_iterator& it) {
244        return it + i;
245}
246
247#endif // _VECTORMAP_H
248
249// Local Variables: //
250// tab-width: 4 //
251// mode: c++ //
252// compile-command: "make install" //
253// End: //
Note: See TracBrowser for help on using the repository browser.