| | 245 | // ------------------ |
| | 246 | // copy |
| | 247 | |
| | 248 | |
| | 249 | template <typename T> |
| | 250 | class copy //! makes char* copyable, so it can be handled like most other types |
| | 251 | { |
| | 252 | T t; |
| | 253 | public: |
| | 254 | copy(const T& t_) : t(t_) {} |
| | 255 | operator const T&() const { return t; } |
| | 256 | }; |
| | 257 | |
| | 258 | template <> |
| | 259 | class copy<const char *> { |
| | 260 | str t; |
| | 261 | public: |
| | 262 | copy(const char *t_) : t(str(t_ ? strdup(t_) : NULL)) {} |
| | 263 | operator const char *() const { return t.value(); } |
| | 264 | }; |
| | 265 | |
| | 266 | template <typename T> class copy< copy<T> > { copy(const copy<T>& t_); }; // avoid copies of copies |
| | 267 | |
| | 268 | template <typename T> inline copy<T> make_copy(const T& t) { return copy<T>(t); } |
| | 269 | |
| | 270 | inline copy<const char *> make_copy(const char *p) { return copy<const char *>(p); } |
| | 271 | inline copy<const char *> make_copy(char *p) { return copy<const char *>(p); } |
| | 272 | inline copy<const char *> make_copy(const unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } |
| | 273 | inline copy<const char *> make_copy(unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } |
| | 274 | inline copy<const char *> make_copy(const signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } |
| | 275 | inline copy<const char *> make_copy(signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } |
| | 276 | |
| | 277 | inline copy<unsigned char> make_copy(char p) { return copy<unsigned char>(p); } |
| | 278 | inline copy<unsigned char> make_copy(unsigned char p) { return copy<unsigned char>(p); } |
| | 279 | inline copy<unsigned char> make_copy(signed char p) { return copy<unsigned char>(p); } |
| | 280 | |
| | 281 | template <typename T> str readable(const copy<T>& v) { return str(val2readable(v)); } |
| | 282 | template <typename T> str readableHex(const copy<T>& v) { return str(val2readableHex(v)); } |
| | 283 | |
| | 284 | template <typename T> bool operator == (const copy<T>& v1, const copy<T>& v2) { return static_cast<const T&>(v1) == static_cast<const T&>(v2); } |
| | 285 | template <typename T> bool operator != (const copy<T>& v1, const copy<T>& v2) { return !(v1 == v2); } |
| | 286 | |
| | 287 | template <> inline bool operator == <const char *>(const copy<const char *>& v1, const copy<const char *>& v2) { |
| | 288 | const char *val1 = v1; |
| | 289 | const char *val2 = v2; |
| | 290 | |
| | 291 | return (val1 == val2) || (val1 && val2 && (strcmp(val1, val2) == 0)); |
| | 292 | } |
| | 293 | |
| | 294 | |
| 352 | | |
| 353 | | |
| 354 | | // ------------------ |
| 355 | | // copy |
| 356 | | |
| 357 | | |
| 358 | | template <typename T> |
| 359 | | class copy //! makes char* copyable, so it can be handled like most other types |
| 360 | | { |
| 361 | | T t; |
| 362 | | public: |
| 363 | | copy(const T& t_) : t(t_) {} |
| 364 | | operator const T&() const { return t; } |
| 365 | | }; |
| 366 | | |
| 367 | | template <> |
| 368 | | class copy<const char *> { |
| 369 | | str t; |
| 370 | | public: |
| 371 | | copy(const char *t_) : t(str(t_ ? strdup(t_) : NULL)) {} |
| 372 | | operator const char *() const { return t.value(); } |
| 373 | | }; |
| 374 | | |
| 375 | | template <typename T> class copy< copy<T> > { copy(const copy<T>& t_); }; // avoid copies of copies |
| 376 | | |
| 377 | | template <typename T> inline copy<T> make_copy(const T& t) { return copy<T>(t); } |
| 378 | | |
| 379 | | inline copy<const char *> make_copy(const char *p) { return copy<const char *>(p); } |
| 380 | | inline copy<const char *> make_copy(char *p) { return copy<const char *>(p); } |
| 381 | | inline copy<const char *> make_copy(const unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } |
| 382 | | inline copy<const char *> make_copy(unsigned char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } |
| 383 | | inline copy<const char *> make_copy(const signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } |
| 384 | | inline copy<const char *> make_copy(signed char *p) { return copy<const char *>(reinterpret_cast<const char *>(p)); } |
| 385 | | |
| 386 | | inline copy<unsigned char> make_copy(char p) { return copy<unsigned char>(p); } |
| 387 | | inline copy<unsigned char> make_copy(unsigned char p) { return copy<unsigned char>(p); } |
| 388 | | inline copy<unsigned char> make_copy(signed char p) { return copy<unsigned char>(p); } |
| 389 | | |
| 390 | | template <typename T> str readable(const copy<T>& v) { return str(val2readable(v)); } |
| 391 | | template <typename T> str readableHex(const copy<T>& v) { return str(val2readableHex(v)); } |
| 392 | | |
| 393 | | template <typename T> bool operator == (const copy<T>& v1, const copy<T>& v2) { return static_cast<const T&>(v1) == static_cast<const T&>(v2); } |
| 394 | | template <typename T> bool operator != (const copy<T>& v1, const copy<T>& v2) { return !(v1 == v2); } |
| 395 | | |
| 396 | | template <> inline bool operator == <const char *>(const copy<const char *>& v1, const copy<const char *>& v2) { |
| 397 | | const char *val1 = v1; |
| 398 | | const char *val2 = v2; |
| 399 | | |
| 400 | | return (val1 == val2) || (val1 && val2 && (strcmp(val1, val2) == 0)); |
| 401 | | } |
| 402 | | |