string_ref.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. // Reference to the range of chars
  2. //
  3. // Platform: ISO C++ 98/11
  4. // $Id$
  5. //
  6. // (c) __vic 2009
  7. #ifndef __VIC_STRING_REF_H
  8. #define __VIC_STRING_REF_H
  9. #include<__vic/defs.h>
  10. #include<__vic/tchar.h>
  11. #include<string>
  12. namespace __vic {
  13. //////////////////////////////////////////////////////////////////////////////
  14. template<class charT>
  15. class basic_string_ref
  16. {
  17. const charT *begin_, *end_;
  18. public:
  19. typedef charT value_type;
  20. typedef const value_type *iterator;
  21. typedef iterator const_iterator;
  22. // Constructors
  23. __VIC_CONSTEXPR_FUNC basic_string_ref() : begin_(nullptr), end_(nullptr) {}
  24. basic_string_ref(const charT *st)
  25. : begin_(st), end_(tchar::end(st)) {}
  26. basic_string_ref(const charT *st, size_t n)
  27. : begin_(st), end_(st + n) {}
  28. basic_string_ref(const charT *b, const charT *e)
  29. : begin_(b), end_(e) {}
  30. template<class Traits, class Alloc>
  31. basic_string_ref(const std::basic_string<charT,Traits,Alloc> &st)
  32. : begin_(&*st.begin()), end_(&*st.end()) {}
  33. basic_string_ref(
  34. typename std::basic_string<charT>::const_iterator begin,
  35. typename std::basic_string<charT>::const_iterator end
  36. ) : begin_(&*begin), end_(&*end) {}
  37. #if __cpp_initializer_lists
  38. basic_string_ref(std::initializer_list<charT> il)
  39. : begin_(&*il.begin()), end_(&*il.end()) {}
  40. #endif
  41. // Accessors
  42. iterator begin() const { return begin_; }
  43. iterator end() const { return end_; }
  44. iterator cbegin() const { return begin(); }
  45. iterator cend() const { return end(); }
  46. charT front() const { return *begin(); }
  47. charT back() const { return *(end() - 1); }
  48. charT operator[](size_t i) const { return begin_[i]; }
  49. const charT *data() const { return begin_; }
  50. bool empty() const { return begin() == end(); }
  51. size_t size() const { return end() - begin(); }
  52. size_t length() const { return size(); }
  53. int compare(basic_string_ref ) const;
  54. // Converters
  55. std::basic_string<charT>
  56. str() const { return std::basic_string<charT>(begin(), end()); }
  57. template<class Traits>
  58. std::basic_string<charT,Traits>
  59. str() const { return std::basic_string<charT,Traits>(begin(), end()); }
  60. template<class Traits, class Alloc>
  61. std::basic_string<charT,Traits,Alloc> str(const Alloc &a = Alloc()) const
  62. { return std::basic_string<charT,Traits,Alloc>(begin(), end(), a); }
  63. operator std::basic_string<charT>() const { return str(); }
  64. };
  65. //////////////////////////////////////////////////////////////////////////////
  66. typedef basic_string_ref<char> string_ref;
  67. //----------------------------------------------------------------------------
  68. template<class charT>
  69. int basic_string_ref<charT>::compare(basic_string_ref<charT> s) const
  70. {
  71. iterator p = begin(), q = s.begin();
  72. for(;; ++p, ++q)
  73. {
  74. if(p == end()) return q == s.end() ? 0 : -1; // s1 < s2
  75. if(q == s.end()) return 1; // s1 > s2
  76. if(*p < *q) return -1; // s1 < s2
  77. if(*p > *q) return 1; // s1 > s2
  78. }
  79. }
  80. //----------------------------------------------------------------------------
  81. template<class charT>
  82. inline bool operator==(basic_string_ref<charT> s1, basic_string_ref<charT> s2)
  83. { return s1.length() == s2.length() && s1.compare(s2) == 0; }
  84. //----------------------------------------------------------------------------
  85. template<class charT>
  86. inline bool operator!=(basic_string_ref<charT> s1, basic_string_ref<charT> s2)
  87. { return !(s1 == s2); }
  88. //----------------------------------------------------------------------------
  89. template<class charT>
  90. inline bool operator<(basic_string_ref<charT> s1, basic_string_ref<charT> s2)
  91. { return s1.compare(s2) < 0; }
  92. //----------------------------------------------------------------------------
  93. template<class charT>
  94. inline bool operator>(basic_string_ref<charT> s1, basic_string_ref<charT> s2)
  95. { return s1.compare(s2) > 0; }
  96. //----------------------------------------------------------------------------
  97. template<class charT>
  98. inline bool operator<=(basic_string_ref<charT> s1, basic_string_ref<charT> s2)
  99. { return s1.compare(s2) <= 0; }
  100. //----------------------------------------------------------------------------
  101. template<class charT>
  102. inline bool operator>=(basic_string_ref<charT> s1, basic_string_ref<charT> s2)
  103. { return s1.compare(s2) >= 0; }
  104. //----------------------------------------------------------------------------
  105. // Non-templated operators to force implicit conversions to string_ref
  106. inline bool operator==(string_ref s1, string_ref s2) { return operator== <>(s1, s2); }
  107. inline bool operator!=(string_ref s1, string_ref s2) { return operator!= <>(s1, s2); }
  108. inline bool operator< (string_ref s1, string_ref s2) { return operator< <>(s1, s2); }
  109. inline bool operator> (string_ref s1, string_ref s2) { return operator> <>(s1, s2); }
  110. inline bool operator<=(string_ref s1, string_ref s2) { return operator<= <>(s1, s2); }
  111. inline bool operator>=(string_ref s1, string_ref s2) { return operator>= <>(s1, s2); }
  112. //----------------------------------------------------------------------------
  113. } // namespace
  114. #ifdef __VIC_DEFINE_OSTREAM_INSERTERS
  115. #include<ostream>
  116. //----------------------------------------------------------------------------
  117. template<class charT, class Traits>
  118. inline std::basic_ostream<charT,Traits> &operator<<(
  119. std::basic_ostream<charT,Traits> &os,
  120. __vic::basic_string_ref<charT> sr)
  121. {
  122. return os.write(sr.begin(), sr.size());
  123. }
  124. //----------------------------------------------------------------------------
  125. inline std::ostream &operator<<(std::ostream &os, __vic::string_ref sr)
  126. {
  127. return operator<< <>(os, sr);
  128. }
  129. //----------------------------------------------------------------------------
  130. #endif
  131. #endif // header guard