Arcane  v3.14.10.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
CaseTableParams.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2023 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* CaseTableParams.cc (C) 2000-2023 */
9/* */
10/* Paramètre d'une fonction du jeu de données. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arcane/utils/ValueConvert.h"
15#include "arcane/utils/String.h"
16#include "arcane/utils/NotSupportedException.h"
17
18#include "arcane/datatype/SmallVariant.h"
19
20#include "arcane/CaseTableParams.h"
21
22#include <algorithm>
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane
28{
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
34{
35 public:
36
38
39 public:
40
42 : m_param_list(v)
43 {}
44 virtual ~ICFParamSetter() {}
45
46 public:
47
48 virtual void value(Integer id, Real& v) const = 0;
49 virtual void value(Integer id, Integer& v) const = 0;
50 virtual CaseTable::eError appendValue(const String& value) = 0;
51 virtual CaseTable::eError setValue(Integer id, const String& value) = 0;
52 virtual CaseTable::eError setValue(Integer id, Real v) = 0;
53 virtual CaseTable::eError setValue(Integer id, Integer v) = 0;
54 virtual void removeValue(Integer id) = 0;
55 virtual void toString(Integer id, String& str) const = 0;
56
57 protected:
58
59 const SmallVariant& param(Integer id) const { return (*m_param_list)[id]; }
60
61 SmallVariant& param(Integer id) { return (*m_param_list)[id]; }
62
63 Params& params() { return *m_param_list; }
64
65 Integer nbElement() const { return m_param_list->size(); }
66
67 private:
68
69 Params* m_param_list;
70};
71
72/*---------------------------------------------------------------------------*/
73/*---------------------------------------------------------------------------*/
74
75template <class Type>
77: public ICFParamSetter
78, private VariantGetterT<Type>
79{
80 public:
81
82 using VariantGetterT<Type>::asType;
83
86 {}
87
88 public:
89
90 void value(Integer id, Real& v) const override;
91 void value(Integer id, Integer& v) const override;
92 CaseTable::eError appendValue(const String& value) override;
93 CaseTable::eError setValue(Integer id, const String& value) override;
94 CaseTable::eError setValue(Integer id, Real v) override;
95 CaseTable::eError setValue(Integer id, Integer v) override;
96 void removeValue(Integer id) override;
97 void toString(Integer id, String& str) const override;
98
99 private:
100
101 bool _checkConvert(Integer id, const String& str, Type& value) const;
102 CaseTable::eError _checkValid(Integer id, Type value) const;
103 CaseTable::eError _setIfValid(Integer id, Type value);
104};
105
106/*---------------------------------------------------------------------------*/
107/*---------------------------------------------------------------------------*/
108
109template <class Type> void CFParamSetterT<Type>::
110value(Integer id, Real& v) const
111{
112 v = (Real)(asType(param(id)));
113}
114template <class Type> void CFParamSetterT<Type>::
115value(Integer id, Integer& v) const
116{
117 v = Convert::toInteger(asType(param(id)));
118}
119template <class Type> void CFParamSetterT<Type>::
120toString(Integer id, String& s) const
121{
122 s = String::fromNumber(asType(param(id)));
123}
124
125template <class Type> CaseTable::eError CFParamSetterT<Type>::
126setValue(Integer id, Real v)
127{
128 return _setIfValid(id, (Type)(Convert::toDouble(v)));
129}
130
131template <class Type> CaseTable::eError CFParamSetterT<Type>::
132setValue(Integer id, Integer v)
133{
134 return _setIfValid(id, (Type)(v));
135}
136
137template <class Type> CaseTable::eError CFParamSetterT<Type>::
138setValue(Integer id, const String& s)
139{
140 Type avalue = Type();
141 if (_checkConvert(id, s, avalue))
143 return _setIfValid(id, avalue);
144}
145
146template <class Type> CaseTable::eError CFParamSetterT<Type>::
147appendValue(const String& s)
148{
149 Type avalue = Type();
150 Integer id = nbElement();
151 if (_checkConvert(id, s, avalue))
153 CaseTable::eError err = _checkValid(id, avalue);
154 if (err == CaseTable::ErrNo) {
155 SmallVariant v;
156 v.setValueAll(avalue);
157 params().add(v);
158 }
159 return err;
160}
161
162template <class Type> void CFParamSetterT<Type>::
163removeValue(Integer index)
164{
165 params().remove(index);
166}
167
168template <class Type> CaseTable::eError CFParamSetterT<Type>::
169_setIfValid(Integer id, Type avalue)
170{
171 CaseTable::eError err = _checkValid(id, avalue);
172 if (err == CaseTable::ErrNo)
173 param(id).setValueAll(avalue);
174 return err;
175}
176
177template <class Type> bool CFParamSetterT<Type>::
178_checkConvert(Integer id, const String& str, Type& avalue) const
179{
180 ARCANE_UNUSED(id);
181 avalue = Type();
182 if (!str.null()) {
183 if (builtInGetValue(avalue, str))
184 return true;
185 }
186 return false;
187}
188
189template <class Type> CaseTable::eError CFParamSetterT<Type>::
190_checkValid(Integer id, Type avalue) const
191{
192 Integer nb_param = nbElement();
193 // Vérifie que le 'begin' courant est supérieur au précédent.
194 if (nb_param != 0 && id > 0) {
195 Type previous_value = asType(param(id - 1));
196 if (avalue < previous_value)
198 }
199
200 // Vérifie que le 'begin' courant est inférieur au suivant.
201 if (nb_param != 0 && (id + 1) < nb_param) {
202 Type next_value = asType(param(id + 1));
203 if (avalue > next_value)
205 }
206
207 return CaseTable::ErrNo;
208}
209
210/*---------------------------------------------------------------------------*/
211/*---------------------------------------------------------------------------*/
212
214{
215 public:
216
217 friend class CaseTableParams;
218
220
221 public:
222
224 ~Impl();
225
226 public:
227
228 void setType(CaseTable::eParamType type);
229
230 private:
231
232 CaseTable::eParamType m_param_type;
233 ICFParamSetter* m_setter;
234 Params m_param_list; //!< Liste des valeurs
235};
236
237/*---------------------------------------------------------------------------*/
238/*---------------------------------------------------------------------------*/
239
240CaseTableParams::Impl::
241Impl(CaseTable::eParamType type)
242: m_param_type(CaseTable::ParamUnknown)
243, m_setter(nullptr)
244{
245 setType(type);
246}
247
248/*---------------------------------------------------------------------------*/
249/*---------------------------------------------------------------------------*/
250
251CaseTableParams::Impl::
252~Impl()
253{
254 delete m_setter;
255}
256
257/*---------------------------------------------------------------------------*/
258/*---------------------------------------------------------------------------*/
259
260void CaseTableParams::Impl::
261setType(CaseTable::eParamType type)
262{
263 delete m_setter;
264
265 if (type == CaseTable::ParamUnknown) {
266 // Normalement on devrait faire un fatal mais pour des raisons de
267 // compatibilité avec l'existant on considère qu'il s'agit d'un paramètre
268 // de type 'Real'.
270 }
271
272 if (type == CaseTable::ParamReal)
273 m_setter = new CFParamSetterT<Real>(&m_param_list);
274 else if (type == CaseTable::ParamInteger)
275 m_setter = new CFParamSetterT<Integer>(&m_param_list);
276 else
277 ARCANE_THROW(NotSupportedException, "Invalid type '{0}'", (int)type);
278
279 m_param_type = type;
280}
281
282/*---------------------------------------------------------------------------*/
283/*---------------------------------------------------------------------------*/
284
285/*---------------------------------------------------------------------------*/
286/*---------------------------------------------------------------------------*/
287
288CaseTableParams::
289CaseTableParams(CaseTable::eParamType v)
290: m_p(new Impl(v))
291{
292}
293
294CaseTableParams::
295~CaseTableParams()
296{
297 delete m_p;
298}
299
300bool CaseTableParams::
301null() const
302{
303 return m_p->m_param_type == CaseTable::ParamUnknown;
304}
305
306Integer CaseTableParams::
307nbElement() const
308{
309 return m_p->m_param_list.size();
310}
311
312void CaseTableParams::
313value(Integer id, Real& v) const
314{
315 m_p->m_setter->value(id, v);
316}
317
318void CaseTableParams::
319value(Integer id, Integer& v) const
320{
321 m_p->m_setter->value(id, v);
322}
323
324CaseTable::eError CaseTableParams::
325appendValue(const String& avalue)
326{
327 return m_p->m_setter->appendValue(avalue);
328}
329
330CaseTable::eError CaseTableParams::
331setValue(Integer id, const String& avalue)
332{
333 return m_p->m_setter->setValue(id, avalue);
334}
335
336CaseTable::eError CaseTableParams::
337setValue(Integer id, Real v)
338{
339 return m_p->m_setter->setValue(id, v);
340}
341
342CaseTable::eError CaseTableParams::
343setValue(Integer id, Integer v)
344{
345 return m_p->m_setter->setValue(id, v);
346}
347
348void CaseTableParams::
349removeValue(Integer id)
350{
351 m_p->m_setter->removeValue(id);
352}
353
354void CaseTableParams::
355toString(Integer id, String& str) const
356{
357 m_p->m_setter->toString(id, str);
358}
359
360void CaseTableParams::
361setType(CaseTable::eParamType new_type)
362{
363 m_p->setType(new_type);
364}
365
366/*---------------------------------------------------------------------------*/
367/*---------------------------------------------------------------------------*/
368
369namespace
370{
371 template <typename T>
372 class Comparer
373 {
374 public:
375
376 bool operator()(const SmallVariant& a, const SmallVariant& b) const
377 {
378 T ta = {};
379 T tb = {};
380 a.value(ta);
381 b.value(tb);
382 return ta < tb;
383 }
384 };
385} // namespace
386
387/*---------------------------------------------------------------------------*/
388/*---------------------------------------------------------------------------*/
389
390template <typename T> void CaseTableParams::
391_getRange(T v, Int32& begin, Int32& end) const
392{
393 // Comme les valeurs des paramètres sont triées, utilise une
394 // dichotomie pour chercher à quelle indice dans le tableau des paramètres
395 // se trouve 'v'.
396 const Int32 max_end = nbElement();
397 begin = 0;
398 end = max_end;
399 Comparer<T> comp;
400 SmallVariant v2(v);
401 ConstArrayView<SmallVariant> params = m_p->m_param_list;
402 auto iter = std::lower_bound(params.begin(), params.end(), v2, comp);
403 Int32 pos = static_cast<Int32>(iter - params.begin());
404 // Augmente l'intervalle pour être sur de traiter les cas limites
405 // où la valeur est proche d'une valeur conservée dans \a params.
406 begin = pos - 2;
407 end = pos + 2;
408 begin = std::clamp(begin, 0, max_end);
409 end = std::clamp(end, 0, max_end);
410}
411
412/*---------------------------------------------------------------------------*/
413/*---------------------------------------------------------------------------*/
414
415void CaseTableParams::
416getRange(Real v, Int32& begin, Int32& end) const
417{
418 _getRange(v, begin, end);
419}
420
421/*---------------------------------------------------------------------------*/
422/*---------------------------------------------------------------------------*/
423
424void CaseTableParams::
425getRange(Integer v, Int32& begin, Int32& end) const
426{
427 _getRange(v, begin, end);
428}
429
430/*---------------------------------------------------------------------------*/
431/*---------------------------------------------------------------------------*/
432
433template class CFParamSetterT<Real>;
434template class CFParamSetterT<Integer>;
435
436/*---------------------------------------------------------------------------*/
437/*---------------------------------------------------------------------------*/
438
439} // namespace Arcane
440
441/*---------------------------------------------------------------------------*/
442/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro pour envoyer une exception avec formattage.
eError
Type des erreurs retournées par la classe.
Definition CaseTable.h:47
@ ErrCanNotConvertParamToRightType
Indique que la conversion du paramètre vers le type souhaité est impossible.
Definition CaseTable.h:52
@ ErrNotGreaterThanPrevious
Indique que le paramètre n'est pas supérieur au précédent.
Definition CaseTable.h:56
@ ErrNotLesserThanNext
Indique que le paramètre n'est pas inférieur au suivant.
Definition CaseTable.h:58
eParamType
Type d'un paramètre d'une fonction.
@ ParamUnknown
Type de paramètre inconnu.
@ ParamReal
Paramètre de type Real.
@ ParamInteger
Paramètre de type Integer.
Classe gérant un type polymorphe.
Integer size() const
Nombre d'éléments du vecteur.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
Integer toInteger(Real r)
Converti un Real en Integer.
Definition Convert.h:53
double toDouble(Real r)
Converti un Real en double.
Definition Convert.h:40
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
Int32 Integer
Type représentant un entier.