Vaucanson 1.4
couple_letter.hxx
00001 // couple_letter.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, 2008 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_LETTER_COUPLE_LETTER_HXX
00019 # define VCSN_ALGEBRA_IMPLEMENTATION_LETTER_COUPLE_LETTER_HXX
00020 
00021 # include <string>
00022 # include <sstream>
00023 # include <utility>
00024 # include <climits>
00025 # include <vector>
00026 
00027 # include <vaucanson/algebra/implementation/letter/couple_letter.hh>
00028 
00029 namespace vcsn
00030 {
00031   namespace algebra
00032   {
00033     template <typename U, typename V>
00034     struct letter_traits< std::pair<U, V> >
00035     {
00036       // we only consider letters of the form (u, v)
00037       typedef misc::true_t is_char_letter;
00038 
00039       enum
00040       {
00041         /*
00042          * Theoretically   cardinal     should   be   the   product   of
00043          * letter_traits<U>::cardinal and letter_traits<V>::cardinal.
00044          * But to  avoid overflows and for
00045          * practical reasons, it is better to consider it infinite.
00046          *
00047          * FIXME: Maybe doing this is not a good idea?
00048          */
00049         cardinal = INT_MAX
00050       };
00051 
00052       // A pair letter has two projections available: U and V.
00053       typedef U first_projection_t;
00054       typedef V second_projection_t;
00055 
00056       static
00057       std::pair<bool, std::pair<U, V> >
00058       literal_to_letter(const std::string& str)
00059       {
00060         // Check for a basic well formed pair: (x,y).
00061         if (str.size() < 5 || str[0] != '(' || *(str.end() - 1) != ')')
00062           return std::make_pair(false, std::make_pair(0, 0));
00063 
00064         // Split the string on commas.
00065         typedef std::vector<std::string> tokens_t;
00066         typedef tokens_t::const_iterator tokens_iter_t;
00067         std::string delim = ",";
00068         std::string buff(str.begin() + 1, str.end() - 1);
00069 
00070         std::string::size_type last_pos = buff.find_first_not_of(delim, 0);
00071         std::string::size_type pos = buff.find_first_of(delim, last_pos);
00072 
00073         tokens_t tokens;
00074 
00075         while (std::string::npos != pos || std::string::npos != last_pos)
00076         {
00077           // Push new token.
00078           tokens.push_back(buff.substr(last_pos, pos - last_pos));
00079           // Update positions.
00080           last_pos = buff.find_first_not_of(delim, pos);
00081           pos = buff.find_first_of(delim, last_pos);
00082         }
00083 
00084         if (tokens.size() != 2)
00085           return std::make_pair(false, std::make_pair(0, 0));
00086 
00087         std::pair<bool, U> fc = algebra::letter_traits<U>::literal_to_letter(tokens[0]);
00088         std::pair<bool, V> sc = algebra::letter_traits<V>::literal_to_letter(tokens[1]);
00089 
00090         if (!(fc.first && sc.first))
00091           return std::make_pair(false, std::make_pair(0, 0));
00092 
00093         return std::make_pair(true, std::make_pair(fc.second, sc.second));
00094       }
00095 
00096       static
00097       std::string
00098       letter_to_literal(const std::pair<U, V>& c)
00099       {
00100         std::stringstream sstr;
00101         sstr << '(' << c.first << ',' << c.second << ')';
00102         return sstr.str();
00103       }
00104 
00105       // A pair is a "tuple" with dimension 2.
00106       static std::string kind() { return "tuple"; }
00107       static int dim() { return 2; }
00108 
00109     };
00110 
00111   } // ! algebra
00112 
00113 } // ! vcsn
00114 
00115 namespace std
00116 {
00117   template <typename U, typename V>
00118   std::ostream& operator<<(std::ostream& s, const std::pair<U, V>& letter)
00119   {
00120     s << vcsn::algebra::letter_traits<std::pair<U, V> >::letter_to_literal(letter);
00121     return s;
00122   }
00123 
00124 } // ! std
00125 
00126 #endif // ! VCSN_ALGEBRA_IMPLEMENTATION_LETTER_COUPLE_LETTER_HXX