1 //                                               -*- C++ -*-
2 /**
3  * @brief This class gives a implementation for object's methods so they can be used in Functions
4  *
5  *  Copyright 2005-2021 Airbus-EDF-IMACS-ONERA-Phimeca
6  *
7  *  This library is free software: you can redistribute it and/or modify
8  *  it under the terms of the GNU Lesser General Public License as published by
9  *  the Free Software Foundation, either version 3 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public License
18  *  along with this library.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #ifndef OPENTURNS_METHODBOUNDEVALUATION_HXX
23 #define OPENTURNS_METHODBOUNDEVALUATION_HXX
24 
25 #include "openturns/EvaluationImplementation.hxx"
26 #include "openturns/FunctionImplementation.hxx"
27 
28 BEGIN_NAMESPACE_OPENTURNS
29 
30 
31 
32 struct OT_API NO_MATCH_ON_ReturnTypeAdapter {};
33 
34 template <typename Tp_> struct ReturnTypeAdapter
35 {
36   typedef NO_MATCH_ON_ReturnTypeAdapter Type_;
37 };
38 
39 template <> struct ReturnTypeAdapter< Scalar >
40 {
41   typedef Scalar Type_;
toPointReturnTypeAdapter42   static inline Point toPoint( const Scalar val )
43   {
44     return Point(1, val) ;
45   }
46 };
47 
48 template <> struct ReturnTypeAdapter< Point >
49 {
50   typedef Point Type_;
toPointReturnTypeAdapter51   static inline Point toPoint( const Point & val )
52   {
53     return val ;
54   }
55 };
56 
57 
58 
59 struct OT_API NO_MATCH_ON_ArgumentTypeAdapter {};
60 
61 template <typename Tp_> struct ArgumentTypeAdapter
62 {
63   typedef NO_MATCH_ON_ArgumentTypeAdapter Type_;
64 };
65 
66 template <> struct ArgumentTypeAdapter< Scalar >
67 {
68   typedef const Scalar Type_;
fromPointArgumentTypeAdapter69   static inline Scalar fromPoint( const Point & val )
70   {
71     return val[0] ;
72   }
73 };
74 
75 template <> struct ArgumentTypeAdapter< Point >
76 {
77   typedef const Point & Type_;
fromPointArgumentTypeAdapter78   static inline Point fromPoint( const Point & val )
79   {
80     return val ;
81   }
82 };
83 
84 
85 
86 template <typename ReturnType_, typename ArgumentType_>
87 struct MethodAdapter : public ReturnTypeAdapter<ReturnType_>, public ArgumentTypeAdapter<ArgumentType_>
88 {
89   typedef typename ArgumentTypeAdapter<ArgumentType_>::Type_ ArgumentType;
90   typedef typename ReturnTypeAdapter<ReturnType_>::Type_     ReturnType;
91 };
92 
93 
94 
95 
96 
97 
98 /**
99  * @class MethodBoundEvaluation
100  *
101  * This class gives a implementation for object's methods so they can be used in Functions
102  */
103 template <typename EvaluableObject, typename ReturnType_, typename ArgumentType_>
104 class MethodBoundEvaluation
105   : public EvaluationImplementation
106 {
107 public:
108 
109 
110 
111   typedef typename MethodAdapter<ReturnType_, ArgumentType_>::ReturnType (EvaluableObject::*EvaluationMethod) (typename MethodAdapter<ReturnType_, ArgumentType_>::ArgumentType) const;
112 
113 
114 
115   /** Default constructor */
MethodBoundEvaluation(const EvaluableObject & obj,EvaluationMethod method,const UnsignedInteger inputDimension,const UnsignedInteger outputDimension)116   MethodBoundEvaluation( const EvaluableObject & obj, EvaluationMethod method, const UnsignedInteger inputDimension, const UnsignedInteger outputDimension )
117     : obj_(obj),
118       method_(method),
119       inputDimension_(inputDimension),
120       outputDimension_(outputDimension)
121   {
122     // Build the descriptions
123     setInputDescription(Description::BuildDefault(inputDimension, "x"));
124     setOutputDescription(Description::BuildDefault(outputDimension, "y"));
125   }
126 
127 
128   /** Virtual constructor */
clone() const129   MethodBoundEvaluation * clone() const override
130   {
131     return new MethodBoundEvaluation(*this);
132   }
133 
134 
135   /** Comparison operator */
operator ==(const MethodBoundEvaluation &) const136   Bool operator ==(const MethodBoundEvaluation & /*other*/) const
137   {
138     return true;
139   }
140 
141 
142   /** String converter */
__repr__() const143   String __repr__() const override
144   {
145     OSS oss;
146     oss << "class=MethodBoundEvaluation name=" << getName();
147     return oss;
148   }
149 
150 
151   /* Here is the interface that all derived class must implement */
152 
153   /** Operator () */
operator ()(const Point & inP) const154   Point operator() (const Point & inP) const override
155   {
156     Point result(ReturnTypeAdapter<ReturnType_>::toPoint( ( obj_.*method_ ) (ArgumentTypeAdapter<ArgumentType_>::fromPoint(inP))));
157     callsNumber_.increment();
158     return result;
159   }
160 
161   /** Accessor for input point dimension */
getInputDimension() const162   UnsignedInteger getInputDimension() const override
163   {
164     return inputDimension_;
165   }
166 
167   /** Accessor for output point dimension */
getOutputDimension() const168   UnsignedInteger getOutputDimension() const override
169   {
170     return outputDimension_;
171   }
172 
isParallel() const173   Bool isParallel() const override
174   {
175     return false;
176   }
177 
178 
179   /** Method save() stores the object through the StorageManager
180    *  The inherited method is sufficient as we do not have any
181    *  attribute
182    */
183 
184   /** Method load() reloads the object from the StorageManager
185    *  The inherited method is sufficient as we do not have any
186    *  attribute
187    */
188 
189 protected:
190 
191 
192 private:
193   const EvaluableObject & obj_;
194   EvaluationMethod method_;
195   UnsignedInteger inputDimension_;
196   UnsignedInteger outputDimension_;
197 
198 }; /* class MethodBoundEvaluation */
199 
200 
201 
202 
203 
204 
205 template <typename EvaluableObject, typename ReturnType_, typename ArgumentType_>
206 FunctionImplementation
bindMethod(const EvaluableObject & obj,typename MethodBoundEvaluation<EvaluableObject,ReturnType_,ArgumentType_>::EvaluationMethod method,const UnsignedInteger inputDimension,const UnsignedInteger outputDimension)207 bindMethod (const EvaluableObject & obj,
208             typename MethodBoundEvaluation<EvaluableObject, ReturnType_, ArgumentType_>::EvaluationMethod method,
209             const UnsignedInteger inputDimension,
210             const UnsignedInteger outputDimension)
211 {
212   return FunctionImplementation(new MethodBoundEvaluation<EvaluableObject, ReturnType_, ArgumentType_>(obj, method, inputDimension, outputDimension));
213 }
214 
215 
216 
217 END_NAMESPACE_OPENTURNS
218 
219 #endif /* OPENTURNS_METHODBOUNDEVALUATION_HXX */
220