Arcane  v3.15.3.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))
142 return CaseTable::ErrCanNotConvertParamToRightType;
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))
152 return CaseTable::ErrCanNotConvertParamToRightType;
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)
197 return CaseTable::ErrNotGreaterThanPrevious;
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)
204 return CaseTable::ErrNotLesserThanNext;
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
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.
Référence à une instance.
Chaîne de caractères unicode.
Vecteur 1D de données avec sémantique par valeur (style STL).
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
double Real
Type représentant un réel.
Int32 Integer
Type représentant un entier.