String: Add str_if_stable() as a const alternative to str()

The `str()` method must be non-const because it may need to internally
mutate the representation of the string in order to have an owned
`std::string` instance holding the exact string (not a superstring).
This is inconvenient in contexts where we can ensure that no mutation
is needed to get a `std::string const&`.

Add a `str_if_stable() const` method that returns `std::string const*`
so we can return `nullptr` if if mutation would be necessary to get a
`std::string const&`.  Add supporting `is_stable() const` and
`stabilize()` methods to check and enforce stable availability of
`std::string const&`.  These can be used to create `String const`
instances from which we can still get a `std::string const&` via
`*str_if_stable()` by maintaining the stability invariant at runtime.
This commit is contained in:
Brad King
2018-11-08 08:12:02 -05:00
parent a0841b59bd
commit 2d68b2c593
3 changed files with 97 additions and 3 deletions

View File

@@ -348,6 +348,20 @@ public:
char back() const noexcept { return view_.back(); }
/** Return true if this instance is stable and otherwise false.
An instance is stable if it is in the 'null' state or if it is
an 'owned' state not produced by substring operations, or
after a call to 'stabilize()' or 'str()'. */
bool is_stable() const;
/** If 'is_stable()' does not return true, mutate so it does. */
void stabilize();
/** Get a pointer to a normal std::string if 'is_stable()' returns
true and otherwise nullptr. The pointer is valid until this
instance is mutated or destroyed. */
std::string const* str_if_stable() const;
/** Get a refernce to a normal std::string. The reference
is valid until this instance is mutated or destroyed. */
std::string const& str();