JH-Toolkit v1.4.1
An engineering-oriented C++20 toolkit with duck-typed concepts, static design, async coroutines, and semantic containers — header-only, RTTI-free, and concurrency-friendly.
Loading...
Searching...
No Matches
jh::immutable_str Class Referencefinal

Immutable string with optional automatic trimming and thread-safe hash caching. More...

#include <jh/core/immutable_str.h>

Public Member Functions

 immutable_str (const char *str)
 Constructs an immutable string from a C-string.
template<typename T>
 immutable_str (T)=delete
 Deleted constructor to prevent unintended conversions.
template<jh::concepts::mutex_like M>
 immutable_str (std::string_view sv, M &mtx)
 Constructs an immutable string from a std::string_view with mutex protection.
 immutable_str (const immutable_str &)=delete
 Deleted copy constructor.
immutable_stroperator= (const immutable_str &)=delete
 Deleted copy assignment operator.
 immutable_str (immutable_str &&)=delete
 Deleted move constructor.
immutable_stroperator= (immutable_str &&)=delete
 Deleted move assignment operator.
const char * c_str () const noexcept
 Returns the raw C-style string pointer.
std::string str () const
 Converts the immutable content to a std::string.
std::string_view view () const noexcept
 Returns a lightweight std::string_view to the immutable data.
pod::string_view pod_view () const noexcept
 Returns a jh::pod::string_view representing this immutable string.
std::uint64_t size () const noexcept
 Returns the length of the immutable string.
bool operator== (const immutable_str &other) const noexcept
 Compares two immutable_str instances for equality.
std::uint64_t hash () const noexcept
 Computes the cached hash value of the immutable string.

Static Public Member Functions

static bool is_static_built ()
 Reports whether this header was built in static mode.

Static Public Attributes

static constexpr bool auto_trim = JH_IMMUTABLE_STR_AUTO_TRIM
 Global flag selecting whether immutable_str performs automatic leading/trailing whitespace trimming.

Detailed Description

Immutable string with optional automatic trimming and thread-safe hash caching.

Overview

immutable_str represents a truly immutable and thread-safe string object. Once constructed, its internal data is fixed in memory and cannot be modified, reallocated, or replaced. It is designed for efficient read-only access in concurrent systems, configuration registries, and shared constant datasets.

Design Goals

  • Guarantee memory-level immutability with zero write access after initialization.
  • Provide deterministic lifetime ownership using unique_ptr<const char[]>.
  • Support concurrent reads safely without synchronization overhead.
  • Enable efficient sharing via std::shared_ptr<immutable_str> (atomic_str_ptr).
  • Offer consistent hashing and transparent equality for unordered containers.

Key Features

  • True Immutability: Internal buffer is never exposed for modification.
  • Thread-Safe Hashing: Cached on first access using std::once_flag.
  • Optional Auto-Trim: Leading/trailing whitespace removed at construction if enabled.
  • Memory Efficiency: Minimal overhead — stores only a pointer, size, and cached hash.
  • Transparent Lookup: Works directly with const char* keys in hash tables.

View Access

The class provides several view accessors for interoperability:

  • c_str() — Returns a null-terminated read-only C-string pointer.
  • view() — Returns a std::string_view to the internal data (no copy).
  • pod_view() — Returns a jh::pod::string_view for POD-style access.
  • str() — Returns a full std::string copy of the immutable buffer.

Note: Only str() performs data copying; other view functions are zero-copy.

Construction Semantics

  • Constructible from const char* or std::string_view (with a lock).
  • Deleted copy and move semantics to preserve immutability guarantees.
  • Preferred factory: jh::make_atomic() for shared atomic usage.

Dual-Mode Header Integration

  • Works under both header-only and static library modes via Dual-Mode Header system.
  • Build mode internally controlled by JH_INTERNAL_SHOULD_DEFINE.
  • Runtime detection available via is_static_built().

Thread Safety

  • All accessors (c_str(), view(), hash(), etc.) are thread-safe.
  • No external synchronization required after construction.
  • Hash is lazily computed once, guarded by std::call_once.

See Also

Constructor & Destructor Documentation

◆ immutable_str() [1/5]

jh::immutable_str::immutable_str ( const char * str)
explicit

Constructs an immutable string from a C-string.

Creates an immutable copy of the provided null-terminated C-string. The constructor performs an internal strlen() to determine the source length and allocates a new immutable buffer.

Parameters
strA null-terminated C-string. May be nullptr, which is treated as an empty string.

The caller must ensure that the input pointer remains valid and unmodified during construction. This is only safe when the input is either:

  • a string literal, or
  • a thread-exclusive buffer not accessed concurrently.

Passing a pointer that can be modified by another thread results in undefined behavior.

Note
  • Marked as explicit to prevent unintended implicit conversions.
  • Uses strlen() internally to determine the input length.
  • Trimming behavior depends on JH_IMMUTABLE_STR_AUTO_TRIM.
  • For non-null-terminated or shared buffers, use immutable_str(std::string_view, Mutex&) instead.
  • Designed for safe interoperation with C-style APIs (e.g., LLVM extern "C").

◆ immutable_str() [2/5]

template<typename T>
jh::immutable_str::immutable_str ( T )
explicitdelete

Deleted constructor to prevent unintended conversions.

This template overload disables single-argument construction from non-C-string types, ensuring that only const char* inputs are accepted. This avoids unsafe or ambiguous conversions that could lead to undefined behavior.

Note
  • Rejects non-string pointer inputs (e.g. numeric types, containers, or temporaries).
  • Ensures that only const char* can be used for direct construction.
  • For data without a null terminator or requiring lifetime protection, use immutable_str(std::string_view, Mutex&) instead.

◆ immutable_str() [3/5]

jh::immutable_str::immutable_str ( std::string_view sv,
M & mtx )
inline

Constructs an immutable string from a std::string_view with mutex protection.

Creates an immutable copy of the data referenced by sv while holding the provided mutex. This overload is intended for cases where the source memory may be transient, mutable, or shared between threads.

Template Parameters
MAny type satisfying jh::concepts::mutex_like — such as std::mutex, std::shared_mutex, or custom types.
Parameters
svA std::string_view representing the source data. It may or may not be null-terminated.
mtxA reference to a mutex protecting the lifetime of the buffer referenced by sv.
Exceptions
std::logic_errorIf sv contains embedded null ('\0') characters.
Note
  • Performs a bounded null-character check using ::strnlen() to verify that no embedded nulls exist within sv.size() bytes.
  • Copies exactly sv.size() bytes into an internal immutable buffer, even if not null-terminated.
  • The provided mtx must guard the same memory region as sv.data(); using an unrelated mutex leads to undefined behavior.
  • Supports both exclusive and shared mutex types, via jh::sync::const_lock.
  • Recommended for constructing immutable strings from shared or non-terminated data regions.
  • Optional optimization:
    If you are certain that the source data is not shared across threads, you may explicitly use jh::typed::null_mutex (from <jh/typed>) as the mutex parameter. It is a zero-cost, concept-compatible dummy mutex, and all locking operations become no-ops.
    Note: This must be explicitly specified; no automatic substitution is performed.

◆ immutable_str() [4/5]

jh::immutable_str::immutable_str ( const immutable_str & )
delete

Deleted copy constructor.

immutable_str manages its string data through std::unique_ptr<const char[]>, enforcing exclusive ownership. Copy construction would require duplicating the underlying data buffer, which is explicitly disallowed to maintain immutability.

Note
  • Prevents unintended shallow copies.
  • Ensures that each instance has a unique, immutable data block.

◆ immutable_str() [5/5]

jh::immutable_str::immutable_str ( immutable_str && )
delete

Deleted move constructor.

Unlike typical movable types, immutable_str forbids move semantics. Moving would transfer ownership of the underlying buffer, violating the immutability principle.

Note
  • Immutability implies that instances cannot change ownership post-construction.
  • To share instances safely, use std::shared_ptr<jh::immutable_str>.

Member Function Documentation

◆ c_str()

const char * jh::immutable_str::c_str ( ) const
nodiscardnoexcept

Returns the raw C-style string pointer.

Provides direct access to the internal immutable buffer as a const char*. The returned pointer is guaranteed to remain valid for the lifetime of the object.

Returns
A pointer to an immutable, null-terminated character sequence.
Note
  • The returned pointer must never be modified.
  • Ownership remains with immutable_str; do not deallocate it.
  • Safe for concurrent read access from multiple threads.

◆ hash()

std::uint64_t jh::immutable_str::hash ( ) const
nodiscardnoexcept

Computes the cached hash value of the immutable string.

Returns a 64-bit hash derived from the string's contents. The computation is performed lazily — the first call initializes the cached value in a thread-safe manner, and all subsequent calls return the stored result without recomputation.

Returns
A 64-bit hash value uniquely representing the string contents.
Note
  • Lazy evaluation ensures hashing is performed only once per instance.
  • Thread-safe: guarded internally by std::once_flag.
  • Equivalent calls always return the same value for the same object.

◆ is_static_built()

bool jh::immutable_str::is_static_built ( )
static

Reports whether this header was built in static mode.

Indicates if the current immutable_str implementation was compiled as part of the static library target (jh-toolkit-static) or used in header-only mode (jh-toolkit).

Returns
true if compiled as part of jh-toolkit-static; otherwise false.
Note
  • This function supports runtime detection for dual-mode header builds.
  • In header-only builds, it always returns false.
  • In static library builds, it returns true (macro JH_IS_STATIC_BUILD defined).
  • Useful for diagnostics or conditional logic depending on linkage mode.

◆ operator=() [1/2]

immutable_str & jh::immutable_str::operator= ( const immutable_str & )
delete

Deleted copy assignment operator.

Copy assignment is disabled to preserve the immutable property of immutable_str. Assigning one immutable instance to another would imply replacing its internal buffer, which contradicts its design.

Note
  • Prevents mutation through reassignment.
  • Use std::shared_ptr<jh::immutable_str> if sharing semantics are required.

◆ operator=() [2/2]

immutable_str & jh::immutable_str::operator= ( immutable_str && )
delete

Deleted move assignment operator.

Move assignment is disabled because immutable_str must remain constant for its entire lifetime. Any form of reassignment or ownership transfer is considered a modification of its internal state.

Note
  • Enforces strict immutability and thread safety.
  • Instances should be shared through std::shared_ptr, not reassigned.

◆ operator==()

bool jh::immutable_str::operator== ( const immutable_str & other) const
noexcept

Compares two immutable_str instances for equality.

Performs a deep, byte-wise comparison of the internal buffers. This operator guarantees that two instances are considered equal only if their contents are identical.

Parameters
otherAnother immutable_str instance to compare with.
Returns
true if both strings contain identical data; otherwise false.
Note
  • Automatically implies operator!= as its logical negation.
  • Comparison is content-based, not pointer-based.
  • Safe for concurrent read operations on both operands.

◆ pod_view()

pod::string_view jh::immutable_str::pod_view ( ) const
nodiscardnoexcept

Returns a jh::pod::string_view representing this immutable string.

Provides a POD-compatible, read-only view over the internal buffer. The returned object has the same layout and semantics as jh::pod::string_view — that is, a pair of const char* and uint64_t describing a non-owning range of bytes.

Returns
A jh::pod::string_view referencing the same data as this object.
Note
  • No memory is copied or allocated.
  • The view remains valid as long as the originating immutable_str exists.
  • It enables deterministic hashing by allowing jh::pod::string_view to compute stable hashes via any algorithm provided by jh::meta::c_hash, unlike the non-deterministic nature of typical runtime hash functions.
  • Comparison and hashing behavior are identical to jh::pod::string_view.

◆ size()

std::uint64_t jh::immutable_str::size ( ) const
nodiscardnoexcept

Returns the length of the immutable string.

Provides the total number of characters contained in the string. The length is determined at construction time and remains constant throughout the object's lifetime.

Returns
The number of characters in the string.
Note
  • The value is fixed after initialization (no dynamic resizing).
  • Equivalent to view().size().
  • Safe for concurrent read access.

◆ str()

std::string jh::immutable_str::str ( ) const
nodiscard

Converts the immutable content to a std::string.

Creates and returns a copy of the internal immutable data as a std::string. This is the only interface that performs a deep copy, preserving immutability while providing a mutable external representation.

Returns
A std::string containing a copy of the immutable data.
Note
  • This operation allocates new memory for the returned std::string.
  • Useful when interoperability with mutable string APIs is required.
  • Thread-safe; does not modify the internal buffer.

◆ view()

std::string_view jh::immutable_str::view ( ) const
nodiscardnoexcept

Returns a lightweight std::string_view to the immutable data.

Provides a non-owning view of the internal string data without copying. This is the most efficient accessor for read-only operations and comparison.

Returns
A std::string_view referencing the immutable string data.
Note
  • The view remains valid for the lifetime of the immutable_str instance.
  • No memory allocation occurs.
  • Safe for concurrent reads; not safe if the underlying object is destroyed.

Member Data Documentation

◆ auto_trim

bool jh::immutable_str::auto_trim = JH_IMMUTABLE_STR_AUTO_TRIM
staticconstexpr

Global flag selecting whether immutable_str performs automatic leading/trailing whitespace trimming.

This value is controlled by the macro JH_IMMUTABLE_STR_AUTO_TRIM. The macro must be defined before including <jh/immutable_str>. If the macro is not defined beforehand, the default value is true.

Because auto_trim is an ordinary constexpr bool, it can be inspected in constexpr contexts and used inside concepts, templates, and other compile-time logic—avoiding the need for preprocessor conditionals (#if / #ifdef).

  • true (default): All constructed immutable_str instances remove leading and trailing ASCII whitespace.
  • false: Whitespace is preserved exactly.

Usage Recommendation

To ensure consistent behavior across translation units — especially when dependencies may include <jh/immutable_str> indirectly — place:

#define JH_IMMUTABLE_STR_AUTO_TRIM false
#include <jh/immutable_str>
Forwarding header for jh::immutable_str.

before any code that might include the header.


The documentation for this class was generated from the following file: