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 
00039 #ifndef _depends_dag_h
00040 #define _depends_dag_h
00041 
00042 #include <vector>
00043 #include <algorithm>
00044 #include <boost/iterator/indirect_iterator.hpp>
00045 
00046 #if DEPENDS_SUPPORT_SERIALIZATION
00047 namespace boost { namespace serialization { class access; } }
00048 #include "Details/serialization.hpp"
00049 #endif
00050 
00051 #include "Details/Iterator.h"
00052 #include "Details/Node.h"
00053 #include "Details/CircularReferenceException.h"
00054 #include "Details/ScopedFlag.h"
00055 #include "Details/Visitors.h"
00056 #include "Details/SortPred.h"
00057 #include "Details/Unlinker.h"
00058 
00059 namespace Depends
00060 {
00125         template <class ValueType>
00126         class DAG
00127         {
00128         public :
00129                 
00130                 typedef ValueType value_type;
00131                 typedef ValueType key_type;
00132                 typedef ValueType & reference;
00133                 typedef const ValueType & const_reference;
00134                 typedef ValueType * pointer;
00135                 typedef const ValueType * const_pointer;
00136                 typedef unsigned long score_type;
00137                 typedef Details::Node<ValueType, score_type> node_type;
00138                 typedef std::vector< node_type* > nodes_type;
00139                 typedef Details::Iterator<
00140                         ValueType, 
00141                         const ValueType &, 
00142                         const ValueType *, 
00143                         score_type, 
00144                         typename nodes_type::iterator> iterator;
00145                 typedef Details::Iterator<
00146                         ValueType, 
00147                         const ValueType &,
00148                         const ValueType *,
00149                         score_type,
00150                         typename nodes_type::iterator> const_iterator;
00151                 typedef Details::ReverseIterator<
00152                         ValueType,
00153                         const ValueType &,
00154                         const ValueType *,
00155                         score_type,
00156                         typename nodes_type::reverse_iterator> reverse_iterator;
00157                 typedef Details::ReverseIterator<
00158                         ValueType,
00159                         const ValueType &,
00160                         const ValueType *,
00161                         score_type,
00162                         typename nodes_type::reverse_iterator>
00163                                 const_reverse_iterator;
00164                 typedef typename std::vector<node_type>::difference_type
00165                         difference_type;
00166                 typedef typename std::vector<node_type>::size_type size_type;
00167 
00170                 typedef Details::CircularReferenceException
00171                         circular_reference_exception;
00172 
00174                 DAG()
00175                 {  }
00177                 DAG(const DAG & d)
00178                         : nodes_(d.nodes)
00179                 {  }
00180         
00182 
00188                 template <typename InputIterator>
00189                 DAG(InputIterator first, InputIterator last)
00190                 {
00191                         insert(first, last);
00192                 }
00193         
00195                 DAG & operator=(const DAG & d)
00196                 {
00197                         nodes_ = d.nodes_;
00198                         return *this;
00199                 }
00200 
00201                 ~DAG()
00202                 {
00203                         for (typename nodes_type::iterator iter = nodes_.begin(); iter != nodes_.end(); ++iter)
00204                                 delete *iter;
00205                 }
00206         
00208                 iterator begin() { return iterator(nodes_.begin()); }
00210                 const_iterator begin() const { return const_iterator(nodes_.begin()); }
00212                 reverse_iterator rbegin() { return reverse_iterator(nodes_.rbegin()); }
00214                 const_reverse_iterator rbegin() const { return const_reverse_iterator(nodes_.rbegin()); }
00215 
00217                 iterator end() { return iterator(nodes_.end()); }
00219                 const_iterator end() const { return const_iterator(nodes_.end()); }
00221                 reverse_iterator rend() { return reverse_iterator(nodes_.rend()); }
00223                 const_reverse_iterator rend() const { return const_reverse_iterator(nodes_.rend()); }
00224 
00226                 size_type size() const { return nodes_.size(); }
00228                 size_type max_size() const { return sizeof(score_type) > sizeof(size_type) ? (size_type)~0 : (score_type)~0; }
00229 
00231                 bool empty() const { return nodes_.empty(); }
00233                 void swap(DAG & d) { nodes_.swap(d.nodes_); }
00234 
00236                 bool operator==(const DAG & d) const
00237                 {
00238                         return (nodes_.size() == d.nodes_.size()) && 
00239                                 std::equal(
00240                                         boost::indirect_iterator< typename nodes_type::const_iterator >(nodes_.begin()),
00241                                         boost::indirect_iterator< typename nodes_type::const_iterator >(nodes_.end()),
00242                                         boost::indirect_iterator< typename nodes_type::const_iterator >(d.nodes_.begin()));
00243                         
00244                 }
00246                 bool operator!=(const DAG & d) const
00247                 {
00248                         return !(*this == d);
00249                 }
00250 
00252                 bool operator<(const DAG & d) const
00253                 {
00254                         return std::lexicographical_compare(
00255                                 boost::indirect_iterator< typename nodes_type::const_iterator >(nodes_.begin()),
00256                                 boost::indirect_iterator< typename nodes_type::const_iterator >(nodes_.end()),
00257                                 boost::indirect_iterator< typename nodes_type::const_iterator >(d.nodes_.begin()),
00258                                 boost::indirect_iterator< typename nodes_type::const_iterator >(d.nodes_.end()),
00259                                 Details::CompareNodesByContents< node_type >()
00260                                 );
00261                 }
00263                 bool operator>(const DAG & d) const { return d < *this; }
00264                 
00266                 bool operator<=(const DAG & d) const { return !(d < *this); }
00268                 bool operator>=(const DAG & d) const { return !(*this < d); }
00269 
00278                 std::pair<iterator, bool> insert(const value_type & val)
00279                 {
00280                         if (std::find_if(nodes_.begin(), nodes_.end(), Details::ValueCompare<node_type>(val)) == nodes_.end())
00281                         {
00282                                 nodes_.insert(nodes_.begin(), new node_type(val));
00283                                 return std::make_pair(begin(), true);
00284                         }
00285                         else
00286                                 return std::make_pair(end(), false);
00287                 }
00288 
00292                 template <typename InputIterator>
00293                 void insert(InputIterator first, InputIterator last)
00294                 {
00295                         for ( ; first != last; ++first)
00296                                 insert(*first);
00297                 }
00298         
00305                 void link(iterator source, iterator target)
00306                 {
00307                         {
00308                                 Details::ScopedFlag<node_type> scoped_flag(source.node(), node_type::VISITED);
00309                                 Details::NodeVisitor<node_type>()(target.node());
00310                         }
00311                         source.node()->targets_.push_back(target.node());
00312 
00313                         
00314                         Details::IncScoreFunctor dag_node_inc_score_functor;
00315                         Details::NodeVisitor<node_type, Details::IncScoreFunctor, score_type>(dag_node_inc_score_functor, source.node()->score_)(target.node());
00316 
00317                         std::sort(nodes_.begin(), nodes_.end(), Details::SortPred<node_type>());
00318                 }
00319 
00326                 void link(iterator source, value_type target)
00327                 {
00328                         iterator target_iter = std::find(begin(), end(), target);
00329 
00330                         if (target_iter == end())
00331                                 throw std::invalid_argument("value not found");
00332                         link(source, target_iter);
00333                 }
00334 
00341                 void link(value_type source, iterator target)
00342                 {
00343                         iterator source_iter = std::find(begin(), end(), source);
00344 
00345                         if (source_iter == end())
00346                                 throw std::invalid_argument("value not found");
00347                         link(source_iter, target);
00348                 }
00349 
00355                 void link(value_type source, value_type target)
00356                 {
00357                         iterator source_iter = std::find(begin(), end(), source);
00358                         iterator target_iter = std::find(begin(), end(), target);
00359 
00360                         if (source_iter == end() || target_iter == end())
00361                                 throw std::invalid_argument("value not found");
00362                         link(source_iter, target_iter);
00363                 }
00364 
00366                 bool linked(iterator source, iterator target) const
00367                 {
00368                         try
00369                         {
00370                                 Details::ScopedFlag<node_type> scoped_flag(target.node(), node_type::VISITED);
00371                                 Details::NodeVisitor<node_type>()(source.node());
00372                         }
00373                         catch (circular_reference_exception &)
00374                         {
00375                                 return true;
00376                         }
00377 
00378                         return false;
00379                 }
00380 
00382                 bool linked(iterator source, value_type target) const
00383                 {
00384                         iterator target_iter = std::find(begin(), end(), target);
00385 
00386                         if (target_iter == end())
00387                                 return false;
00388                         return linked(source, target_iter);
00389                 }
00390 
00392                 bool linked(value_type source, iterator target) const
00393                 {
00394                         iterator source_iter = std::find(begin(), end(), source);
00395 
00396                         if (source_iter == end())
00397                                 return false;
00398                         return linked(source_iter, target);
00399                 }
00400 
00402                 bool linked(value_type source, value_type target) const
00403                 {
00404                         iterator source_iter = std::find(begin(), end(), source);
00405                         iterator target_iter = std::find(begin(), end(), target);
00406 
00407                         if (source_iter == end() || target_iter == end())
00408                                 return false;
00409                         return linked(source_iter, target_iter);
00410                 }
00411 
00413                 bool unlink(iterator source, iterator target)
00414                 {
00415                         bool rv(true);
00416                         typename node_type::targets_type::iterator where(std::find(source.node()->targets_.begin(), source.node()->targets_.end(), target.node()));
00417                         if (where != source.node()->targets_.end())
00418                                 source.node()->targets_.erase(where);
00419                         else
00420                                 rv = false;
00421 
00422                         
00423                         Details::DecScoreFunctor dag_node_dec_score_functor;
00424                         Details::NodeVisitor<node_type, Details::DecScoreFunctor, score_type>(dag_node_dec_score_functor, source.node()->score_)(target.node());
00425 
00426                         std::sort(nodes_.begin(), nodes_.end());
00427 
00428                         return rv;
00429                 }
00430 
00432                 bool unlink(iterator source, value_type target)
00433                 {
00434                         iterator target_iter = std::find(begin(), end(), target);
00435 
00436                         if (target_iter == end())
00437                                 throw std::invalid_argument("value not found");
00438                         return unlink(source, target_iter);
00439                 }
00440 
00442                 bool unlink(value_type source, iterator target)
00443                 {
00444                         iterator source_iter = std::find(begin(), end(), source);
00445 
00446                         if (source_iter == end())
00447                                 throw std::invalid_argument("value not found");
00448                         return unlink(source_iter, target);
00449                 }
00450 
00452                 bool unlink(value_type source, value_type target)
00453                 {
00454                         iterator source_iter = std::find(begin(), end(), source);
00455                         iterator target_iter = std::find(begin(), end(), target);
00456 
00457                         if (source_iter == end() || target_iter == end())
00458                                 throw std::invalid_argument("value not found");
00459                         return unlink(source_iter, target_iter);
00460                 }
00461 
00465                 iterator erase(iterator where)
00466                 {
00467                         while (!where.node()->targets_.empty())
00468                                 unlink(where, (where.node()->targets_[0])->value_);
00469                         std::for_each(nodes_.begin(), nodes_.end(), Details::Unlinker<node_type>(where.node()));
00470 
00471                         delete where.node();
00472                         typename nodes_type::iterator whence(nodes_.erase(where.iter_));
00473 
00474                         return iterator(whence);
00475                 }
00476         
00482                 iterator erase(iterator begin, iterator end)
00483                 {
00484                         iterator retval = begin;
00485                         
00486                         for (iterator where(begin); where != end; ++where)
00487                                 delete where.node();
00488                         return iterator(nodes_.erase(begin.iter_, end.iter_));
00489                 }
00490 
00494                 void clear()
00495                 {
00496                         erase(begin(), end());
00497                 }
00498                 
00499         private :
00500 #if DEPENDS_SUPPORT_SERIALIZATION
00501                 template < typename Archive >
00502                 void serialize( Archive & ar, const unsigned int version )
00503                 {
00504                         ar & boost::serialization::make_nvp("nodes_", nodes_);
00505                 }
00506 #endif
00507 
00508                 mutable nodes_type nodes_;
00509 
00510 #if DEPENDS_SUPPORT_SERIALIZATION
00511                 friend class boost::serialization::access;
00512 #endif
00513         };
00514 }
00515 
00516 #if DEPENDS_USE_DEPRECATED_NAMES
00517 namespace rlc
00518 {
00519         using namespace Depends;
00520         template < typename ValueType >
00521         struct dag : public Depends::DAG< ValueType >
00522         {  };
00523 }
00524 #endif
00525 
00526 #endif
00527