Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
NekManager.hpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: NekManager.hpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description:
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
36 #ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP
37 #define NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP
38 
39 #include <map>
40 
41 #include <boost/function.hpp>
42 #include <boost/call_traits.hpp>
43 #include <boost/concept_check.hpp>
44 
45 #include <boost/shared_ptr.hpp>
47 
48 using namespace std;
49 
50 namespace Nektar
51 {
52  namespace LibUtilities
53  {
54  template <typename KeyType>
56  {
57  bool operator()(const KeyType &lhs, const KeyType &rhs) const
58  {
59  return lhs < rhs;
60  }
61  };
62 
63  template <typename KeyType, typename ValueT, typename opLessCreator = defOpLessCreator<KeyType> >
64  class NekManager
65  {
66  public:
67  BOOST_CLASS_REQUIRE(KeyType, boost, LessThanComparableConcept);
68 
69  typedef boost::shared_ptr<ValueT> ValueType;
70  typedef boost::function<ValueType (const KeyType& key)> CreateFuncType;
71  typedef std::map<KeyType, ValueType> ValueContainer;
72  typedef boost::shared_ptr<ValueContainer> ValueContainerShPtr;
73  typedef std::map<KeyType, CreateFuncType, opLessCreator> CreateFuncContainer;
74  typedef std::map<std::string, boost::shared_ptr<ValueContainer> > ValueContainerPool;
75  typedef boost::shared_ptr<bool> BoolSharedPtr;
76  typedef std::map<std::string, BoolSharedPtr> FlagContainerPool;
77 
78  NekManager(std::string whichPool="") :
79  m_values(),
80  m_globalCreateFunc(),
81  m_keySpecificCreateFuncs()
82  {
83  if (!whichPool.empty())
84  {
85  typename ValueContainerPool::iterator iter = m_ValueContainerPool.find(whichPool);
86  if (iter != m_ValueContainerPool.end())
87  {
88  m_values = iter->second;
89  m_managementEnabled = m_managementEnabledContainerPool[whichPool];
90  }
91  else
92  {
93  m_values = ValueContainerShPtr(new ValueContainer);
94  m_ValueContainerPool[whichPool] = m_values;
95  if (m_managementEnabledContainerPool.find(whichPool) == m_managementEnabledContainerPool.end())
96  {
97  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
98  }
99  m_managementEnabled = m_managementEnabledContainerPool[whichPool];
100  }
101  }
102  else
103  {
104  m_values = ValueContainerShPtr(new ValueContainer);
105  m_managementEnabled = BoolSharedPtr(new bool(true));
106  }
107  };
108 
109 
110  explicit NekManager(CreateFuncType f, std::string whichPool="") :
111  m_values(),
112  m_globalCreateFunc(f),
113  m_keySpecificCreateFuncs()
114  {
115  if (!whichPool.empty())
116  {
117  typename ValueContainerPool::iterator iter = m_ValueContainerPool.find(whichPool);
118  if (iter != m_ValueContainerPool.end())
119  {
120  m_values = iter->second;
121  m_managementEnabled = m_managementEnabledContainerPool[whichPool];
122  }
123  else
124  {
125  m_values = ValueContainerShPtr(new ValueContainer);
126  m_ValueContainerPool[whichPool] = m_values;
127  if (m_managementEnabledContainerPool.find(whichPool) == m_managementEnabledContainerPool.end())
128  {
129  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
130  }
131  m_managementEnabled = m_managementEnabledContainerPool[whichPool];
132  }
133 
134  }
135  else
136  {
137  m_values = ValueContainerShPtr(new ValueContainer);
138  m_managementEnabled = BoolSharedPtr(new bool(true));
139  }
140  }
141 
143  {
144  }
145 
146  /// Register the given function and associate it with the key.
147  /// The return value is just to facilitate calling statically.
148  bool RegisterCreator(typename boost::call_traits<KeyType>::const_reference key,
149  const CreateFuncType& createFunc)
150  {
151  m_keySpecificCreateFuncs[key] = createFunc;
152 
153  return true;
154  }
155 
156  /// Register the Global Create Function.
157  /// The return value is just to facilitate calling statically.
158  bool RegisterGlobalCreator(const CreateFuncType& createFunc)
159  {
160  m_globalCreateFunc = createFunc;
161 
162  return true;
163  }
164 
165  bool AlreadyCreated(typename boost::call_traits<KeyType>::const_reference key)
166  {
167  bool value = false;
168  typename ValueContainer::iterator found = m_values->find(key);
169  if( found != m_values->end() )
170  {
171  value = true;
172  }
173 
174  return value;
175  }
176 
177  ValueType operator[](typename boost::call_traits<KeyType>::const_reference key)
178  {
179  typename ValueContainer::iterator found = m_values->find(key);
180 
181  if( found != m_values->end() )
182  {
183  return (*found).second;
184  }
185  else
186  {
187  // No object, create a new one.
188  CreateFuncType f = m_globalCreateFunc;
189  typename CreateFuncContainer::iterator keyFound = m_keySpecificCreateFuncs.find(key);
190  if( keyFound != m_keySpecificCreateFuncs.end() )
191  {
192  f = (*keyFound).second;
193  }
194 
195  if( f )
196  {
197  ValueType v = f(key);
198  if (*m_managementEnabled)
199  {
200  (*m_values)[key] = v;
201  }
202  return v;
203  }
204  else
205  {
206  std::string keyAsString = boost::lexical_cast<std::string>(key);
207  std::string message = std::string("No create func found for key ") + keyAsString;
208  NEKERROR(ErrorUtil::efatal, message.c_str());
209  static ValueType result;
210  return result;
211  }
212  }
213  }
214 
215  void DeleteObject(typename boost::call_traits<KeyType>::const_reference key)
216  {
217  typename ValueContainer::iterator found = m_values->find(key);
218 
219  if( found != m_values->end() )
220  {
221  m_values->erase(found);
222  }
223  }
224 
225  static void ClearManager(std::string whichPool = "")
226  {
227  typename ValueContainerPool::iterator x;
228  if (!whichPool.empty())
229  {
230  x = m_ValueContainerPool.find(whichPool);
231  ASSERTL1(x != m_ValueContainerPool.end(),
232  "Could not find pool " + whichPool);
233  x->second->clear();
234  }
235  else
236  {
237  for (x = m_ValueContainerPool.begin(); x != m_ValueContainerPool.end(); ++x)
238  {
239  x->second->clear();
240  }
241  }
242  }
243 
244  static void EnableManagement(std::string whichPool = "")
245  {
246  typename FlagContainerPool::iterator x;
247  if (!whichPool.empty())
248  {
249  x = m_managementEnabledContainerPool.find(whichPool);
250  if (x != m_managementEnabledContainerPool.end())
251  {
252  (*x->second) = true;
253  }
254  else
255  {
256  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(true));
257  }
258  }
259  }
260 
261  static void DisableManagement(std::string whichPool = "")
262  {
263  typename FlagContainerPool::iterator x;
264  if (!whichPool.empty())
265  {
266  x = m_managementEnabledContainerPool.find(whichPool);
267  if (x != m_managementEnabledContainerPool.end())
268  {
269  (*x->second) = false;
270  }
271  else
272  {
273  m_managementEnabledContainerPool[whichPool] = BoolSharedPtr(new bool(false));
274  }
275  }
276  }
277 
278  private:
281 
288  };
289  template <typename KeyType, typename ValueT, typename opLessCreator> typename NekManager<KeyType, ValueT, opLessCreator>::ValueContainerPool NekManager<KeyType, ValueT, opLessCreator>::m_ValueContainerPool;
291  }
292 }
293 
294 
295 #endif //NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_MANAGER_HPP