string_buffer.h.xml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. <chapter xml:id="string_buffer.h">
  2. <title><tt>__vic/string_buffer.h</tt></title>
  3. <chapter xml:id="string_buffer">
  4. <title><tt>string_buffer</tt></title>
  5. <code-block lang="C++"><![CDATA[
  6. class string_buffer : public std::string
  7. {
  8. public:
  9. string_buffer();
  10. explicit string_buffer(size_type n);
  11. string_buffer(const char *str);
  12. string_buffer(std::string str);
  13. string_buffer(string_ref sr);
  14. string_buffer(const std::string &str, size_type off, size_type n = npos);
  15. string_buffer(const char *char_buf, size_type n);
  16. string_buffer(const char *begin, const char *end);
  17. template<class InputIterator>
  18. string_buffer(InputIterator begin, InputIterator end);
  19. string_buffer &operator<<(const char *str);
  20. string_buffer &operator<<(const std::string &str);
  21. string_buffer &operator<<(string_ref sr);
  22. string_buffer &operator<<(char ch);
  23. string_buffer &operator<<(long long n);
  24. string_buffer &operator<<(long n);
  25. string_buffer &operator<<(int n);
  26. string_buffer &operator<<(short n);
  27. string_buffer &operator<<(signed char ch);
  28. string_buffer &operator<<(unsigned long long n);
  29. string_buffer &operator<<(unsigned long n);
  30. string_buffer &operator<<(unsigned n);
  31. string_buffer &operator<<(unsigned short n);
  32. string_buffer &operator<<(unsigned char ch);
  33. string_buffer &operator<<(long double n);
  34. string_buffer &operator<<(double n);
  35. string_buffer &operator<<(float n);
  36. string_buffer &operator<<(bool flag);
  37. string_buffer &operator<<(const void *p);
  38. string_buffer &operator=(string_ref sr);
  39. string_buffer &operator+=(string_ref sr);
  40. string_buffer &assign(string_ref sr);
  41. string_buffer &append(string_ref sr);
  42. // improved std::string calls
  43. string_buffer &assign(const std::string &str,
  44. size_type off, size_type n = npos);
  45. string_buffer &append(const std::string &str,
  46. size_type off, size_type n = npos);
  47. string_buffer &insert(size_type pos, const std::string &str,
  48. size_type off, size_type n = npos);
  49. string_buffer &reserve(size_type n);
  50. string_buffer &clear();
  51. // missing container interface of std::string
  52. reference front();
  53. reference back();
  54. const_reference front() const;
  55. const_reference back() const;
  56. void pop_back();
  57. operator const char *() const;
  58. };
  59. string_buffer operator+(const string_buffer &s1, const string_buffer &s2);
  60. string_buffer operator+(const string_buffer &s1, const std::string &s2);
  61. string_buffer operator+(const std::string &s1, const string_buffer &s2);
  62. string_buffer operator+(const string_buffer &s1, const char *s2);
  63. string_buffer operator+(const char *s1, const string_buffer &s2);
  64. string_buffer operator+(const string_buffer &s, char ch);
  65. string_buffer operator+(char ch, const string_buffer &s);
  66. template<class T>
  67. string_buffer &operator<<(string_buffer &&s, const T &v); // C++11
  68. using msg = string_buffer;
  69. ]]></code-block>
  70. <p>Класс является улучшенным и расширенным <tt>std::string</tt>. Он имеет
  71. следующие преимущества:</p>
  72. <list style="numbered">
  73. <item>Лево-ассоциативная операция конкатенации (<tt>&lt;&lt;</tt>),
  74. позволяющая конструкции, вроде:
  75. <code-block lang="C++"><![CDATA[
  76. str << "Error message: " << err_msg << "\n";
  77. ]]></code-block></item>
  78. <item>В конструкторе можно зарезервировать место под строку в целях
  79. оптимизации, чтобы избежать многократного перераспределения буфера, что
  80. значительно улучшает производительность. Часто имеется возможность оценить
  81. максимальный размер строки. Но если она вдруг окажется длиннее, то буфер
  82. автоматически расширится, как и у <tt>std::string</tt>.
  83. <code-block lang="C++">
  84. __vic::string_buffer st(4096);
  85. // Эффект аналогичен
  86. std::string st;
  87. st.reserve(4096);
  88. </code-block></item>
  89. <item>Оператор <tt>&lt;&lt;</tt> воспринимает все фундаментальные типы:
  90. числа, символы, указатели, <tt>bool</tt>.
  91. <code-block lang="C++"><![CDATA[
  92. for(int i=0; i<10; i++)
  93. str << "i = " << i << '\n';
  94. ]]></code-block></item>
  95. <item>Все операции, работающие с <tt>const char *</tt>, корректно воспринимают
  96. пустой указатель как пустую строку. Реализации <tt>std::string</tt> не
  97. проверяют указатель на пустоту и пытаются читать по нему в любом случае.
  98. <code-block lang="C++">
  99. std::string s1("Str");
  100. const char *p = nullptr;
  101. s1.append(p); // Oops.... Null pointer access!
  102. __vic::string_buffer s2("Str");
  103. s2.append(p); // Ok. s2 == "Str" still
  104. s2 = p; // Ok. s2.empty() == true
  105. </code-block></item>
  106. <item>Автоматическое преобразование в <tt>const char *</tt> позволяет
  107. использовать объекты в контекстах, требующих C-строку без явного преобразования.
  108. <code-block lang="C++">
  109. std::string fname(...);
  110. FILE *fp = fopen(fname.c_str(), "r");
  111. __vic::string_buffer fname(...);
  112. FILE *fp = fopen(fname, "r");)
  113. </code-block></item>
  114. <item>Исправлены нерегулярности в дизайне класса <tt>std::string</tt>. Например,
  115. класс является полноценным контейнером с доступом к его началу и концу, но у
  116. него отсутствуют операции <tt>front()</tt> и <tt>back()</tt> в C++98.
  117. Также класс имеет операцию <tt>push_back()</tt>, но не имеет симметричной
  118. <tt>pop_back()</tt>.</item>
  119. </list>
  120. <p>При всех этих улучшениях, объекты данного типа полностью совместимы по
  121. структуре с <tt>std::string</tt> и могут передаваться в контексты, требующие
  122. <tt>std::string</tt>. Никаких дополнительных членов-данных в классе нет.</p>
  123. <p>Использование инсертера (оператора <tt>&lt;&lt;</tt>) данного класса –
  124. это простейший способ преобразовать число или указатель в строку. Механизм,
  125. конечно, не такой мощный, как использование <tt>std::ostringstream</tt>,
  126. например нельзя задать основание системы счисления или форматирование, но зато
  127. самый простой и эффективный. Для вывода диагностики, к примеру, обычно его
  128. вполне достаточно.</p>
  129. <p>Также для данного типа введён синоним <tt>msg</tt>, который удобно
  130. использовать для конструирования составных сообщений на лету одним
  131. выражением без введения дополнительных переменных:</p>
  132. <code-block lang="C++"><![CDATA[
  133. oresult res = db_open(db_name);
  134. if(res != 0) throw __vic::exception(
  135. __vic::msg(64) << "Cannot open DB " << db_name << ". res = " << res
  136. );
  137. ]]></code-block>
  138. <p>Как видно в примере, в конструктор в целях оптимизации передан максимальный
  139. ожидаемый размер строки.</p>
  140. <section><title>Члены класса</title>
  141. <synopsis>
  142. <prototype>string_buffer()</prototype>
  143. <p>Создаёт пустую строку.</p>
  144. <postcondition><tt>empty() == true</tt></postcondition>
  145. </synopsis>
  146. <synopsis>
  147. <prototype>explicit string_buffer(size_type n)</prototype>
  148. <p>Вызывает <tt>reserve(n)</tt>.</p>
  149. <postcondition><tt>capacity() >= n</tt></postcondition>
  150. </synopsis>
  151. <synopsis>
  152. <prototype>string_buffer(const char *str)</prototype>
  153. <prototype>string_buffer(std::string str)</prototype>
  154. <p>Создаёт копию <tt>str</tt>.</p>
  155. </synopsis>
  156. <synopsis>
  157. <prototype>string_buffer(const std::string &amp;str, size_type off, size_type n = npos)</prototype>
  158. <p>Создаёт копию подстроки <tt>str</tt>.</p>
  159. </synopsis>
  160. <synopsis>
  161. <prototype>string_buffer(const char *char_buf, size_type n)</prototype>
  162. <p>Создаёт строку из буфера и его длины.</p>
  163. </synopsis>
  164. <synopsis>
  165. <prototype>string_buffer(string_ref sr)</prototype>
  166. <prototype>string_buffer(const char *begin, const char *end)</prototype>
  167. <prototype>template&lt;class InputIterator>
  168. string_buffer(InputIterator begin, InputIterator end)</prototype>
  169. <p>Создаёт строку из диапазона символов.</p>
  170. </synopsis>
  171. <synopsis>
  172. <prototype>string_buffer &amp;operator&lt;&lt;(const char *str)</prototype>
  173. <prototype>string_buffer &amp;operator&lt;&lt;(const std::string &amp;str)</prototype>
  174. <prototype>string_buffer &amp;operator&lt;&lt;(string_ref sr)</prototype>
  175. <prototype>string_buffer &amp;operator&lt;&lt;(char ch)</prototype>
  176. <p>Вызывает <tt>std::string::append()</tt>.</p>
  177. </synopsis>
  178. <synopsis>
  179. <prototype>string_buffer &amp;operator&lt;&lt;(long long n)</prototype>
  180. <prototype>string_buffer &amp;operator&lt;&lt;(long n)</prototype>
  181. <prototype>string_buffer &amp;operator&lt;&lt;(int n)</prototype>
  182. <prototype>string_buffer &amp;operator&lt;&lt;(short n)</prototype>
  183. <prototype>string_buffer &amp;operator&lt;&lt;(signed char ch)</prototype>
  184. <prototype>string_buffer &amp;operator&lt;&lt;(unsigned long long n)</prototype>
  185. <prototype>string_buffer &amp;operator&lt;&lt;(unsigned long n)</prototype>
  186. <prototype>string_buffer &amp;operator&lt;&lt;(unsigned n)</prototype>
  187. <prototype>string_buffer &amp;operator&lt;&lt;(unsigned short n)</prototype>
  188. <prototype>string_buffer &amp;operator&lt;&lt;(unsigned char ch)</prototype>
  189. <prototype>string_buffer &amp;operator&lt;&lt;(long double n)</prototype>
  190. <prototype>string_buffer &amp;operator&lt;&lt;(double n)</prototype>
  191. <prototype>string_buffer &amp;operator&lt;&lt;(float n)</prototype>
  192. <p>Добавляет к строке десятичное представление <tt>n</tt>.</p>
  193. </synopsis>
  194. <synopsis>
  195. <prototype>string_buffer &amp;operator&lt;&lt;(const void *p)</prototype>
  196. <p>Добавляет к строке значение указателя в формате <tt>std::printf</tt>.</p>
  197. </synopsis>
  198. <synopsis>
  199. <prototype>string_buffer &amp;operator&lt;&lt;(bool flag)</prototype>
  200. <p>Добавляет к строке <tt>1</tt> (для <tt>true</tt>) или <tt>0</tt> (для
  201. <tt>false</tt>).</p>
  202. </synopsis>
  203. <synopsis>
  204. <prototype>string_buffer &amp;operator=(string_ref sr)</prototype>
  205. <prototype>string_buffer &amp;operator+=(string_ref sr)</prototype>
  206. <prototype>string_buffer &amp;assign(string_ref sr)</prototype>
  207. <prototype>string_buffer &amp;append(string_ref sr)</prototype>
  208. <p>Операции для <tt>string_ref</tt>.</p>
  209. </synopsis>
  210. <synopsis>
  211. <prototype>string_buffer &amp;reserve(size_type n)</prototype>
  212. <prototype>string_buffer &amp;clear()</prototype>
  213. <p>Вызывают одноимённую операцию <tt>std::string</tt> и дополнительно возвращают
  214. ссылку на себя, что позволяет использовать вызовы в составных выражениях.</p>
  215. </synopsis>
  216. <synopsis>
  217. <prototype>reference front()</prototype>
  218. <prototype>reference back()</prototype>
  219. <prototype>const_reference front() const</prototype>
  220. <prototype>const_reference back() const</prototype>
  221. <prototype>void pop_back()</prototype>
  222. <p>Недостающие операции интерфейса <tt>std::string</tt> в C++98.</p>
  223. </synopsis>
  224. <synopsis>
  225. <prototype>operator const char *() const</prototype>
  226. <p>Вызывает <tt>std::string::c_str()</tt>.</p>
  227. </synopsis>
  228. <synopsis>
  229. <prototype>string_buffer operator+(const string_buffer &amp;s1, const string_buffer &amp;s2)</prototype>
  230. <prototype>string_buffer operator+(const string_buffer &amp;s1, const std::string &amp;s2)</prototype>
  231. <prototype>string_buffer operator+(const std::string &amp;s1, const string_buffer &amp;s2)</prototype>
  232. <prototype>string_buffer operator+(const string_buffer &amp;s1, const char *s2)</prototype>
  233. <prototype>string_buffer operator+(const char *s1, const string_buffer &amp;s2)</prototype>
  234. <prototype>string_buffer operator+(const string_buffer &amp;s, char ch)</prototype>
  235. <prototype>string_buffer operator+(char ch, const string_buffer &amp;s)</prototype>
  236. <p>Конкатенация строк и символов.</p>
  237. </synopsis>
  238. <synopsis>
  239. <prototype><![CDATA[template<class T>
  240. string_buffer &operator<<(string_buffer &&s, const T &v)]]> <sign>C++11</sign></prototype>
  241. <p>Вызывает <tt>operator&lt;&lt;(string_buffer &amp;s, const T &amp;v)</tt>.</p>
  242. </synopsis>
  243. </section>
  244. </chapter>
  245. </chapter>