Caffa  1.1.0
C++ Application Framework for Embedded Systems with introspection
cafFactory.h
1 //##################################################################################################
2 //
3 // Custom Visualization Core library
4 // Copyright (C) 2011-2013 Ceetron AS
5 //
6 // This library may be used under the terms of either the GNU General Public License or
7 // the GNU Lesser General Public License as follows:
8 //
9 // GNU General Public License Usage
10 // This library is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but WITHOUT ANY
16 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 // FITNESS FOR A PARTICULAR PURPOSE.
18 //
19 // See the GNU General Public License at <<http://www.gnu.org/licenses/gpl.html>>
20 // for more details.
21 //
22 // GNU Lesser General Public License Usage
23 // This library is free software; you can redistribute it and/or modify
24 // it under the terms of the GNU Lesser General Public License as published by
25 // the Free Software Foundation; either version 2.1 of the License, or
26 // (at your option) any later version.
27 //
28 // This library is distributed in the hope that it will be useful, but WITHOUT ANY
29 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
30 // FITNESS FOR A PARTICULAR PURPOSE.
31 //
32 // See the GNU Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
33 // for more details.
34 //
35 //##################################################################################################
36 
37 #pragma once
38 
39 #include "cafAssert.h"
40 
41 #include <cstddef>
42 #include <map>
43 #include <vector>
44 
45 // Taken from gtest.h
46 //
47 // Due to C++ preprocessor weirdness, we need double indirection to
48 // concatenate two tokens when one of them is __LINE__. Writing
49 //
50 // foo ## __LINE__
51 //
52 // will result in the token foo__LINE__, instead of foo followed by
53 // the current line number. For more details, see
54 // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6
55 #define CAFFA_FACTORY_CONCATENATE_STRINGS( foo, bar ) CAFFA_FACTORY_CONCATENATE_STRINGS_IMPL_( foo, bar )
56 #define CAFFA_FACTORY_CONCATENATE_STRINGS_IMPL_( foo, bar ) foo##bar
57 
58 #define CAFFA_UNIQUE_COMPILE_UNIT_VAR_NAME( foo ) CAFFA_FACTORY_CONCATENATE_STRINGS( foo, __LINE__ )
59 
62 
63 #define CAFFA_FACTORY_REGISTER( BaseType, TypeToCreate, KeyType, key ) \
64  static bool CAFFA_UNIQUE_COMPILE_UNIT_VAR_NAME( my##TypeToCreate ) = \
65  caffa::Factory<BaseType, KeyType>::instance()->registerCreator<TypeToCreate>( key )
66 #define CAFFA_FACTORY_REGISTER2( BaseType, TypeToCreate, KeyType, key ) \
67  static bool CAFFA_UNIQUE_COMPILE_UNIT_VAR_NAME( my2##TypeToCreate ) = \
68  caffa::Factory<BaseType, KeyType>::instance()->registerCreator<TypeToCreate>( key )
69 
70 namespace caffa
71 {
72 //==================================================================================================
92 //==================================================================================================
93 
94 template <typename BaseType, typename KeyType>
95 class Factory
96 {
97  class ObjectCreatorBase;
98 
99 public:
100  typedef typename std::map<KeyType, ObjectCreatorBase*>::iterator iterator_type;
101 
102  static Factory<BaseType, KeyType>* instance()
103  {
105  return fact;
106  }
107 
108  template <typename TypeToCreate>
109  bool registerCreator( const KeyType& key )
110  {
111  iterator_type entryIt;
112 
113  entryIt = m_factoryMap.find( key );
114  if ( entryIt == m_factoryMap.end() )
115  {
116  m_factoryMap[key] = new ObjectCreator<TypeToCreate>();
117  return true;
118  }
119  return false;
120  }
121 
122  BaseType* create( const KeyType& key )
123  {
124  iterator_type entryIt;
125 
126  entryIt = m_factoryMap.find( key );
127  if ( entryIt != m_factoryMap.end() )
128  {
129  return entryIt->second->create();
130  }
131  else
132  {
133  return nullptr;
134  }
135  }
136 
137  std::vector<KeyType> allKeys()
138  {
139  std::vector<KeyType> keys;
140 
141  iterator_type entryIt;
142  for ( entryIt = m_factoryMap.begin(); entryIt != m_factoryMap.end(); ++entryIt )
143  {
144  keys.push_back( entryIt->first );
145  }
146 
147  return keys;
148  }
149 
150 private:
151  Factory() {}
152  ~Factory()
153  {
154  iterator_type entryIt;
155 
156  for ( entryIt = m_factoryMap.begin(); entryIt != m_factoryMap.end(); ++entryIt )
157  {
158  delete ( entryIt->second );
159  }
160  }
161 
162  // Internal helper classes
163 
164  class ObjectCreatorBase
165  {
166  public:
167  ObjectCreatorBase() {}
168  virtual ~ObjectCreatorBase() {}
169  virtual BaseType* create() = 0;
170  };
171 
172  template <typename TypeToCreate>
173  class ObjectCreator : public ObjectCreatorBase
174  {
175  public:
176  BaseType* create() override { return new TypeToCreate(); }
177  };
178 
179  // Map to store factory
180  std::map<KeyType, ObjectCreatorBase*> m_factoryMap;
181 };
182 
183 } // End of namespace caffa
Definition: cafFactory.h:96
Main Caffa namespace.
Definition: __init__.py:1