RString#

Fully qualified name: carb::RString

Defined in carb/RString.h

class RString : public carb::detail::RStringTraits<false>#

Carbonite registered strings.

The Carbonite framework has a rich string-interning interface that is very easily used through the RString (and other) classes. This implements a Flyweight pattern for strings. The registered string interface is fully ABI-safe due to versioning, and can even be used in an application prior to the main(), WinMain() or DllMain() functions being called. Furthermore, the API is fully thread-safe.

Registered strings have pre-computed hashes which make them ideal for identifiers and map keys, and string (in-)equality checks are O(1) constant time. For ordered containers, registered strings have an owner_before() function that can be used for stable (though not lexicographical) ordering. If lexicographical ordering is desired, O(n) compare() functions are provided.

Variations exist around case-sensitivity. The RStringU class (the U stands for “un-cased” which is used in this API to denote case-insensitivity) is used to register a string that will compare in a case-insensitive manner. Although RString and RStringU cannot be directly compared for equality, RString::toUncased() exists to explicitly create a case-insensitive RStringU from an RString which can then be compared.

Variations also exist around using registered strings as a key value. It can be useful to have an associated number to denote multiple instances of a registered string: hence the RStringKey and RStringUKey classes.

To register a string, pass a string to the RString constructor RAII-style. Strings that are registered stay as such for the entire run of the application; strings are never unregistered. Registered strings are stored in a named section of shared memory accessible by all modules loaded by an application. The memory for registered strings is allocated directly from the operating system to avoid cross-DLL heap issues.

Variations:

  • RStringU - an “un-cased” (i.e. case-insensitive) registered string

  • RStringKey - Adds a numeric component to RString to create an identifier or key.

  • RStringUKey - Adds a numeric component to RStringU to create an identifier or key that is case-insensitive.

Note

Registered strings are a limited resource, but there exists slots for approximately two million strings.

Public Functions

constexpr RString() noexcept#

Default constructor.

isEmpty() will report true.

constexpr RString(eRString staticString) noexcept#

Initializes this registered string to one of the static pre-defined registered strings.

Parameters:

staticString – The pre-defined registered string to use.

explicit RString(const char *str, RStringOp op = RStringOp::eRegister)#

Finds or registers a new string.

Parameters:
  • str – The string to find or register.

  • op – The operation to perform. If directed to RStringOp::eFindExisting and the string has not been previously registered, *this is initialized as if with the default constructor.

explicit RString(
const char *str,
size_t len,
RStringOp op = RStringOp::eRegister,
)#

Finds or registers a new counted string.

Note

While generally not recommended, passing len allows the given string to contain embedded NUL (‘\0’) characters.

Parameters:
  • str – The string to find or register.

  • len – The number of characters of str to include.

  • op – The operation to perform. If directed to RStringOp::eFindExisting and the string has not been previously registered, *this is initialized as if with the default constructor.

explicit RString(
const std::string &str,
RStringOp op = RStringOp::eRegister,
)#

Finds or registers a new std::string.

Note

If str contains embedded NUL (‘\0’) characters, the RString will contain the embedded NUL characters as well.

Parameters:
  • str – The std::string to find or register.

  • op – The operation to perform. If directed to RStringOp::eFindExisting and the string has not been previously registered, *this is initialized as if with the default constructor.

explicit RString(const RStringKey &other) noexcept#

Truncates RStringKey into only the registered string portion.

Parameters:

other – The RStringKey to truncate.

RStringU toUncased() const noexcept#

Converts this registered string into an “un-cased” (i.e.

case-insensitive) registered string.

Note

The returned string may differ in case to *this when retrieved with c_str() or toString().

Returns:

An “un-cased” (i.e. case-insensitive) string that matches *this when compared in a case-insensitive manner.

RString truncate() const noexcept#

Returns a copy of this registered string.

Note

This function exists for compatibility with the RStringKey interface.

Returns:

*this since this string already has no number component.

RStringKey toRStringKey(int32_t number = 0) const#

Appends a number to the registered string to form a RStringKey.

Parameters:

number – An optional number to append (default = 0).

Returns:

An RStringKey based on *this and the provided number.

bool operator==(const RString &other) const noexcept#

Equality comparison between this registered string and another.

Parameters:

other – Another registered string.

Returns:

true if *this and other represent the same registered string; false otherwise.

bool operator!=(const RString &other) const noexcept#

Inequality comparison between this registered string and another.

Parameters:

other – Another registered string.

Returns:

false if *this and other represent the same registered string; true otherwise.

bool owner_before(const RString &other) const noexcept#

Checks whether this registered string is stably (but not lexicographically) ordered before another registered string.

This ordering is to make registered strings usable as keys in ordered associative containers in O(1) time.

Note

This is NOT a lexicographical comparison; for that use one of the compare() functions. To reduce ambiguity between a strict ordering and lexicographical comparison there is no operator< function for this string class. While a lexicographical comparison would be O(n), this comparison is O(1).

Parameters:

other – Another registered string.

Returns:

true if *this should be ordered-before other; false otherwise.

bool isValid() const noexcept#

Checks to see if this registered string has been corrupted.

Note

It is not possible for this registered string to become corrupted through normal use of the API. It could be caused by bad casts or use-after-free.

Returns:

true if *this represents a valid registered string; false if *this is corrupted.

constexpr bool isEmpty() const noexcept#

Checks to see if this registered string represents the “” (empty) value.

Returns:

true if *this is default-initialized or initialized to eRString::Empty; false otherwise.

constexpr bool isUncased() const noexcept#

Checks to see if this registered string represents an “un-cased” (i.e.

case-insensitive) registered string.

Returns:

true if *this is “un-cased” (i.e. case-insensitive); false if case-sensitive.

constexpr uint32_t getStringId() const noexcept#

Returns the registered string ID.

This ID is only useful for debugging purposes and should not be used for comparisons.

Returns:

The string ID for this registered string.

size_t getHash() const#

Returns the hash value as by carb::hashString(this->c_str()).

Note

This value is computed once for a registered string and cached, so this operation is generally very fast.

Returns:

The hash value as computed by carb::hashString(this->c_str()).

size_t getUncasedHash() const noexcept#

Returns the hash value as by carb::hashLowercaseString(this->c_str()).

Note

This value is pre-computed for registered strings and cached, so this operation is always O(1).

Returns:

The hash value as computed by carb::hashLowercaseString(this->c_str()).

const char *c_str() const noexcept#

Resolves this registered string to a C-style NUL-terminated string.

Note

This operation is O(1).

Returns:

The C-style string previously registered.

const char *data() const noexcept#

An alias for c_str(); resolves this registered string to a C-style NUL-terminated string.

Note

This operation is O(1).

Returns:

The C-style string previously registered.

size_t length() const noexcept#

Returns the length of the registered string.

If the string contains embedded NUL (‘\0’) characters this may differ from std::strlen(c_str()).

Note

This operation is O(1).

Returns:

The length of the registered string not including the NUL terminator.

bool operator==(const RStringTraits &other) const#

Equality comparison between this registered string and another.

Parameters:

other – Another registered string.

Returns:

true if *this and other represent the same registered string; false otherwise.

bool operator!=(const RStringTraits &other) const#

Inequality comparison between this registered string and another.

Parameters:

other – Another registered string.

Returns:

false if *this and other represent the same registered string; true otherwise.

bool owner_before(const RStringTraits &other) const#

Checks whether this registered string is stably (but not lexicographically) ordered before another registered string.

This ordering is to make registered strings usable as keys in ordered associative containers in O(1) time.

Note

This is NOT a lexicographical comparison; for that use one of the compare() functions. To reduce ambiguity between a strict ordering and lexicographical comparison there is no operator< function for this string class. While a lexicographical comparison would be O(n), this comparison is O(1).

Parameters:

other – Another registered string.

Returns:

true if *this should be ordered-before other; false otherwise.

int compare(
const RStringTraits<OtherUncased, OtherBase> &other,
) const#

Lexicographically compares this registered string with another.

Note

If either *this or other is “un-cased” (i.e. case-insensitive), a case-insensitive compare is performed.

Template Parameters:

OtherUncasedtrue if other is “un-cased” (i.e. case-insensitive); false otherwise.

Parameters:

other – Another registered string to compare against.

Returns:

0 if the strings are equal, >0 if other is lexicographically ordered before *this, or <0 if *this is lexicographically ordered before other. See note above regarding case-sensitivity.

int compare(const char *s) const#

Lexicographically compares this registered string with a C-style string.

Note

If *this is “un-cased” (i.e. case-insensitive), a case-insensitive compare is performed.

Parameters:

s – A C-style string to compare against.

Returns:

0 if the strings are equal, >0 if s is lexicographically ordered before *this, or <0 if *this is lexicographically ordered before s. See note above regarding case-sensitivity.

int compare(size_t pos, size_t count, const char *s) const#

Lexicographically compares a substring of this registered string with a C-style string.

Note

If *this is “un-cased” (i.e. case-insensitive), a case-insensitive compare is performed.

Parameters:
  • pos – The starting offset of the registered string represented by *this. Must less-than-or-equal-to the length of the registered string.

  • count – The length from pos to use in the comparison. This value is automatically clamped to the end of the registered string.

  • s – A C-style string to compare against.

Returns:

0 if the strings are equal, >0 if s is lexicographically ordered before the substring of *this, or <0 if the substring of *this is lexicographically ordered before s. See note above regarding case-sensitivity.

int compare(
size_t pos,
size_t count,
const char *s,
size_t len,
) const#

Lexicographically compares a substring of this registered string with a C-style string.

Note

If *this is “un-cased” (i.e. case-insensitive), a case-insensitive compare is performed.

Parameters:
  • pos – The starting offset of the registered string represented by *this. Must less-than-or-equal-to the length of the registered string.

  • count – The length from pos to use in the comparison. This value is automatically clamped to the end of the registered string.

  • s – A C-style string to compare against.

  • len – The number of characters of s to compare against.

Returns:

0 if the strings are equal, >0 if s is lexicographically ordered before the substring of *this, or <0 if the substring of *this is lexicographically ordered before s. See note above regarding case-sensitivity.

int compare(const std::string &s) const#

Lexicographically compares this registered string with a string.

Note

If *this is “un-cased” (i.e. case-insensitive), a case-insensitive compare is performed.

Parameters:

s – A string to compare against.

Returns:

0 if the strings are equal, >0 if s is lexicographically ordered before *this, or <0 if *this is lexicographically ordered before s. See note above regarding case-sensitivity.

int compare(size_t pos, size_t count, const std::string &s) const#

Lexicographically compares a substring of this registered string with a string.

Note

If *this is “un-cased” (i.e. case-insensitive), a case-insensitive compare is performed.

Parameters:
  • pos – The starting offset of the registered string represented by *this. Must less-than-or-equal-to the length of the registered string.

  • count – The length from pos to use in the comparison. This value is automatically clamped to the end of the registered string.

  • s – A string to compare against.

Returns:

0 if the strings are equal, >0 if s is lexicographically ordered before the substring of *this, or <0 if the substring of *this is lexicographically ordered before s. See note above regarding case-sensitivity.

Public Static Attributes

static constexpr bool IsUncased#

Constant that indicates whether this is “un-cased” (i.e.

case-insensitive).