Program Listing for File Any.h

Return to documentation for file (include/flamegpu/detail/Any.h)

#ifndef INCLUDE_FLAMEGPU_DETAIL_ANY_H_
#define INCLUDE_FLAMEGPU_DETAIL_ANY_H_

#include <cstring>

namespace flamegpu {
namespace detail {

struct Any {
    Any(const void *_ptr, const size_t _length, const std::type_index &_type, const unsigned int _elements)
        : ptr(malloc(_length))
        , length(_length)
        , type(_type)
        , elements(_elements) {
        memcpy(ptr, _ptr, length);
    }
    template<typename T>
    explicit Any(const T other)
        : ptr(malloc(sizeof(T)))
        , length(sizeof(T))
        , type(typeid(T))
        , elements(1) {
        memcpy(ptr, &other, sizeof(T));
    }
    Any(const Any &_other)
        : ptr(malloc(_other.length))
        , length(_other.length)
        , type(_other.type)
        , elements(_other.elements) {
        memcpy(ptr, _other.ptr, length);
    }
    /*
     * Releases the allocated memory
     */
    ~Any() {
        free(ptr);
    }
    void operator=(const Any &_other) = delete;
    bool operator==(const Any &rhs) const {
        if (this == &rhs)
            return true;
        if (this->length == rhs.length &&
            this->type == rhs.type &&  // Could check the pointed to map matches instead
            this->elements == rhs.elements) {
            const char *const t_ptr = static_cast<char *>(this->ptr);
            const char *const t_ptr2 = static_cast<char *>(rhs.ptr);
            for (size_t i = 0; i < length; ++i) {
                if (t_ptr[i] != t_ptr2[i])
                    return false;
            }
            return true;
        }
        return false;
    }
    void *const ptr;
    const size_t length;
    const std::type_index type;
    const unsigned int elements;
};

}  // namespace detail
}  // namespace flamegpu

#endif  // INCLUDE_FLAMEGPU_DETAIL_ANY_H_