From 0615f413c9274a998b0a85c2ddc3ec89ded84d8a Mon Sep 17 00:00:00 2001 From: Thomas Fischer <thomas.fischer@ufz.de> Date: Tue, 18 Nov 2014 13:19:06 +0100 Subject: [PATCH] [ML] Move property implementation to separate file. --- MeshLib/Mesh.cpp | 6 +- MeshLib/Mesh.h | 71 +---------------- MeshLib/Properties.h | 130 +++++++++++++++++++++++++++++++ Tests/MeshLib/MeshProperties.cpp | 4 +- 4 files changed, 140 insertions(+), 71 deletions(-) create mode 100644 MeshLib/Properties.h diff --git a/MeshLib/Mesh.cpp b/MeshLib/Mesh.cpp index 9fd14af9d8c..3a881b17446 100644 --- a/MeshLib/Mesh.cpp +++ b/MeshLib/Mesh.cpp @@ -34,7 +34,8 @@ Mesh::Mesh(const std::string &name, _edge_length(std::numeric_limits<double>::max(), 0), _node_distance(std::numeric_limits<double>::max(), 0), _name(name), _nodes(nodes), _elements(elements), - _n_base_nodes(n_base_nodes==0 ? nodes.size() : n_base_nodes) + _n_base_nodes(n_base_nodes==0 ? nodes.size() : n_base_nodes), + _properties(*this) { assert(n_base_nodes <= nodes.size()); this->resetNodeIDs(); @@ -54,7 +55,8 @@ Mesh::Mesh(const Mesh &mesh) _edge_length(mesh._edge_length.first, mesh._edge_length.second), _node_distance(mesh._node_distance.first, mesh._node_distance.second), _name(mesh.getName()), _nodes(mesh.getNNodes()), _elements(mesh.getNElements()), - _n_base_nodes(mesh.getNBaseNodes()) + _n_base_nodes(mesh.getNBaseNodes()), + _properties(*this) { const std::vector<Node*> nodes (mesh.getNodes()); const size_t nNodes (nodes.size()); diff --git a/MeshLib/Mesh.h b/MeshLib/Mesh.h index 1766c680c16..b0da85d7213 100644 --- a/MeshLib/Mesh.h +++ b/MeshLib/Mesh.h @@ -28,7 +28,7 @@ #include "BaseLib/Counter.h" #include "MeshEnums.h" -#include "Location.h" +#include "Properties.h" namespace MeshLib { @@ -127,49 +127,8 @@ public: /// Return true if the mesh has any nonlinear nodes bool isNonlinear() const { return (getNNodes() != getNBaseNodes()); } - /// Method to get a vector of property values. - template <typename T> - boost::optional<std::vector<T> const&> - getProperty(std::string const& name) const - { - PropertyKeyType property_key(name, MeshItemType::Cell); - std::map<PropertyKeyType, boost::any>::const_iterator it( - _properties.find(property_key) - ); - if (it != _properties.end()) { - try { - boost::any_cast<std::vector<T> const&>(it->second); - return boost::any_cast<std::vector<T> const&>(it->second); - } catch (boost::bad_any_cast const&) { - ERR("A property with the desired data type is not available."); - return boost::optional<std::vector<T> const&>(); - } - } else { - return boost::optional<std::vector<T> const&>(); - } - } - - /// Method to store a vector of property values assigned to a property name. - /// Since the implementation makes no assumption about the number of data - /// items stored within the vector, it is possible either to use a small - /// number of properties where each particular property can be assigned to - /// several mesh items. In contrast to this it is possible to have a - /// separate value for each mesh item. - /// The user has to ensure the correct usage of the vector later on. - template <typename T> - void addProperty(std::string const& name, std::vector<T> const& property) - { - PropertyKeyType property_key(name, MeshItemType::Cell); - std::map<PropertyKeyType, boost::any>::const_iterator it( - _properties.find(property_key) - ); - if (it != _properties.end()) { - WARN("A property of the name \"%s\" already assigned to the mesh.", - name.c_str()); - return; - } - _properties[property_key] = boost::any(property); - } + MeshLib::Properties & getProperties() { return _properties; } + MeshLib::Properties const& getProperties() const { return _properties; } protected: /// Set the minimum and maximum length over the edges of the mesh. @@ -210,29 +169,7 @@ protected: std::vector<Node*> _nodes; std::vector<Element*> _elements; std::size_t _n_base_nodes; - - struct PropertyKeyType - { - PropertyKeyType(std::string const& n, MeshItemType t) - : name(n), mesh_item_type(t) - {} - - std::string name; - MeshItemType mesh_item_type; - - bool operator<(PropertyKeyType const& other) const - { - if (name.compare(other.name) == 0) { - return mesh_item_type < other.mesh_item_type; - } - return name.compare(other.name) < 0 ? true : false; - } - }; - - /// A mapping from property's name to the stored object of any type. - /// See addProperty() and getProperty() documentation. - std::map<PropertyKeyType, boost::any> _properties; - + Properties _properties; }; /* class */ } /* namespace */ diff --git a/MeshLib/Properties.h b/MeshLib/Properties.h new file mode 100644 index 00000000000..c1fa9e09a8c --- /dev/null +++ b/MeshLib/Properties.h @@ -0,0 +1,130 @@ +/** + * \file + * \brief Definition of the class Properties that implements a container of + * properties. + * + * \copyright + * Copyright (c) 2012-2014, OpenGeoSys Community (http://www.opengeosys.org) + * Distributed under a Modified BSD License. + * See accompanying file LICENSE.txt or + * http://www.opengeosys.org/project/license + * + */ + +#ifndef PROPERTIES_H_ +#define PROPERTIES_H_ + +#include <cstdlib> +#include <string> +#include <vector> +#include <map> + +#include <boost/any.hpp> +#include <boost/optional.hpp> + +#include "logog/include/logog.hpp" + +#include "Location.h" + +namespace MeshLib +{ +// forward declaration +class Mesh; + +/// Properties associated to mesh items (nodes or elements). +class Properties +{ +public: + explicit Properties(MeshLib::Mesh const& mesh) + : _mesh(mesh) + {} + + /// Method to get a vector of property values. + template <typename T> + boost::optional<std::vector<T> const&> + getProperty(std::string const& name) const + { + PropertyKeyType property_key(name, MeshItemType::Cell); + std::map<PropertyKeyType, boost::any>::const_iterator it( + _properties.find(property_key) + ); + if (it != _properties.end()) { + try { + boost::any_cast<std::vector<T> const&>(it->second); + return boost::any_cast<std::vector<T> const&>(it->second); + } catch (boost::bad_any_cast const&) { + ERR("A property with the desired data type is not available."); + return boost::optional<std::vector<T> const&>(); + } + } else { + return boost::optional<std::vector<T> const&>(); + } + } + + /// Method to store a vector of property values assigned to a property name. + /// Since the implementation makes no assumption about the number of data + /// items stored within the vector, it is possible either to use a small + /// number of properties where each particular property can be assigned to + /// several mesh items. In contrast to this it is possible to have a + /// separate value for each mesh item. + /// The user has to ensure the correct usage of the vector later on. + template <typename T> + void addProperty(std::string const& name, std::vector<T> const& property) + { + PropertyKeyType property_key(name, MeshItemType::Cell); + std::map<PropertyKeyType, boost::any>::const_iterator it( + _properties.find(property_key) + ); + if (it != _properties.end()) { + WARN("A property of the name \"%s\" already assigned to the mesh.", + name.c_str()); + return; + } + _properties[property_key] = boost::any(property); + } + + void removeProperty(std::string const& name, + MeshItemType mesh_item_type = MeshItemType::Cell) + { + PropertyKeyType property_key(name, mesh_item_type); + std::map<PropertyKeyType, boost::any>::const_iterator it( + _properties.find(property_key) + ); + if (it == _properties.end()) { + WARN("A property of the name \"%s\" does not exist.", + name.c_str()); + return; + } + _properties.erase(it); + } + +private: + struct PropertyKeyType + { + PropertyKeyType(std::string const& n, MeshItemType t) + : name(n), mesh_item_type(t) + {} + + std::string name; + MeshItemType mesh_item_type; + + bool operator<(PropertyKeyType const& other) const + { + if (name.compare(other.name) == 0) { + return mesh_item_type < other.mesh_item_type; + } + return name.compare(other.name) < 0 ? true : false; + } + }; + + /// Mesh object the properties are assigned to. + MeshLib::Mesh const& _mesh; + /// A mapping from property's name to the stored object of any type. + /// See addProperty() and getProperty() documentation. + std::map<PropertyKeyType, boost::any> _properties; +}; // end class + +} // end namespace MeshLib + +#endif + diff --git a/Tests/MeshLib/MeshProperties.cpp b/Tests/MeshLib/MeshProperties.cpp index 834597d3654..4d92c9e86e4 100644 --- a/Tests/MeshLib/MeshProperties.cpp +++ b/Tests/MeshLib/MeshProperties.cpp @@ -41,10 +41,10 @@ TEST_F(MeshLibMeshProperties, AddDoubleProperties) std::string const& prop_name("FirstTestProperty"); // add a vector with property values to the mesh - mesh->addProperty(prop_name, double_properties); + mesh->getProperties().addProperty(prop_name, double_properties); boost::optional<std::vector<double> const&> - double_properties_cpy(mesh->getProperty<double>(prop_name)); + double_properties_cpy(mesh->getProperties().getProperty<double>(prop_name)); for (std::size_t k(0); k<size; k++) { ASSERT_EQ(double_properties[k], (*double_properties_cpy)[k]); -- GitLab