#pragma once
#include <xs/Scalar.h>
namespace xs {
using xs::my_perl;
struct HashEntry {
HashEntry (HE* he = NULL) : he(he) {}
U32 hash () const { return HeHASH(he); }
panda::string_view key () const { return panda::string_view(HeKEY(he), HeKLEN(he)); }
HEK* hek () const { return HeKEY_hek(he); }
Scalar value () const {
Scalar ret;
ret.set(HeVAL(he));
return ret;
}
void value (const Scalar& val) {
SvREFCNT_inc_simple_void(val.get());
auto old = HeVAL(he);
HeVAL(he) = val.get();
SvREFCNT_dec(old);
}
void value (SV* v) { value(Scalar(v)); }
void value (const Sv& v) { value(Scalar(v)); }
void value (const Array&) = delete;
void value (const Hash&) = delete;
void value (const Sub&) = delete;
void value (const Io&) = delete;
bool operator== (const HashEntry& oth) const { return he == oth.he; }
explicit
operator bool () const { return he; }
operator HE* () const { return he; }
HE* operator-> () const { return he; }
private:
HE* he;
};
}
#if (__cplusplus >= 201703L)
// structured bindings for C++17 and newer
namespace std
{
template<>
struct tuple_size<xs::HashEntry>
{
static constexpr size_t value = 2;
};
template<>
struct tuple_element<0, xs::HashEntry>
{
using type = panda::string_view;
};
template<>
struct tuple_element<1, xs::HashEntry>
{
using type = xs::Scalar;
};
}//namespace std
namespace xs {
template<std::size_t Index>
std::tuple_element_t<Index, xs::HashEntry> get(const xs::HashEntry& he)
{
if constexpr (Index == 0) return he.key();
if constexpr (Index == 1) return he.value();
}
}
#endif