libpointmatcher  1.3.1
Registrar.h
1 // kate: replace-tabs off; indent-width 4; indent-mode normal
2 // vim: ts=4:sw=4:noexpandtab
3 /*
4 
5 Copyright (c) 2010--2012,
6 François Pomerleau and Stephane Magnenat, ASL, ETHZ, Switzerland
7 You can contact the authors at <f dot pomerleau at gmail dot com> and
8 <stephane at magnenat dot net>
9 
10 All rights reserved.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright
15  notice, this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright
17  notice, this list of conditions and the following disclaimer in the
18  documentation and/or other materials provided with the distribution.
19  * Neither the name of the <organization> nor the
20  names of its contributors may be used to endorse or promote products
21  derived from this software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26 DISCLAIMED. IN NO EVENT SHALL ETH-ASL BE LIABLE FOR ANY
27 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #ifndef __POINTMATCHER_REGISTRAR_H
37 #define __POINTMATCHER_REGISTRAR_H
38 
39 #include "Parametrizable.h"
40 #include "PointMatcher.h"
41 #include <boost/format.hpp>
42 #include <boost/typeof/typeof.hpp>
43 
44 
45 #ifdef SYSTEM_YAML_CPP
46  namespace YAML
47  {
48  class Node;
49  }
50 #else
51  namespace YAML_PM
52  {
53  class Node;
54  }
55 #endif // HAVE_YAML_CPP
56 
57 namespace PointMatcherSupport
58 {
59 #ifdef SYSTEM_YAML_CPP
60  namespace YAML = ::YAML;
61 #else
62  namespace YAML = ::YAML_PM;
63 #endif
64 
66  void getNameParamsFromYAML(const YAML::Node& module, std::string& name, Parametrizable::Parameters& params);
67 
69  struct InvalidElement: std::runtime_error
70  {
71  InvalidElement(const std::string& reason);
72  };
73 
75  template<typename Interface>
76  struct Registrar
77  {
78  public:
79  typedef Interface TargetType;
80 
83  {
85  virtual ~ClassDescriptor() {}
87  virtual std::shared_ptr<Interface> createInstance(const std::string& className, const Parametrizable::Parameters& params) const = 0;
89  virtual const std::string description() const = 0;
91  virtual const Parametrizable::ParametersDoc availableParameters() const = 0;
92  };
93 
95  template<typename C>
97  {
98  virtual std::shared_ptr<Interface> createInstance(const std::string& className, const Parametrizable::Parameters& params) const
99  {
100  std::shared_ptr<C> instance = std::make_shared<C>(params);
101 
102  // check that all parameters were set
103  for (BOOST_AUTO(it, params.begin()); it != params.end() ;++it)
104  {
105  if (instance->parametersUsed.find(it->first) == instance->parametersUsed.end()){
107  (boost::format("Parameter %1% for module %2% was set but is not used") % it->first % className).str()
108  );
109  }
110  }
111 
112  return instance;
113  }
114  virtual const std::string description() const
115  {
116  return C::description();
117  }
119  {
120  return C::availableParameters();
121  }
122  };
123 
125  template<typename C>
127  {
128  virtual std::shared_ptr<Interface> createInstance(const std::string& className, const Parametrizable::Parameters& params) const
129  {
130  for (BOOST_AUTO(it, params.begin()); it != params.end() ;++it)
132  (boost::format("Parameter %1% was set but module %2% dos not use any parameter") % it->first % className).str()
133  );
134  return std::make_shared<C>();
135  }
136  virtual const std::string description() const
137  {
138  return C::description();
139  }
141  {
143  }
144  };
145 
146  protected:
147  typedef std::map<std::string, ClassDescriptor*> DescriptorMap;
149 
150  public:
153  {
154  for (BOOST_AUTO(it, classes.begin()); it != classes.end(); ++it)
155  delete it->second;
156  }
158  void reg(const std::string &name, ClassDescriptor* descriptor)
159  {
160  classes[name] = descriptor;
161  }
162 
164  const ClassDescriptor* getDescriptor(const std::string& name) const
165  {
166  BOOST_AUTO(it, classes.find(name));
167  if (it == classes.end())
168  {
169  std::cerr << "No element named " << name << " is registered. Known ones are:\n";
170  dump(std::cerr);
171  throw InvalidElement(
172  (boost::format("Trying to instanciate unknown element %1% from registrar") % name).str()
173  );
174  }
175  return it->second;
176  }
177 
179  std::shared_ptr<Interface> create(const std::string& name, const Parametrizable::Parameters& params = Parametrizable::Parameters()) const
180  {
181  return getDescriptor(name)->createInstance(name, params);
182  }
183 
185  std::shared_ptr<Interface> createFromYAML(const YAML::Node& module) const
186  {
187  std::string name;
189 
190  getNameParamsFromYAML(module, name, params);
191 
192  return create(name, params);
193  }
194 
196  const std::string getDescription(const std::string& name) const
197  {
198  return getDescriptor(name)->description();
199  }
200 
202  void dump(std::ostream &stream) const
203  {
204  for (BOOST_AUTO(it, classes.begin()); it != classes.end(); ++it)
205  stream << "- " << it->first << "\n";
206  }
207 
209  typename DescriptorMap::const_iterator begin() const
210  {
211  return classes.begin();
212  }
214  typename DescriptorMap::const_iterator end() const
215  {
216  return classes.end();
217  }
218  };
219 
220  #define REG(name) name##Registrar
221  #define DEF_REGISTRAR(name) PointMatcherSupport::Registrar< name > name##Registrar;
222  #define DEF_REGISTRAR_IFACE(name, ifaceName) PointMatcherSupport::Registrar< ifaceName > name##Registrar;
223  #define ADD_TO_REGISTRAR(name, elementName, element) { \
224  typedef typename PointMatcherSupport::Registrar< name >::template GenericClassDescriptor< element > Desc; \
225  name##Registrar.reg(# elementName, new Desc() ); \
226  }
227  #define ADD_TO_REGISTRAR_NO_PARAM(name, elementName, element) { \
228  typedef typename PointMatcherSupport::Registrar< name >::template GenericClassDescriptorNoParam< element > Desc; \
229  name##Registrar.reg(# elementName, new Desc() ); \
230  }
231 } // namespace PointMatcherSupport
232 
233 #endif // __POINTMATCHER_REGISTRAR_H
DescriptorMap::const_iterator end() const
end for const iterator over classes descriptions
Definition: Registrar.h:214
An exception thrown when one tries to instanciate an element that does not exist in the registrar.
Definition: Registrar.h:69
virtual std::shared_ptr< Interface > createInstance(const std::string &className, const Parametrizable::Parameters &params) const =0
Create an instance of Interface using params.
public interface
std::shared_ptr< Interface > create(const std::string &name, const Parametrizable::Parameters &params=Parametrizable::Parameters()) const
Create an instance.
Definition: Registrar.h:179
virtual ~ClassDescriptor()
Virtual destructor, do nothing.
Definition: Registrar.h:85
A factor for subclasses of Interface.
Definition: Registrar.h:76
virtual const std::string description() const
Return the description of this class.
Definition: Registrar.h:136
virtual const Parametrizable::ParametersDoc availableParameters() const
Return the available parameters for this class.
Definition: Registrar.h:118
A descriptor for a class C that provides parameters.
Definition: Registrar.h:96
The interface for class descriptors.
Definition: Registrar.h:82
A descriptor for a class C that does not provide any parameter.
Definition: Registrar.h:126
Interface TargetType
alias to recover the template parameter
Definition: Registrar.h:79
virtual std::shared_ptr< Interface > createInstance(const std::string &className, const Parametrizable::Parameters &params) const
Create an instance of Interface using params.
Definition: Registrar.h:128
DescriptorMap classes
known classes that can be constructed
Definition: Registrar.h:148
std::shared_ptr< Interface > createFromYAML(const YAML::Node &module) const
Create an instance from a YAML node.
Definition: Registrar.h:185
std::map< std::string, Parameter > Parameters
Parameters stored as a map of string->string.
Definition: Parametrizable.h:156
Functions and classes that are not dependant on scalar type are defined in this namespace.
Definition: PointMatcher.h:78
void getNameParamsFromYAML(const YAML::Node &module, std::string &name, Parametrizable::Parameters &params)
Retrieve name and parameters from a yaml node.
InvalidElement(const std::string &reason)
Construct an invalid-element exception.
Definition: Registry.cpp:55
virtual std::shared_ptr< Interface > createInstance(const std::string &className, const Parametrizable::Parameters &params) const
Create an instance of Interface using params.
Definition: Registrar.h:98
const ClassDescriptor * getDescriptor(const std::string &name) const
Return a descriptor following a name, throw an exception if name is invalid.
Definition: Registrar.h:164
~Registrar()
Destructor, remove all classes descriptors.
Definition: Registrar.h:152
void reg(const std::string &name, ClassDescriptor *descriptor)
Register a class by storing an instance of a descriptor helper class.
Definition: Registrar.h:158
An exception thrown when one tries to fetch the value of an unexisting parameter.
Definition: Parametrizable.h:101
DescriptorMap::const_iterator begin() const
begin for const iterator over classes descriptions
Definition: Registrar.h:209
virtual const Parametrizable::ParametersDoc availableParameters() const =0
Return the available parameters for this class.
std::vector< ParameterDoc > ParametersDoc
The documentation of all parameters.
Definition: Parametrizable.h:144
virtual const Parametrizable::ParametersDoc availableParameters() const
Return the available parameters for this class.
Definition: Registrar.h:140
std::map< std::string, ClassDescriptor * > DescriptorMap
descriptors for sub-classes of Interface, indexed by their names
Definition: Registrar.h:147
void dump(std::ostream &stream) const
Print the list of registered classes to stream.
Definition: Registrar.h:202
virtual const std::string description() const
Return the description of this class.
Definition: Registrar.h:114
virtual const std::string description() const =0
Return the description of this class.
const std::string getDescription(const std::string &name) const
Get the description of a class.
Definition: Registrar.h:196