1 /*!
2  * \file   mfront/src/MaterialPropertyInterfaceFactory.cxx
3  *
4  * \brief
5  * \author Thomas Helfer
6  * \date   17 Jan 2007
7  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
8  * reserved.
9  * This project is publicly released under either the GNU GPL Licence
10  * or the CECILL-A licence. A copy of thoses licences are delivered
11  * with the sources of TFEL. CEA or EDF may also distribute this
12  * project under specific licensing conditions.
13  */
14 
15 #include<cassert>
16 #include<iterator>
17 #include<stdexcept>
18 #include<algorithm>
19 #include"TFEL/Raise.hxx"
20 #include"MFront/MaterialPropertyInterfaceFactory.hxx"
21 
22 namespace mfront{
23 
24   MaterialPropertyInterfaceFactory&
getMaterialPropertyInterfaceFactory()25   MaterialPropertyInterfaceFactory::getMaterialPropertyInterfaceFactory()
26   {
27     static MaterialPropertyInterfaceFactory f;
28     return f;
29   } // end of MaterialPropertyInterfaceFactory::getMaterialPropertyInterfaceFactory
30 
31   MaterialPropertyInterfaceFactory::InterfaceDependencyContainer&
getDependenciesMap() const32   MaterialPropertyInterfaceFactory::getDependenciesMap() const
33   {
34     static InterfaceDependencyContainer map;
35     return map;
36   } // end of MaterialPropertyInterfaceFactory::getDependenciesMap
37 
38   MaterialPropertyInterfaceFactory::InterfaceCreatorsContainer&
getInterfaceCreatorsMap() const39   MaterialPropertyInterfaceFactory::getInterfaceCreatorsMap() const
40   {
41     static InterfaceCreatorsContainer map;
42     return map;
43   } // end of MaterialPropertyInterfaceFactory::getInterfaceCreatorsMap
44 
45   MaterialPropertyInterfaceFactory::AliasContainer&
getAliasesMap() const46   MaterialPropertyInterfaceFactory::getAliasesMap() const
47   {
48     static AliasContainer map;
49     return map;
50   } // end of MaterialPropertyInterfaceFactory::getAliasesMap
51 
52   MaterialPropertyInterfaceFactory::MaterialPropertyInterfaceFactory() = default;
53 
54   std::vector<std::string>
getRegistredInterfaces() const55   MaterialPropertyInterfaceFactory::getRegistredInterfaces() const
56   {
57     using namespace std;
58     vector<string> res;
59     for(const auto& a : this->getAliasesMap()){
60       res.push_back(a.first);
61     }
62     return res;
63   }
64 
65   void
registerInterfaceCreator(const std::string & i,const MaterialPropertyInterfaceFactory::InterfaceCreator f)66   MaterialPropertyInterfaceFactory::registerInterfaceCreator(const std::string& i,
67 							     const MaterialPropertyInterfaceFactory::InterfaceCreator f)
68   {
69     auto& imap = this->getInterfaceCreatorsMap();
70     tfel::raise_if(imap.find(i)!=imap.end(),
71 		   "MaterialPropertyInterfaceFactory::registerInterfaceCreator: "
72 		   "interface creator '"+i+"' already declared");
73     imap.insert(make_pair(i,f));
74   }
75 
76   void
registerInterfaceAlias(const std::string & i,const std::string & a)77   MaterialPropertyInterfaceFactory::registerInterfaceAlias(const std::string& i,
78 							   const std::string& a)
79   {
80     auto& amap = this->getAliasesMap();
81     tfel::raise_if(amap.find(a)!=amap.end(),
82 		   "MaterialPropertyInterfaceFactory::registerInterfaceCreator: "
83 		   "interface alias '"+a+"' already declared");
84     amap.insert(make_pair(a,i));
85   }
86 
87   void
registerInterfaceDependency(const std::string & name,const std::string & dep)88   MaterialPropertyInterfaceFactory::registerInterfaceDependency(const std::string& name,
89 								const std::string& dep)
90   {
91     this->getDependenciesMap()[name].push_back(dep);
92   } // end of MaterialPropertyInterfaceFactory::registerInterfaceDependency
93 
94   std::vector<std::string>
getInterfaceDependencies(const std::string & name) const95   MaterialPropertyInterfaceFactory::getInterfaceDependencies(const std::string& name) const
96   {
97     std::vector<std::string> res;
98     std::vector<std::string> tmp;
99     auto p = this->getAliasesMap().find(name);
100     if(p==this->getAliasesMap().end()){
101       auto msg = std::string("MaterialPropertyInterfaceFactory::getInterfaceDependencies: ");
102       msg += "no interface named '"+name+"'.\n";
103       msg += "Available interface are : \n";
104       for(p=this->getAliasesMap().begin();p!=this->getAliasesMap().end();++p){
105 	msg += p->first + " ";
106       }
107       tfel::raise(msg);
108     }
109     const auto& deps = this->getDependenciesMap()[p->second];
110     copy(deps.begin(),deps.end(),back_inserter(tmp));
111     for(const auto& d : deps){
112       const auto& deps2 = this->getInterfaceDependencies(d);
113       std::copy(deps2.begin(),deps2.end(),std::back_inserter(tmp));
114     }
115     std::unique_copy(tmp.begin(),tmp.end(),std::back_inserter(res));
116     return res;
117   } // end of MaterialPropertyInterfaceFactory::getInterfaceDependencies
118 
119   bool
exists(const std::string & n) const120   MaterialPropertyInterfaceFactory::exists(const std::string& n) const
121   {
122     return this->getAliasesMap().count(n)!=0;
123   } // end of MaterialPropertyInterfaceFactory::exists
124 
125   std::shared_ptr<AbstractMaterialPropertyInterface>
getInterface(const std::string & interfaceName) const126   MaterialPropertyInterfaceFactory::getInterface(const std::string& interfaceName) const
127   {
128     auto p2 = this->getAliasesMap().find(interfaceName);
129     if(p2==this->getAliasesMap().end()){
130       auto msg = std::string("MaterialPropertyInterfaceFactory::createNewInterface: ");
131       msg += "no interface named '"+interfaceName+"'.\n";
132       msg += "Available interface are : \n";
133       for(p2  = this->getAliasesMap().begin();
134 	  p2 != this->getAliasesMap().end();++p2){
135 	msg += p2->first + " ";
136       }
137       tfel::raise(msg);
138     }
139     auto p = this->getInterfaceCreatorsMap().find(p2->second);
140     assert(p!=this->getInterfaceCreatorsMap().end());
141     auto c = p->second;
142     return c();
143   }
144 
145   MaterialPropertyInterfaceFactory::~MaterialPropertyInterfaceFactory() = default;
146 
147 } // end of namespace mfront
148