trimmed.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //
  2. // $Id$
  3. //
  4. #include<__vic/string_utils.h>
  5. #include<__vic/algorithm.h>
  6. #include<__vic/char_predicates.h>
  7. namespace __vic {
  8. #if __cpp_lib_string_view // C++17
  9. namespace {
  10. //----------------------------------------------------------------------------
  11. template<class charT, class Traits, class Pred>
  12. inline std::basic_string_view<charT,Traits> trimmed_if_back(
  13. std::basic_string_view<charT,Traits> st, Pred pred)
  14. {
  15. const charT *begin = st.data();
  16. const charT *end = skip_if_back(begin, begin + st.length(), pred);
  17. return {begin, static_cast<std::size_t>(end - begin)};
  18. }
  19. //----------------------------------------------------------------------------
  20. template<class charT, class Traits, class Pred>
  21. inline std::basic_string_view<charT,Traits> trimmed_if_front(
  22. std::basic_string_view<charT,Traits> st, Pred pred)
  23. {
  24. const charT *begin = st.data();
  25. const charT *end = begin + st.length();
  26. begin = skip_if_front(begin, end, pred);
  27. return {begin, static_cast<std::size_t>(end - begin)};
  28. }
  29. //----------------------------------------------------------------------------
  30. template<class charT, class Traits, class Pred>
  31. inline std::basic_string_view<charT,Traits> trimmed_if(
  32. std::basic_string_view<charT,Traits> st, Pred pred)
  33. {
  34. const charT *begin = st.data();
  35. const charT *end = begin + st.length();
  36. end = skip_if_back(begin, end, pred);
  37. begin = skip_if_front(begin, end, pred);
  38. return {begin, static_cast<std::size_t>(end - begin)};
  39. }
  40. //----------------------------------------------------------------------------
  41. } // namespace
  42. //----------------------------------------------------------------------------
  43. std::string_view trimmed(std::string_view st)
  44. {
  45. return trimmed_if(st, is_ascii_ws());
  46. }
  47. //----------------------------------------------------------------------------
  48. std::string_view trimmed_back(std::string_view st)
  49. {
  50. return trimmed_if_back(st, is_ascii_ws());
  51. }
  52. //----------------------------------------------------------------------------
  53. std::string_view trimmed_front(std::string_view st)
  54. {
  55. return trimmed_if_front(st, is_ascii_ws());
  56. }
  57. //----------------------------------------------------------------------------
  58. std::string_view trimmed(std::string_view st, char ch)
  59. {
  60. return trimmed_if(st, is_eq_char(ch));
  61. }
  62. //----------------------------------------------------------------------------
  63. std::string_view trimmed_back(std::string_view st, char ch)
  64. {
  65. return trimmed_if_back(st, is_eq_char(ch));
  66. }
  67. //----------------------------------------------------------------------------
  68. std::string_view trimmed_front(std::string_view st, char ch)
  69. {
  70. return trimmed_if_front(st, is_eq_char(ch));
  71. }
  72. //----------------------------------------------------------------------------
  73. std::string_view trimmed(std::string_view st, const char *set)
  74. {
  75. return set ? trimmed_if(st, is_one_of_chars(set)) : st;
  76. }
  77. //----------------------------------------------------------------------------
  78. std::string_view trimmed_back(std::string_view st, const char *set)
  79. {
  80. return set ? trimmed_if_back(st, is_one_of_chars(set)) : st;
  81. }
  82. //----------------------------------------------------------------------------
  83. std::string_view trimmed_front(std::string_view st, const char *set)
  84. {
  85. return set ? trimmed_if_front(st, is_one_of_chars(set)) : st;
  86. }
  87. //----------------------------------------------------------------------------
  88. #else // no string_view
  89. namespace {
  90. //----------------------------------------------------------------------------
  91. template<class charT, class Traits, class Alloc, class Pred>
  92. inline std::basic_string<charT,Traits,Alloc> trimmed_if_back(
  93. const std::basic_string<charT,Traits,Alloc> &st, Pred pred)
  94. {
  95. const charT *begin = st.data();
  96. return std::basic_string<charT,Traits,Alloc>(
  97. begin, skip_if_back(begin, &*st.end(), pred));
  98. }
  99. //----------------------------------------------------------------------------
  100. template<class charT, class Traits, class Alloc, class Pred>
  101. inline std::basic_string<charT,Traits,Alloc> trimmed_if_front(
  102. const std::basic_string<charT,Traits,Alloc> &st, Pred pred)
  103. {
  104. const charT *end = &*st.end();
  105. return std::basic_string<charT,Traits,Alloc>(
  106. skip_if_front(st.data(), end, pred), end);
  107. }
  108. //----------------------------------------------------------------------------
  109. template<class charT, class Traits, class Alloc, class Pred>
  110. inline std::basic_string<charT,Traits,Alloc> trimmed_if(
  111. const std::basic_string<charT,Traits,Alloc> &st, Pred pred)
  112. {
  113. const charT *begin = st.data();
  114. const charT *e = skip_if_back(begin, &*st.end(), pred);
  115. const charT *b = skip_if_front(begin, e, pred);
  116. return std::basic_string<charT,Traits,Alloc>(b, e);
  117. }
  118. //----------------------------------------------------------------------------
  119. } // namespace
  120. //----------------------------------------------------------------------------
  121. std::string trimmed(const std::string &st)
  122. {
  123. return trimmed_if(st, is_ascii_ws());
  124. }
  125. //----------------------------------------------------------------------------
  126. std::string trimmed_back(const std::string &st)
  127. {
  128. return trimmed_if_back(st, is_ascii_ws());
  129. }
  130. //----------------------------------------------------------------------------
  131. std::string trimmed_front(const std::string &st)
  132. {
  133. return trimmed_if_front(st, is_ascii_ws());
  134. }
  135. //----------------------------------------------------------------------------
  136. std::string trimmed(const std::string &st, char ch)
  137. {
  138. return trimmed_if(st, is_eq_char(ch));
  139. }
  140. //----------------------------------------------------------------------------
  141. std::string trimmed_back(const std::string &st, char ch)
  142. {
  143. return trimmed_if_back(st, is_eq_char(ch));
  144. }
  145. //----------------------------------------------------------------------------
  146. std::string trimmed_front(const std::string &st, char ch)
  147. {
  148. return trimmed_if_front(st, is_eq_char(ch));
  149. }
  150. //----------------------------------------------------------------------------
  151. std::string trimmed(const std::string &st, const char *set)
  152. {
  153. return set ? trimmed_if(st, is_one_of_chars(set)) : st;
  154. }
  155. //----------------------------------------------------------------------------
  156. std::string trimmed_back(const std::string &st, const char *set)
  157. {
  158. return set ? trimmed_if_back(st, is_one_of_chars(set)) : st;
  159. }
  160. //----------------------------------------------------------------------------
  161. std::string trimmed_front(const std::string &st, const char *set)
  162. {
  163. return set ? trimmed_if_front(st, is_one_of_chars(set)) : st;
  164. }
  165. //----------------------------------------------------------------------------
  166. #endif
  167. } // namespace