00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00035 #ifndef _depends_depends_h
00036 #define _depends_depends_h
00037
00038 #include <algorithm>
00039 #include <cassert>
00040 #include <set>
00041 #include "DAG.h"
00042
00043 namespace Depends
00044 {
00100 template < typename ValueType >
00101 class Depends
00102 {
00103
00104 typedef std::set< ValueType > Storage;
00105 public :
00107 typedef typename Storage::iterator iterator;
00109 typedef typename Storage::const_iterator const_iterator;
00111 typedef typename Storage::reverse_iterator reverse_iterator;
00113 typedef typename Storage::const_reverse_iterator const_reverse_iterator;
00114
00116 typedef typename std::iterator_traits< iterator >::value_type value_type;
00118 typedef typename std::iterator_traits< iterator >::reference reference;
00120 typedef typename std::iterator_traits< const_iterator >::reference const_reference;
00122 typedef typename std::iterator_traits< iterator >::pointer pointer;
00124 typedef typename std::iterator_traits< iterator >::difference_type difference_type;
00126 typedef typename Storage::size_type size_type;
00127
00129 Depends()
00130 : selected_(0)
00131 { }
00133 template < typename InputIterator >
00134 Depends(InputIterator begin, InputIterator end)
00135 : selected_(0)
00136 { insert(begin, end); }
00137
00139 bool empty() const throw()
00140 { return storage_.empty(); }
00141 size_type size() const throw()
00142 { return storage_.size(); }
00143
00145 iterator begin()
00146 { return iterator(storage_.begin()); }
00148 const_iterator begin() const
00149 { return const_iterator(storage_.begin()); }
00151 iterator end()
00152 { return iterator(storage_.end()); }
00154 const_iterator end() const
00155 { return const_iterator(storage_.end()); }
00157 reverse_iterator rbegin()
00158 { return reverse_iterator(storage_.rbegin()); }
00160 const_reverse_iterator rbegin() const
00161 { return const_reverse_iterator(storage_.rbegin()); }
00163 reverse_iterator rend()
00164 { return reverse_iterator(storage_.rend()); }
00166 const_reverse_iterator rend() const
00167 { return const_reverse_iterator(storage_.rend()); }
00168
00170 template < typename V >
00171 const_iterator find(const V & v) const throw()
00172 { return storage_.find(v); }
00173 template < typename V >
00174 iterator find(const V & v) throw()
00175 { return storage_.find(v); }
00176
00178 template < typename InputIterator >
00179 void insert(InputIterator begin, InputIterator end)
00180 {
00181 for (InputIterator where(begin); where != end; ++where)
00182 insert(*where);
00183 }
00185 std::pair< iterator, bool > insert( const value_type & v )
00186 {
00187 std::pair< iterator, bool > retval(storage_.insert(v));
00188 if (retval.second)
00189 {
00190 prerequisites_.insert(getPointer(retval.first));
00191 dependants_.insert(getPointer(retval.first));
00192 }
00193 else
00194 { }
00195
00196 return retval;
00197 }
00199 iterator insert( const iterator & where, const value_type & what )
00200 { return insert(what).first; }
00201
00203 template < typename V >
00204 size_type erase(const V & v)
00205 {
00206 size_type erased(0);
00207 iterator where;
00208 while ((where = find(v)) != end())
00209 {
00210 erase(where);
00211 ++erased;
00212 }
00213
00214 return erased;
00215 }
00216
00217 void erase(iterator where)
00218 {
00219 if (selected_)
00220 {
00221 if (where == *selected_)
00222 clearSelection();
00223 else
00224 { }
00225 }
00226 else
00227 { }
00228 pointer p(getPointer(where));
00229 bool found_in_blockers(false);
00230 typename DAG< pointer >::iterator whence(std::find(dependants_.begin(), dependants_.end(), p));
00231 if (whence != dependants_.end())
00232 {
00233 dependants_.erase(whence);
00234 found_in_blockers = true;
00235 }
00236 else
00237 { }
00238 whence = std::find(prerequisites_.begin(), prerequisites_.end(), p);
00239 if (whence != prerequisites_.end())
00240 {
00241 prerequisites_.erase(whence);
00242 assert(found_in_blockers);
00243 }
00244 else
00245 {
00246 assert(!found_in_blockers);
00247 }
00248 storage_.erase(where);
00249 }
00250
00251 void erase(const iterator & begin, const iterator & end)
00252 {
00253 for (iterator where(begin); where != end; erase(where++))
00254 ;
00255 }
00256
00257 void clear()
00258 {
00259 clearSelection();
00260 dependants_.clear();
00261 prerequisites_.clear();
00262 storage_.clear();
00263 }
00264
00267 void select(const_iterator what)
00268 {
00269 clearSelection();
00270 if (what == end())
00271 throw std::invalid_argument("Cannot select end");
00272 else
00273 { }
00274 selected_ = new const_iterator(what);
00275 }
00279 void select(const value_type & v)
00280 {
00281 select(insert(v).first);
00282 }
00283
00285 void addPrerequisite(const_iterator whence)
00286 {
00287 assert(selected_);
00288 prerequisites_.link(getPointer(*selected_), getPointer(whence));
00289 dependants_.link(getPointer(whence), getPointer(*selected_));
00290 }
00292 void addPrerequisite(const value_type & v)
00293 {
00294 addPrerequisite(insert(v).first);
00295 }
00298 void removePrerequisite(const_iterator whence)
00299 {
00300 assert(selected_);
00301 if (whence == end())
00302 return;
00303 else
00304 { }
00305 bool was_prereq(prerequisites_.unlink(getPointer(*selected_), getPointer(whence)));
00306 bool was_dep(dependants_.unlink(getPointer(whence), getPointer(*selected_)));
00307 assert((was_dep && was_prereq) || (!was_dep && !was_prereq));
00308 }
00311 void removePrerequisite(const value_type & value)
00312 {
00313 removePrerequisite(find(value));
00314 }
00319 std::set< value_type > getPrerequisites(bool all = false) const
00320 {
00321 std::set< value_type > retval;
00322 typename DAG< pointer >::const_iterator selected(std::find(prerequisites_.begin(), prerequisites_.end(), getPointer(*selected_)));
00323 const typename DAG< pointer >::node_type * selected_node(selected.node());
00324 if (all)
00325 {
00326 typedef Details::NodeVisitor< typename DAG< pointer >::node_type, Details::RetrieveTargets, std::set< pointer > * > Visitor;
00327 std::set< pointer > temp;
00328 Visitor visitor(Details::RetrieveTargets(), &temp);
00329 std::for_each(
00330 selected_node->targets_.begin(),
00331 selected_node->targets_.end(),
00332 visitor);
00333 std::copy(
00334 boost::indirect_iterator< typename std::set< pointer >::const_iterator >(temp.begin()),
00335 boost::indirect_iterator< typename std::set< pointer >::const_iterator >(temp.end()),
00336 std::inserter(retval, retval.begin()));
00337 }
00338 else
00339 {
00340 typename DAG< pointer >::node_type::targets_type::const_iterator end(selected_node->targets_.end());
00341 typename DAG< pointer >::node_type::targets_type::const_iterator where(selected_node->targets_.begin());
00342 while (where != end)
00343 {
00344 retval.insert(*((*where)->value_));
00345 ++where;
00346 }
00347 }
00348
00349 return retval;
00350 }
00351
00353 void addDependant(const_iterator whence)
00354 {
00355 assert(selected_);
00356 dependants_.link(getPointer(*selected_), getPointer(whence));
00357 prerequisites_.link(getPointer(whence), getPointer(*selected_));
00358 }
00360 void addDependant(const value_type & v)
00361 {
00362 addDependant(insert(v).first);
00363 }
00366 void removeDependant(const_iterator whence)
00367 {
00368 assert(selected_);
00369 if (whence == end())
00370 return;
00371 else
00372 { }
00373 dependants_.unlink(getPointer(*selected_), getPointer(whence));
00374 prerequisites_.unlink(getPointer(whence), getPointer(*selected_));
00375 }
00378 void removeDependant(const value_type & value)
00379 {
00380 removeDependant(find(value));
00381 }
00386 std::set< value_type > getDependants(bool all = false) const
00387 {
00388 std::set< value_type > retval;
00389 typename DAG< pointer >::const_iterator selected(std::find(dependants_.begin(), dependants_.end(), getPointer(*selected_)));
00390 const typename DAG< pointer >::node_type * selected_node(selected.node());
00391 if (all)
00392 {
00393 typedef Details::NodeVisitor< typename DAG< pointer >::node_type, Details::RetrieveTargets, std::set< pointer > * > Visitor;
00394 std::set< pointer > temp;
00395 Visitor visitor(Details::RetrieveTargets(), &temp);
00396 std::for_each(
00397 selected_node->targets_.begin(),
00398 selected_node->targets_.end(),
00399 visitor);
00400 std::copy(
00401 boost::indirect_iterator< typename std::set< pointer >::const_iterator >(temp.begin()),
00402 boost::indirect_iterator< typename std::set< pointer >::const_iterator >(temp.end()),
00403 std::inserter(retval, retval.begin()));
00404 }
00405 else
00406 {
00407 typename DAG< pointer >::node_type::targets_type::const_iterator end(selected_node->targets_.end());
00408 typename DAG< pointer >::node_type::targets_type::const_iterator where(selected_node->targets_.begin());
00409 while (where != end)
00410 {
00411 retval.insert(*((*where)->value_));
00412 ++where;
00413 }
00414 }
00415
00416 return retval;
00417 }
00418
00419
00421 bool depends(const_iterator target, const_iterator source) const
00422 {
00423 if (target == end() || source == end())
00424 return false;
00425 else
00426 { }
00427
00428
00429
00430 #ifndef NDEBUG
00431 assert(
00432 (dependants_.linked(getPointer(source), getPointer(target)) && prerequisites_.linked(getPointer(target), getPointer(source))) ||
00433 ((!dependants_.linked(getPointer(source), getPointer(target))) && (!prerequisites_.linked(getPointer(target), getPointer(source)))));
00434 #endif
00435 return dependants_.linked(getPointer(source), getPointer(target));
00436 }
00438 bool depends(const_iterator target, const value_type & source) const
00439 {
00440 return depends(target, find(source));
00441 }
00443 bool depends(const value_type & target, const_iterator source) const
00444 {
00445 return depends(find(target), source);
00446 }
00448 bool depends(const value_type & target, const value_type & source) const
00449 {
00450 return depends(find(target), find(source));
00451 }
00452
00453 private :
00454
00455 Depends(const Depends &);
00456 Depends & operator=(const Depends &);
00457
00460 void clearSelection()
00461 {
00462 delete selected_;
00463 selected_ = 0;
00464 }
00465
00466 static pointer getPointer(const_iterator i)
00467 {
00468 return const_cast< pointer >(&(*i));
00469 }
00470
00471 #if DEPENDS_SUPPORT_SERIALIZATION
00472 template < typename Archive >
00473 void serialize( Archive & ar, const unsigned int version )
00474 {
00475 ar & boost::serialization::make_nvp("storage_", storage_)
00476 & boost::serialization::make_nvp("dependants_", dependants_)
00477 & boost::serialization::make_nvp("prerequisites_", prerequisites_)
00478 ;
00479 }
00480 #endif
00481
00482 Storage storage_;
00483 DAG< pointer > dependants_;
00484 DAG< pointer > prerequisites_;
00489 const_iterator * selected_;
00490
00491 #if DEPENDS_SUPPORT_SERIALIZATION
00492 friend class boost::serialization::access;
00493 #endif
00494 };
00495 }
00496
00497 #endif