Vaucanson 1.4
|
00001 // escaper.hxx: this file is part of the Vaucanson project. 00002 // 00003 // Vaucanson, a generic library for finite state machines. 00004 // 00005 // Copyright (C) 2004, 2005, 2006 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 #ifndef VCSN_MISC_ESCAPER_HXX 00018 # define VCSN_MISC_ESCAPER_HXX 00019 00028 # include <string> 00029 # include <sstream> 00030 00031 # include <vaucanson/misc/escaper.hh> 00032 # include <vaucanson/misc/usual_escaped_characters.hh> 00033 00034 namespace vcsn 00035 { 00036 namespace misc 00037 { 00038 00040 inline 00041 int 00042 escaped () 00043 { 00044 static const int idx = std::ios::xalloc (); 00045 return idx; 00046 } 00047 00048 /*--------. 00049 | escaper | 00050 `--------*/ 00051 00052 template <class T> 00053 escaper<T>::escaper (const T& w) : w_ (w) 00054 { 00055 } 00056 00057 template <class T> 00058 std::ostream& 00059 escaper<T>::operator() (std::ostream& ostr) const 00060 { 00061 std::ostringstream o; 00062 o << w_; 00063 std::string w = o.str (); 00064 const std::set<char>& e = getesc (ostr); 00065 for (std::string::const_iterator i = w.begin (); i != w.end (); ++i) 00066 if (e.find (*i) != e.end ()) 00067 ostr << "\\" << *i; 00068 else 00069 ostr << *i; 00070 return ostr; 00071 } 00072 00073 /*-------------. 00074 | make_escaper | 00075 `-------------*/ 00076 00077 template <class T> 00078 escaper<T> 00079 make_escaper (const T& w) 00080 { 00081 return escaper<T> (w); 00082 } 00083 00084 /*-------. 00085 | setesc | 00086 `-------*/ 00087 00088 inline 00089 setesc::setesc (const std::set<char>& s) : s_ (s) 00090 { 00091 } 00092 00093 inline 00094 std::ostream& 00095 setesc::operator() (std::ostream& ostr) const 00096 { 00097 typedef std::set<char> esc_set; 00098 const int idx = escaped (); 00099 00100 if (not ostr.pword (idx)) 00101 ostr.register_callback (pword_delete<esc_set>, idx); 00102 else 00103 delete static_cast<esc_set*> (ostr.pword (idx)); 00104 ostr.pword (idx) = new esc_set (s_); 00105 return ostr; 00106 } 00107 00108 /*-------. 00109 | getesc | 00110 `-------*/ 00111 00112 inline 00113 std::set<char>& getesc (std::ostream& ostr) 00114 { 00115 const int idx = escaped (); 00116 00117 if (not ostr.pword (idx)) 00118 ostr << setesc (vcsn::misc::usual_escaped_characters ()); 00119 return *static_cast<std::set<char>*> (ostr.pword (idx)); 00120 } 00121 00122 } // End of namespace misc. 00123 } // End of namespace vcsn. 00124 00125 #endif // ! VCSN_MISC_ESCAPER_HXX