Generated on: Thu Mar 29 07:46:58 PDT 2012 for custom file set | ||
|
||
00001 // Copyright 2010-2012 Google 00002 // Licensed under the Apache License, Version 2.0 (the "License"); 00003 // you may not use this file except in compliance with the License. 00004 // You may obtain a copy of the License at 00005 // 00006 // http://www.apache.org/licenses/LICENSE-2.0 00007 // 00008 // Unless required by applicable law or agreed to in writing, software 00009 // distributed under the License is distributed on an "AS IS" BASIS, 00010 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00011 // See the License for the specific language governing permissions and 00012 // limitations under the License. 00013 00014 #ifndef OR_TOOLS_BASE_CONCISE_ITERATOR_H_ 00015 #define OR_TOOLS_BASE_CONCISE_ITERATOR_H_ 00016 00017 #include <deque> 00018 #include <vector> 00019 00020 namespace operations_research { 00021 00022 // Concise STL iterator wrapper 00023 // 00024 // The ConstIter<> and MutableIter<> classes have similar syntax to 00025 // STL iterators, but allow writing much more concise iteration loops. 00026 // 00027 // They internally keep track of the container, so there is additional 00028 // memory cost of an extra pointer. As iterators are usually allocated 00029 // on the stack, this is irrelevant most of the time. 00030 // 00031 // The container is required to provide begin/end() and an STL iterator 00032 // that defines same operations that you'll be using on concise iterator. 00033 // 00034 // NOTE: ConstReverseIter<> and MutableReverseIter<> are provided for 00035 // reverse iteration. 00036 // 00037 // EXAMPLES: 00038 // 00039 // std::vector<int> my_vector; 00040 // my_vector.push_back(1); 00041 // my_vector.push_back(2); 00042 // 00043 // for (ConstIter<std::vector<int> > it(my_vector); !it.at_end(); ++it) 00044 // LOG(INFO) << *it; 00045 // 00046 // std::map<int, std::string> my_map; 00047 // my_map[1] = "a"; 00048 // my_map[2] = "b"; 00049 // 00050 // for (ConstIter<std::map<int, std::string> > it(my_map); !it.at_end(); ++it) 00051 // LOG(INFO) << it->first << " " << it->second; 00052 // 00053 // Includes a quick and safe "erase" feature: 00054 // (note the absence of "++it" in the for()) 00055 // for (MutableIter<std::map<int, std::string> > it(my_map); !it.at_end();) { 00056 // if ( ... it->first) { 00057 // it.erase(); // <- safely deletes that entry and moves the iterator one 00058 // // step ahead. 00059 // } else { 00060 // ++it; 00061 // } 00062 // } 00063 00064 template<class Container> 00065 class Eraser; 00066 00067 template<class Container> 00068 class ConstIter { 00069 public: 00070 typedef Container container_type; 00071 typedef typename Container::value_type value_type; 00072 typedef typename Container::const_iterator const_iterator_type; 00073 00074 explicit ConstIter(const container_type& container) 00075 : container_(&container), iterator_(container.begin()) {} 00076 ConstIter(const ConstIter& source) { 00077 container_ = source.container_; 00078 iterator_ = source.iterator_; 00079 } 00080 ConstIter& operator= (const ConstIter& source) { 00081 container_ = source.container_; 00082 iterator_ = source.iterator_; 00083 return *this; 00084 } 00085 bool operator== (const ConstIter& iter) const { 00086 return iterator_ == iter.iterator_; 00087 } 00088 const value_type* operator->() const { return iterator_.operator->(); } 00089 const value_type& operator*() const { return iterator_.operator*(); } 00090 const container_type* const_container() const { return container_; } 00091 const_iterator_type const_iterator() const { return iterator_; } 00092 ConstIter& operator++() { 00093 ++iterator_; 00094 return *this; 00095 } 00096 ConstIter operator++(int unused) { 00097 ConstIter a = *this; 00098 ++(*this); 00099 return a; 00100 } 00101 bool at_end() const { return iterator_ == container_->end(); } 00102 00103 private: 00104 const container_type* container_; 00105 const_iterator_type iterator_; 00106 }; 00107 00108 // Note: this class is not compatible with sets (operator* returns a non-const 00109 // reference). 00110 template<class Container> 00111 class MutableIter { 00112 public: 00113 typedef Container container_type; 00114 typedef typename Container::value_type value_type; 00115 typedef typename Container::iterator iterator_type; 00116 typedef typename Container::const_iterator const_iterator_type; 00117 00118 explicit MutableIter(container_type& container) // NOLINT 00119 : container_(&container), iterator_(container.begin()) {} 00120 MutableIter(const MutableIter& source) { 00121 container_ = source.container_; 00122 iterator_ = source.iterator_; 00123 } 00124 MutableIter& operator= (const MutableIter& source) { 00125 container_ = source.container_; 00126 iterator_ = source.iterator_; 00127 return *this; 00128 } 00129 bool operator== (const MutableIter& iter) const { 00130 return iterator_ == iter.iterator_; 00131 } 00132 value_type* operator->() const { return iterator_.operator->(); } 00133 value_type& operator*() const { return iterator_.operator*(); } 00134 const container_type* const_container() const { return container_; } 00135 const_iterator_type const_iterator() const { return iterator_; } 00136 container_type* container() const { return container_; } 00137 iterator_type iterator() const { return iterator_; } 00138 MutableIter& operator++() { 00139 ++iterator_; 00140 return *this; 00141 } 00142 MutableIter operator++(int unused) { 00143 MutableIter a = *this; 00144 ++(*this); 00145 return a; 00146 } 00147 bool at_end() const { return iterator_ == container_->end(); } 00148 MutableIter& erase() { 00149 Eraser<Container>::erase(container_, &iterator_); 00150 return *this; 00151 } 00152 private: 00153 container_type* container_; 00154 iterator_type iterator_; 00155 }; 00156 00157 template<class Container> 00158 class ConstReverseIter { 00159 public: 00160 typedef Container container_type; 00161 typedef typename Container::value_type value_type; 00162 typedef typename Container::const_reverse_iterator 00163 const_reverse_iterator_type; 00164 00165 explicit ConstReverseIter(const container_type& container) 00166 : container_(&container), iterator_(container.rbegin()) {} 00167 ConstReverseIter(const ConstReverseIter& source) { 00168 container_ = source.container_; 00169 iterator_ = source.iterator_; 00170 } 00171 ConstReverseIter& operator= (const ConstReverseIter& source) { 00172 container_ = source.container_; 00173 iterator_ = source.iterator_; 00174 return *this; 00175 } 00176 bool operator== (const ConstReverseIter& iter) const { 00177 return iterator_ == iter.iterator_; 00178 } 00179 const value_type* operator->() const { return iterator_.operator->(); } 00180 const value_type& operator*() const { return iterator_.operator*(); } 00181 const container_type* const_container() const { return container_; } 00182 const_reverse_iterator_type const_reverse_iterator() const { 00183 return iterator_; } 00184 ConstReverseIter& operator++() { 00185 ++iterator_; 00186 return *this; 00187 } 00188 ConstReverseIter operator++(int unused) { 00189 ConstReverseIter a = *this; 00190 ++(*this); 00191 return a; 00192 } 00193 bool at_end() const { return iterator_ == container_->rend(); } 00194 00195 private: 00196 const container_type* container_; 00197 const_reverse_iterator_type iterator_; 00198 }; 00199 00200 template<class Container> 00201 class MutableReverseIter { 00202 public: 00203 typedef Container container_type; 00204 typedef typename Container::value_type value_type; 00205 typedef typename Container::reverse_iterator reverse_iterator_type; 00206 typedef typename Container::const_reverse_iterator 00207 const_reverse_iterator_type; 00208 00209 explicit MutableReverseIter(container_type& container) // NOLINT 00210 : container_(&container), iterator_(container.rbegin()) {} 00211 MutableReverseIter(const MutableReverseIter& source) { 00212 container_ = source.container_; 00213 iterator_ = source.iterator_; 00214 } 00215 MutableReverseIter& operator= (const MutableReverseIter& source) { 00216 container_ = source.container_; 00217 iterator_ = source.iterator_; 00218 return *this; 00219 } 00220 bool operator== (const MutableReverseIter& iter) const { 00221 return iterator_ == iter.iterator_; 00222 } 00223 value_type* operator->() const { return iterator_.operator->(); } 00224 value_type& operator*() const { return iterator_.operator*(); } 00225 const container_type* const_container() const { return container_; } 00226 const_reverse_iterator_type const_reverse_iterator() const { 00227 return iterator_; } 00228 container_type* container() const { return container_; } 00229 reverse_iterator_type reverse_iterator() const { return iterator_; } 00230 MutableReverseIter& operator++() { 00231 ++iterator_; 00232 return *this; 00233 } 00234 MutableReverseIter operator++(int unused) { 00235 MutableReverseIter a = *this; 00236 ++(*this); 00237 return a; 00238 } 00239 bool at_end() const { return iterator_ == container_->rend(); } 00240 // erase(reverse_iterator) is not supported by STL containers. 00241 00242 private: 00243 container_type* container_; 00244 reverse_iterator_type iterator_; 00245 }; 00246 00247 // This class performs an iterator-friendly erasure: the element pointed at gets 00248 // removed from the container and the iterator remains valid and points to the 00249 // next element. 00250 // This is only valid for set, multiset, map, multimap and list. 00251 // Vectors and Deques are special cases that need specialized processing 00252 // defined in the specific template classes below. 00253 template<class Container> 00254 class Eraser { 00255 public: 00256 typedef typename Container::iterator iterator_type; 00257 static iterator_type* erase(Container* container, iterator_type* iterator) { 00258 container->erase((*iterator)++); 00259 return iterator; 00260 } 00261 }; 00262 00263 // This version of the Eraser works for vectors 00264 template<class T> class Eraser<std::vector<T> > { 00265 public: 00266 typedef typename std::vector<T>::iterator iterator_type; 00267 static iterator_type* erase(std::vector<T>* container, 00268 iterator_type* iterator) { 00269 *iterator = container->erase(*iterator); 00270 return iterator; 00271 } 00272 }; 00273 00274 // This version of the Eraser works for deques 00275 template<class T> class Eraser<std::deque<T> > { 00276 public: 00277 typedef typename std::deque<T>::iterator iterator_type; 00278 static iterator_type* erase(std::deque<T>* container, 00279 iterator_type* iterator) { 00280 *iterator = container->erase(*iterator); 00281 return iterator; 00282 } 00283 }; 00284 } // namespace operations_research 00285 00286 #endif // OR_TOOLS_BASE_CONCISE_ITERATOR_H_