37 #ifndef BOOST_PP_IS_ITERATING
39 #ifndef NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_FACTORY_HPP
40 #define NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_FACTORY_HPP
42 #include <boost/preprocessor/repetition.hpp>
43 #include <boost/preprocessor/arithmetic/sub.hpp>
44 #include <boost/preprocessor/punctuation/comma_if.hpp>
45 #include <boost/preprocessor/iteration/iterate.hpp>
46 #include <boost/thread/shared_mutex.hpp>
47 #include <boost/thread/locks.hpp>
49 #include <boost/shared_ptr.hpp>
58 #define MAX_PARAM 5 // default maximum number of parameters to support
63 namespace LibUtilities
69 #define FACTORY_print(z, n, data) BOOST_PP_CAT(data, n) = none
70 typedef boost::unique_lock<boost::shared_mutex>
WriteLock;
71 typedef boost::shared_lock<boost::shared_mutex>
ReadLock;
113 template <
typename tKey,
163 BOOST_PP_ENUM_BINARY_PARAMS(
MAX_PARAM, tParam, x))
184 catch (
const std::string& s)
186 std::stringstream errstr;
187 errstr <<
"Unable to create module: " << idKey <<
"\n";
195 std::stringstream errstr;
196 errstr <<
"No such module: " << idKey << std::endl;
216 tDescription pDesc =
"")
221 getMapFactory()->insert(std::pair<tKey,ModuleEntry>(idKey, e));
251 pOut << std::endl <<
"Available classes: " << std::endl;
252 TMapFactoryIterator it;
255 pOut << std::endl <<
"Available classes: " << std::endl;
256 TMapFactoryIterator it;
259 pOut <<
" " << it->first;
260 if (it->second.m_desc !=
"")
262 pOut <<
":" << std::endl <<
" "
263 << it->second.m_desc << std::endl;
281 TMapFactoryIterator it;
284 if (it->second.m_desc == pDesc)
289 std::string errstr =
"Module '"
290 + boost::lexical_cast<std::string>(pDesc)
306 std::stringstream errstr;
307 errstr <<
"No such module: " << idKey << std::endl;
309 return it->second.m_desc;
334 #define BOOST_PP_ITERATION_LIMITS (0, MAX_PARAM-1)
335 #define BOOST_PP_FILENAME_1 "LibUtilities/BasicUtils/NekFactory.hpp"
336 #include BOOST_PP_ITERATE()
341 #endif // end NEKTAR_LIB_UTILITIES_BASIC_UTILS_NEK_FACTORY_HPP
347 #define n BOOST_PP_ITERATION()
349 #define FACTORY_print(z, n, data) data
350 #include <boost/thread/shared_mutex.hpp>
351 #include <boost/thread/locks.hpp>
353 typedef boost::unique_lock<boost::shared_mutex>
WriteLock;
354 typedef boost::shared_lock<boost::shared_mutex>
ReadLock;
356 template <
typename tKey,
357 typename tBase BOOST_PP_COMMA_IF(n)
358 BOOST_PP_ENUM_PARAMS(n, typename tParam) >
359 class NekFactory< tKey, tBase,
360 BOOST_PP_ENUM_PARAMS(n, tParam)BOOST_PP_COMMA_IF(n)
364 typedef std::string tDescription;
365 typedef std::less<tKey> tPredicator;
366 typedef boost::shared_ptr<tBase> tBaseSharedPtr;
367 typedef tBaseSharedPtr (*CreatorFunction) (BOOST_PP_ENUM_PARAMS(n, tParam));
371 ModuleEntry(CreatorFunction pFunc,
const tDescription pDesc)
376 CreatorFunction m_func;
379 typedef std::map<tKey, ModuleEntry, tPredicator> TMapFactory;
382 NekFactory() : m_mutex() {}
384 tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(n)
385 BOOST_PP_ENUM_BINARY_PARAMS(n, tParam, x))
387 ReadLock vReadLock(m_mutex);
389 TMapFactoryIterator it = getMapFactory()->find(idKey);
390 if (it != getMapFactory()->end())
392 ModuleEntry *tmp = &(it->second);
399 return tmp->m_func(BOOST_PP_ENUM_PARAMS(n, x));
401 catch (
const std::string& s)
403 std::stringstream errstr;
404 errstr <<
"Unable to create module: " << idKey <<
"\n";
410 std::stringstream errstr;
411 errstr <<
"No such module: " << idKey << std::endl;
412 PrintAvailableClasses(errstr);
414 return tBaseSharedPtr();
417 tKey RegisterCreatorFunction(tKey idKey,
418 CreatorFunction classCreator,
419 tDescription pDesc =
"") {
420 WriteLock vWriteLock(m_mutex);
422 ModuleEntry e(classCreator, pDesc);
423 getMapFactory()->insert(std::pair<tKey,ModuleEntry>(idKey, e));
427 bool ModuleExists(tKey idKey)
429 ReadLock vReadLock(m_mutex);
432 TMapFactoryIterator it = getMapFactory()->find(idKey);
434 if (it != getMapFactory()->end())
441 void PrintAvailableClasses(std::ostream& pOut = std::cout)
443 ReadLock vReadLock(m_mutex);
445 pOut << std::endl <<
"Available classes: " << std::endl;
446 TMapFactoryIterator it;
447 for (it = getMapFactory()->begin(); it != getMapFactory()->end(); ++it)
449 pOut <<
" " << it->first;
450 if (it->second.m_desc !=
"")
452 pOut <<
":" << std::endl <<
" "
453 << it->second.m_desc << std::endl;
462 tKey GetKey(tDescription pDesc)
464 ReadLock vReadLock(m_mutex);
466 TMapFactoryIterator it;
467 for (it = getMapFactory()->begin(); it != getMapFactory()->end(); ++it)
469 if (it->second.m_desc == pDesc)
474 std::string errstr =
"Module '"
475 + boost::lexical_cast<std::string>(pDesc)
480 std::string GetClassDescription(tKey idKey)
482 ReadLock vReadLock(m_mutex);
485 TMapFactoryIterator it = getMapFactory()->find(idKey);
487 std::stringstream errstr;
488 errstr <<
"No such module: " << idKey << std::endl;
489 ASSERTL0 (it != getMapFactory()->end(), errstr.str());
490 return it->second.m_desc;
494 TMapFactory * getMapFactory() {
499 NekFactory(
const NekFactory& rhs);
500 NekFactory& operator=(
const NekFactory& rhs);
502 TMapFactory mMapFactory;
503 boost::shared_mutex m_mutex;
boost::unique_lock< boost::shared_mutex > WriteLock
#define ASSERTL0(condition, msg)
ModuleEntry(CreatorFunction pFunc, const tDescription pDesc)
void PrintAvailableClasses(std::ostream &pOut=std::cout)
Prints the available classes to stdout.
tBaseSharedPtr CreateInstance(tKey idKey BOOST_PP_COMMA_IF(MAX_PARAM) BOOST_PP_ENUM_BINARY_PARAMS(MAX_PARAM, tParam, x))
Create an instance of the class referred to by idKey.
std::string GetClassDescription(tKey idKey)
Returns the description of a class.
CreatorFunction m_func
Function used to create instance of class.
TMapFactory * getMapFactory()
Ensure the factory's map is created.
#define FACTORY_print(z, n, data)
Define a struct to hold the information about a module.
boost::shared_ptr< tBase > tBaseSharedPtr
Shared pointer to an object of baseclass type.
TMapFactory::iterator TMapFactoryIterator
Iterator for factory map.
std::less< tKey > tPredicator
Comparison predicator of key.
bool ModuleExists(tKey idKey)
Checks if a particular module is available.
std::string tDescription
Description datatype.
boost::shared_lock< boost::shared_mutex > ReadLock
boost::shared_mutex m_mutex
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
tKey GetKey(tDescription pDesc)
Retrieves a key, given a description.
tBaseSharedPtr(* CreatorFunction)(BOOST_PP_ENUM_PARAMS(MAX_PARAM, tParam))
CreatorFunction type which takes parameter and returns base class shared pointer. ...
NekFactory & operator=(const NekFactory &rhs)
std::map< tKey, ModuleEntry, tPredicator > TMapFactory
Factory map between key and module data.
tDescription m_desc
Description of class for use in listing available classes.
Provides a generic Factory class.
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.