BWAPI
|
00001 // Copyright (c) 2005 Stanford University (USA). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or 00005 // modify it under the terms of the GNU Lesser General Public License as 00006 // published by the Free Software Foundation; version 2.1 of the License. 00007 // See the file LICENSE.LGPL distributed with CGAL. 00008 // 00009 // Licensees holding a valid commercial license may use this file in 00010 // accordance with the commercial license agreement provided with the software. 00011 // 00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00014 // 00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Kinetic_data_structures/include/CGAL/Kinetic/Active_objects_vector.h $ 00016 // $Id: Active_objects_vector.h 40530 2007-10-04 11:14:00Z drussel $ 00017 // 00018 // 00019 // Author(s) : Daniel Russel <drussel@alumni.princeton.edu> 00020 00021 #ifndef CGAL_KINETIC_NOTIFYING_TABLE_BASE_3_H 00022 #define CGAL_KINETIC_NOTIFYING_TABLE_BASE_3_H 00023 #include <CGAL/Kinetic/basic.h> 00024 #include <CGAL/Tools/Label.h> 00025 #include <CGAL/Kinetic/Ref_counted.h> 00026 #include <CGAL/Tools/Counter.h> 00027 #include <CGAL/Kinetic/internal/debug_counters.h> 00028 #include <iostream> 00029 #include <CGAL/Kinetic/Multi_listener.h> 00030 #include <set> 00031 #include <map> 00032 #include <vector> 00033 #include <sstream> 00034 //#include <boost/iterator/filter_iterator.hpp> 00035 #include <CGAL/iterator.h> 00036 #include <boost/iterator/transform_iterator.hpp> 00037 00038 CGAL_KINETIC_BEGIN_NAMESPACE; 00039 00041 00059 template <class Value_t > 00060 class Active_objects_vector: 00061 public Ref_counted<Active_objects_vector<Value_t > > 00062 { 00063 public: 00064 typedef typename CGAL::Label<Value_t> Key; 00065 typedef Value_t Data; 00066 protected: 00068 typedef Active_objects_vector<Value_t> This; 00069 typedef std::pair<Key, Value_t> Storage_item; 00070 typedef std::vector<Storage_item > Storage; 00071 CGAL_KINETIC_MULTILISTENER1(IS_EDITING); 00072 00073 public: 00074 00076 Active_objects_vector():editing_(false), num_valid_(false){} 00077 00078 ~Active_objects_vector(){CGAL_KINETIC_MULTILISTENER_DESTRUCTOR;} 00079 00081 const Data &operator[](Key key) const 00082 { 00083 CGAL_precondition(key.is_valid()); 00084 CGAL_precondition(storage_[key.index()].first == key); 00085 CGAL_precondition(static_cast<unsigned int>(key.index()) < storage_.size()); 00086 //if (static_cast<unsigned int>(key.index()) >= storage_.size()) return null_object(); 00087 /*else*/ 00088 return storage_[key.index()].second; 00089 } 00090 00092 const Data& at(Key key) const 00093 { 00094 return operator[](key); 00095 } 00096 00098 00102 void set_is_editing(bool is_e) { 00103 if (is_e== editing_) return; 00104 editing_=is_e; 00105 if (!editing_) { 00106 finish_editing(); 00107 } 00108 } 00109 00111 bool is_editing() const 00112 { 00113 return editing_; 00114 } 00115 00117 00130 void set(Key key, const Data &new_value) { 00131 CGAL_precondition(key.is_valid()); 00132 CGAL_precondition(storage_[key.index()].first == key); 00133 //CGAL_precondition(editing_); 00134 //CGAL_precondition(static_cast<unsigned int>(key.index()) < storage_.size()); 00135 if (storage_.size() <= static_cast<unsigned int>(key.index())) { 00136 storage_.resize(key.index()+1); 00137 } 00138 storage_[key.index()].first=key; 00139 storage_[key.index()].second=new_value; 00140 changed_objects_.push_back(key); 00141 CGAL_expensive_assertion_code(for (unsigned int i=0; i< storage_.size(); ++i) ) { 00142 CGAL_expensive_assertion_code(if (key.index() != i && storage_[i].second == storage_[key.index()].second) CGAL_LOG(Log::SOME, "WARNING Objects " << Key(i) << " and " << key << " have equal trajectories.\n")); 00143 } 00144 00145 if (!editing_) finish_editing(); 00146 } 00147 00149 00152 Key insert(const Data &ob) { 00153 //CGAL_precondition(editing_); 00154 storage_.push_back(Storage_item(Key(storage_.size()), ob)); 00155 new_objects_.push_back(storage_.back().first); 00156 00157 CGAL_expensive_assertion_code(for (unsigned int i=0; i< storage_.size()-1; ++i) ) { 00158 00159 CGAL_expensive_assertion_code(if ( storage_[i].second == storage_.back().second) CGAL_LOG(Log::SOME, "WARNING Objects " << Key(i) << " and " << storage_.back().first << " have equal trajectories.\n")); 00160 } 00161 if (!editing_) finish_editing(); 00162 return storage_.back().first; 00163 } 00164 00166 00174 void erase(Key key) { 00175 CGAL_precondition(key.is_valid()); 00176 CGAL_precondition(storage_[key.index()].first == key); 00177 //CGAL_precondition(editing_); 00178 CGAL_precondition(static_cast<unsigned int>(key.index()) < storage_.size()); 00179 CGAL_expensive_precondition_code(for (Inserted_iterator dit= inserted_begin(); dit != inserted_end(); ++dit)) 00180 {CGAL_expensive_precondition(*dit != key);} 00181 CGAL_expensive_precondition_code(for (Changed_iterator dit= changed_begin(); dit != changed_end(); ++dit)) 00182 {CGAL_expensive_precondition(*dit != key);} 00183 deleted_objects_.push_back(key); 00184 if (!editing_) finish_editing(); 00185 } 00186 00188 void clear() { 00189 deleted_objects_.insert(deleted_objects_.end(), keys_begin(), keys_end()); 00190 //storage_.clear(); 00191 if (!editing_) finish_editing(); 00192 } 00193 00194 struct Get_key { 00195 typedef Key result_type; 00196 Key operator()(const Storage_item &o) const { 00197 return o.first; 00198 } 00199 }; 00200 00201 struct Is_ok { 00202 typedef bool result_type; 00203 //typedef const Storage_item& argument_type; 00204 template <class T> 00205 bool operator()(const T& p) const { 00206 return !p->first.is_valid(); 00207 } 00208 }; 00209 00211 typedef CGAL::Filter_iterator<typename Storage::const_iterator, Is_ok> Fiterator; 00212 typedef boost::transform_iterator<Get_key, Fiterator> Key_iterator; 00213 00214 00216 Key_iterator keys_begin() const 00217 { 00218 return Key_iterator(Fiterator(storage_.end(), Is_ok(), storage_.begin()), Get_key()); 00219 } 00221 Key_iterator keys_end() const 00222 { 00223 return Key_iterator(Fiterator(storage_.end(), Is_ok()), Get_key()); 00224 } 00225 00227 00230 typedef typename std::vector<Key>::const_iterator Changed_iterator; 00231 Changed_iterator changed_begin() const 00232 { 00233 return changed_objects_.begin(); 00234 } 00235 Changed_iterator changed_end() const 00236 { 00237 return changed_objects_.end(); 00238 } 00240 00243 typedef typename std::vector<Key>::const_iterator Inserted_iterator; 00245 Inserted_iterator inserted_begin() const 00246 { 00247 return new_objects_.begin(); 00248 } 00250 Inserted_iterator inserted_end() const 00251 { 00252 return new_objects_.end(); 00253 } 00255 00258 typedef typename std::vector<Key>::const_iterator Erased_iterator; 00260 Erased_iterator erased_begin() const 00261 { 00262 return deleted_objects_.begin(); 00263 } 00265 Erased_iterator erased_end() const 00266 { 00267 return deleted_objects_.end(); 00268 } 00270 00275 unsigned int size() const 00276 { 00277 return num_valid_; 00278 } 00279 00280 std::ostream &write(std::ostream &out) const { 00281 for (unsigned int i=0; i< storage_.size(); ++i){ 00282 out << storage_[i].second << std::endl; 00283 } 00284 return out; 00285 } 00286 00287 std::istream &read(std::istream &in) { 00288 if (!storage_.empty()) { 00289 set_is_editing(true); 00290 for (Key_iterator kit= keys_begin(); kit != keys_end(); ++kit){ 00291 erase(*kit); 00292 } 00293 set_is_editing(false); 00294 storage_.clear(); 00295 } 00296 set_is_editing(true); 00297 do { 00298 char buf[10000]; 00299 in.getline(buf, 10000); 00300 if (!in || buf[0]=='\0' || buf[0]=='#') break; 00301 std::istringstream iss(buf); 00302 Data d; 00303 iss >> d; 00304 if (!iss) { 00305 CGAL_ERROR("ERROR reading object from line " << buf); 00306 ++internal::io_errors__; 00307 } else { 00308 //CGAL_LOG(Log::LOTS, "Read " << d << std::endl); 00309 insert(d); 00310 } 00311 } while (true); 00312 set_is_editing(false); 00313 return in; 00314 } 00315 00316 private: 00317 00318 void finish_editing() { 00319 CGAL_KINETIC_MULTINOTIFY(IS_EDITING); 00320 00321 num_valid_+= new_objects_.size(); 00322 num_valid_-= deleted_objects_.size(); 00323 CGAL_assertion(num_valid_ >=0); 00324 for (Erased_iterator it= erased_begin(); it != erased_end(); ++it) { 00325 storage_[it->index()].second=Data(); 00326 storage_[it->index()].first=Key(); 00327 } 00328 00329 changed_objects_.clear(); 00330 deleted_objects_.clear(); 00331 new_objects_.clear(); 00332 } 00333 00334 00335 protected: 00336 00337 Storage storage_; 00338 std::vector<bool> valid_; 00339 std::vector<Key> changed_objects_; 00340 std::vector<Key> deleted_objects_; 00341 std::vector<Key> new_objects_; 00342 bool editing_; 00343 int num_valid_; 00344 00345 /*static const Data &null_object() { 00346 static Data o; 00347 return o; 00348 }*/ 00349 }; 00350 00351 template <class V > 00352 inline std::ostream &operator<<(std::ostream &out, const Active_objects_vector<V> &v) { 00353 return v.write(out); 00354 } 00355 00356 00357 template <class V > 00358 inline std::istream &operator>>(std::istream &in, Active_objects_vector<V> &v) { 00359 return v.read(in); 00360 } 00361 00362 CGAL_KINETIC_END_NAMESPACE; 00363 #endif