TFCweb  1.0.4 $Rev: 483 $
TFC Primavera 2012: Nucli d'un servidor web
utils.h
Veure la documentació d'aquest fitxer.
1 #if !defined(_UTILS_H_)
2 #define _UTILS_H_
3 
12 /*
13  * Copyright (c) 2012 Toni Corvera
14  *
15  * This file is part of TFCWeb.
16  *
17  * TFCWeb is free software: you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation, either version 3 of the License, or
20  * (at your option) any later version.
21  *
22  * TFCWeb is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with TFCWeb. If not, see <http://www.gnu.org/licenses/>.
29  */
30 
31 #include "portabilitat.h"
32 
33 #include <istream>
34 #include <sstream>
35 #include <string>
36 #include <ostream>
37 #include <boost/bind.hpp>
38 #include <boost/date_time.hpp>
39 #include <boost/filesystem.hpp>
40 #include <boost/function.hpp>
41 
42 namespace tfc {
43 
44 // Forward declarations
45 template<typename T, typename TDesti> class Te_Operador_Insercio;
46 template<typename T, typename TOrigen> class Te_Operador_Extraccio;
47 
51 namespace utils {
52 
54 // Definició en forma de signatura C:
55 typedef std::ios_base&(manipulador_ios_base_t)(std::ios_base&);
57 // Definició amb boost::function:
58 typedef boost::function<std::ostream& (std::ostream&)> manipulador_ostream_t;
59 
60 } // ns utils
61 
62 } // ns tfc
63 
71 std::ostream& operator<<(std::ostream & os, tfc::utils::manipulador_ostream_t fn);
72 
73 namespace tfc {
74 
75 namespace utils {
76 
91 template<typename T> std::string to_string(const T & obj,
92  manipulador_ios_base_t base = std::dec)
93 {
95  std::ostringstream ss;
96  ss << base << obj;
97  return ss.str();
98 }
99 
118 template<typename T> T from_string(const std::string & s,
119  manipulador_ios_base_t base = std::dec)
120 {
122  T ret;
123  std::istringstream ss(s);
124  ss >> base >> ret;
125  return ret;
126 }
127  // FIXME: Massa general? Usar basic_string? http://www.sgi.com/tech/stl/basic_string.html
135 template<typename Str> const typename Str::value_type final(const Str & s) {
136  assert( s.size() > 0 ); // PRECONDICIÓ
137  return *(--s.end());
138 }
139 
148 bool es_llegible(const boost::filesystem::path & p) throw ();
149 
155 bool es_canonic(const boost::filesystem::path & p) throw ();
156 
163 std::string lpad(const std::string & s, size_t mida, char f = ' ');
164 
171 std::string rpad(const std::string & s, size_t mida, char f = ' ');
172 
190 std::string formata_data(const boost::posix_time::ptime & t, const std::string & fmt);
191 
192 // Nota: La interpretació de dates textuals no s'ha generalitzat, principalment
193 // perquè Boost Date Time no inclou lectura de fusos horaris estàndards
194 // vegeu llegeix_data_http() per el cas concret del format utilitzat en HTTP
195 
199 std::string formata_data(const std::time_t t, const std::string & fmt);
200 
202 namespace impl {
203 
204 // Cal una implementació amb nom no polimòrfic per què el compilador
205 // la interpreti correctament en les funcions generadores que utilitzen
206 // boost::bind (vegeu les utils::each_shl())
207 // XXX: parametritzar Separador potser és excessiu
208 template<typename Iterador, typename Separador = std::string>
209 std::ostream& each_shl(std::ostream& os,
210  Iterador ini, Iterador fi,
211  const Separador & sep)
212 {
213  while (ini != (fi-1)) { // Fins el penúltim element, l'imprimim seguit del separador
214  os << *ini << sep;
215  ini++;
216  }
217  return os << *ini; // Últim element, sense separador
218 }
219 
220 } // ns impl
221 
239 template<typename Iterador, typename Separador = std::string>
240 std::ostream& each_shl(std::ostream& os,
241  Iterador ini, Iterador fi,
242  const Separador & sep = "\n") {
243  return impl::each_shl(os, ini, fi, sep);
244 }
245 
264 template<typename Iterador, typename Separador = std::string>
265 manipulador_ostream_t each_shl(Iterador ini, Iterador fi, const Separador & sep = "\n") {
266  // No compila: return boost::bind<std::ostream&>(&each_shl<Iterador>, _1, ini, fi);
267  return boost::bind<std::ostream&>(&impl::each_shl<Iterador>, _1, ini, fi, sep);
268 }
269 
294 template<typename Contenidor, typename Separador = std::string>
295 manipulador_ostream_t each_shl(const Contenidor & c, const Separador & sep = "\n") {
296  return each_shl(c.begin(), c.end(), sep);
297  // typedef typename Contenidor::const_iterator const_iterator;
298  // return boost::bind<std::ostream&>(&impl::each_shl<const_iterator>, _1, c.begin(), c.end());
299 }
300 
301 
311 inline std::string formata_data(const std::string & fmt) {
312  return formata_data(boost::posix_time::second_clock::universal_time(), fmt);
313 }
314 
315 } // ns tfc::utils
316 
317 // Constraints
318 //
319 // La tècnica de les constraints està explicada pel propi Bjarne Stroustrup a:
320 // <http://www2.research.att.com/~bs/bs_faq2.html#constraints>
321 //
322 // Són construccions evaluables en la compilació que impossen restriccions en
323 // els tipus de les plantilles (prevenint la compilació si els tipus passats no
324 // compleixen la condició impossada). Un cop evaluades no generen codi.
325 //
326 
344 template<typename T>
346  static void constraint(T & t) {
347  const std::string first = t.first;
348  const std::string second = t.second;
349  }
350 public:
352  UNUSED void (*p_ct)(T&) = constraint;
353  }
354 };
355 
372 template<typename T>
374  static void constraint(T & t) {
375  t();
376  }
377 public:
379  UNUSED void (*p_ct)(T&) = constraint;
380  }
381 };
382 
398 template<typename T, typename TDesti = std::ostream>
400  static void constraint(T & t, TDesti & desti) {
401  desti << t;
402  }
403 public:
405  UNUSED void (*p_ct)(T&, TDesti&) = constraint;
406  }
407 };
408 
424 template<typename T, typename TOrigen = std::istream>
426  static void constraint(T & t, TOrigen & origen) {
427  origen >> t;
428  }
429 public:
431  UNUSED void (*p_ct)(T&, TOrigen&) = constraint;
432  }
433 };
434 
435 } // ns tfc
436 
437 #endif // _UTILS_H_
438 
439 // vim:set ts=4 et ai: //