agent/native/libphpbridge/code/AutoZval.h (56 lines of code) (raw):
#pragma once
#include <array>
#include <stdexcept>
#include <Zend/zend_API.h>
#include <Zend/zend_types.h>
#include <Zend/zend_variables.h>
namespace elasticapm::php {
template<std::size_t SIZE = 1>
class AutoZval {
public:
AutoZval(const AutoZval&) = delete;
AutoZval& operator=(const AutoZval&) = delete;
// TODO implement copy constructor or safer - copy_full() and copy_ref() methods
// TODO implement constructor or separate class for external pointer and don't use member storage then
AutoZval() {
for (std::size_t idx = 0; idx < SIZE; ++idx) {
ZVAL_UNDEF(&value[idx]);
}
}
~AutoZval() {
for (std::size_t idx = 0; idx < SIZE; ++idx) {
zval_ptr_dtor(&value[idx]);
}
}
constexpr zval &operator*() noexcept {
return value[0];
}
constexpr zval *get() noexcept {
return &value[0];
}
constexpr zval &at(std::size_t index) {
if (index >= SIZE) {
throw std::out_of_range("AutoZval index greater or equal capacity");
}
return value[index];
}
constexpr zval *get(std::size_t index) {
if (index >= SIZE) {
throw std::out_of_range("AutoZval index greater or equal capacity");
}
return value[index];
}
zval *data() {
return &value[0];
}
zval &operator[](std::size_t index) {
if (index >= SIZE) {
throw std::out_of_range("AutoZval index greater or equal capacity");
}
return value[index];
}
constexpr std::size_t size() const noexcept {
return SIZE;
}
private:
zval value[SIZE];
};
}