readonly_cstring.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. // The simple non-mutable null-terminated string class
  2. // with automatic memory management
  3. //
  4. // Platform: ISO C++ 98/11
  5. // $Id$
  6. //
  7. // (c) __vic 2007
  8. #ifndef __VIC_READONLY_CSTRING_H
  9. #define __VIC_READONLY_CSTRING_H
  10. #include<__vic/defs.h>
  11. #include __VIC_SWAP_HEADER
  12. #include<cstring>
  13. namespace __vic {
  14. //////////////////////////////////////////////////////////////////////////////
  15. class readonly_cstring
  16. {
  17. const char *st;
  18. static const char *dup(const char * , size_t = size_t(-1));
  19. public:
  20. __VIC_CONSTEXPR_FUNC readonly_cstring() : st(nullptr) {}
  21. readonly_cstring(const char *s) : st(dup(s)) {}
  22. readonly_cstring(const char *begin, const char *end) : st(dup(begin, end-begin)) {}
  23. readonly_cstring(const char *s, size_t n) : st(dup(s, n)) {}
  24. readonly_cstring(const readonly_cstring &s) : st(dup(s.st)) {}
  25. ~readonly_cstring() noexcept; // for error.h
  26. readonly_cstring &operator=(const char * );
  27. readonly_cstring &operator=(const readonly_cstring & );
  28. readonly_cstring &assign(const char * , const char * );
  29. readonly_cstring &assign(const char * , size_t );
  30. #if __cpp_rvalue_references
  31. readonly_cstring(readonly_cstring &&s) noexcept : st(s.st) { s.st = nullptr; }
  32. readonly_cstring &operator=(readonly_cstring &&s) noexcept
  33. { swap(s); return *this; }
  34. #endif
  35. // allocates internal buffer and returns pointer to it. Use with care!
  36. // specified size must include space for '\0' terminator!
  37. char *reserve(size_t );
  38. int compare(const char *s) const { return std::strcmp(*this, s ? s : ""); }
  39. bool empty() const { return !st || *st == '\0'; }
  40. const char *c_str() const { return st ? st : ""; }
  41. operator const char*() const { return c_str(); }
  42. void swap(readonly_cstring &s) noexcept { std::swap(st, s.st); }
  43. };
  44. //////////////////////////////////////////////////////////////////////////////
  45. //----------------------------------------------------------------------------
  46. // readonly_cstring compare function and operators
  47. //----------------------------------------------------------------------------
  48. inline int compare(const readonly_cstring &s1, const readonly_cstring &s2)
  49. {
  50. return std::strcmp(s1, s2);
  51. }
  52. inline int compare(const readonly_cstring &s1, const char *s2)
  53. {
  54. return s1.compare(s2);
  55. }
  56. inline int compare(const char *s1, const readonly_cstring &s2)
  57. {
  58. return s2.compare(s1);
  59. }
  60. //----------------------------------------------------------------------------
  61. #define __VIC_DEFINE_OP(OP,T1,T2) \
  62. inline bool operator OP(T1 s1, T2 s2) { return compare(s1, s2) OP 0; }
  63. __VIC_DEFINE_OP(==, const readonly_cstring &, const readonly_cstring &)
  64. __VIC_DEFINE_OP(!=, const readonly_cstring &, const readonly_cstring &)
  65. __VIC_DEFINE_OP(< , const readonly_cstring &, const readonly_cstring &)
  66. __VIC_DEFINE_OP(> , const readonly_cstring &, const readonly_cstring &)
  67. __VIC_DEFINE_OP(<=, const readonly_cstring &, const readonly_cstring &)
  68. __VIC_DEFINE_OP(>=, const readonly_cstring &, const readonly_cstring &)
  69. __VIC_DEFINE_OP(==, const readonly_cstring &, const char *)
  70. __VIC_DEFINE_OP(!=, const readonly_cstring &, const char *)
  71. __VIC_DEFINE_OP(< , const readonly_cstring &, const char *)
  72. __VIC_DEFINE_OP(> , const readonly_cstring &, const char *)
  73. __VIC_DEFINE_OP(<=, const readonly_cstring &, const char *)
  74. __VIC_DEFINE_OP(>=, const readonly_cstring &, const char *)
  75. __VIC_DEFINE_OP(==, const char *, const readonly_cstring &)
  76. __VIC_DEFINE_OP(!=, const char *, const readonly_cstring &)
  77. __VIC_DEFINE_OP(< , const char *, const readonly_cstring &)
  78. __VIC_DEFINE_OP(> , const char *, const readonly_cstring &)
  79. __VIC_DEFINE_OP(<=, const char *, const readonly_cstring &)
  80. __VIC_DEFINE_OP(>=, const char *, const readonly_cstring &)
  81. #undef __VIC_DEFINE_OP
  82. //----------------------------------------------------------------------------
  83. inline void swap(readonly_cstring &s1, readonly_cstring &s2) noexcept
  84. {
  85. s1.swap(s2);
  86. }
  87. //----------------------------------------------------------------------------
  88. } // namespace
  89. #endif // header guard