Vaucanson 1.4
str_words.hxx
00001 // str_words.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010 The Vaucanson
00006 // Group.
00007 //
00008 // This program is free software; you can redistribute it and/or
00009 // modify it under the terms of the GNU General Public License
00010 // as published by the Free Software Foundation; either version 2
00011 // of the License, or (at your option) any later version.
00012 //
00013 // The complete GNU General Public Licence Notice can be found as the
00014 // `COPYING' file in the root directory.
00015 //
00016 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00017 //
00018 #ifndef VCSN_ALGEBRA_IMPLEMENTATION_MONOID_STR_WORDS_HXX
00019 # define VCSN_ALGEBRA_IMPLEMENTATION_MONOID_STR_WORDS_HXX
00020 
00021 # include <vaucanson/algebra/implementation/monoid/str_words.hh>
00022 
00023 # include <vaucanson/misc/char_traits.hh>
00024 
00025 namespace vcsn {
00026 
00027   namespace algebra {
00028 
00029     template <typename A>
00030     std::pair<bool, int>
00031     op_parse(const FreeMonoid<A>& s,
00032              std::basic_string<typename A::letter_t>& v,
00033              const std::string& in)
00034     {
00035       if (in.empty())
00036         return std::make_pair(true, 0);
00037 
00038       std::string& empty = s.representation()->empty;
00039       int empty_size = empty.size();
00040       std::string& concat = s.representation()->concat;
00041       int concat_size = concat.size();
00042       bool last_token_is_letter = false;
00043 
00044       size_t i;
00045       for (i = 0; i < in.size();)
00046         {
00047           // Is this a concatenation symbol?
00048           if ((concat_size > 0) && !in.compare(i, concat_size, concat))
00049             {
00050               if (!last_token_is_letter)
00051                 return std::make_pair(false, i);
00052               i += concat_size;
00053               last_token_is_letter = false;
00054               continue;
00055             }
00056 
00059           // if (last_token_is_letter && concat_size > 0)
00060           //   return std::make_pair(false, i);
00061 
00062           // Is this the empty word?
00063           if (!in.compare(i, empty_size, empty))
00064             {
00065               i += empty_size;
00066               last_token_is_letter = true;
00067               continue;
00068             }
00069 
00070           // Finally try to read a real letter.
00071           // Note that op_parse will update i.
00072           std::pair<bool, typename A::letter_t> letter =
00073             op_parse(s.alphabet().structure(), s.alphabet().value(), in, i);
00074           if (!letter.first)
00075             return std::make_pair(false, i);
00076           v.push_back(letter.second);
00077           last_token_is_letter = true;
00078         }
00079       return std::make_pair(last_token_is_letter, i);
00080     }
00081 
00082     template<typename A>
00083     void
00084     op_in_mul(const algebra::FreeMonoid<A>&,
00085               std::basic_string<typename A::letter_t>& dst,
00086               const std::basic_string<typename A::letter_t>& src)
00087     {
00088       dst += src;
00089     }
00090 
00091     template<typename A>
00092     std::basic_string<typename A::letter_t>
00093     op_mul(const algebra::FreeMonoid<A>&,
00094            const std::basic_string<typename A::letter_t>& a,
00095            const std::basic_string<typename A::letter_t>& b)
00096     {
00097       return a + b;
00098     }
00099 
00100     template<typename A, typename St, typename U, typename V>
00101     St&
00102     op_rout(const FreeMonoid<A>& s,
00103             St& st,
00104             const std::basic_string<typename A::letter_t, U, V>& v)
00105     {
00106       if (v.empty())
00107         st << s.representation()->empty;
00108       else
00109       {
00110         // Type helpers.
00111         typedef typename A::letter_t letter_t;
00112         typedef algebra::letter_traits<letter_t> letter_traits_t;
00113         typedef typename std::basic_string<letter_t, U, V>::const_iterator
00114           iter_t;
00115 
00116         iter_t i = v.begin();
00117 
00118         // Print the first letter.
00119         st << letter_traits_t::letter_to_literal(*i);
00120         ++i;
00121 
00122         // Print the following letters using the concat string.
00123         while (i != v.end())
00124         {
00125           st << s.representation()->concat
00126              << letter_traits_t::letter_to_literal(*i);
00127           ++i;
00128         }
00129       }
00130 
00131       return st;
00132     }
00133 
00134     template <typename A>
00135     bool
00136     op_xeq(const algebra::FreeMonoid<A>& s,
00137            const std::basic_string<typename A::letter_t>& a,
00138            const std::basic_string<typename A::letter_t>& b)
00139     {
00140       typename std::basic_string<typename A::letter_t>::const_iterator
00141         m = b.begin();
00142       typename std::basic_string<typename A::letter_t>::const_iterator l;
00143       for (l = a.begin(); m != b.end() && l != a.end(); ++l)
00144         {
00145           if (! s.alphabet().letter_equality(*l, *m))
00146             return false;
00147           ++m;
00148         }
00149       return (m == b.end() && l == a.end());
00150     }
00151 
00152     template<typename A>
00153     const std::basic_string<typename A::letter_t>&
00154     identity_value(SELECTOR(algebra::FreeMonoid<A>),
00155                    SELECTOR(std::basic_string<typename A::letter_t>))
00156     {
00157       static const std::basic_string<typename A::letter_t> instance;
00158       return instance;
00159     }
00160 
00161     template<typename A>
00162     const std::basic_string<typename A::letter_t,
00163                             misc::char_traits<typename A::letter_t> >&
00164     identity_value(SELECTOR(algebra::FreeMonoid<A>),
00165                    SELECTOR2(std::basic_string<typename A::letter_t,
00166                             misc::char_traits<typename A::letter_t> >))
00167     {
00168       static const std::basic_string<typename A::letter_t,
00169         misc::char_traits<typename A::letter_t> > instance;
00170       return instance;
00171     }
00172 
00173     template<typename A>
00174     std::basic_string<typename A::letter_t>
00175     op_convert(SELECTOR(algebra::FreeMonoid<A>),
00176                SELECTOR(std::basic_string<typename A::letter_t>),
00177                const typename A::letter_t& c)
00178     {
00179       std::basic_string<typename A::letter_t> str;
00180       str = c;
00181       return str;
00182     }
00183 
00184     template<typename A, typename B, typename C, typename D>
00185     bool
00186     op_is_atom(const algebra::FreeMonoid<A>&,
00187                const std::basic_string<B, C, D>& v)
00188     {
00189       return v.size() <= 1;
00190     }
00191 
00192 
00193     template <class A>
00194     Element<algebra::FreeMonoid<A>, std::basic_string<typename A::letter_t> >
00195     op_choose(const algebra::FreeMonoid<A>& s,
00196               SELECTOR(std::basic_string<typename A::letter_t>))
00197     {
00198       unsigned length =
00199         misc::random::generate<unsigned>(0, op_choose_max_word_length);
00200       std::basic_string<typename A::letter_t> r;
00201       for (unsigned i = 0; i < length; ++i)
00202         r = r + s.alphabet().choose();
00203       return Element<algebra::FreeMonoid<A>,
00204         std::basic_string<typename A::letter_t> >(s, r);
00205     }
00206 
00207 # define WORD_TRAITS \
00208     word_traits<FreeMonoid<A>, std::basic_string<typename A::letter_t> >
00209 
00210     template <typename A>
00211     inline typename WORD_TRAITS::first_projection_value_t
00212     WORD_TRAITS::first_projection(const WORD_TRAITS::word_value_t& str)
00213     {
00214       // We can not project if the type does not support it.
00215       static_assertion_(not (misc::static_eq<first_projection_t,
00216                              undefined_type>::value), need_first_projection);
00217 
00218       first_projection_value_t R;
00219 
00220       // We assume we can access the first projection with "first".
00221       for_all_const_(word_value_t, i, str)
00222         R += (*i).first;
00223 
00224       return R;
00225     }
00226 
00227     template <typename A>
00228     inline typename WORD_TRAITS::first_projection_t
00229     WORD_TRAITS::first_projection(const WORD_TRAITS::first_monoid_t& mon,
00230                                   const WORD_TRAITS::word_t& word)
00231     {
00232       // We can not project if the type does not support it.
00233       static_assertion_(not (misc::static_eq<first_projection_t,
00234                              undefined_type>::value), need_first_projection);
00235 
00236       first_projection_t R(mon);
00237 
00238       R.value() = first_projection(word.value());
00239 
00240       return R;
00241     }
00242 
00243     template <typename A>
00244     inline typename WORD_TRAITS::second_projection_value_t
00245     WORD_TRAITS::second_projection(const WORD_TRAITS::word_value_t& str)
00246     {
00247       // We can not project if the type does not support it.
00248       static_assertion_(not (misc::static_eq<second_projection_t,
00249                              undefined_type>::value), need_second_projection);
00250 
00251       second_projection_value_t R;
00252 
00253       // We assume we can access the second projection with "second".
00254       for_all_const_(word_value_t, i, str)
00255         R += (*i).second;
00256 
00257       return R;
00258     }
00259 
00260     template <typename A>
00261     inline typename WORD_TRAITS::second_projection_t
00262     WORD_TRAITS::second_projection(const WORD_TRAITS::second_monoid_t& mon,
00263                                    const WORD_TRAITS::word_t& word)
00264     {
00265       // We can not project if the type does not support it.
00266       static_assertion_(not (misc::static_eq<second_projection_t,
00267                              undefined_type>::value), need_second_projection);
00268 
00269       second_projection_t R(mon);
00270 
00271       R.value() = second_projection(word.value());
00272 
00273       return R;
00274     }
00275 
00276 # undef WORD_TRAITS
00277 
00278   } // ! algebra
00279 
00280 } // ! vcsn
00281 
00282 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_MONOID_STR_WORDS_HXX