]> git.llucax.com Git - z.facultad/75.42/string.git/blob - universalstring.h
Se termina el TP, falta solo un poco de documentación.
[z.facultad/75.42/string.git] / universalstring.h
1 /* vim: set et sts=4 sw=4 fdm=marker fmr={,} fdn=1 fo+=t tw=80:
2  *
3  * Taller de Programación (75.42).
4  *
5  * Ejercicio Número 4:
6  * Ordena texto ASCII o Unicode.
7  *
8  * Copyleft 2003 - Leandro Lucarella <llucare@fi.uba.ar>
9  * Puede copiar, modificar y distribuir este programa bajo los términos de
10  * la licencia GPL (http://www.gnu.org/).
11  *
12  * Creado: sáb sep 27 15:38:29 ART 2003
13  *
14  * $Id$
15  */
16
17 #ifndef UNIVERSALSTRING_H
18 #define UNIVERSALSTRING_H
19
20 #include <ostream>
21 #include <istream>
22 #include <iterator>
23 #include <vector>
24 #include <cctype>
25
26 #ifdef DEBUG
27 #   include <iostream>
28 #endif
29
30 /// String Universal.
31 template < class T >
32 class UniversalString {
33
34         /// Cadena de caracteres.
35         std::vector< T > string;
36
37     public:
38
39         /// Constructor.
40         UniversalString(void) {
41 #ifdef DEBUG
42             std::cerr << "En constructor de UniversalString." << std::endl;
43 #endif
44         }
45
46         /// Constructor a partir de un string C.
47         UniversalString(const char* str) {
48 #ifdef DEBUG
49             std::cerr << "En constructor de UniversalString desde string C."
50                 << std::endl;
51 #endif
52             int len = strlen(str);
53             // Limpio cadena de caracteres anterior.
54             string.clear();
55             // Reservo nuevo espacio.
56             string.reserve(len);
57             // Agrego cada caracter.
58             for (int i = 0; i < len; i++) {
59                 string.push_back(str[i]);
60             }
61         }
62
63         /// Constructor a partir de otro UniversalString.
64         template < class T2 >
65         UniversalString(const UniversalString< T2 >& str) {
66 #ifdef DEBUG
67             std::cerr << "En constructor de UniversalString a partir de otro."
68                 << std::endl;
69 #endif
70             *this = str;
71         }
72
73         /// Constructor de copia.
74         UniversalString(const UniversalString& str) {
75 #ifdef DEBUG
76             std::cerr << "En constructor de copia de UniversalString."
77                 << std::endl;
78 #endif
79             string = str.string;
80         }
81
82         /// Destructor.
83         virtual ~UniversalString(void) {
84 #ifdef DEBUG
85             std::cerr << "En destructor de UniversalString." << std::endl;
86 #endif
87         }
88
89         /// Asignación de una instancia a otra.
90         UniversalString& operator=(const UniversalString& str) {
91 #ifdef DEBUG
92             std::cerr << "En operator= de UniversalString." << std::endl;
93 #endif
94             // Asigno la cadena de caracteres del string str.
95             string = str.string;
96             return *this;
97         }
98
99         /// Asignación de una instancia a otra de distinto tipo.
100         template < class T2 >
101         UniversalString& operator=(const UniversalString< T2 >& str) {
102 #ifdef DEBUG
103             std::cerr << "En operator= de UniversalString de tipos distintos."
104                 << std::endl;
105 #endif
106             // Obtengo un vector con los caracteres del string str.
107             std::vector< T2 > v = str.to_vector();
108             // Limpio mi cadena de caracteres.
109             string.clear();
110             // Reservo el nuevo espacio para mi cadena.
111             string.reserve(v.size());
112             // Voy agregando caracter a caracter.
113             for (size_t i = 0; i < v.size(); i++) {
114                 string.push_back(T(v[i]));
115             }
116             return *this;
117         }
118
119         /// Comparación por menor de dos instancias.
120         bool operator<(const UniversalString& str) {
121 #ifdef DEBUG
122             std::cerr << "En operator< de UniversalString." << std::endl;
123 #endif
124             return string < str.string;
125         }
126
127         /// Comparación por igual de dos instancias.
128         bool operator==(const UniversalString& str) {
129 #ifdef DEBUG
130             std::cerr << "En operator== de UniversalString." << std::endl;
131 #endif
132             return string == str.string;
133         }
134
135         /// Devuelve un vector de caracteres T.
136         std::vector< T > to_vector(void) const {
137             return string;
138         }
139
140         /// Volcado a un stream de salida.
141         friend std::ostream& operator<<(std::ostream& out,
142                 const UniversalString< T >& str) {
143 #ifdef DEBUG
144             std::cerr << "En operator<< de UniversalString." << std::endl;
145 #endif
146             // Copio el vector de caracteres al stream de salida.
147             std::copy(str.string.begin(), str.string.end(),
148                     std::ostream_iterator< T >(out, ""));
149             return out;
150         }
151
152         /// Captura desde un stream de entrada.
153         friend std::istream& operator>>(std::istream& in,
154                 UniversalString< T >& str) {
155 #ifdef DEBUG
156             std::cerr << "En operator>> de UniversalString." << std::endl;
157 #endif
158             // Limpio la cadena actual.
159             str.string.clear();
160             // Obtengo primer caracter, incluyendo espacios.
161             T c;
162             in >> std::noskipws >> c;
163             // Mientras que no sea un fin de línea, sigo leyendo caracteres.
164             while (c != '\n') {
165                 str.string.push_back(c);
166                 in >> std::noskipws >> c;
167             }
168             // Vuelvo a setear que ignore espacios.
169             in >> std::skipws;
170             return in;
171         }
172
173 };
174
175 #endif // UNIVERSALSTRING_H