diff --git a/dune/grid/common/CMakeLists.txt b/dune/grid/common/CMakeLists.txt index df2de386e245604404f9473288bdf7847141bb76..35edcb8f0e8b5b5a24f20303cbcf29e89c0bfe7a 100644 --- a/dune/grid/common/CMakeLists.txt +++ b/dune/grid/common/CMakeLists.txt @@ -27,7 +27,8 @@ set(HEADERS partitionset.hh rangegenerators.hh sizecache.hh - scsgmapper.hh) + scsgmapper.hh + userdata.hh) add_subdirectory(test) diff --git a/dune/grid/common/grid.hh b/dune/grid/common/grid.hh index 5f4e66b8109b3880c6339b2712125a955c362588..9fcb0c80c028098f100aeec3cc4775d88c0359fa 100644 --- a/dune/grid/common/grid.hh +++ b/dune/grid/common/grid.hh @@ -10,8 +10,10 @@ */ // system includes #include <iostream> +#include <typeinfo> #include <string> #include <vector> +#include <map> // dune-common includes #include <dune/common/fvector.hh> @@ -29,6 +31,7 @@ #include <dune/grid/common/gridview.hh> #include <dune/grid/common/defaultgridview.hh> #include <dune/grid/common/entityseed.hh> +#include <dune/grid/common/userdata.hh> // include this file after all other, because other files might undef the // macros that are defined in that file @@ -971,8 +974,42 @@ namespace Dune { return false; } + /*! \brief return shared_ptr to user data object of given type + * + * \return shared_ptr< UserData > which either contains a pointer to a + * previously registered object or is empty. + */ + template <class UserData> + std::shared_ptr< UserData > getUserData() const + { + const std::string name( typeid( UserData ).name() ); + auto it = userData_.find( name ); + if( it != userData_.end() ) + return it->second->template get< UserData >(); + else + return std::shared_ptr< UserData >(); + } + + /*! \brief register shared_ptr to user data object provided as shared + * + * \note: Only one object of each type can be registered. + */ + template <class UserData> + void registerUserData( std::shared_ptr< UserData > userData ) const + { + const std::string name( typeid( UserData ).name() ); + auto it = userData_.find( name ); + if( it != userData_.end() ) + DUNE_THROW(InvalidStateException,"addUserData: can only add a type once!"); + + typedef GridUserDataObject< UserData > ObjectType; + std::shared_ptr< GridUserDataIF > ptr( new ObjectType( userData ) ); + userData_.insert( std::make_pair( name, ptr ) ); + } + protected: using Grid< dim, dimworld, ct, GridFamily >::asImp; + mutable std::map< const std::string, std::shared_ptr< GridUserDataIF > > userData_; }; /** @} */ diff --git a/dune/grid/common/userdata.hh b/dune/grid/common/userdata.hh new file mode 100644 index 0000000000000000000000000000000000000000..059a32ceea9b63d3f5b56ed8ceba5bff7f4781d2 --- /dev/null +++ b/dune/grid/common/userdata.hh @@ -0,0 +1,62 @@ +// SPDX-FileCopyrightText: Copyright © DUNE Project contributors, see file LICENSE.md in module root +// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception +// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// vi: set et ts=4 sw=2 sts=2: +#ifndef DUNE_GRID_COMMON_USERDATA_HH +#define DUNE_GRID_COMMON_USERDATA_HH + +#include <typeinfo> +#include <memory> + +namespace Dune +{ + template <class Implementation> + class GridUserDataObject; + + /** \brief interface class for user data storage + */ + class GridUserDataIF + { + protected: + GridUserDataIF () {} + public: + virtual ~GridUserDataIF() {} + virtual std::string name() const { return std::string("interface"); } + + template <class Implementation> + bool compare() const + { + return typeid(Implementation).name() == this->name(); + } + + template <class Implementation> + std::shared_ptr< Implementation >& get() + { + typedef GridUserDataObject< Implementation > GridUserDataObjectType; + //assert( dynamic_cast< GridUserDataObjectType& > (*this) ); + return dynamic_cast< GridUserDataObjectType& > (*this).object(); + } + }; + + template <class Implementation> + class GridUserDataObject : public GridUserDataIF + { + typedef std::shared_ptr< Implementation > ObjectPointerType; + ObjectPointerType obj_; + public: + GridUserDataObject( const ObjectPointerType& obj ) + : obj_( obj ) + {} + + GridUserDataObject( ObjectPointerType&& obj ) + : obj_( std::forward(obj) ) + {} + + std::string name() const override { return typeid(Implementation).name(); } + + std::shared_ptr< Implementation >& object() { return obj_; } + }; + +} // end namespace Dune + +#endif