Back to index

nordugrid-arc-nox  1.1.0~rc6
IString.h
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 #ifndef __ARC_ISTRING__
00004 #define __ARC_ISTRING__
00005 
00006 #include <list>
00007 #include <string>
00008 #include <ostream>
00009 
00010 #include <sigc++/slot.h>
00011 #include <glibmm.h>
00012 
00013 #include <stdio.h>  // snprintf
00014 #include <stdlib.h> // free
00015 #include <string.h> // strcpy, strdup
00016 
00017 #define istring(x) (x)
00018 
00019 namespace Arc {
00020 
00021   class PrintFBase {
00022   public:
00023     PrintFBase();
00024     virtual ~PrintFBase();
00025     virtual void msg(std::ostream& os) = 0;
00026     void Retain();
00027     bool Release();
00028   private:
00029     // Copying not allowed
00030     PrintFBase(const PrintFBase&);
00031     // Assignment not allowed
00032     PrintFBase& operator=(const PrintFBase&);
00033     int refcount;
00034   };
00035 
00036   const char* FindTrans(const char *p);
00037   const char* FindNTrans(const char *s, const char *p, unsigned long n);
00038 
00039   template<class T0 = int, class T1 = int, class T2 = int, class T3 = int,
00040            class T4 = int, class T5 = int, class T6 = int, class T7 = int>
00041   class PrintF
00042     : public PrintFBase {
00043 
00044   public:
00045 
00046     PrintF(const std::string& m,
00047            const T0& tt0 = 0, const T1& tt1 = 0,
00048            const T2& tt2 = 0, const T3& tt3 = 0,
00049            const T4& tt4 = 0, const T5& tt5 = 0,
00050            const T6& tt6 = 0, const T7& tt7 = 0)
00051       : PrintFBase(),
00052         m(m) {
00053       Copy(t0, tt0);
00054       Copy(t1, tt1);
00055       Copy(t2, tt2);
00056       Copy(t3, tt3);
00057       Copy(t4, tt4);
00058       Copy(t5, tt5);
00059       Copy(t6, tt6);
00060       Copy(t7, tt7);
00061     }
00062 
00063     ~PrintF() {
00064       for (std::list<char*>::iterator it = ptrs.begin();
00065            it != ptrs.end(); it++)
00066         free(*it);
00067     }
00068 
00069     void msg(std::ostream& os) {
00070 
00071       char buffer[2048];
00072       snprintf(buffer, 2048, Get(m),
00073                Get(t0), Get(t1), Get(t2), Get(t3),
00074                Get(t4), Get(t5), Get(t6), Get(t7));
00075       os << buffer;
00076     }
00077 
00078   private:
00079 
00080     // general case
00081     template<class T, class U>
00082     inline void Copy(T& t, const U& u) {
00083       t = u;
00084     }
00085 
00086     // char[] and const char[]
00087     template<class T>
00088     inline void Copy(T& t, const char u[]) {
00089       strcpy(t, u);
00090     }
00091 
00092     // const char*
00093     inline void Copy(const char*& t, const char*const& u) {
00094       t = strdup(u);
00095       ptrs.push_back(const_cast<char*>(t));
00096     }
00097 
00098     // char*
00099     inline void Copy(char*& t, char*const& u) {
00100       t = strdup(u);
00101       ptrs.push_back(t);
00102     }
00103 
00104     // general case
00105     template<class T>
00106     inline static const T& Get(const T& t) {
00107       return t;
00108     }
00109 
00110     // const char[] and const char*
00111     inline static const char* Get(const char*const& t) {
00112       return FindTrans(t);
00113     }
00114 
00115     // char[] and char*
00116     inline static const char* Get(char*const& t) {
00117       return FindTrans(const_cast<const char*&>(t));
00118     }
00119 
00120     // std::string
00121     inline static const char* Get(const std::string& t) {
00122       return FindTrans(t.c_str());
00123     }
00124 
00125     // std::string ()()
00126     inline static const char* Get(std::string (*t)()) {
00127       return FindTrans(t().c_str());
00128     }
00129 
00130     // Glib::ustring
00131     inline static const char* Get(const Glib::ustring& t) {
00132       return FindTrans(t.c_str());
00133     }
00134 
00135     // Glib::ustring ()()
00136     inline static const char* Get(Glib::ustring (*t)()) {
00137       return FindTrans(t().c_str());
00138     }
00139 
00140     // sigc::slot<const char*>*
00141     inline static const char* Get(const sigc::slot<const char*> *t) {
00142       return (*t)();
00143     }
00144 
00145     std::string m;
00146     T0 t0;
00147     T1 t1;
00148     T2 t2;
00149     T3 t3;
00150     T4 t4;
00151     T5 t5;
00152     T6 t6;
00153     T7 t7;
00154     std::list<char*> ptrs;
00155   };
00156 
00157   class IString {
00158 
00159   public:
00160 
00161     IString(const std::string& m)
00162       : p(new PrintF<>(m)) {}
00163 
00164     template<class T0>
00165     IString(const std::string& m, const T0& t0)
00166       : p(new PrintF<T0>(m, t0)) {}
00167 
00168     template<class T0, class T1>
00169     IString(const std::string& m, const T0& t0, const T1& t1)
00170       : p(new PrintF<T0, T1>(m, t0, t1)) {}
00171 
00172     template<class T0, class T1, class T2>
00173     IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2)
00174       : p(new PrintF<T0, T1, T2>(m, t0, t1, t2)) {}
00175 
00176     template<class T0, class T1, class T2, class T3>
00177     IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2, const T3& t3)
00178       : p(new PrintF<T0, T1, T2, T3>(m, t0, t1, t2, t3)) {}
00179 
00180     template<class T0, class T1, class T2, class T3, class T4>
00181     IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4)
00182       : p(new PrintF<T0, T1, T2, T3, T4>(m, t0, t1, t2, t3, t4)) {}
00183 
00184     template<class T0, class T1, class T2, class T3, class T4, class T5>
00185     IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
00186       : p(new PrintF<T0, T1, T2, T3, T4, T5>(m, t0, t1, t2, t3, t4, t5)) {}
00187 
00188     template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
00189     IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6)
00190       : p(new PrintF<T0, T1, T2, T3, T4, T5, T6>(m, t0, t1, t2, t3, t4, t5, t6)) {}
00191 
00192     template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
00193     IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7)
00194       : p(new PrintF<T0, T1, T2, T3, T4, T5, T6, T7>(m, t0, t1, t2, t3, t4, t5, t6, t7)) {}
00195 
00196     ~IString();
00197 
00198     IString(const IString& istr);
00199     IString& operator=(const IString& istr);
00200 
00201   private:
00202 
00203     PrintFBase *p;
00204 
00205     friend std::ostream& operator<<(std::ostream& os, const IString& msg);
00206   };
00207 
00208   std::ostream& operator<<(std::ostream& os, const IString& msg);
00209 
00210 } // namespace Arc
00211 
00212 #endif // __ARC_ISTRING__