ARC SDK
IString.h
1 // -*- indent-tabs-mode: nil -*-
2 
3 #ifndef __ARC_ISTRING__
4 #define __ARC_ISTRING__
5 
6 #include <list>
7 #include <string>
8 #include <ostream>
9 
10 #include <sigc++/slot.h>
11 #include <glibmm.h>
12 
13 #include <stdio.h> // snprintf
14 #include <stdlib.h> // free
15 #include <string.h> // strcpy, strdup
16 
17 #define istring(x) (x)
18 
19 namespace Arc {
20 
22  class PrintFBase {
23  public:
24  PrintFBase();
25  virtual ~PrintFBase();
26  virtual void msg(std::ostream& os) = 0;
27  virtual void msg(std::string& s) = 0;
28  void Retain();
29  bool Release();
30  private:
31  // Copying not allowed
32  PrintFBase(const PrintFBase&);
33  // Assignment not allowed
34  PrintFBase& operator=(const PrintFBase&);
35  int refcount;
36  };
39 
40 
41  const char* FindTrans(const char *p);
43 
44  const char* FindNTrans(const char *s, const char *p, unsigned long n);
45 
47  template<class T0 = int, class T1 = int, class T2 = int, class T3 = int,
48  class T4 = int, class T5 = int, class T6 = int, class T7 = int>
49  class PrintF
50  : public PrintFBase {
51 
52  public:
53 
54  PrintF(const std::string& m,
55  const T0& tt0 = 0, const T1& tt1 = 0,
56  const T2& tt2 = 0, const T3& tt3 = 0,
57  const T4& tt4 = 0, const T5& tt5 = 0,
58  const T6& tt6 = 0, const T7& tt7 = 0)
59  : PrintFBase(),
60  m(m) {
61  Copy(t0, tt0);
62  Copy(t1, tt1);
63  Copy(t2, tt2);
64  Copy(t3, tt3);
65  Copy(t4, tt4);
66  Copy(t5, tt5);
67  Copy(t6, tt6);
68  Copy(t7, tt7);
69  }
70 
71  ~PrintF() {
72  for (std::list<char*>::iterator it = ptrs.begin();
73  it != ptrs.end(); it++)
74  free(*it);
75  }
76 
77  virtual void msg(std::ostream& os) {
78 
79  char buffer[2048];
80  snprintf(buffer, 2048, Get(m),
81  Get(t0), Get(t1), Get(t2), Get(t3),
82  Get(t4), Get(t5), Get(t6), Get(t7));
83  os << buffer;
84  }
85 
86  virtual void msg(std::string& s) {
87 
88  char buffer[2048];
89  snprintf(buffer, 2048, Get(m),
90  Get(t0), Get(t1), Get(t2), Get(t3),
91  Get(t4), Get(t5), Get(t6), Get(t7));
92  s = buffer;
93  }
94 
95  private:
96 
97  // general case
98  template<class T, class U>
99  inline void Copy(T& t, const U& u) {
100  t = u;
101  }
102 
103  // char[] and const char[]
104  template<class T>
105  inline void Copy(T& t, const char u[]) {
106  strcpy(t, u);
107  }
108 
109  // const char*
110  inline void Copy(const char*& t, const char*const& u) {
111  t = strdup(u);
112  ptrs.push_back(const_cast<char*>(t));
113  }
114 
115  // char*
116  inline void Copy(char*& t, char*const& u) {
117  t = strdup(u);
118  ptrs.push_back(t);
119  }
120 
121  // general case
122  template<class T>
123  inline static const T& Get(const T& t) {
124  return t;
125  }
126 
127  // const char[] and const char*
128  inline static const char* Get(const char*const& t) {
129  return FindTrans(t);
130  }
131 
132  // char[] and char*
133  inline static const char* Get(char*const& t) {
134  return FindTrans(const_cast<const char*&>(t));
135  }
136 
137  // std::string
138  inline static const char* Get(const std::string& t) {
139  return FindTrans(t.c_str());
140  }
141 
142  // std::string ()()
143  inline static const char* Get(std::string (*t)()) {
144  return FindTrans(t().c_str());
145  }
146 
147  // Glib::ustring
148  inline static const char* Get(const Glib::ustring& t) {
149  return FindTrans(t.c_str());
150  }
151 
152  // Glib::ustring ()()
153  inline static const char* Get(Glib::ustring (*t)()) {
154  return FindTrans(t().c_str());
155  }
156 
157  // sigc::slot<const char*>*
158  inline static const char* Get(const sigc::slot<const char*> *t) {
159  return (*t)();
160  }
161 
162  std::string m;
163  T0 t0;
164  T1 t1;
165  T2 t2;
166  T3 t3;
167  T4 t4;
168  T5 t5;
169  T6 t6;
170  T7 t7;
171  std::list<char*> ptrs;
172  };
175 
176 
180  class IString {
181 
182  public:
183 
184  IString(const std::string& m)
185  : p(new PrintF<>(m)) {}
186 
187  template<class T0>
188  IString(const std::string& m, const T0& t0)
189  : p(new PrintF<T0>(m, t0)) {}
190 
191  template<class T0, class T1>
192  IString(const std::string& m, const T0& t0, const T1& t1)
193  : p(new PrintF<T0, T1>(m, t0, t1)) {}
194 
195  template<class T0, class T1, class T2>
196  IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2)
197  : p(new PrintF<T0, T1, T2>(m, t0, t1, t2)) {}
198 
199  template<class T0, class T1, class T2, class T3>
200  IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2, const T3& t3)
201  : p(new PrintF<T0, T1, T2, T3>(m, t0, t1, t2, t3)) {}
202 
203  template<class T0, class T1, class T2, class T3, class T4>
204  IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4)
205  : p(new PrintF<T0, T1, T2, T3, T4>(m, t0, t1, t2, t3, t4)) {}
206 
207  template<class T0, class T1, class T2, class T3, class T4, class T5>
208  IString(const std::string& m, const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5)
209  : p(new PrintF<T0, T1, T2, T3, T4, T5>(m, t0, t1, t2, t3, t4, t5)) {}
210 
211  template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
212  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)
213  : p(new PrintF<T0, T1, T2, T3, T4, T5, T6>(m, t0, t1, t2, t3, t4, t5, t6)) {}
214 
215  template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7>
216  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)
217  : p(new PrintF<T0, T1, T2, T3, T4, T5, T6, T7>(m, t0, t1, t2, t3, t4, t5, t6, t7)) {}
218 
219  ~IString();
220 
221  IString(const IString& istr);
222  IString& operator=(const IString& istr);
223  std::string str(void);
224 
225  private:
226 
227  PrintFBase *p;
228 
229  friend std::ostream& operator<<(std::ostream& os, const IString& msg);
230  };
231 
233  std::ostream& operator<<(std::ostream& os, const IString& msg);
234 
235 } // namespace Arc
236 
237 #endif // __ARC_ISTRING__