String.hpp

Simple class to facilitate string manipulations.

Todo:

Make constexpr

Make handle non-‘char’ strings (i.e., use CharT template parameter)

Make handle allocators

Make work more broadly with stringviews

Maybe add special construct types like RESERVE, REPEAT, and TO_STRING for special builds?

Note

Status: ALPHA

Functions

template<typename ...Ts>
inline String MakeString(Ts&&... args)
inline const String &MakeString(const String &in)
inline String MakeEscaped(char c)
inline String MakeEscaped(const String &in)
inline String MakeCSVSafe(const String &in)
inline String MakeWebSafe(const String &in)

Take a string and replace reserved HTML characters with character entities.

inline String MakeLiteral(char value)

Take a char and convert it to a C++-style literal.

inline String MakeLiteral(const std::string &value)

Take a string or iterable and convert it to a C++-style literal.

template<typename T>
inline String MakeLiteral(const T &value)
inline char MakeFromLiteral_Char(const String &value)

Convert a literal character representation to an actual string. (i.e., ‘A’, ‘;’, or ‘

’)

inline String MakeFromLiteral_String(const String &value)

Convert a literal string representation to an actual string.

template<typename T>
inline T MakeFromLiteral(const String &value)
inline String MakeUpper(const String &value)

Convert a string to all uppercase.

inline String MakeLower(const String &value)

Convert a string to all lowercase.

inline String MakeTitleCase(String value)

Make first letter of each word upper case.

inline String MakeCount(int val, String item, const String &plural_suffix)

Make a string with the correct pluralization of the item being counted. For example, MakeCount(1, “cow”) would produce “1 cow”, but MakeCount(2, “cow”) would produce “2 cows”.

inline String MakeRoman(int val)

Convert an integer to a roman numeral string.

template<typename CONTAINER_T>
inline String MakeEnglishList(const CONTAINER_T &container)
template<typename ...Args>
inline String MakeFormatted(const String &format, Args... args)
inline String MakeRepeat(String base, size_t n)

Concatenate n copies of a string.

inline String MakeTrimFront(const String &in, const CharSet &chars = WhitespaceCharSet())
inline String MakeTrimBack(const String &in, const CharSet &chars = WhitespaceCharSet())
inline String MakeTrimmed(String in, const CharSet &chars)

Remove chars from the beginning AND end of a string.

inline String MakeCompressed(String in, const CharSet &chars = WhitespaceCharSet(), char compress_to = ' ', bool trim_start = true, bool trim_end = true)
inline String MakeRemoveChars(String in, const CharSet &chars)

Remove all instances of specified characters from file.

inline String MakeSlugify(String in)

Make a string safe(r)

template<typename CONTAINER_T>
inline String Join(const CONTAINER_T &container, std::string join_str = "", std::string open = "", std::string close = "")

This function returns values from a container as a single string separated by a given delimeter and with optional surrounding strings.

Parameters:
  • container – is any standard-interface container holding objects to be joined.

  • join_str – optional delimeter

  • open – string to place before each string (e.g., “[” or “’”)

  • close – string to place after each string (e.g., “]” or “’”)

Returns:

merged string of all values

inline String MakeCount(int val, String item)
template<typename ...Args>
String MakeFormatted(const std::string &format, Args... args)

Apply sprintf-like formatting to a string. See https://en.cppreference.com/w/cpp/io/c/fprintf. Adapted from https://stackoverflow.com/a/26221725.

class String : public std::string
#include <String.hpp>

Public Functions

String() = default
inline String(const std::string &_str)
inline String(std::string &&_str)
inline String(const char *_str)
inline String(size_t count, char _str)
inline String(std::initializer_list<char> _str)
inline String(const String &_str, size_t start, size_t count = npos)
inline String(const std::string &_str, size_t start, size_t count = npos)
inline String(const char *_str, size_t count)
template<class InputIt>
inline String(InputIt first, InputIt last)
String(std::nullptr_t) = delete
String(const String&) = default
String(String&&) = default
inline String(const std::string &_str, std::function<char(char)> transform_fun)
inline String(const std::string &_str, std::function<String(char)> transform_fun)
String &operator=(const String&) = default
String &operator=(String&&) = default
inline String &operator=(const std::string &_in)
inline String &operator=(std::string &&_in)
inline String &operator=(const char *_in)
inline String &operator=(char _in)
inline String &operator=(std::string_view _in)
inline String &operator=(std::initializer_list<char> _in)
String &operator=(std::nullptr_t) = delete
template<typename ...ARG_Ts>
inline String &assign(ARG_Ts&&... args)
inline std::string &str()
inline const std::string &str() const
inline char &operator[](size_t pos)
inline char operator[](size_t pos) const
inline char &front()
inline char front() const
inline char &back()
inline char back() const
inline char &Get(size_t pos)
inline char Get(size_t pos) const
inline String substr(size_t pos = 0, size_t count = npos) const
inline String GetRange(std::size_t start_pos, std::size_t end_pos) const
inline std::string_view View(size_t start = 0, size_t out_size = npos) const
inline std::string_view ViewFront(size_t out_size) const
inline std::string_view ViewBack(size_t out_size) const
inline std::string_view ViewRange(size_t start, size_t end) const
inline std::string_view ViewTo(CharSet stop_chars, size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline std::string_view ViewBackTo(CharSet stop_chars, size_t start = npos, const Syntax &syntax = Syntax::None()) const
inline std::string_view ViewWord(const Syntax &syntax = Syntax::Quotes(), size_t start = 0) const
inline std::string_view ViewLine(const Syntax &syntax = Syntax::Quotes(), size_t start = 0) const
inline bool HasAt(const String test, size_t pos) const
inline bool HasPrefix(const String &prefix) const
inline bool HasSuffix(const String &suffix) const
inline size_t Hash() const noexcept
inline size_t Count(char c, size_t start = 0) const
inline size_t Count(char c, size_t start, size_t end) const
inline bool IsLiteralChar() const

Test if an string is formatted as a literal character.

Test if an input string is properly formatted as a literal character.

inline bool IsLiteralString(const String &quote_marks = "\"") const

Test if an string is formatted as a literal string.

Test if an input string is properly formatted as a literal string.

inline String DiagnoseLiteralString(const String &quote_marks = "\"") const

Explain what string is NOT formatted as a literal string.

Test if an input string is properly formatted as a literal string.

inline bool IsComposedOf(CharSet char_set) const

Is string composed only of a set of characters (can be provided as a string)

inline bool IsNumber() const

Is string a valid number (int, floating point, or scientific notation all valid)

Determine if this string represents a proper number.

inline bool IsIdentifier() const

Is string a valid identifier? At least one char; cannot begin with digit, only letters, digits and _

inline bool OnlyLower() const
inline bool OnlyUpper() const
inline bool OnlyDigits() const
inline bool OnlyAlphanumeric() const
inline bool OnlyWhitespace() const
inline bool HasOneOf(CharSet char_set) const
inline bool Has(char c) const
inline bool HasWhitespace() const
inline bool HasNonwhitespace() const
inline bool HasUpper() const
inline bool HasLower() const
inline bool HasLetter() const
inline bool HasDigit() const
inline bool HasAlphanumeric() const
inline bool HasCharAt(char c, size_t pos) const
inline bool HasOneOfAt(CharSet opts, size_t pos) const
inline bool HasDigitAt(size_t pos) const
inline bool HasLetterAt(size_t pos) const
inline bool HasWhitespaceAt(size_t pos) const
inline size_t CountWhitespace() const
inline size_t CountNonwhitespace() const
inline size_t CountUpper() const
inline size_t CountLower() const
inline size_t CountLetters() const
inline size_t CountDigits() const
inline size_t CountAlphanumeric() const
inline String &clear() noexcept
inline String &erase(size_t index = 0, size_t count = npos)
inline iterator erase(const_iterator pos)
inline iterator erase(const_iterator first, const_iterator last)
inline String &RemoveWhitespace()
inline String &RemoveUpper()
inline String &RemoveLower()
inline String &RemoveLetters()
inline String &RemoveDigits()
inline String &RemovePunctuation()
inline bool PopIf(char c)
inline bool PopIf(String in)
inline String PopAll()

Pop the entire string.

inline String PopFixed(std::size_t end_pos, size_t delim_size = 0)

Pop a segment from the beginning of a string as another string, shortening original.

inline String Pop(CharSet chars = " \n\t\r", const Syntax &syntax = Syntax::None())

Remove a prefix of the string (up to a specified delimeter) and return it. If the delimeter is not found, return the entire string and clear it.

inline String PopTo(String delim, const Syntax &syntax = Syntax::None())

Remove a prefix of the string (up to a specified delimeter) and return it. If the delimeter is not found, return the entire string and clear it.

inline String PopWord(const Syntax &syntax = Syntax::None())
inline String PopLine(const Syntax &syntax = Syntax::None())
inline String PopQuote(const Syntax &syntax = Syntax::Quotes())
inline String PopParen(const Syntax &syntax = Syntax::Parens())
inline String PopLiteralSigned()
inline long long PopSigned()
inline String PopLiteralUnsigned()
inline unsigned long long PopUnsigned()
inline String PopLiteralFloat()
inline double PopFloat()
inline String PopLiteralChar(const Syntax &syntax = Syntax::CharQuotes())
inline char PopChar()
template<typename T>
inline String PopLiteral(const Syntax &syntax = Syntax::Quotes())
template<typename T>
inline T PopFromLiteral(const Syntax &syntax = Syntax::Quotes())
inline String &insert(size_t index, const String &in)
inline String &insert(size_t index, const String &in, size_t pos, size_t count = npos)
template<typename ...ARG_Ts>
inline String &insert(size_t index, ARG_Ts&&... args)
template<typename ...ARG_Ts>
inline String &insert(const_iterator pos, ARG_Ts&&... args)
inline String &append(const String &in)
inline String &append(const String &in, size_t pos, size_t count)
template<typename ...ARG_Ts>
inline String &append(ARG_Ts&&... args)
template<typename ARG_T>
inline String &operator+=(ARG_T &&arg)
inline String &PadFront(char padding, size_t target_size)
inline String &PadBack(char padding, size_t target_size)
template<typename ...ARG_Ts>
inline String &replace(ARG_Ts&&... args)
inline String &resize(size_t count, char c = '\0')
inline String &ReplaceChar(char from, char to, size_t start = 0)
inline String &ReplaceRange(size_t start, size_t end, String value)
template<typename MAP_T>
String &ReplaceVars(const MAP_T &var_map, String symbol = "$", const Syntax &syntax = Syntax::Full())

Find any instances of ${X} and replace with dictionary lookup of X.

template<typename FUN_T>
String &ReplaceMacro(String start_str, String end_str, FUN_T &&fun, const Syntax &syntax = Syntax{"\"", "()"})

Find any instance of MACRO_NAME(ARGS) and replace it with fun(ARGS).

Todo:

Separate syntax into find_start syntax and find_end (inside macro) syntax.

Parameters:
  • start_str – Initial sequence of macro to look for; for example “REPLACE(”

  • end_str – Sequence that ends the macro; for example “)”

  • macro_fun – Function to call with contents of macro. Params are macro_args (string), line_num (size_t), and hit_num (size_t)

  • syntax – What values should we skip as quotes or parens?

Returns:

This string object, post processing.

inline size_t FindQuoteMatch(size_t pos = 0) const
inline size_t FindParenMatch(size_t pos = 0, const Syntax &syntax = Syntax::Parens()) const
inline size_t RFindQuoteMatch(size_t pos = npos) const
inline size_t RFindParenMatch(size_t pos = npos, const Syntax &syntax = Syntax::RParens()) const
inline size_t FindMatch(size_t pos = 0, const Syntax &syntax = Syntax::Full()) const
inline size_t RFindMatch(size_t pos = npos, const Syntax &syntax = Syntax::Full()) const
inline size_t Find(char target, size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t Find(String target, size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t Find(const CharSet &char_set, size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t Find(const char *target, size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t RFind(char target, size_t start = npos, const Syntax &syntax = Syntax::None()) const
inline size_t RFind(String target, size_t start = npos, const Syntax &syntax = Syntax::None()) const
inline size_t RFind(const CharSet &char_set, size_t start = npos, const Syntax &syntax = Syntax::None()) const
inline size_t RFind(const char *target, size_t start = npos, const Syntax &syntax = Syntax::None()) const
inline void FindAll(char target, vector<size_t> &results, const Syntax &syntax = Syntax::None()) const
inline vector<size_t> FindAll(char target, const Syntax &syntax = Syntax::None()) const
template<typename ...Ts>
inline size_t FindAnyOfFrom(size_t start, String test1, Ts... tests) const
template<typename T, typename ...Ts>
inline size_t FindAnyOf(T test1, Ts... tests) const
inline size_t FindID(String target, size_t start, const Syntax &syntax = Syntax::Quotes()) const
inline size_t FindWhitespace(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindNonWhitespace(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindUpperChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindNonUpperChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindLowerChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindNonLowerChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindLetterChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindNonLetterChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindDigitChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindNonDigitChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindAlphanumericChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindNonAlphanumericChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindIDChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline size_t FindNonIDChar(size_t start = 0, const Syntax &syntax = Syntax::None()) const
inline std::string_view ViewNestedBlock(size_t start = 0, const Syntax &syntax = Syntax::Quotes()) const
inline std::string_view ViewQuote(size_t start = 0, const Syntax &syntax = Syntax::Quotes()) const
inline std::string_view ScanTo(size_t &pos, size_t stop_pos) const
inline std::string_view ScanWhile(size_t &pos, CharSet chars) const
inline std::string_view ScanView(std::function<std::string_view(size_t pos)> fun, size_t &pos) const
inline std::string_view ScanWord(size_t &pos) const
inline char ScanChar(size_t &pos) const
inline std::string_view ScanWhitespace(size_t &pos) const
inline std::string_view ScanUpper(size_t &pos) const
inline std::string_view ScanLower(size_t &pos) const
inline std::string_view ScanLetters(size_t &pos) const
inline std::string_view ScanDigits(size_t &pos) const
inline std::string_view ScanAlphanumeric(size_t &pos) const
inline std::string_view ScanNestedBlock(size_t &pos) const
inline std::string_view ScanQuote(size_t &pos) const
template<typename T>
inline T ConvertTo()
inline void Slice(vector<String> &out_set, String delim = ",", const Syntax &syntax = Syntax::Quotes(), bool trim_whitespace = false) const

Cut up a string based on the provided delimiter; fill them in to the provided vector.

Parameters:
  • out_set – destination vector

  • delim – delimiter to split on (default: “,”)

  • syntax – identify quotes and parens that should be kept together.

  • trim_whitespace – Should whitespace around delim or assign be ignored? (default: true)

inline vector<String> Slice(String delim = ",", const Syntax &syntax = Syntax::Quotes(), bool trim_whitespace = false) const

Slice a String on a delimiter; return a vector of results.

Note

May be less efficient, but easier than other version of Slice()

Parameters:
  • delim – delimiter to split on (default: “,”)

  • syntax – identify quotes and parens that should be kept together.

  • trim_whitespace – Should whitespace around delim or assign be ignored? (default: true)

inline void ViewSlices(vector<std::string_view> &out_set, String delim = ",", const Syntax &syntax = Syntax::Quotes()) const

Fill vector out_set of string_views based on the provided delimiter.

Parameters:
  • out_set – destination vector

  • delim – delimiter to split on (default: “,”)

  • syntax – identify quotes and parens that should be kept together.

inline vector<std::string_view> ViewSlices(String delim = ",", const Syntax &syntax = Syntax::Quotes()) const

Generate vector of string_views based on the provided delimiter.

Parameters:
  • delim – delimiter to split on (default: “,”)

  • syntax – identify quotes and parens that should be kept together.

inline void SliceAssign(std::map<String, String> &out_map, String delim = ",", String assign_op = "=", const Syntax &syntax = Syntax::Quotes(), bool trim_whitespace = true) const

Slice a string and treat each section as an assignment; place results in provided map.

Parameters:
  • delim – delimiter to split on (default ‘,’)

  • assign_op – separator for left and right side of assignment (default: “=”)

  • syntax – identify quotes and parens that should be kept together.

  • trim_whitespace – Should whitespace around delim or assign be ignored? (default: true)

inline std::map<String, String> SliceAssign(String delim = ",", String assign_op = "=", const Syntax &syntax = Syntax::Quotes(), bool trim_whitespace = true) const

Slice a string and treat each section as an assignment; fill out a map and return it.

Parameters:
  • delim – delimiter to split on (default ‘,’)

  • assign_op – separator for left and right side of assignment (default: “=”)

  • syntax – identify quotes and parens that should be kept together.

  • trim_whitespace – Should whitespace around delim or assign be ignored? (default: true)

inline String operator*(size_t count) const
template<typename ...Ts>
inline String &Append(Ts... args)
template<typename ...Ts>
inline String &Set(Ts... args)
template<typename T>
inline T As() const
inline String &AppendEscaped(char c)
inline String &SetEscaped(char c)
inline String &AppendEscaped(const String &in)
inline String &SetEscaped(const String &in)
inline String &SetEscaped()
inline String AsEscaped() const
inline String &AppendCSVSafe(String in)
inline String &SetCSVSafe(const String &in)
inline String &SetCSVSafe()
inline String AsCSVSafe() const
inline String &AppendWebSafe(String in)
inline String &SetWebSafe(const String &in)
inline String &SetWebSafe()
inline String AsWebSafe() const
template<typename T>
inline String &AppendLiteral(const T &in)
template<typename T>
inline String &SetLiteral(const T &in)
inline String &SetLiteral()
inline String AsLiteral() const
inline String &AppendUpper(const String &in)
inline String &SetUpper(const String &in)
inline String &SetUpper()
inline String AsUpper()
inline String &AppendLower(const String &in)
inline String &SetLower(const String &in)
inline String &SetLower()
inline String AsLower()
inline String &AppendTitleCase(const String &in)
inline String &SetTitleCase(const String &in)
inline String &SetTitleCase()
inline String AsTitleCase() const
inline String &AppendCount(int val, String item, String suffix = "s")
inline String &SetCount(int val, String item, String suffix = "s")
inline String &SetAsCount(int val, String suffix = "s")
inline String &AppendRoman(int val)
inline String &SetRoman(int val)
template<typename CONTAINER_T>
inline String &AppendEnglishList(const CONTAINER_T &container)
template<typename CONTAINER_T>
inline String &SetEnglishList(const CONTAINER_T &container)
template<typename ...ARG_Ts>
inline String &AppendFormatted(const std::string &format, ARG_Ts... args)
template<typename ...ARG_Ts>
inline String &SetFormatted(const std::string &format, ARG_Ts... args)
inline String &AppendTrimFront(const String &in, const CharSet &chars = WhitespaceCharSet())
inline String &SetTrimFront(const String &in, const CharSet &chars = WhitespaceCharSet())
inline String &TrimFront(const CharSet &chars = WhitespaceCharSet())
inline String AsTrimFront(const CharSet &chars = WhitespaceCharSet()) const
inline String &AppendTrimBack(const String &in, const CharSet &chars = WhitespaceCharSet())
inline String &SetTrimBack(const String &in, const CharSet &chars = WhitespaceCharSet())
inline String &TrimBack(const CharSet &chars = WhitespaceCharSet())
inline String AsTrimBack(const CharSet &chars = WhitespaceCharSet()) const
inline String &AppendTrimmed(const String &in, const CharSet &chars = WhitespaceCharSet())
inline String &SetTrimmed(const String &in, const CharSet &chars = WhitespaceCharSet())
inline String &Trim(const CharSet &chars = WhitespaceCharSet())
inline String AsTrimmed(const CharSet &chars = WhitespaceCharSet()) const
inline String &AppendCompressed(const String &in, const CharSet &chars = WhitespaceCharSet(), char compress_to = ' ', bool trim_start = true, bool trim_end = true)
inline String &SetCompressed(const String &in, const CharSet &chars = WhitespaceCharSet(), char compress_to = ' ', bool trim_start = true, bool trim_end = true)
inline String &Compress(const CharSet &chars = WhitespaceCharSet(), char compress_to = ' ', bool trim_start = true, bool trim_end = true)
inline String AsCompressed(const CharSet &chars = WhitespaceCharSet(), char compress_to = ' ', bool trim_start = true, bool trim_end = true) const
inline String &AppendRemoveChars(const String &in, const CharSet &chars)
inline String &SetRemoveChars(const String &in, const CharSet &chars)
inline String &RemoveChars(const CharSet &chars)
inline String AsRemoveChars(const CharSet &chars) const
inline String &AppendSlugify(String in)
inline String &SetSlugify(String in)
inline String &Slugify()
inline String AsSlugify() const
template<typename CONTAINER_T>
inline String &AppendJoin(const CONTAINER_T &container, String delim = "", String open = "", String close = "")
template<typename CONTAINER_T>
inline String &SetJoin(const CONTAINER_T &container, String delim = "", String open = "", String close = "")

Public Static Functions

static inline const String &Empty()
template<typename ...Ts>
static inline String Make(Ts... args)

Private Types

using Syntax = StringSyntax

Private Functions

inline void _AssertPos([[maybe_unused]] size_t pos) const
inline auto _Iterator(size_t pos) const

Private Static Functions

static inline char &NoChar()
static inline const String &_ToString(const String &in)
template<typename T>
static inline String _ToString(const std::vector<T> &in)
template<typename T>
static inline String _ToString(T &&in)
template<typename T>
static inline decltype(std::declval<T>()._ToString()) _Convert(const T &in, bool)
template<typename T>
static inline auto _Convert(const T &in, int) -> decltype(_ToString(in))
template<>
struct hash<String>
#include <String.hpp>

Public Functions

inline size_t operator()(const String &str) const noexcept