Clarify data flow in GPU task assignment
[gromacs.git] / src / gromacs / utility / stringutil.h
blob525037883833fb164fa86e3093db81425055834c
1 /*
2 * This file is part of the GROMACS molecular simulation package.
4 * Copyright (c) 2011,2012,2013,2014,2015,2016,2017, 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.
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.
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.
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.
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.
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.
35 /*! \file
36 * \brief
37 * Declares common string utility and formatting routines.
39 * \author Teemu Murtola <teemu.murtola@gmail.com>
40 * \inpublicapi
41 * \ingroup module_utility
43 #ifndef GMX_UTILITY_STRINGUTIL_H
44 #define GMX_UTILITY_STRINGUTIL_H
46 #include <cstdarg>
47 #include <cstring>
49 #include <string>
50 #include <vector>
52 namespace gmx
55 //! \addtogroup module_utility
56 //! \{
58 /*! \brief
59 * Tests whether a string is null or empty.
61 * Does not throw.
63 static inline bool isNullOrEmpty(const char *str)
65 return str == nullptr || str[0] == '\0';
68 /*! \brief
69 * Tests whether a string starts with another string.
71 * \param[in] str String to process.
72 * \param[in] prefix Prefix to find.
73 * \returns true if \p str starts with \p prefix.
75 * Returns true if \p prefix is empty.
76 * Does not throw.
78 static inline bool startsWith(const std::string &str, const std::string &prefix)
80 return str.compare(0, prefix.length(), prefix) == 0;
82 //! \copydoc startsWith(const std::string &, const std::string &)
83 static inline bool startsWith(const char *str, const char *prefix)
85 return std::strncmp(str, prefix, std::strlen(prefix)) == 0;
88 /*! \brief
89 * Tests whether a string ends with another string.
91 * \param[in] str String to process.
92 * \param[in] suffix Suffix to find.
93 * \returns true if \p str ends with \p suffix.
95 * Returns true if \p suffix is NULL or empty.
96 * Does not throw.
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)
102 return endsWith(str.c_str(), suffix);
105 /*! \brief
106 * Tests whether a string contains another as a substring.
108 * \param[in] str String to process.
109 * \param[in] substr Substring to find.
110 * \returns true if \p str contains \p substr.
112 * Does not throw.
114 static inline bool contains(const std::string &str, const char *substr)
116 return str.find(substr) != std::string::npos;
118 //! \copydoc contains(const std::string &str, const char *substr)
119 static inline bool contains(const std::string &str, const std::string &substr)
121 return str.find(substr) != std::string::npos;
124 /*!\brief Returns number of space-separated words in zero-terminated char ptr
126 * \param s Character pointer to zero-terminated, which will not be changed.
128 * \returns number of words in string.
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.
133 std::size_t
134 countWords(const char *s);
136 /*!\brief Returns the number of space-separated words in a string object
138 * \param str Reference to string object, which will not be changed.
140 * \returns number of words in string.
142 std::size_t
143 countWords(const std::string &str);
145 //! \copydoc endsWith(const std::string &str, const char *suffix)
146 static inline bool endsWith(const std::string &str, const std::string &suffix)
148 return endsWith(str, suffix.c_str());
151 /*! \brief
152 * Removes a suffix from a string.
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.
160 * Returns \p str if \p suffix is NULL or empty.
162 std::string stripSuffixIfPresent(const std::string &str, const char *suffix);
163 /*! \brief
164 * Removes leading and trailing whitespace from a string.
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.
170 std::string stripString(const std::string &str);
171 /*! \brief
172 * Formats a string (snprintf() wrapper).
174 * \throws std::bad_alloc if out of memory.
176 * This function works like sprintf(), except that it returns an std::string
177 * instead of requiring a preallocated buffer. Arbitrary length output is
178 * supported.
180 std::string formatString(const char *fmt, ...);
181 /*! \brief
182 * Formats a string (vsnprintf() wrapper).
184 * \throws std::bad_alloc if out of memory.
186 * This function works like vsprintf(), except that it returns an std::string
187 * instead of requiring a preallocated buffer. Arbitrary length output is
188 * supported.
190 std::string formatStringV(const char *fmt, va_list ap);
192 /*! \brief Function object that wraps a call to formatString() that
193 * expects a single conversion argument, for use with algorithms. */
194 class StringFormatter
196 public:
197 /*! \brief Constructor
199 * \param[in] format The printf-style format string that will
200 * be applied to convert values of type T to
201 * string. Exactly one argument to the conversion
202 * specification(s) in `format` is supported. */
203 explicit StringFormatter(const char *format) : format_(format)
207 //! Implements the formatting functionality
208 template <typename T>
209 std::string operator()(const T &value) const
211 return formatString(format_, value);
214 private:
215 //! Format string to use
216 const char *format_;
219 /*! \brief Function object to implement the same interface as
220 * `StringFormatter` to use with strings that should not be formatted
221 * further. */
222 class IdentityFormatter
224 public:
225 //! Implements the formatting non-functionality
226 std::string operator()(const std::string &value) const
228 return value;
232 /*! \brief Formats all the range as strings, and then joins them with
233 * a separator in between.
235 * \param[in] begin Iterator the beginning of the range to join.
236 * \param[in] end Iterator the end of the range to join.
237 * \param[in] separator String to put in between the joined strings.
238 * \param[in] formatter Function object to format the objects in
239 * `container` as strings
240 * \returns All objects in the range from `begin` to `end` formatted
241 * as strings and concatenated with `separator` between each pair.
242 * \throws std::bad_alloc if out of memory.
244 template <typename InputIterator, typename FormatterType>
245 std::string formatAndJoin(InputIterator begin, InputIterator end, const char *separator, const FormatterType &formatter)
247 std::string result;
248 const char *currentSeparator = "";
249 for (InputIterator i = begin; i != end; ++i)
251 result.append(currentSeparator);
252 result.append(formatter(*i));
253 currentSeparator = separator;
255 return result;
258 /*! \brief Formats all elements of the container as strings, and then
259 * joins them with a separator in between.
261 * \param[in] container Objects to join.
262 * \param[in] separator String to put in between the joined strings.
263 * \param[in] formatter Function object to format the objects in
264 * `container` as strings
265 * \returns All objects from `container` formatted as strings and
266 * concatenated with `separator` between each pair.
267 * \throws std::bad_alloc if out of memory.
269 template <typename ContainerType, typename FormatterType>
270 std::string formatAndJoin(const ContainerType &container, const char *separator, const FormatterType &formatter)
272 return formatAndJoin(container.begin(), container.end(), separator, formatter);
275 /*! \brief
276 * Joins strings from a range with a separator in between.
278 * \param[in] begin Iterator the beginning of the range to join.
279 * \param[in] end Iterator the end of the range to join.
280 * \param[in] separator String to put in between the joined strings.
281 * \returns All strings from (`begin`, `end`) concatenated with `separator`
282 * between each pair.
283 * \throws std::bad_alloc if out of memory.
285 template <typename InputIterator>
286 std::string joinStrings(InputIterator begin, InputIterator end,
287 const char *separator)
289 return formatAndJoin(begin, end, separator, IdentityFormatter());
292 /*! \brief
293 * Joins strings from a container with a separator in between.
295 * \param[in] container Strings to join.
296 * \param[in] separator String to put in between the joined strings.
297 * \returns All strings from `container` concatenated with `separator`
298 * between each pair.
299 * \throws std::bad_alloc if out of memory.
301 template <typename ContainerType>
302 std::string joinStrings(const ContainerType &container, const char *separator)
304 return joinStrings(container.begin(), container.end(), separator);
307 /*! \brief
308 * Joins strings from an array with a separator in between.
310 * \param[in] array Array of strings to join.
311 * \param[in] separator String to put in between the joined strings.
312 * \tparam count Deduced number of elements in \p array.
313 * \returns All strings from `aray` concatenated with `separator`
314 * between each pair.
315 * \throws std::bad_alloc if out of memory.
317 template <size_t count>
318 std::string joinStrings(const char *const (&array)[count], const char *separator)
320 return joinStrings(array, array + count, separator);
323 /*! \brief
324 * Splits a string to whitespace separated tokens.
326 * \param[in] str String to process.
327 * \returns \p str split into tokens at each whitespace sequence.
328 * \throws std::bad_alloc if out of memory.
330 * This function works like `split` in Python, i.e., leading and trailing
331 * whitespace is ignored, and consecutive whitespaces are treated as a single
332 * separator.
334 std::vector<std::string> splitString(const std::string &str);
335 /*! \brief
336 * Splits a string to tokens separated by a given delimiter.
338 * \param[in] str String to process.
339 * \param[in] delim Delimiter to use for splitting.
340 * \returns \p str split into tokens at delimiter.
341 * \throws std::bad_alloc if out of memory.
343 * Unlike splitString(), consecutive delimiters will generate empty tokens, as
344 * will leading or trailing delimiters.
345 * Empty input will return an empty vector.
347 std::vector<std::string> splitDelimitedString(const std::string &str, char delim);
348 /*! \brief
349 * Splits \c str to tokens separated by delimiter \c delim. Removes
350 * leading and trailing whitespace from those strings with std::isspace.
352 * \param[in] str String to process.
353 * \param[in] delim Delimiter to use for splitting.
354 * \returns \p str split into tokens at delimiter, with whitespace stripped.
355 * \throws std::bad_alloc if out of memory.
357 * Unlike splitString(), consecutive delimiters will generate empty tokens, as
358 * will leading or trailing delimiters.
359 * Empty input will return an empty vector.
360 * Input with only whitespace will return a vector of size 1,
361 * that contains an empty token.
363 std::vector<std::string> splitAndTrimDelimitedString(const std::string &str, char delim);
365 /*! \brief
366 * Replace all occurrences of a string with another string.
368 * \param[in] input Input string.
369 * \param[in] from String to find.
370 * \param[in] to String to use to replace \p from.
371 * \returns Copy of \p input with all occurrences of \p from replaced with \p to.
372 * \throws std::bad_alloc if out of memory.
374 * The replacement is greedy and not recursive: starting from the beginning of
375 * \p input, each match of \p from is replaced with \p to, and the search for
376 * the next match begins after the end of the previous match.
378 * Compexity is O(N), where N is length of output.
380 * \see replaceAllWords()
382 std::string replaceAll(const std::string &input,
383 const char *from, const char *to);
384 //! \copydoc replaceAll(const std::string &, const char *, const char *)
385 std::string replaceAll(const std::string &input,
386 const std::string &from, const std::string &to);
387 /*! \brief
388 * Replace whole words with others.
390 * \param[in] input Input string.
391 * \param[in] from String to find.
392 * \param[in] to String to use to replace \p from.
393 * \returns Copy of \p input with all \p from words replaced with \p to.
394 * \throws std::bad_alloc if out of memory.
396 * Works as replaceAll(), but a match is only considered if it is delimited by
397 * non-alphanumeric characters.
399 * \see replaceAll()
401 std::string replaceAllWords(const std::string &input,
402 const char *from, const char *to);
403 //! \copydoc replaceAllWords(const std::string &, const char *, const char *)
404 std::string replaceAllWords(const std::string &input,
405 const std::string &from, const std::string &to);
407 class TextLineWrapper;
409 /*! \brief
410 * Stores settings for line wrapping.
412 * Methods in this class do not throw.
414 * \see TextLineWrapper
416 * \inpublicapi
418 class TextLineWrapperSettings
420 public:
421 /*! \brief
422 * Initializes default wrapper settings.
424 * Default settings are:
425 * - No maximum line width (only explicit line breaks).
426 * - No indentation.
427 * - No continuation characters.
428 * - Do not keep final spaces in input strings.
430 TextLineWrapperSettings();
432 /*! \brief
433 * Sets the maximum length for output lines.
435 * \param[in] length Maximum length for the lines after wrapping.
437 * If this method is not called, or is called with zero \p length, the
438 * wrapper has no maximum length (only wraps at explicit line breaks).
440 void setLineLength(int length) { maxLength_ = length; }
441 /*! \brief
442 * Sets the indentation for output lines.
444 * \param[in] indent Number of spaces to add for indentation.
446 * If this method is not called, the wrapper does not add indentation.
448 void setIndent(int indent) { indent_ = indent; }
449 /*! \brief
450 * Sets the indentation for first output line after a line break.
452 * \param[in] indent Number of spaces to add for indentation.
454 * If this method is not called, or called with \p indent equal to -1,
455 * the value set with setIndent() is used.
457 void setFirstLineIndent(int indent) { firstLineIndent_ = indent; }
458 /*! \brief
459 * Sets whether final spaces in input should be kept.
461 * \param[in] bKeep Whether to keep spaces at the end of the input.
463 * This means that wrapping a string that ends in spaces also keeps
464 * those spaces in the output. This allows using the wrapper for
465 * partial lines where the initial part of the line may end in a space.
466 * By default, all trailing whitespace is removed. Note that this
467 * option does not affect spaces before an explicit newline: those are
468 * always removed.
470 void setKeepFinalSpaces(bool bKeep) { bKeepFinalSpaces_ = bKeep; }
471 /*! \brief
472 * Sets a continuation marker for wrapped lines.
474 * \param[in] continuationChar Character to use to mark continuation
475 * lines.
477 * If set to non-zero character code, this character is added at the
478 * end of each line where a line break is added by TextLineWrapper
479 * (but not after lines produced by explicit line breaks).
480 * The default (\c '\0') is to not add continuation markers.
482 * Note that currently, the continuation char may cause the output line
483 * length to exceed the value set with setLineLength() by at most two
484 * characters.
486 void setContinuationChar(char continuationChar)
488 continuationChar_ = continuationChar;
491 //! Returns the maximum length set with setLineLength().
492 int lineLength() const { return maxLength_; }
493 //! Returns the indentation set with setIndent().
494 int indent() const { return indent_; }
495 /*! \brief
496 * Returns the indentation set with setFirstLineIndent().
498 * If setFirstLineIndent() has not been called or has been called with
499 * -1, indent() is returned.
501 int firstLineIndent() const
503 return (firstLineIndent_ >= 0 ? firstLineIndent_ : indent_);
506 private:
507 //! Maximum length of output lines, or <= 0 if no limit.
508 int maxLength_;
509 //! Number of spaces to indent each output line with.
510 int indent_;
511 /*! \brief
512 * Number of spaces to indent the first line after a newline.
514 * If -1, \a indent_ is used.
516 int firstLineIndent_;
517 //! Whether to keep spaces at end of input.
518 bool bKeepFinalSpaces_;
519 //! If not \c '\0', mark each wrapping point with this character.
520 char continuationChar_;
522 //! Needed to access the members.
523 friend class TextLineWrapper;
526 /*! \brief
527 * Wraps lines to a predefined length.
529 * This utility class wraps lines at word breaks to produce lines that are not
530 * longer than a predefined length. Explicit newlines ('\\n') are preserved.
531 * Only space is considered a word separator. If a single word exceeds the
532 * maximum line length, it is still printed on a single line.
533 * Extra whitespace is stripped from the end of produced lines.
534 * Other options on the wrapping, such as the line length or indentation,
535 * can be changed using a TextLineWrapperSettings object.
537 * Two interfaces to do the wrapping are provided:
538 * -# High-level interface using either wrapToString() (produces a single
539 * string with embedded newlines) or wrapToVector() (produces a vector of
540 * strings with each line as one element).
541 * These methods operate on std::string and wrap the entire input string.
542 * -# Low-level interface using findNextLine() and formatLine().
543 * findNextLine() operates either on a C string or an std::string, and does
544 * not do any memory allocation (so it does not throw). It finds the next
545 * line to be wrapped, considering the wrapping settings.
546 * formatLine() does whitespace operations on the line found by
547 * findNextLine() and returns an std::string.
548 * These methods allow custom wrapping implementation to either avoid
549 * exceptions or to wrap only a part of the input string.
551 * Typical usage:
552 * \code
553 gmx::TextLineWrapper wrapper;
554 wrapper.settings().setLineLength(78);
555 printf("%s\n", wrapper.wrapToString(textToWrap).c_str());
556 \endcode
558 * \inpublicapi
560 class TextLineWrapper
562 public:
563 /*! \brief
564 * Constructs a new line wrapper with default settings.
566 * Does not throw.
568 TextLineWrapper()
571 /*! \brief
572 * Constructs a new line wrapper with given settings.
574 * \param[in] settings Wrapping settings.
576 * Does not throw.
578 explicit TextLineWrapper(const TextLineWrapperSettings &settings)
579 : settings_(settings)
583 /*! \brief
584 * Provides access to settings of this wrapper.
586 * \returns The settings object for this wrapper.
588 * The returned object can be used to modify settings for the wrapper.
589 * All subsequent calls to wrapToString() and wrapToVector() use the
590 * modified settings.
592 * Does not throw.
594 TextLineWrapperSettings &settings() { return settings_; }
596 //! Returns true if the wrapper would not modify the input string.
597 bool isTrivial() const;
599 /*! \brief
600 * Finds the next line to be wrapped.
602 * \param[in] input String to wrap.
603 * \param[in] lineStart Index of first character of the line to find.
604 * \returns Index of first character of the next line.
606 * If this is the last line, returns the length of \p input.
607 * In determining the length of the returned line, this function
608 * considers the maximum line length, leaving space for indentation,
609 * and also whitespace stripping behavior.
610 * Thus, the line returned may be longer than the maximum line length
611 * if it has leading and/or trailing space.
612 * When wrapping a line on a space (not on an explicit line break),
613 * the returned index is always on a non-whitespace character after the
614 * space.
616 * To iterate over lines in a string, use the following code:
617 * \code
618 gmx::TextLineWrapper wrapper;
619 // <set desired wrapping settings>
620 size_t lineStart = 0;
621 size_t length = input.length();
622 while (lineStart < length)
624 size_t nextLineStart = wrapper.findNextLine(input, lineStart);
625 std::string line = wrapper.formatLine(input, lineStart, nextLineStart));
626 // <do something with the line>
627 lineStart = nextLineStart;
629 return result;
630 \endcode
632 * Does not throw.
634 size_t findNextLine(const char *input, size_t lineStart) const;
635 //! \copydoc findNextLine(const char *, size_t)const
636 size_t findNextLine(const std::string &input, size_t lineStart) const;
637 /*! \brief
638 * Formats a single line for output according to wrapping settings.
640 * \param[in] input Input string.
641 * \param[in] lineStart Index of first character of the line to format.
642 * \param[in] lineEnd Index of first character of the next line.
643 * \returns The line with leading and/or trailing whitespace removed
644 * and indentation applied.
645 * \throws std::bad_alloc if out of memory.
647 * Intended to be used on the lines found by findNextLine().
648 * When used with the lines returned from findNextLine(), the returned
649 * line conforms to the wrapper settings.
650 * Trailing whitespace is always stripped (including any newlines,
651 * i.e., the return value does not contain a newline).
653 std::string formatLine(const std::string &input,
654 size_t lineStart, size_t lineEnd) const;
656 /*! \brief
657 * Formats a string, producing a single string with all the lines.
659 * \param[in] input String to wrap.
660 * \returns \p input with added newlines such that maximum line
661 * length is not exceeded.
662 * \throws std::bad_alloc if out of memory.
664 * Newlines in the input are preserved, including terminal newlines.
665 * Note that if the input does not contain a terminal newline, the
666 * output does not either.
668 std::string wrapToString(const std::string &input) const;
669 /*! \brief
670 * Formats a string, producing a vector with all the lines.
672 * \param[in] input String to wrap.
673 * \returns \p input split into lines such that maximum line length
674 * is not exceeded.
675 * \throws std::bad_alloc if out of memory.
677 * The strings in the returned vector do not contain newlines at the
678 * end.
679 * Note that a single terminal newline does not affect the output:
680 * "line\\n" and "line" both produce the same output (but "line\\n\\n"
681 * produces two lines, the second of which is empty).
683 std::vector<std::string> wrapToVector(const std::string &input) const;
685 private:
686 TextLineWrapperSettings settings_;
689 /*! \brief Construct a vector of decimal digits parsed from an \c input string.
691 * \param[in] input String that must contain only decimal digits, or only
692 * decimal digits separated by comma delimiters.
694 * \returns Vector of any digits found in \c input.
696 * \throws std::bad_alloc if out of memory
697 * InvalidInputError if an invalid digit character is found.
699 std::vector<int> parseDigitsFromString(const std::string &input);
701 //! \}
703 } // namespace gmx
705 #endif