aGrUM  0.20.3
a C++ library for (probabilistic) graphical models
operatorRegister4MultiDim.h
Go to the documentation of this file.
1 /**
2  *
3  * Copyright (c) 2005-2021 by 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
118  erase(const std::string& operation_name, const std::string& type1, const std::string& type2);
119 
120  /**
121  * @brief Indicates whether a given entry exists in the register.
122  *
123  * Indicates if the register contains a function that performs the
124  * operation described by \e operation_name, and that takes in argument a
125  * multiDim of type \e type1 and one multiDim of type \e type2
126  *
127  * @param operation_name describes the name of the operation performed by
128  * the function we look for. Usual operation names are "+", "*", "/", "-",
129  * "max", "min"
130  *
131  * @param type1 the \e real type of the first multiDim taken in argument by
132  * the function we look for
133  *
134  * @param type2 the \e real type of the second multiDim taken in argument
135  * by the function we look for
136  */
137  bool exists(const std::string& operation_name,
138  const std::string& type1,
139  const std::string& type2) const;
140 
141  /**
142  * @brief returns the specialized operator assigned to a given pair of
143  * MultiDimImplementations
144  *
145  * returns the function, if any, that performs the operation described by
146  * \e operation_name, and that takes in argument a multiDim of type \e
147  * type1 and one multiDim of type \e type2
148  *
149  * @param operation_name describes the name of the operation performed by
150  * the function we look for. Usual operation names are "+", "*", "/", "-",
151  * "max", "min"
152  *
153  * @param type1 the \e real type of the first multiDim taken in argument by
154  * the function we look for
155  *
156  * @param type2 the \e real type of the second multiDim taken in argument
157  * by the function we look for
158  *
159  * @throws NotFound exception is thrown if the operator we look for does
160  * not exist within this register.
161  */
162  OperatorPtr get(const std::string& operation_name,
163  const std::string& type1,
164  const std::string& type2) const;
165 
166  /// @}
167  // ========================================================================
168  /// @name Named Constructors
169  // ========================================================================
170  /// @{
171 
172  /**
173  * @brief A named constructor that constructs one and only one Register per
174  * data type.
175  *
176  * Note that this constructor prevents the famous init order fiasco.
177  */
178  static OperatorRegister4MultiDim< GUM_SCALAR >& Register();
179 
180  /// @}
181 
182  private:
183  // ========================================================================
184  /// @name Constructors / Destructors
185  // ========================================================================
186  /// @{
187 
188  /// Default constructor: creates an empty register
189  OperatorRegister4MultiDim();
190 
191  /// Copy operator: never to be used
192  OperatorRegister4MultiDim(const OperatorRegister4MultiDim< GUM_SCALAR >&);
193 
194  /// Destructor
195  ~OperatorRegister4MultiDim();
196 
197  /// @}
198 
199  /// The set of associations for a given operation type
200  typedef HashTable< std::pair< std::string, std::string >, OperatorPtr > OperatorSet;
201 
202  /**
203  * @brief A mapping from pairs of types of MultiDimImplementations to
204  * operators.
205  *
206  * In this type, the strings represent the very types of the
207  * MultiDimImplementations that will be combined. To a pair of strings,
208  * hence to a pair of types of MultiDimImplementations, is associated a
209  * function to combine them (the OperatorPtr).
210  */
211  HashTable< std::string, OperatorSet* > _set_;
212  };
213 
214  /// A function to more easily register new operators in MultiDims
215  template < typename GUM_SCALAR >
216  void registerOperator(const std::string& operation_name,
217  const std::string& type1,
218  const std::string& type2,
219  typename OperatorRegister4MultiDim< GUM_SCALAR >::OperatorPtr function);
220 
221 } /* namespace gum */
222 
223 // always include the implementations
224 #include <agrum/tools/multidim/utils/operators/operatorRegister4MultiDim_tpl.h>
225 
226 #endif /* GUM_OPERATOR_REGISTER_MULTI_DIM_H */