Program Listing for File EnvironmentDirectedGraphDescription.cuh
↰ Return to documentation for file (include/flamegpu/model/EnvironmentDirectedGraphDescription.cuh
)
#ifndef INCLUDE_FLAMEGPU_MODEL_ENVIRONMENTDIRECTEDGRAPHDESCRIPTION_CUH_
#define INCLUDE_FLAMEGPU_MODEL_ENVIRONMENTDIRECTEDGRAPHDESCRIPTION_CUH_
#include <vector>
#include <memory>
#include <string>
#include "flamegpu/model/EnvironmentDirectedGraphData.cuh"
#include "flamegpu/model/EnvironmentDescription.h"
namespace flamegpu {
class CEnvironmentDirectedGraphDescription {
friend struct EnvironmentDirectedGraphData;
public:
explicit CEnvironmentDirectedGraphDescription(std::shared_ptr<EnvironmentDirectedGraphData> data);
explicit CEnvironmentDirectedGraphDescription(std::shared_ptr<const EnvironmentDirectedGraphData> data);
CEnvironmentDirectedGraphDescription(const CEnvironmentDirectedGraphDescription& other_graph) = default;
CEnvironmentDirectedGraphDescription(CEnvironmentDirectedGraphDescription&& other_graph) = default;
CEnvironmentDirectedGraphDescription& operator=(const CEnvironmentDirectedGraphDescription& other_graph) = default;
CEnvironmentDirectedGraphDescription& operator=(CEnvironmentDirectedGraphDescription&& other_graph) = default;
bool operator==(const CEnvironmentDirectedGraphDescription& rhs) const;
bool operator!=(const CEnvironmentDirectedGraphDescription& rhs) const;
std::string getName() const;
const std::type_index& getVertexPropertyType(const std::string& property_name) const;
const std::type_index& getEdgePropertyType(const std::string& property_name) const;
size_t getVertexPropertySize(const std::string& property_name) const;
size_t getEdgePropertySize(const std::string& property_name) const;
flamegpu::size_type getVertexPropertyLength(const std::string& property_name) const;
flamegpu::size_type getEdgePropertyLength(const std::string& property_name) const;
flamegpu::size_type geVertexPropertiesCount() const;
flamegpu::size_type getEdgePropertiesCount() const;
bool hasVertexProperty(const std::string& property_name) const;
bool hasEdgeProperty(const std::string& property_name) const;
protected:
std::shared_ptr<EnvironmentDirectedGraphData> graph;
};
class EnvironmentDirectedGraphDescription : public CEnvironmentDirectedGraphDescription {
public:
explicit EnvironmentDirectedGraphDescription(std::shared_ptr<EnvironmentDirectedGraphData> data);
EnvironmentDirectedGraphDescription(const EnvironmentDirectedGraphDescription& other_graph) = default;
EnvironmentDirectedGraphDescription(EnvironmentDirectedGraphDescription&& other_graph) = default;
EnvironmentDirectedGraphDescription& operator=(const EnvironmentDirectedGraphDescription& other_graph) = default;
EnvironmentDirectedGraphDescription& operator=(EnvironmentDirectedGraphDescription&& other_graph) = default;
template<typename T, size_type N>
void newVertexProperty(const std::string& property_name, const std::array<T, N>& default_value = {});
template<typename T, size_type N>
void newEdgeProperty(const std::string& property_name, const std::array<T, N>& default_value = {});
#ifndef SWIG
template<typename T>
void newVertexProperty(const std::string& property_name, const T& default_value = {});
template<typename T>
void newEdgeProperty(const std::string& property_name, const T& default_value = {});
#else
template<typename T>
void newVertexProperty(const std::string& property_name, const T& default_value = 0);
template<typename T>
void newVertexPropertyArray(const std::string& property_name, size_type length, const std::vector<T>& default_value = {});
template<typename T>
void newEdgeProperty(const std::string& property_name, const T& default_value = 0);
template<typename T>
void newEdgePropertyArray(const std::string& property_name, size_type length, const std::vector<T>& default_value = {});
#endif
};
template<typename T>
void EnvironmentDirectedGraphDescription::newVertexProperty(const std::string& property_name, const T& default_value) {
newVertexProperty<T, 1>(property_name, { default_value });
}
template<typename T, flamegpu::size_type N>
void EnvironmentDirectedGraphDescription::newVertexProperty(const std::string& property_name, const std::array<T, N>& default_value) {
if (!property_name.empty() && property_name[0] == '_') {
THROW exception::ReservedName("Graph property names cannot begin with '_', this is reserved for internal usage, "
"in EnvironmentDirectedGraphDescription::newVertexProperty().");
}
// Array length 0 makes no sense
static_assert(detail::type_decode<T>::len_t * N > 0, "A property cannot have 0 elements.");
if (graph->vertexProperties.find(property_name) == graph->vertexProperties.end()) {
const std::array<typename detail::type_decode<T>::type_t, detail::type_decode<T>::len_t* N>* casted_default =
reinterpret_cast<const std::array<typename detail::type_decode<T>::type_t, detail::type_decode<T>::len_t* N>*>(&default_value);
graph->vertexProperties.emplace(property_name, Variable(*casted_default));
return;
}
THROW exception::InvalidGraphProperty("Graph ('%s') already contains vertex property '%s', "
"in EnvironmentDirectedGraphDescription::newVertexProperty().",
graph->name.c_str(), property_name.c_str());
}
template<typename T>
void EnvironmentDirectedGraphDescription::newEdgeProperty(const std::string& property_name, const T& default_value) {
newEdgeProperty<T, 1>(property_name, { default_value });
}
template<typename T, flamegpu::size_type N>
void EnvironmentDirectedGraphDescription::newEdgeProperty(const std::string& property_name, const std::array<T, N>& default_value) {
if (!property_name.empty() && property_name[0] == '_') {
THROW exception::ReservedName("Graph property names cannot begin with '_', this is reserved for internal usage, "
"in EnvironmentDirectedGraphDescription::newEdgeProperty().");
}
// Array length 0 makes no sense
static_assert(detail::type_decode<T>::len_t * N > 0, "A property cannot have 0 elements.");
if (graph->edgeProperties.find(property_name) == graph->edgeProperties.end()) {
const std::array<typename detail::type_decode<T>::type_t, detail::type_decode<T>::len_t* N>* casted_default =
reinterpret_cast<const std::array<typename detail::type_decode<T>::type_t, detail::type_decode<T>::len_t* N>*>(&default_value);
graph->edgeProperties.emplace(property_name, Variable(*casted_default));
return;
}
THROW exception::InvalidGraphProperty("Graph ('%s') already contains edge property '%s', "
"in EnvironmentDirectedGraphDescription::newEdgeProperty().",
graph->name.c_str(), property_name.c_str());
}
#ifdef SWIG
template<typename T>
void EnvironmentDirectedGraphDescription::newVertexPropertyArray(const std::string& property_name, const size_type length, const std::vector<T>& default_value) {
if (!property_name.empty() && property_name[0] == '_') {
THROW exception::ReservedName("Graph property names cannot begin with '_', this is reserved for internal usage, "
"in EnvironmentDirectedGraphDescription::newVertexPropertyArray().");
}
if (length == 0) {
THROW exception::InvalidGraphProperty("Graph property arrays must have a length greater than 0."
"in EnvironmentDirectedGraphDescription::newVertexPropertyArray().");
}
if (default_value.size() && default_value.size() != length) {
THROW exception::InvalidGraphProperty("Graph vertex property array length specified as %d, but default value provided with %llu elements, "
"in EnvironmentDirectedGraphDescription::newVertexPropertyArray().",
length, static_cast<unsigned int>(default_value.size()));
}
if (graph->vertexProperties.find(property_name) == graph->vertexProperties.end()) {
std::vector<typename detail::type_decode<T>::type_t> temp(static_cast<size_t>(detail::type_decode<T>::len_t * length));
if (default_value.size()) {
memcpy(temp.data(), default_value.data(), sizeof(typename detail::type_decode<T>::type_t) * detail::type_decode<T>::len_t * length);
}
graph->vertexProperties.emplace(property_name, Variable(detail::type_decode<T>::len_t * length, temp));
return;
}
THROW exception::InvalidGraphProperty("Graph ('%s') already contains vertex property '%s', "
"in EnvironmentDirectedGraphDescription::newVertexPropertyArray().",
graph->name.c_str(), property_name.c_str());
}
template<typename T>
void EnvironmentDirectedGraphDescription::newEdgePropertyArray(const std::string& property_name, const size_type length, const std::vector<T>& default_value) {
if (!property_name.empty() && property_name[0] == '_') {
THROW exception::ReservedName("Graph property names cannot begin with '_', this is reserved for internal usage, "
"in EnvironmentDirectedGraphDescription::newEdgePropertyArray().");
}
if (length == 0) {
THROW exception::InvalidGraphProperty("Graph property arrays must have a length greater than 0."
"in EnvironmentDirectedGraphDescription::newEdgePropertyArray().");
}
if (default_value.size() && default_value.size() != length) {
THROW exception::InvalidGraphProperty("Graph vertex property array length specified as %d, but default value provided with %llu elements, "
"in EnvironmentDirectedGraphDescription::newEdgePropertyArray().",
length, static_cast<unsigned int>(default_value.size()));
}
if (graph->edgeProperties.find(property_name) == graph->edgeProperties.end()) {
std::vector<typename detail::type_decode<T>::type_t> temp(static_cast<size_t>(detail::type_decode<T>::len_t * length));
if (default_value.size()) {
memcpy(temp.data(), default_value.data(), sizeof(typename detail::type_decode<T>::type_t) * detail::type_decode<T>::len_t * length);
}
graph->edgeProperties.emplace(property_name, Variable(detail::type_decode<T>::len_t * length, temp));
return;
}
THROW exception::InvalidGraphProperty("Graph ('%s') already contains edge property '%s', "
"in EnvironmentDirectedGraphDescription::newEdgePropertyArray().",
graph->name.c_str(), property_name.c_str());
}
#endif
} // namespace flamegpu
#endif // INCLUDE_FLAMEGPU_MODEL_ENVIRONMENTDIRECTEDGRAPHDESCRIPTION_CUH_