bmig_graph_impl.hxx

00001 // boost_graph.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2007, 2008 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 
00018 #ifndef VCSN_AUTOMATA_IMPLEMENTATION_BMIG_GRAPH_IMPL_HXX_
00019 # define VCSN_AUTOMATA_IMPLEMENTATION_BMIG_GRAPH_IMPL_HXX_
00020 
00021 # include <vaucanson/automata/implementation/bmig_graph_impl.hh>
00022 
00023 namespace vcsn
00024 {
00025   namespace bmig
00026   {
00027 
00028     /*--------------------.
00029     | Convenient macros.  |
00030     `--------------------*/
00031 
00032 # define BMIGRAPH_TPARAM                                                \
00033     template <class Kind, class WordValue, class WeightValue,           \
00034               class SeriesValue, class Letter, class Tag, class GeometryCoords>
00035 
00036 # define BMIGRAPH                                                       \
00037     Graph<Kind, WordValue, WeightValue, SeriesValue, Letter, Tag, GeometryCoords>
00038 
00039     /*-------------------------.
00040     | Graph's implementation.  |
00041     `-------------------------*/
00042 
00043     /*---------------.
00044     | Constructors.  |
00045     `---------------*/
00046 
00047     BMIGRAPH_TPARAM
00048     BMIGRAPH::Graph ()
00049       : initial_bitset_(0),
00050         final_bitset_(0),
00051         number_of_epsilon_(0),
00052         number_of_state_(0)
00053     {
00054     }
00055 
00065     BMIGRAPH_TPARAM
00066     BMIGRAPH::Graph (unsigned initial_number_of_states,
00067                       unsigned)
00068       : initial_bitset_(initial_number_of_states),
00069         final_bitset_(initial_number_of_states),
00070         number_of_epsilon_(0),
00071         number_of_state_(initial_number_of_states),
00072         states_(initial_number_of_states)
00073     {
00074       for (unsigned i = 0; i < initial_number_of_states; ++i)
00075       {
00076         boost::shared_ptr<std::size_t> p(new std::size_t(i));
00077         states_[i] = p;
00078       }
00079     }
00080 
00081     BMIGRAPH_TPARAM
00082     BMIGRAPH::Graph (const self_t& g)
00083     {
00084       tag_ = g.tag_;
00085       initial_bitset_ = g.initial_bitset_;
00086       final_bitset_ = g.final_bitset_;
00087       number_of_epsilon_ = g.number_of_epsilon_;
00088       number_of_state_ = g.number_of_state_;
00089       label_container_ = g.label_container_;
00090       initial_.clear();
00091       final_.clear();
00092       states_.resize(g.number_of_state_);
00093       for (unsigned i = 0; i < g.number_of_state_; ++i)
00094       {
00095         boost::shared_ptr<std::size_t> p(new std::size_t(i));
00096         states_[i] = p;
00097       }
00098       graph_.clear();
00099       for (typename graph_data_t::const_iterator i = g.graph_.begin();
00100           i != g.graph_.end();
00101           ++i)
00102         graph_.insert(edge_data_t(states_[*i->from_],
00103                                   states_[*i->to_],
00104                                   i->label_));
00105 //                                label_container_.get_hlabel(g.label_container_.get_label(i->label_))));
00106   # define VCSN_COPY_I_T(Set)                                                                   \
00107       for (typename Set##t::const_iterator i = g.Set.begin();                                   \
00108           i != g.Set.end();                                                                     \
00109           ++i)                                                                                  \
00110         Set.insert(initial_value_t (states_[*i->first], i->second));
00111       VCSN_COPY_I_T(initial_)
00112       VCSN_COPY_I_T(final_)
00113   # undef VCSN_COPY_I_T
00114 
00115   # define VCSN_COPY_GEOMETRY(Type)                                                                     \
00116       {                                                                                                 \
00117         typename geometry_t::Type##_geometry_map_t& map_##Type = geometry_.Type();                      \
00118         map_##Type.clear();                                                                             \
00119         for (typename geometry_t::Type##_geometry_map_t::const_iterator i = g.geometry_.Type().begin(); \
00120             i != g.geometry_.Type().end();                                                              \
00121             ++i)                                                                                                \
00122         map_##Type[i->first] = i->second;                                                               \
00123       }
00124       VCSN_COPY_GEOMETRY(states)
00125       VCSN_COPY_GEOMETRY(initials)
00126       VCSN_COPY_GEOMETRY(finals)
00127 # undef VCSN_COPY_GEOMETRY
00128       {
00129         typename geometry_t::transitions_geometry_map_t& map_transitions = geometry_.transitions();
00130         map_transitions.clear();
00131         for (typename geometry_t::transitions_geometry_map_t::const_iterator i = g.geometry_.transitions().begin();
00132             i != g.geometry_.transitions().end();
00133             ++i)
00134         {
00135           typename graph_data_t::const_iterator tmp = find_edge(states_[*i->first.value()->from_],
00136               states_[*i->first.value()->to_],
00137               i->first.value()->label_);
00138           //label_container_.get_hlabel(g.label_container_.get_label(i->first.value()->label_)));
00139           if (tmp != graph_.end())
00140             map_transitions[htransition_t(tmp)] = i->second;
00141         }
00142       }
00143     }
00144 
00145     /*--------------.
00146     | Destructors.  |
00147     `--------------*/
00148 
00149     BMIGRAPH_TPARAM
00150     BMIGRAPH::~Graph ()
00151     {
00152     }
00153 
00154     BMIGRAPH_TPARAM
00155     typename BMIGRAPH::self_t&
00156     BMIGRAPH::operator= (const self_t& g)
00157     {
00158       if (this == &g)
00159         return *this;
00160       tag_ = g.tag_;
00161       initial_bitset_ = g.initial_bitset_;
00162       final_bitset_ = g.final_bitset_;
00163       number_of_epsilon_ = g.number_of_epsilon_;
00164       number_of_state_ = g.number_of_state_;
00165       label_container_ = g.label_container_;
00166       initial_.clear();
00167       final_.clear();
00168       states_.resize(g.number_of_state_);
00169       for (unsigned i = 0; i < g.number_of_state_; ++i)
00170       {
00171         boost::shared_ptr<std::size_t> p(new std::size_t(i));
00172         states_[i] = p;
00173       }
00174       graph_.clear();
00175       for (typename graph_data_t::const_iterator i = g.graph_.begin();
00176           i != g.graph_.end();
00177           ++i)
00178         graph_.insert(edge_data_t(states_[*i->from_],
00179               states_[*i->to_],
00180               i->label_));
00181 # define VCSN_COPY_I_T(Set)                                                                     \
00182       for (typename Set##t::const_iterator i = g.Set.begin();                                   \
00183           i != g.Set.end();                                                                     \
00184           ++i)                                                                                  \
00185       Set.insert(initial_value_t (states_[*i->first], i->second));
00186       VCSN_COPY_I_T(initial_)
00187       VCSN_COPY_I_T(final_)
00188 # undef VCSN_COPY_I_T
00189 
00190 # define VCSN_COPY_GEOMETRY(Type)                                                                       \
00191       {                                                                                                 \
00192         typename geometry_t::Type##_geometry_map_t& map_##Type = geometry_.Type();                      \
00193         map_##Type.clear();                                                                             \
00194         for (typename geometry_t::Type##_geometry_map_t::const_iterator i = g.geometry_.Type().begin(); \
00195             i != g.geometry_.Type().end();                                                              \
00196             ++i)                                                                                                \
00197         map_##Type[i->first] = i->second;                                                               \
00198       }
00199       VCSN_COPY_GEOMETRY(states)
00200       VCSN_COPY_GEOMETRY(initials)
00201       VCSN_COPY_GEOMETRY(finals)
00202 # undef VCSN_COPY_GEOMETRY
00203       {
00204         typename geometry_t::transitions_geometry_map_t& map_transitions = geometry_.transitions();
00205         map_transitions.clear();
00206         for (typename geometry_t::transitions_geometry_map_t::const_iterator i = g.geometry_.transitions().begin();
00207             i != g.geometry_.transitions().end();
00208             ++i)
00209         {
00210           typename graph_data_t::const_iterator tmp = find_edge(states_[*i->first.value()->from_],
00211               states_[*i->first.value()->to_],
00212               i->first.value()->label_);
00213           //label_container_.get_hlabel(g.label_container_.get_label(i->first.value()->label_)));
00214           if (tmp != graph_.end())
00215             map_transitions[htransition_t(tmp)] = i->second;
00216         }
00217       }
00218       return *this;
00219     }
00220 
00221     /*------------------.
00222     | Basic accessors.  |
00223     `------------------*/
00224 
00225     BMIGRAPH_TPARAM
00226     typename BMIGRAPH::states_t
00227     BMIGRAPH::states() const
00228     {
00229       return misc::Support<states_data_t>(states_);
00230     }
00231 
00232     BMIGRAPH_TPARAM
00233     typename BMIGRAPH::edges_t
00234     BMIGRAPH::edges() const
00235     {
00236       return edges_t(graph_);
00237     }
00238 
00239     BMIGRAPH_TPARAM
00240     typename BMIGRAPH::initial_support_t
00241     BMIGRAPH::initial () const
00242     {
00243       return initial_support_t(initial_);
00244     }
00245 
00246     BMIGRAPH_TPARAM
00247     typename BMIGRAPH::final_support_t
00248     BMIGRAPH::final () const
00249     {
00250       return final_support_t(final_);
00251     }
00252 
00253 
00254     /*----------------------.
00255     | State manipulations.  |
00256     `----------------------*/
00257 
00258     BMIGRAPH_TPARAM
00259     bool
00260     BMIGRAPH::has_state (const hstate_t& s) const
00261     {
00262       // May be we should add a set or a hashtable to have
00263       // a searching time better than linear
00264       bool b = false;
00265       for_all_iterator(states_data_t::const_iterator, i, states_)
00266         if (*i == s.value())
00267           b = true;
00268       return b;
00269     }
00270 
00271     BMIGRAPH_TPARAM
00272     typename BMIGRAPH::hstate_t
00273     BMIGRAPH::add_state ()
00274     {
00275       initial_bitset_.append(false);
00276       final_bitset_.append(false);
00277       boost::shared_ptr<std::size_t> p(new std::size_t(number_of_state_++));
00278       state_t h(p);
00279       states_.push_back(h);
00280       return hstate_t(h);
00281     }
00282 
00283     BMIGRAPH_TPARAM
00284     typename BMIGRAPH::hstate_t
00285     BMIGRAPH::get_state (unsigned s) const
00286     {
00287       precondition(s < states_.size());
00288       return hstate_t(states_[s]);
00289     }
00290 
00291     BMIGRAPH_TPARAM
00292     void
00293     BMIGRAPH::del_state (const hstate_t& s)
00294     {
00295       precondition (has_state(s));
00296 
00297       // One removes the state h
00298       graph_.template get<src>().erase(s.value());
00299       graph_.template get<dst>().erase(s.value());
00300 
00301       if (s != (number_of_state_ - 1) && (number_of_state_ - 1))
00302       {
00303         state_t lastone = states_.back();
00304         states_[s] = lastone;
00305   # define VCSN_UPDATE(Set)                                   \
00306         if (Set##bitset_[*lastone])                           \
00307         {                                                     \
00308           if (Set##bitset_[s])                                \
00309             Set.erase(s.value());                             \
00310           else                                                \
00311             Set##bitset_[s] = true;                           \
00312         }                                                     \
00313         else                                                  \
00314         {                                                     \
00315           if (Set##bitset_[s])                                \
00316           {                                                   \
00317             Set##bitset_[s] = false;                          \
00318             Set.erase(s.value());                             \
00319           }                                                   \
00320         }
00321 
00322         //Updating initial/final states information
00323         VCSN_UPDATE(initial_)
00324         VCSN_UPDATE(final_)
00325   # undef VCSN_UPDATE
00326         *lastone = *s.value();
00327       }
00328       else
00329       {
00330         initial_.erase(s.value());
00331         final_.erase(s.value());
00332       }
00333 
00334       --number_of_state_;
00335       states_.pop_back();
00336       postcondition(states_.size() == number_of_state_);
00337       //delete s.value();
00338       initial_bitset_.resize(number_of_state_);
00339       final_bitset_.resize(number_of_state_);
00340 
00341       //Useless postcondition since the states are 'renamed'
00342       //postcondition(!has_state(h));
00343     }
00344 
00345     BMIGRAPH_TPARAM
00346     void
00347     BMIGRAPH::set_initial (const hstate_t& s,
00348                            const series_set_elt_value_t& v,
00349                            const series_set_elt_value_t& z)
00350     {
00351       precondition(has_state(s));
00352       if (z == v)
00353       {
00354         initial_.erase (s.value());
00355         initial_bitset_[s] = false;
00356       }
00357       else if (!initial_bitset_[s])
00358       {
00359         initial_.insert (initial_value_t (s.value(), v));
00360         initial_bitset_[s] = true;
00361       }
00362       else
00363         initial_.modify(initial_.find(s.value()), update_label<initial_value_t>(v));
00364     }
00365 
00366     BMIGRAPH_TPARAM
00367     const typename BMIGRAPH::series_set_elt_value_t&
00368     BMIGRAPH::get_initial(const hstate_t& s, const series_set_elt_value_t &zero) const
00369     {
00370       precondition(has_state(s));
00371       typename initial_t::const_iterator it = initial_.find(s.value());
00372 
00373       if (it == initial_.end())
00374         return zero;
00375       return it->second;
00376     }
00377 
00378     BMIGRAPH_TPARAM
00379     bool
00380     BMIGRAPH::is_initial(const hstate_t& s, const series_set_elt_value_t&) const
00381     {
00382       precondition(has_state(s));
00383       return initial_bitset_[s];
00384     }
00385 
00386     BMIGRAPH_TPARAM
00387     void
00388     BMIGRAPH::clear_initial()
00389     {
00390       initial_.clear();
00391       initial_bitset_.reset();
00392     }
00393 
00394     BMIGRAPH_TPARAM
00395     void
00396     BMIGRAPH::set_final(const hstate_t& s,
00397                           const series_set_elt_value_t& v,
00398                           const series_set_elt_value_t& z)
00399     {
00400       precondition(has_state(s));
00401       if (z == v)
00402       {
00403         final_.erase (s.value());
00404         final_bitset_[s] = false;
00405       }
00406       else if (!final_bitset_[s])
00407       {
00408         final_.insert (initial_value_t (s.value(), v));
00409         final_bitset_[s] = true;
00410       }
00411       else
00412         final_.modify(final_.find(s.value()), update_label<final_value_t>(v));
00413     }
00414 
00415     BMIGRAPH_TPARAM
00416     const typename BMIGRAPH::series_set_elt_value_t&
00417     BMIGRAPH::get_final(const hstate_t& s, const series_set_elt_value_t &zero) const
00418     {
00419       precondition(has_state(s));
00420       typename final_t::const_iterator it = final_.find(s.value());
00421 
00422       if (it == final_.end())
00423         return zero;
00424       return it->second;
00425     }
00426 
00427     BMIGRAPH_TPARAM
00428     bool
00429     BMIGRAPH::is_final(const hstate_t& s, const series_set_elt_value_t&) const
00430     {
00431       precondition(has_state(s));
00432       return final_bitset_[s];
00433     }
00434 
00435     BMIGRAPH_TPARAM
00436     void
00437     BMIGRAPH::clear_final()
00438     {
00439       final_.clear();
00440       final_bitset_.reset();
00441     }
00442 
00443     /*---------------------.
00444     | Edge manipulations.  |
00445     `---------------------*/
00446 
00447     BMIGRAPH_TPARAM
00448     bool
00449     BMIGRAPH::has_edge (const hedge_t& h) const
00450     {
00451       succ_range r = graph_.equal_range(boost::make_tuple(h.value()->from_,
00452                                                     h.value()->label_));
00453       succ_iterator it;
00454       state_t to = h.value()->to_;
00455       for (it = r.first; it != r.second && it->to_ != to; ++it)
00456         /*Nothing*/;
00457 
00458       return it != r.second;
00459     }
00460 
00461     BMIGRAPH_TPARAM
00462     typename BMIGRAPH::hedge_t
00463     BMIGRAPH::add_edge (const hstate_t& from, const hstate_t& to, const label_t& l)
00464     {
00465       //hlabel_t hl = label_container_.insert (l);
00466       return hedge_t (graph_.insert (edge_data_t (from.value(), to.value(), l)).first);
00467     }
00468 
00469     BMIGRAPH_TPARAM
00470     void
00471     BMIGRAPH::del_edge (const hedge_t& h)
00472     {
00473       precondition (has_edge(h));
00474 
00475       hlabel_t l = h.value()->label_;
00476       graph_.erase(h.value());
00477       //label_container_.erase(l);
00478 
00479       // h points to an invalid edgeValue since it is already destroyed.
00480       // We can't check this postcondition anymore!
00481       //postcondition(!has_edge(h));
00482     }
00483 
00484     BMIGRAPH_TPARAM
00485     typename BMIGRAPH::hstate_t
00486     BMIGRAPH::src_of (const hedge_t& h) const
00487     {
00488       return hstate_t(h.value()->from_);
00489     }
00490 
00491     BMIGRAPH_TPARAM
00492     typename BMIGRAPH::hstate_t
00493     BMIGRAPH::dst_of (const hedge_t& h) const
00494     {
00495       return hstate_t(h.value()->to_);
00496     }
00497 
00498     BMIGRAPH_TPARAM
00499     const typename BMIGRAPH::label_t&
00500     BMIGRAPH::label_of (const hedge_t& h) const
00501     {
00502       return h.value()->label_;
00503 //      return label_container_.get_label(h.value()->label_);
00504     }
00505 
00506     BMIGRAPH_TPARAM
00507     void
00508     BMIGRAPH::update(const hedge_t& h, const label_t& l)
00509     {
00510       label_container_.update(h->label_, l);
00511       graph_.modify(h.value(), update_hlabel<hlabel_t>(h->label_));
00512     }
00513 
00514     BMIGRAPH_TPARAM
00515     template <class S>
00516     bool
00517     BMIGRAPH::exists (const AutomataBase<S>& s) const
00518     {
00519       typename WordValue::iterator      it;
00520       typename label_t::const_iterator  r;
00521       label_t                           l;
00522       WordValue                         w;
00523 
00524       for (typename graph_data_t::iterator i = graph_.begin(); i != graph_.end(); ++i)
00525       {
00526         // Make sure that source and destination of edge are part of the
00527         // automaton.
00528         if (!has_state(dst_of(hedge_t(i))) ||
00529             !has_state(src_of(hedge_t(i))))
00530           return false;
00531 
00532         // Make sure that every letter of the edge is in the alphabet.
00533         l = label_of(hedge_t(i));
00534         for (r = l.begin(); r != l.end(); ++r)
00535         {
00536           w = r->first;
00537           for (it = w.begin(); it != w.end(); ++it)
00538             if (!s.series().monoid().alphabet().contains(*it))
00539               return false;
00540         }
00541       }
00542       return true;
00543     }
00544 
00545     BMIGRAPH_TPARAM
00546     inline
00547     typename BMIGRAPH::tag_t&
00548     BMIGRAPH::tag ()
00549     {
00550       return tag_;
00551     }
00552 
00553     BMIGRAPH_TPARAM
00554     inline
00555     const typename BMIGRAPH::tag_t&
00556     BMIGRAPH::tag () const
00557     {
00558       return tag_;
00559     }
00560 
00561     BMIGRAPH_TPARAM
00562     inline
00563     typename BMIGRAPH::geometry_t&
00564     BMIGRAPH::geometry ()
00565     {
00566       return geometry_;
00567     }
00568 
00569     BMIGRAPH_TPARAM
00570     inline
00571     const typename BMIGRAPH::geometry_t&
00572     BMIGRAPH::geometry () const
00573     {
00574       return geometry_;
00575     }
00576 
00577     template <class Kind, class WordValue, class WeightValue, class SeriesValue,
00578               class Letter, class Tag, class GeometryCoords, class I>
00579     Tag&
00580     op_tag(const AutomataBase<I>&, BMIGRAPH &g)
00581     {
00582       return g.tag();
00583     }
00584 
00585     template <class Kind, class WordValue, class WeightValue, class SeriesValue,
00586               class Letter, class Tag, class GeometryCoords, class I>
00587     const Tag&
00588     op_tag(const AutomataBase<I>&, BMIGRAPH &g)
00589     {
00590       return g.tag();
00591     }
00592 
00593     template <class Kind, class WordValue, class WeightValue, class SeriesValue,
00594               class Letter, class Tag, class GeometryCoords, class I>
00595     typename BMIGRAPH::geometry_t&
00596     op_geometry(const AutomataBase<I>&, BMIGRAPH &g)
00597     {
00598       return g.geometry();
00599     }
00600 
00601     template <class Kind, class WordValue, class WeightValue, class SeriesValue,
00602               class Letter, class Tag, class GeometryCoords, class I>
00603     const typename BMIGRAPH::geometry_t&
00604     op_geometry(const AutomataBase<I>&, const BMIGRAPH &g)
00605     {
00606       return g.geometry();
00607     }
00608 
00609     BMIGRAPH_TPARAM
00610     typename BMIGRAPH::graph_data_t::const_iterator
00611     BMIGRAPH::find_edge(const state_t& from, const state_t& to,
00612                           const hlabel_t& label) const
00613     {
00614       succ_range r = graph_.equal_range(::boost::make_tuple(from, label));
00615       for (succ_iterator i = r.first; i != r.second; ++i)
00616         if (i->to_ == to)
00617           return i;
00618       return graph_.end();
00619     }
00620 
00621     /*------------------.
00622     | Delta functions.  |
00623     `------------------*/
00624 
00625   # define DEFINE_DELTA_FUNCTION(FunName, DeltaKind, Target, GetElt)            \
00626     BMIGRAPH_TPARAM                                                             \
00627     template <typename OutputIterator, typename Query>                          \
00628     void                                                                        \
00629     BMIGRAPH::FunName(OutputIterator res,                                       \
00630                         const typename BMIGRAPH::hstate_t& s,                   \
00631                         const Query& query,                                     \
00632                         ::vcsn::delta_kind::DeltaKind) const                    \
00633     {                                                                           \
00634       assertion(has_state(s));                                                  \
00635       Target##_range r = graph_.template get<Target>().equal_range(s.value());          \
00636       for (Target##_iterator e = r.first; e != r.second; ++e)                   \
00637         if (query(hedge_t(graph_.project<0>(e))))                               \
00638           *res++ = GetElt;                                                      \
00639     }
00640 
00641     DEFINE_DELTA_FUNCTION (delta, transitions, src, hedge_t(graph_.project<0>(e)));
00642     DEFINE_DELTA_FUNCTION (delta, states, src, hstate_t(e->to_));
00643     DEFINE_DELTA_FUNCTION (rdelta, transitions, dst, hedge_t(graph_.project<0>(e)));
00644     DEFINE_DELTA_FUNCTION (rdelta, states, dst, hstate_t(e->from_));
00645 
00646   # undef DEFINE_DELTA_FUNCTION
00647 
00648   # define DEFINE_DELTAF_FUNCTION(FunName, DeltaKind, Target, IsBool, Action)   \
00649     BMIGRAPH_TPARAM                                                             \
00650     template <typename Functor, typename Query>                                 \
00651     void                                                                        \
00652     BMIGRAPH::FunName(Functor& f,                                               \
00653                         const typename BMIGRAPH::hstate_t& s,                   \
00654                         const Query& query,                                     \
00655                         ::vcsn::delta_kind::DeltaKind,                          \
00656                         misc::IsBool##_t) const                                 \
00657     {                                                                           \
00658       assertion(has_state(s));                                                  \
00659       Target##_range r = graph_.template get<Target>().equal_range(s.value());          \
00660       for (Target##_iterator e = r.first; e != r.second; ++e)                   \
00661         if (query(htransition_t(graph_.project<0>(e))))                         \
00662         {                                                                       \
00663           Action;                                                               \
00664         }                                                                       \
00665     }
00666 
00667     DEFINE_DELTAF_FUNCTION (deltaf, transitions, src, true, if (not f(hedge_t(graph_.project<0>(e)))) break);
00668     DEFINE_DELTAF_FUNCTION (deltaf, transitions, src, false, f(hedge_t(graph_.project<0>(e))));
00669     DEFINE_DELTAF_FUNCTION (deltaf, states, src, true, if (not f(hstate_t(e->to_))) break);
00670     DEFINE_DELTAF_FUNCTION (deltaf, states, src, false, f(hstate_t(e->to_)));
00671 
00672     DEFINE_DELTAF_FUNCTION (rdeltaf, transitions, dst, true, if (not f(hedge_t(graph_.project<0>(e)))) break);
00673     DEFINE_DELTAF_FUNCTION (rdeltaf, transitions, dst, false, f(hedge_t(graph_.project<0>(e))));
00674     DEFINE_DELTAF_FUNCTION (rdeltaf, states, dst, true, if (not f(hstate_t(e->from_))) break);
00675     DEFINE_DELTAF_FUNCTION (rdeltaf, states, dst, false, f(hstate_t(e->from_)));
00676 
00677   # undef DEFINE_DELTAF_FUNCTION
00678 
00679     namespace deltaf_helper {
00680       template <typename T, typename R, typename Arg>
00681       char is_returning_bool_helper (R (T::*) (Arg));
00682 
00683       template <typename T, typename Arg>
00684       int is_returning_bool_helper (bool (T::*) (Arg));
00685 
00686   # define is_returning_bool(T)                                                 \
00687       (sizeof (deltaf_helper::is_returning_bool_helper (T)) == sizeof (int))
00688     }
00689 
00690   # define DEFINE_DELTAF_HELPER(FunName)                                        \
00691     BMIGRAPH_TPARAM                                                             \
00692     template <typename Functor, class Query, typename DeltaKind>                \
00693     void                                                                        \
00694     BMIGRAPH::FunName(Functor& f,                                               \
00695                     const typename BMIGRAPH::hstate_t& s,                       \
00696                     const Query& query,                                         \
00697                     ::vcsn::delta_kind::kind<DeltaKind> k) const                \
00698     {                                                                           \
00699       FunName (f, s, query, k,                                                  \
00700               BOOL_TO_TYPE (is_returning_bool (&Functor::operator ())) ());     \
00701     }
00702 
00703     DEFINE_DELTAF_HELPER (deltaf);
00704     DEFINE_DELTAF_HELPER (rdeltaf);
00705 
00706   # undef DEFINE_DELTAF_HELPER
00707   # undef is_returning_bool
00708 
00709   # define DEFINE_DELTAI_FUNCTION(DeltaKind)                                    \
00710     BMIGRAPH_TPARAM                                                             \
00711     std::pair<typename BMIGRAPH::DeltaKind##_iterator,                          \
00712               typename BMIGRAPH::DeltaKind##_iterator>                          \
00713     BMIGRAPH::deltai(const hstate_t& s, DeltaKind##_iterator) const             \
00714     {                                                                           \
00715       assertion(has_state(s));                                                  \
00716       return graph_.template get<DeltaKind>().equal_range(s.value());           \
00717     }
00718 
00719     DEFINE_DELTAI_FUNCTION(src);
00720     DEFINE_DELTAI_FUNCTION(dst);
00721   # undef DEFINE_DELTAI_FUNCTION
00722 
00723     BMIGRAPH_TPARAM
00724     template <typename I>
00725     typename BMIGRAPH::htransition_t
00726     BMIGRAPH::get_htransition(const I& i) const
00727     {
00728       return htransition_t(graph_.project<0>(i));
00729     }
00730 
00731     // End of syntactic sugar
00732 # undef BMIGRAPH_TPARAM
00733 # undef BMIGRAPH
00734   } // End of namespace boost
00735 } // End of namespace vcsn
00736 
00737 #endif // !VCSN_AUTOMATA_IMPLEMENTATION_BMIG_GRAPH_IMPL_HXX_ //

Generated on Thu Oct 9 20:22:34 2008 for Vaucanson by  doxygen 1.5.1