LCOV - code coverage report
Current view: top level - ugbase/registry - class_name_provider.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 20.4 % 54 11
Test Date: 2025-09-21 23:31:46 Functions: 30.0 % 10 3

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2010-2012:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Andreas Vogel
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include "class_name_provider.h"
      34              : 
      35              : namespace ug
      36              : {
      37              : namespace bridge
      38              : {
      39              : 
      40         2734 : ClassNameNode::ClassNameNode()
      41              : {
      42              :         m_name.clear();
      43         2734 : }
      44              : 
      45         3731 : void ClassNameNode::set_name(const std::string& name)
      46              : {
      47              : //      set name
      48         7462 :         m_name = std::string(name);
      49              : 
      50              : //      check size
      51         3731 :         if(m_name.empty())
      52            0 :                 UG_THROW_REGISTRY_MSG("Name must be longer than 0 characters.");
      53         3731 : }
      54              : 
      55         1084 : void ClassNameNode::add_base_class(const ClassNameNode& node)
      56              : {
      57              :         std::vector<const ClassNameNode*>::iterator it
      58         1084 :                 = std::find(m_vBaseClass.begin(), m_vBaseClass.end(), &node);
      59         1084 :         if(it == m_vBaseClass.end())
      60         1084 :                 m_vBaseClass.push_back(&node);
      61         1084 : }
      62              : 
      63            0 : bool ClassNameNode::named() const
      64              : {
      65              : //      if string is empty, then has not been named
      66            0 :         if(empty()) return false;
      67              : 
      68              : //      if string starts with '[' then has only been predeclared
      69            0 :         if(m_name.c_str()[0] == '[') return false;
      70              : 
      71              : //      has been named
      72              :         return true;
      73              : }
      74              : 
      75              : 
      76            0 : bool ClassNameVecContains(const std::vector<const char*>& names, const std::string& name)
      77              : {
      78              :         //  return true if pointers are equal
      79            0 :                 for(size_t i = 0; i < names.size(); ++i)
      80            0 :                         if(name.c_str() == names[i]) return true;
      81              : 
      82              :         //  security fallback: if pointers not equal, compare also strings
      83            0 :                 for(size_t i = 0; i < names.size(); ++i)
      84            0 :                         if(name == names[i]) return true;
      85              : 
      86              :         //  both comparisons fail. Name is not this class, nor on of its parents
      87              :                 return false;
      88              : }
      89              : 
      90            0 : void ExtractClassNameVec(std::vector<const char*>& names, const ClassNameNode& node, bool clearVec)
      91              : {
      92              : //      clear vector
      93            0 :         if(clearVec)
      94              :                 names.clear();
      95              : 
      96              : //      add node name
      97            0 :         names.push_back(node.name().c_str());
      98              : 
      99              : //      add all base classes
     100            0 :         for(size_t i = 0; i < node.num_base_classes(); ++i)
     101            0 :                 ExtractClassNameVec(names, node.base_class(i), false);
     102            0 : }
     103              : 
     104            0 : bool ClassNameTreeContains(const ClassNameNode& node, const std::string& name)
     105              : {
     106              : //      if the node is the name, return true
     107            0 :         if(node.name() == name) return true;
     108              : 
     109              : //      else search in parents
     110              :         bool bContains = false;
     111              : 
     112            0 :         for(size_t i = 0; i < node.num_base_classes(); ++i)
     113            0 :                 bContains |= ClassNameTreeContains(node.base_class(i), name);
     114              : 
     115              : //      return if found in parents
     116              :         return bContains;
     117              : }
     118              : 
     119            0 : bool ClassNameTreeWay(std::vector<size_t>& vWay, const ClassNameNode& node,
     120              :                       const std::string& name)
     121              : {
     122              : //      if the node is the name, return true
     123            0 :         if(node.name() == name) return true;
     124              : 
     125              : //      look in parents
     126            0 :         for(size_t i = 0; i < node.num_base_classes(); ++i)
     127              :         {
     128            0 :                 if(ClassNameTreeWay(vWay, node.base_class(i), name))
     129              :                 {
     130            0 :                         vWay.push_back(i);
     131            0 :                         return true;
     132              :                 }
     133              :         }
     134              : //      return if found in parents
     135            0 :         return false;
     136              : }
     137              : 
     138            0 : void* ClassCastProvider::
     139              : cast_to_base_class(void* pDerivVoid, const ClassNameNode*& node, const std::string& baseName)
     140              : {
     141              : //      find way to base class
     142              :         std::vector<size_t> vWay;
     143            0 :         if(!ClassNameTreeWay(vWay, *node, baseName))
     144              :         {
     145            0 :                 UG_ERR_LOG("ERROR in ClassCastProvider::cast_to_base_class: Request"
     146              :                                 " to cast from derived class '"<< node->name()<<"' to "
     147              :                                 " base class '"<<baseName<<"', but no such base class in"
     148              :                                 " registered class hierarchy.");
     149            0 :                 throw new UGError_ClassCastFailed(node->name(), baseName);
     150              :         }
     151              : 
     152              :         void* currPtr = pDerivVoid;
     153            0 :         const ClassNameNode* pCurrNode = node;
     154              : 
     155              : //      cast all the way down
     156            0 :         while(!vWay.empty())
     157              :         {
     158              :         //      get base class to cast to
     159            0 :                 const ClassNameNode* pBaseClassNode = &pCurrNode->base_class(vWay.back());
     160              : 
     161              :         //      get name pair
     162              :                 std::pair<const ClassNameNode*, const ClassNameNode*> namePair(pBaseClassNode, pCurrNode);
     163              : 
     164              :         //      find in map
     165              :                 std::map<std::pair<const ClassNameNode*, const ClassNameNode*>, CastFunc>::iterator it;
     166              :                 it = m_mmCast.find(namePair);
     167              : 
     168            0 :                 if(it == m_mmCast.end())
     169              :                 {
     170            0 :                         UG_ERR_LOG("ERROR in ClassCastProvider::cast_to_base_class:"
     171              :                                         " Request intermediate cast from derived class '" <<
     172              :                                         pCurrNode->name() <<"' to direct base class '"
     173              :                                         <<pBaseClassNode->name()<<"', but no such cast "
     174              :                                         " function registered.");
     175            0 :                         throw new UGError_ClassCastFailed(node->name(), baseName);
     176              :                 }
     177              : 
     178              :         //      get cast function
     179            0 :                 CastFunc pCastFunc = it->second;
     180              : 
     181              :         //      cast
     182            0 :                 currPtr = (*pCastFunc)(currPtr);
     183              : 
     184              :         //      set node to base class
     185              :                 pCurrNode = pBaseClassNode;
     186              : 
     187              :         //      pop way
     188              :                 vWay.pop_back();
     189              :         }
     190              : 
     191              : //      write current node on exit
     192            0 :         node = pCurrNode;
     193              : 
     194              : //      return current pointer
     195            0 :         return currPtr;
     196            0 : }
     197              : 
     198              : 
     199            0 : const void* ClassCastProvider::
     200              : cast_to_base_class(const void* pDerivVoid, const ClassNameNode*& node, const std::string& baseName)
     201              : {
     202            0 :         return const_cast<const void*>(cast_to_base_class(const_cast<void*>(pDerivVoid), node, baseName));
     203              : }
     204              : 
     205              : 
     206              : 
     207              : 
     208              : std::map<std::pair<const ClassNameNode*, const ClassNameNode*>, void* (*)(void*)>
     209              :         ClassCastProvider::m_mmCast = std::map<std::pair<const ClassNameNode*, const ClassNameNode*>,  void* (*)(void*)> ();
     210              : 
     211              : }//     end of namespace
     212              : }//     end of namespace
        

Generated by: LCOV version 2.0-1