Warn for type mismatch for gmx printf like functions 3/3
[alexxy/gromacs.git] / src / gromacs / utility / stringutil.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \file
36  * \brief
37  * Declares common string utility and formatting routines.
38  *
39  * \author Teemu Murtola <teemu.murtola@gmail.com>
40  * \inpublicapi
41  * \ingroup module_utility
42  */
43 #ifndef GMX_UTILITY_STRINGUTIL_H
44 #define GMX_UTILITY_STRINGUTIL_H
45
46 #include <cstdarg>
47 #include <cstring>
48
49 #include <string>
50 #include <vector>
51
52 namespace gmx
53 {
54
55 //! \addtogroup module_utility
56 //! \{
57
58 /*! \brief
59  * Tests whether a string is null or empty.
60  *
61  * Does not throw.
62  */
63 static inline bool isNullOrEmpty(const char *str)
64 {
65     return str == nullptr || str[0] == '\0';
66 }
67
68 /*! \brief
69  * Tests whether a string starts with another string.
70  *
71  * \param[in] str    String to process.
72  * \param[in] prefix Prefix to find.
73  * \returns   true if \p str starts with \p prefix.
74  *
75  * Returns true if \p prefix is empty.
76  * Does not throw.
77  */
78 static inline bool startsWith(const std::string &str, const std::string &prefix)
79 {
80     return str.compare(0, prefix.length(), prefix) == 0;
81 }
82 //! \copydoc startsWith(const std::string &, const std::string &)
83 static inline bool startsWith(const char *str, const char *prefix)
84 {
85     return std::strncmp(str, prefix, std::strlen(prefix)) == 0;
86 }
87
88 /*! \brief
89  * Tests whether a string ends with another string.
90  *
91  * \param[in] str    String to process.
92  * \param[in] suffix Suffix to find.
93  * \returns   true if \p str ends with \p suffix.
94  *
95  * Returns true if \p suffix is NULL or empty.
96  * Does not throw.
97  */
98 bool endsWith(const char *str, const char *suffix);
99 //! \copydoc endsWith(const char *, const char *)
100 static inline bool endsWith(const std::string &str, const char *suffix)
101 {
102     return endsWith(str.c_str(), suffix);
103 }
104
105 /*! \brief
106  * Tests whether a string contains another as a substring.
107  *
108  * \param[in] str    String to process.
109  * \param[in] substr Substring to find.
110  * \returns   true if \p str contains \p substr.
111  *
112  * Does not throw.
113  */
114 static inline bool contains(const std::string &str, const char *substr)
115 {
116     return str.find(substr) != std::string::npos;
117 }
118 //! \copydoc contains(const std::string &str, const char *substr)
119 static inline bool contains(const std::string &str, const std::string &substr)
120 {
121     return str.find(substr) != std::string::npos;
122 }
123
124 /*!\brief Returns number of space-separated words in zero-terminated char ptr
125  *
126  * \param s Character pointer to zero-terminated, which will not be changed.
127  *
128  * \returns number of words in string.
129  *
130  * \note This routine is mainly meant to support legacy code in GROMACS. For
131  *       new source you should try hard to use C++ string objects instead.
132  */
133 std::size_t
134 countWords(const char *s);
135
136 /*!\brief Returns the number of space-separated words in a string object
137  *
138  * \param str Reference to string object, which will not be changed.
139  *
140  * \returns number of words in string.
141  */
142 std::size_t
143 countWords(const std::string &str);
144
145 //! \copydoc endsWith(const std::string &str, const char *suffix)
146 static inline bool endsWith(const std::string &str, const std::string &suffix)
147 {
148     return endsWith(str, suffix.c_str());
149 }
150
151 /*! \brief
152  * Removes a suffix from a string.
153  *
154  * \param[in] str    String to process.
155  * \param[in] suffix Suffix to remove.
156  * \returns   \p str with \p suffix removed, or \p str unmodified if it does
157  *      not end with \p suffix.
158  * \throws    std::bad_alloc if out of memory.
159  *
160  * Returns \p str if \p suffix is NULL or empty.
161  */
162 std::string stripSuffixIfPresent(const std::string &str, const char *suffix);
163 /*! \brief
164  * Removes leading and trailing whitespace from a string.
165  *
166  * \param[in] str  String to process.
167  * \returns   \p str with leading and trailing whitespaces removed.
168  * \throws    std::bad_alloc if out of memory.
169  */
170 std::string stripString(const std::string &str);
171 #ifdef __GNUC__
172 #define gmx_format(archetype, string_index, first_to_check) \
173     __attribute__ ((format (archetype, string_index, first_to_check)))
174 #else
175 /*! \brief GCC like function format attribute
176  *
177  * The format attribute specifies that a function takes printf, scanf, ...
178  * style arguments that should be type-checked against a format string.
179  * The attribute has to be placed after the function.
180  * This attribute is only valid for function declarations and not function
181  * definitions (GCC limitation). For member functions the implicit `this`
182  * pointer is included in the argument count.
183  */
184 #define gmx_format(archetype, string_index, first_to_check)
185 #endif
186 #ifdef _MSC_VER
187 #define gmx_fmtstr _In_ _Printf_format_string_
188 #else
189 /*! \brief MSVC like function format attribute
190  *
191  * Does type checking for printf like format strings in MSVC style.
192  * Attribute has to be placed before format string.
193  */
194 #define gmx_fmtstr
195 #endif
196 /*! \brief
197  * Formats a string (snprintf() wrapper).
198  *
199  * \throws  std::bad_alloc if out of memory.
200  *
201  * This function works like sprintf(), except that it returns an std::string
202  * instead of requiring a preallocated buffer.  Arbitrary length output is
203  * supported.
204  */
205 std::string formatString(gmx_fmtstr const char *fmt, ...) gmx_format(printf, 1, 2);
206
207 /*! \brief
208  * Formats a string (vsnprintf() wrapper).
209  *
210  * \throws  std::bad_alloc if out of memory.
211  *
212  * This function works like vsprintf(), except that it returns an std::string
213  * instead of requiring a preallocated buffer.  Arbitrary length output is
214  * supported.
215  */
216 std::string formatStringV(const char *fmt, va_list ap);
217
218 /*! \brief Function object that wraps a call to formatString() that
219  * expects a single conversion argument, for use with algorithms. */
220 class StringFormatter
221 {
222     public:
223         /*! \brief Constructor
224          *
225          * \param[in] format The printf-style format string that will
226          *     be applied to convert values of type T to
227          *     string. Exactly one argument to the conversion
228          *     specification(s) in `format` is supported. */
229         explicit StringFormatter(const char *format) : format_(format)
230         {
231         }
232
233         //! Implements the formatting functionality
234         template <typename T>
235         std::string operator()(const T &value) const
236         {
237             return formatString(format_, value);
238         }
239
240     private:
241         //! Format string to use
242         const char *format_;
243 };
244
245 /*! \brief Function object to implement the same interface as
246  * `StringFormatter` to use with strings that should not be formatted
247  * further. */
248 class IdentityFormatter
249 {
250     public:
251         //! Implements the formatting non-functionality
252         std::string operator()(const std::string &value) const
253         {
254             return value;
255         }
256 };
257
258 /*! \brief Formats all the range as strings, and then joins them with
259  * a separator in between.
260  *
261  * \param[in] begin      Iterator the beginning of the range to join.
262  * \param[in] end        Iterator the end of the range to join.
263  * \param[in] separator  String to put in between the joined strings.
264  * \param[in] formatter  Function object to format the objects in
265  *     `container` as strings
266  * \returns   All objects in the range from `begin` to `end` formatted
267  *     as strings and concatenated with `separator` between each pair.
268  * \throws    std::bad_alloc if out of memory.
269  */
270 template <typename InputIterator, typename FormatterType>
271 std::string formatAndJoin(InputIterator begin, InputIterator end, const char *separator, const FormatterType &formatter)
272 {
273     std::string result;
274     const char *currentSeparator = "";
275     for (InputIterator i = begin; i != end; ++i)
276     {
277         result.append(currentSeparator);
278         result.append(formatter(*i));
279         currentSeparator = separator;
280     }
281     return result;
282 }
283
284 /*! \brief Formats all elements of the container as strings, and then
285  * joins them with a separator in between.
286  *
287  * \param[in] container  Objects to join.
288  * \param[in] separator  String to put in between the joined strings.
289  * \param[in] formatter  Function object to format the objects in
290  *     `container` as strings
291  * \returns   All objects from `container` formatted as strings and
292  *     concatenated with `separator` between each pair.
293  * \throws    std::bad_alloc if out of memory.
294  */
295 template <typename ContainerType, typename FormatterType>
296 std::string formatAndJoin(const ContainerType &container, const char *separator, const FormatterType &formatter)
297 {
298     return formatAndJoin(container.begin(), container.end(), separator, formatter);
299 }
300
301 /*! \brief
302  * Joins strings from a range with a separator in between.
303  *
304  * \param[in] begin      Iterator the beginning of the range to join.
305  * \param[in] end        Iterator the end of the range to join.
306  * \param[in] separator  String to put in between the joined strings.
307  * \returns   All strings from (`begin`, `end`) concatenated with `separator`
308  *     between each pair.
309  * \throws    std::bad_alloc if out of memory.
310  */
311 template <typename InputIterator>
312 std::string joinStrings(InputIterator begin, InputIterator end,
313                         const char *separator)
314 {
315     return formatAndJoin(begin, end, separator, IdentityFormatter());
316 }
317
318 /*! \brief
319  * Joins strings from a container with a separator in between.
320  *
321  * \param[in] container  Strings to join.
322  * \param[in] separator  String to put in between the joined strings.
323  * \returns   All strings from `container` concatenated with `separator`
324  *     between each pair.
325  * \throws    std::bad_alloc if out of memory.
326  */
327 template <typename ContainerType>
328 std::string joinStrings(const ContainerType &container, const char *separator)
329 {
330     return joinStrings(container.begin(), container.end(), separator);
331 }
332
333 /*! \brief
334  * Joins strings from an array with a separator in between.
335  *
336  * \param[in] array      Array of strings to join.
337  * \param[in] separator  String to put in between the joined strings.
338  * \tparam    count      Deduced number of elements in \p array.
339  * \returns   All strings from `aray` concatenated with `separator`
340  *     between each pair.
341  * \throws    std::bad_alloc if out of memory.
342  */
343 template <size_t count>
344 std::string joinStrings(const char *const (&array)[count], const char *separator)
345 {
346     return joinStrings(array, array + count, separator);
347 }
348
349 /*! \brief
350  * Splits a string to whitespace separated tokens.
351  *
352  * \param[in] str  String to process.
353  * \returns   \p str split into tokens at each whitespace sequence.
354  * \throws    std::bad_alloc if out of memory.
355  *
356  * This function works like `split` in Python, i.e., leading and trailing
357  * whitespace is ignored, and consecutive whitespaces are treated as a single
358  * separator.
359  */
360 std::vector<std::string> splitString(const std::string &str);
361 /*! \brief
362  * Splits a string to tokens separated by a given delimiter.
363  *
364  * \param[in] str   String to process.
365  * \param[in] delim Delimiter to use for splitting.
366  * \returns   \p str split into tokens at delimiter.
367  * \throws    std::bad_alloc if out of memory.
368  *
369  * Unlike splitString(), consecutive delimiters will generate empty tokens, as
370  * will leading or trailing delimiters.
371  * Empty input will return an empty vector.
372  */
373 std::vector<std::string> splitDelimitedString(const std::string &str, char delim);
374 /*! \brief
375  * Splits \c str to tokens separated by delimiter \c delim. Removes
376  * leading and trailing whitespace from those strings with std::isspace.
377  *
378  * \param[in] str   String to process.
379  * \param[in] delim Delimiter to use for splitting.
380  * \returns   \p str split into tokens at delimiter, with whitespace stripped.
381  * \throws    std::bad_alloc if out of memory.
382  *
383  * Unlike splitString(), consecutive delimiters will generate empty tokens, as
384  * will leading or trailing delimiters.
385  * Empty input will return an empty vector.
386  * Input with only whitespace will return a vector of size 1,
387  * that contains an empty token.
388  */
389 std::vector<std::string> splitAndTrimDelimitedString(const std::string &str, char delim);
390
391 /*! \brief
392  * Replace all occurrences of a string with another string.
393  *
394  * \param[in] input  Input string.
395  * \param[in] from   String to find.
396  * \param[in] to     String to use to replace \p from.
397  * \returns   Copy of \p input with all occurrences of \p from replaced with \p to.
398  * \throws    std::bad_alloc if out of memory.
399  *
400  * The replacement is greedy and not recursive: starting from the beginning of
401  * \p input, each match of \p from is replaced with \p to, and the search for
402  * the next match begins after the end of the previous match.
403  *
404  * Compexity is O(N), where N is length of output.
405  *
406  * \see replaceAllWords()
407  */
408 std::string replaceAll(const std::string &input,
409                        const char *from, const char *to);
410 //! \copydoc replaceAll(const std::string &, const char *, const char *)
411 std::string replaceAll(const std::string &input,
412                        const std::string &from, const std::string &to);
413 /*! \brief
414  * Replace whole words with others.
415  *
416  * \param[in] input  Input string.
417  * \param[in] from   String to find.
418  * \param[in] to     String to use to replace \p from.
419  * \returns   Copy of \p input with all \p from words replaced with \p to.
420  * \throws    std::bad_alloc if out of memory.
421  *
422  * Works as replaceAll(), but a match is only considered if it is delimited by
423  * non-alphanumeric characters.
424  *
425  * \see replaceAll()
426  */
427 std::string replaceAllWords(const std::string &input,
428                             const char *from, const char *to);
429 //! \copydoc replaceAllWords(const std::string &, const char *, const char *)
430 std::string replaceAllWords(const std::string &input,
431                             const std::string &from, const std::string &to);
432
433 class TextLineWrapper;
434
435 /*! \brief
436  * Stores settings for line wrapping.
437  *
438  * Methods in this class do not throw.
439  *
440  * \see TextLineWrapper
441  *
442  * \inpublicapi
443  */
444 class TextLineWrapperSettings
445 {
446     public:
447         /*! \brief
448          * Initializes default wrapper settings.
449          *
450          * Default settings are:
451          *  - No maximum line width (only explicit line breaks).
452          *  - No indentation.
453          *  - No continuation characters.
454          *  - Do not keep final spaces in input strings.
455          */
456         TextLineWrapperSettings();
457
458         /*! \brief
459          * Sets the maximum length for output lines.
460          *
461          * \param[in] length  Maximum length for the lines after wrapping.
462          *
463          * If this method is not called, or is called with zero \p length, the
464          * wrapper has no maximum length (only wraps at explicit line breaks).
465          */
466         void setLineLength(int length) { maxLength_ = length; }
467         /*! \brief
468          * Sets the indentation for output lines.
469          *
470          * \param[in] indent  Number of spaces to add for indentation.
471          *
472          * If this method is not called, the wrapper does not add indentation.
473          */
474         void setIndent(int indent) { indent_ = indent; }
475         /*! \brief
476          * Sets the indentation for first output line after a line break.
477          *
478          * \param[in] indent  Number of spaces to add for indentation.
479          *
480          * If this method is not called, or called with \p indent equal to -1,
481          * the value set with setIndent() is used.
482          */
483         void setFirstLineIndent(int indent) { firstLineIndent_ = indent; }
484         /*! \brief
485          * Sets whether final spaces in input should be kept.
486          *
487          * \param[in] bKeep  Whether to keep spaces at the end of the input.
488          *
489          * This means that wrapping a string that ends in spaces also keeps
490          * those spaces in the output.  This allows using the wrapper for
491          * partial lines where the initial part of the line may end in a space.
492          * By default, all trailing whitespace is removed.  Note that this
493          * option does not affect spaces before an explicit newline: those are
494          * always removed.
495          */
496         void setKeepFinalSpaces(bool bKeep) { bKeepFinalSpaces_ = bKeep; }
497         /*! \brief
498          * Sets a continuation marker for wrapped lines.
499          *
500          * \param[in] continuationChar  Character to use to mark continuation
501          *      lines.
502          *
503          * If set to non-zero character code, this character is added at the
504          * end of each line where a line break is added by TextLineWrapper
505          * (but not after lines produced by explicit line breaks).
506          * The default (\c '\0') is to not add continuation markers.
507          *
508          * Note that currently, the continuation char may cause the output line
509          * length to exceed the value set with setLineLength() by at most two
510          * characters.
511          */
512         void setContinuationChar(char continuationChar)
513         {
514             continuationChar_ = continuationChar;
515         }
516
517         //! Returns the maximum length set with setLineLength().
518         int lineLength() const { return maxLength_; }
519         //! Returns the indentation set with setIndent().
520         int indent() const { return indent_; }
521         /*! \brief
522          * Returns the indentation set with setFirstLineIndent().
523          *
524          * If setFirstLineIndent() has not been called or has been called with
525          * -1, indent() is returned.
526          */
527         int firstLineIndent() const
528         {
529             return (firstLineIndent_ >= 0 ? firstLineIndent_ : indent_);
530         }
531
532     private:
533         //! Maximum length of output lines, or <= 0 if no limit.
534         int                     maxLength_;
535         //! Number of spaces to indent each output line with.
536         int                     indent_;
537         /*! \brief
538          * Number of spaces to indent the first line after a newline.
539          *
540          * If -1, \a indent_ is used.
541          */
542         int                     firstLineIndent_;
543         //! Whether to keep spaces at end of input.
544         bool                    bKeepFinalSpaces_;
545         //! If not \c '\0', mark each wrapping point with this character.
546         char                    continuationChar_;
547
548         //! Needed to access the members.
549         friend class TextLineWrapper;
550 };
551
552 /*! \brief
553  * Wraps lines to a predefined length.
554  *
555  * This utility class wraps lines at word breaks to produce lines that are not
556  * longer than a predefined length.  Explicit newlines ('\\n') are preserved.
557  * Only space is considered a word separator.  If a single word exceeds the
558  * maximum line length, it is still printed on a single line.
559  * Extra whitespace is stripped from the end of produced lines.
560  * Other options on the wrapping, such as the line length or indentation,
561  * can be changed using a TextLineWrapperSettings object.
562  *
563  * Two interfaces to do the wrapping are provided:
564  *  -# High-level interface using either wrapToString() (produces a single
565  *     string with embedded newlines) or wrapToVector() (produces a vector of
566  *     strings with each line as one element).
567  *     These methods operate on std::string and wrap the entire input string.
568  *  -# Low-level interface using findNextLine() and formatLine().
569  *     findNextLine() operates either on a C string or an std::string, and does
570  *     not do any memory allocation (so it does not throw).  It finds the next
571  *     line to be wrapped, considering the wrapping settings.
572  *     formatLine() does whitespace operations on the line found by
573  *     findNextLine() and returns an std::string.
574  *     These methods allow custom wrapping implementation to either avoid
575  *     exceptions or to wrap only a part of the input string.
576  *
577  * Typical usage:
578  * \code
579    gmx::TextLineWrapper wrapper;
580    wrapper.settings().setLineLength(78);
581    printf("%s\n", wrapper.wrapToString(textToWrap).c_str());
582    \endcode
583  *
584  * \inpublicapi
585  */
586 class TextLineWrapper
587 {
588     public:
589         /*! \brief
590          * Constructs a new line wrapper with default settings.
591          *
592          * Does not throw.
593          */
594         TextLineWrapper()
595         {
596         }
597         /*! \brief
598          * Constructs a new line wrapper with given settings.
599          *
600          * \param[in] settings  Wrapping settings.
601          *
602          * Does not throw.
603          */
604         explicit TextLineWrapper(const TextLineWrapperSettings &settings)
605             : settings_(settings)
606         {
607         }
608
609         /*! \brief
610          * Provides access to settings of this wrapper.
611          *
612          * \returns  The settings object for this wrapper.
613          *
614          * The returned object can be used to modify settings for the wrapper.
615          * All subsequent calls to wrapToString() and wrapToVector() use the
616          * modified settings.
617          *
618          * Does not throw.
619          */
620         TextLineWrapperSettings &settings() { return settings_; }
621
622         //! Returns true if the wrapper would not modify the input string.
623         bool isTrivial() const;
624
625         /*! \brief
626          * Finds the next line to be wrapped.
627          *
628          * \param[in] input     String to wrap.
629          * \param[in] lineStart Index of first character of the line to find.
630          * \returns   Index of first character of the next line.
631          *
632          * If this is the last line, returns the length of \p input.
633          * In determining the length of the returned line, this function
634          * considers the maximum line length, leaving space for indentation,
635          * and also whitespace stripping behavior.
636          * Thus, the line returned may be longer than the maximum line length
637          * if it has leading and/or trailing space.
638          * When wrapping a line on a space (not on an explicit line break),
639          * the returned index is always on a non-whitespace character after the
640          * space.
641          *
642          * To iterate over lines in a string, use the following code:
643          * \code
644            gmx::TextLineWrapper wrapper;
645            // <set desired wrapping settings>
646            size_t lineStart = 0;
647            size_t length = input.length();
648            while (lineStart < length)
649            {
650                size_t nextLineStart = wrapper.findNextLine(input, lineStart);
651                std::string line = wrapper.formatLine(input, lineStart, nextLineStart));
652                // <do something with the line>
653                lineStart = nextLineStart;
654            }
655            return result;
656            \endcode
657          *
658          * Does not throw.
659          */
660         size_t findNextLine(const char *input, size_t lineStart) const;
661         //! \copydoc findNextLine(const char *, size_t)const
662         size_t findNextLine(const std::string &input, size_t lineStart) const;
663         /*! \brief
664          * Formats a single line for output according to wrapping settings.
665          *
666          * \param[in] input     Input string.
667          * \param[in] lineStart Index of first character of the line to format.
668          * \param[in] lineEnd   Index of first character of the next line.
669          * \returns   The line with leading and/or trailing whitespace removed
670          *      and indentation applied.
671          * \throws    std::bad_alloc if out of memory.
672          *
673          * Intended to be used on the lines found by findNextLine().
674          * When used with the lines returned from findNextLine(), the returned
675          * line conforms to the wrapper settings.
676          * Trailing whitespace is always stripped (including any newlines,
677          * i.e., the return value does not contain a newline).
678          */
679         std::string formatLine(const std::string &input,
680                                size_t lineStart, size_t lineEnd) const;
681
682         /*! \brief
683          * Formats a string, producing a single string with all the lines.
684          *
685          * \param[in] input  String to wrap.
686          * \returns   \p input with added newlines such that maximum line
687          *      length is not exceeded.
688          * \throws    std::bad_alloc if out of memory.
689          *
690          * Newlines in the input are preserved, including terminal newlines.
691          * Note that if the input does not contain a terminal newline, the
692          * output does not either.
693          */
694         std::string wrapToString(const std::string &input) const;
695         /*! \brief
696          * Formats a string, producing a vector with all the lines.
697          *
698          * \param[in] input  String to wrap.
699          * \returns   \p input split into lines such that maximum line length
700          *      is not exceeded.
701          * \throws    std::bad_alloc if out of memory.
702          *
703          * The strings in the returned vector do not contain newlines at the
704          * end.
705          * Note that a single terminal newline does not affect the output:
706          * "line\\n" and "line" both produce the same output (but "line\\n\\n"
707          * produces two lines, the second of which is empty).
708          */
709         std::vector<std::string> wrapToVector(const std::string &input) const;
710
711     private:
712         TextLineWrapperSettings settings_;
713 };
714
715 //! \}
716
717 } // namespace gmx
718
719 #endif