Skip to content

Migrating to stdstring

Edwin Lee edited this page Apr 23, 2014 · 1 revision

As one of the first post C++ conversion refactoring tasks EnergyPlus is migrating from Fortran-like Fstring to std::string. This will make the code more familiar to new C++ developers, more space-efficient, easier to author, and faster. But we will have to get used to C++ std::string semantics, and they differ significantly from Fortran.

Some key differences:

  • std::string is not fixed length: the length can be changed by assignment or operations such as += or the append() method to grow the string and the erase() method to reduce it.
    • To clear a std::string to an empty (zero-length) string use mystring.clear() or mystring = "" instead of the Fortran-ic mystring = " ", which creates a 1-character string that is not equal to an empty string.
  • std::string indexes starting from 0, not 1.
    • Because 0 is a valid string index, std::string functions return a special value, std::string::npos, to indicate that, for example, a search within a string did not find any matches.
  • std::string comparisons don't ignore trailing spaces like Fortran does.
  • Substrings are created with the substr() method and are copies, not live proxies to the original string. Other methods such as replace() can be used to alter a string in place.
  • std::string has both an index-based and iterator-based API: the iterator usage can be more convenient, especially with C++11 range-based for loops, and allows strings to be used with generic iterator based algorithms.

The migration to std::string moves all the way to a more typical C++ usage, where strings are right-sized (without trailing spaces) and thus all the slow trim() calls were eliminated and len_trim() calls replaced with faster len() and length() calls. To preserve the performance gains we should keep this approach and not start passing around strings with slack space that must be trimmed down for use. The migration also included some performance-oriented changes, such as replacing some uppercasing-then-compare usage with case-insensitive comparisons that don't require creating string temporaries.

While the std::string API is adequate it is missing some calls that allow for clearer and more consise usage. The ObjexxFCL string.functions.hh provides a set of useful add-ons for std::string and we may find that we want more such convenience functions in the future. There are some calls in string.functions that are more familiar looking so we might have Pos = index( haystack, needle ) rather than the equivalent Pos = haystack.find( needle ) but the more native usage is fine going forward (subject to any EnergyPlus C++ guidelines).

The best way to get familiar with std::string usage is to look at the migrated code and compare it to the earlier Fstring code. Please add more string notes and tips here as you go.

Clone this wiki locally