NAME

XS::Framework::Manual::SVAPI::Hash - XS::Framework Hash C++ class reference

Hash

Overview

The Hash class is the wrapper around Perls HV* type, which is a variant of SV*. As with Sv, it might hold an underlying Perl hash HV* or might not.

Construction

static Hash noinc  (SV* val)
static Hash noinc  (HV* val)

Hash (std::nullptr_t = nullptr)
Hash (SV* sv, bool policy = INCREMENT)
Hash (HV* sv, bool policy = INCREMENT)

The new Hash is created, and it either takes ownership on the underlying SV*/HV* with corresponding refcounting policy, or just empty wrapper is created, which holds no value. On invalid SV*, e.g. pointer to Arrray, an exception will be thrown. The valid SV* should be either HV* or reference to HV* or undef.

Please, note, that empty Hash means that it holds no value (aka NULL), it is not the same, when it holds underlying empty HV* with zero items.

static Hash create()
static Hash create (size_t cap)

It is possible to create new Hash with empty underlying HV*, optionally reserving space for cap items (SV*).

It is possible to create Hash object in-place via itializer list, which should contain name (string) / value (Scalar) pairs, i.e.:

static Hash create (std::initializer_list<std::tuple<panda::string_view, Scalar>> l)
Hash (std::initializer_list<std::tuple<panda::string_view, Scalar>>)

For example,

auto h = Hash::create({
    {"key-int", Simple(1)},
    {"key-string", Simple("val2")},
});

The copy and move constructors are also available:

Hash (const Hash& oth)
Hash (Hash&&      oth)
Hash (const Sv&   oth)
Hash (Sv&&        oth)

assignment operators

Hash& operator= (SV* val)
Hash& operator= (HV* val)
Hash& operator= (const Hash& oth)
Hash& operator= (Hash&& oth)
Hash& operator= (const Sv& oth)
Hash& operator= (Sv&& oth)

The assignment operators are complementaty to the constructors above. They inherit behaviour from Sv, including NULL-safety. The previously held SV* will be dec-remented.

The last operator performs proxy call in scalar context, the same as in appropriate constructor above.

void set (SV* val)

The set method directly assigns the value to the underlying SV*, bypassing all checks. Use the method with caution.

getters

There are zero-cost NULL-safe getters:

operator HV* () const
HV* operator-> () const
template <typename T = SV> one_of_t<T,SV,HV>* get ()

For example,

Hash hash = ...;
HV* hv = hash.get<HV>();

element access

Scalar fetch (const panda::string_view& key) const
Scalar at (const panda::string_view& key) const
Scalar operator[] (const panda::string_view& key) const
KeyProxy operator[] (const panda::string_view& key)

The first three methods return Scalar type. fetch provides bounary-safe access to the elements, if the index is out of bounds, then empty Scalar is returned and underlying HV* is kept untouched. The at method also checks key existance, and if it is not found, then an exception will be thrown (similar to std::map::at()). The operator[] is an alias for fetch. The non-const acccessor is needed to allow in-place fast modification and lazy creation of underlying element, i.e.

Hash hash = ...;
hash["key"] = Simple(10);

fetch, at and operator[] const are NULL-safe; while mofifying operator[] is NULL-unsafe.

void store (const panda::string_view& key, const Scalar& val, U32 hash = 0)
void store (const panda::string_view& key, std::nullptr_t,    U32 hash = 0)
void store (const panda::string_view& key, SV* v,             U32 hash = 0)
void store (const panda::string_view& key, const Sv& v,       U32 hash = 0)

The store method is used store item in the hash. If underlyging Perl array HV* is NULL, then store will throw exception. The hash parameter is the precomputed hash value; if it is zero then Perl will compute it.

To check element existance, the NULL-safe exist method (or it's alias contains) can be used:

bool exists   (const panda::string_view& key) const
bool contains (const panda::string_view& key) const

To delete arbitrary element by key the NULL-unsafe erase method can be used (the previous value, if existed, is returned; empty Scalar is returned otherwise).

Scalar erase (const panda::string_view& key)

clear()

void clear ()

Frees all items in the underlying HV* array. This is NULL-safe method.

undef()

void undef()

Frees all items in the underlying HV* hash; the hash container HV* itself remains alive. This is NULL-safe method.

push_on_stack()

U32 push_on_stack (SV** sp) const

This method copies all hash items into perl stack SV**.

It returns the count of copied items. The method takes care of all needed mechanis, e.g. sv_2mortal and increasing refcounter of the items.

This is NULL-unsafe method.

size()

size_t  size      () const

Returns size of underlying hash, i.e. number of used keys. If it is NULL, then 0 is returned. In other words, this method is NULL-safe.

capacity()

size_t  capacity  () const

Returns capacity of underlying hash. If it is NULL, then 0 is returned. In other words, this method is NULL-safe.

reserve()

void reserve (size_t newsz)

Increases the capacity of the container. This is NULL-unsafe method.

itearators

Hash provides iterator and const-iterator random-access accessors for it's content:

const_iterator cbegin () const
const_iterator cend   () const
const_iterator begin  () const
const_iterator end    () const
iterator       begin  ()
iterator       end    ()

This methods are NULL-safe. As usually, when underlying array is modified, the used iterators become invalid, and should not used any longer.

Usage example:

Hash hash = ...;
for (auto it = hash.begin(); it != hash.end(); ++it) {
    panda::string_view key = it->key();
    Scalar value = it->value();
    U32 key_hash = it->hash();
}

SEE ALSO

XS::Framework

XS::Framework::Manual::SVAPI

XS::Framework::Manual::SVAPI::Sv

XS::Framework::Manual::SVAPI::Stash