source: src/Common/VectorMap.h @ 5ce0659

ADTast-experimental
Last change on this file since 5ce0659 was 6b0b624, checked in by Peter A. Buhr <pabuhr@…>, 7 years ago

change #ifndef to #pragma once

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