aGrUM  0.20.2
a C++ library for (probabilistic) graphical models
operatorRegister4MultiDim.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright 2005-2020 Pierre-Henri WUILLEMIN(@LIP6) & Christophe GONZALES(@AMU)
4  * info_at_agrum_dot_org
5  *
6  * This library is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this library. If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 /**
23  * @file
24  * @brief A container for registering binary functions on
25  * multiDimImplementations
26  *
27  * @author Christophe GONZALES(@AMU) and Pierre-Henri WUILLEMIN(@LIP6)
28  */
29 
30 #ifndef GUM_OPERATOR_REGISTER_4_MULTI_DIM_H
31 #define GUM_OPERATOR_REGISTER_4_MULTI_DIM_H
32 
33 #include <agrum/tools/core/hashTable.h>
34 #include <iostream>
35 #include <string>
36 #include <utility>
37 
38 namespace gum {
39 
40  // the base object used by combinations
41  template < typename GUM_SCALAR >
42  class MultiDimImplementation;
43 
44  // ===========================================================================
45  // === GUM_MULTI_DIM_OPERATOR_REGISTER ===
46  // ===========================================================================
47  // clang-format off
48  /**
49  * @class OperatorRegister4MultiDim
50  * @headerfile operatorRegister4MultiDim.h <agrum/multdim/operators/operatorRegister4MultiDim.h>
51  * @ingroup multidim_op_group
52  *
53  * @brief A container for registering binary functions on
54  * multiDimImplementations
55  */
56  // clang-format on
57  template < typename GUM_SCALAR >
58  class OperatorRegister4MultiDim {
59  public:
60  /// The type of functions used by the register
61  typedef MultiDimImplementation< GUM_SCALAR >* (*OperatorPtr)(
62  const MultiDimImplementation< GUM_SCALAR >*,
63  const MultiDimImplementation< GUM_SCALAR >*);
64 
65  // ========================================================================
66  /// @name Accessors / Modifiers
67  // ========================================================================
68  /// @{
69 
70  /**
71  * @brief adds a new entry into the register
72  *
73  * This method inserts a new function (\e newFunction) taking two multiDim
74  * in arguments of types \e type1 and type2 respectively (which actually
75  * inherit from MultiDimImplementation). This new function's purpose is to
76  * achieve the operator described by \e operation_name. For instance, if
77  * operator_name is "+", "-", "/" or "*", the new function performs the
78  * usual algebraic operations.
79  *
80  * @param operation_name describes the name of the operation performed by
81  * newFunction. Usual operation names are "+", "*", "/", "-", "max", "min"
82  *
83  * @param type1 the \e real type of the first multiDim taken in argument by
84  * function \e newFunction
85  *
86  * @param type2 the \e real type of the second multiDim taken in argument
87  * by function \e newFunction
88  *
89  * @param newFunction a pointer to the new function to register. Note that
90  * although \e newFunction actually performs an operation on multiDims of
91  * types \e type1 and \e type2, it should be declared as taking in argument
92  * two MultiDimImplementations. This constraint is imposed by the C++
93  * typing system.
94  */
95  void insert(const std::string& operation_name,
96  const std::string& type1,
97  const std::string& type2,
98  OperatorPtr newFunction);
99 
100  /**
101  * @brief removes a given entry from the register
102  *
103  * removes the function, if any, that performs the operation described by
104  * \e operation_name, and that takes in argument a multiDim of type \e
105  * type1 and one multiDim of type \e type2
106  *
107  * @param operation_name describes the name of the operation performed by
108  * the function to remove. Usual operation names are "+", "*", "/", "-",
109  * "max", "min"
110  *
111  * @param type1 the \e real type of the first multiDim taken in argument by
112  * the function to remove
113  *
114  * @param type2 the \e real type of the second multiDim taken in argument
115  * by the function to remove.
116  */
117  void erase(const std::string& operation_name,
118  const std::string& type1,
119  const std::string& type2);
120 
121  /**
122  * @brief Indicates whether a given entry exists in the register.
123  *
124  * Indicates if the register contains a function that performs the
125  * operation described by \e operation_name, and that takes in argument a
126  * multiDim of type \e type1 and one multiDim of type \e type2
127  *
128  * @param operation_name describes the name of the operation performed by
129  * the function we look for. Usual operation names are "+", "*", "/", "-",
130  * "max", "min"
131  *
132  * @param type1 the \e real type of the first multiDim taken in argument by
133  * the function we look for
134  *
135  * @param type2 the \e real type of the second multiDim taken in argument
136  * by the function we look for
137  */
138  bool exists(const std::string& operation_name,
139  const std::string& type1,
140  const std::string& type2) const;
141 
142  /**
143  * @brief returns the specialized operator assigned to a given pair of
144  * MultiDimImplementations
145  *
146  * returns the function, if any, that performs the operation described by
147  * \e operation_name, and that takes in argument a multiDim of type \e
148  * type1 and one multiDim of type \e type2
149  *
150  * @param operation_name describes the name of the operation performed by
151  * the function we look for. Usual operation names are "+", "*", "/", "-",
152  * "max", "min"
153  *
154  * @param type1 the \e real type of the first multiDim taken in argument by
155  * the function we look for
156  *
157  * @param type2 the \e real type of the second multiDim taken in argument
158  * by the function we look for
159  *
160  * @throws NotFound exception is thrown if the operator we look for does
161  * not exist within this register.
162  */
163  OperatorPtr get(const std::string& operation_name,
164  const std::string& type1,
165  const std::string& type2) const;
166 
167  /// @}
168  // ========================================================================
169  /// @name Named Constructors
170  // ========================================================================
171  /// @{
172 
173  /**
174  * @brief A named constructor that constructs one and only one Register per
175  * data type.
176  *
177  * Note that this constructor prevents the famous init order fiasco.
178  */
179  static OperatorRegister4MultiDim< GUM_SCALAR >& Register();
180 
181  /// @}
182 
183  private:
184  // ========================================================================
185  /// @name Constructors / Destructors
186  // ========================================================================
187  /// @{
188 
189  /// Default constructor: creates an empty register
190  OperatorRegister4MultiDim();
191 
192  /// Copy operator: never to be used
193  OperatorRegister4MultiDim(const OperatorRegister4MultiDim< GUM_SCALAR >&);
194 
195  /// Destructor
196  ~OperatorRegister4MultiDim();
197 
198  /// @}
199 
200  /// The set of associations for a given operation type
201  typedef HashTable< std::pair< std::string, std::string >, OperatorPtr >
202  OperatorSet;
203 
204  /**
205  * @brief A mapping from pairs of types of MultiDimImplementations to
206  * operators.
207  *
208  * In this type, the strings represent the very types of the
209  * MultiDimImplementations that will be combined. To a pair of strings,
210  * hence to a pair of types of MultiDimImplementations, is associated a
211  * function to combine them (the OperatorPtr).
212  */
213  HashTable< std::string, OperatorSet* > set__;
214  };
215 
216  /// A function to more easily register new operators in MultiDims
217  template < typename GUM_SCALAR >
218  void registerOperator(
219  const std::string& operation_name,
220  const std::string& type1,
221  const std::string& type2,
222  typename OperatorRegister4MultiDim< GUM_SCALAR >::OperatorPtr function);
223 
224 } /* namespace gum */
225 
226 // always include the implementations
227 #include <agrum/tools/multidim/utils/operators/operatorRegister4MultiDim_tpl.h>
228 
229 #endif /* GUM_OPERATOR_REGISTER_MULTI_DIM_H */