Arcane  4.1.12.0
User documentation
Loading...
Searching...
No Matches
CaseTableParams.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2026 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/* Parameter of a dataset function. */
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/core/CaseTableParams.h"
21
22#include <algorithm>
23
24/*---------------------------------------------------------------------------*/
25/*---------------------------------------------------------------------------*/
26
27namespace Arcane
28{
29
30/*---------------------------------------------------------------------------*/
31/*---------------------------------------------------------------------------*/
32
33class ICFParamSetter
34{
35 public:
36
37 using Params = UniqueArray<SmallVariant>;
38
39 public:
40
41 ICFParamSetter(Params* v)
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>
76class CFParamSetterT
77: public ICFParamSetter
78, private VariantGetterT<Type>
79{
80 public:
81
82 using VariantGetterT<Type>::asType;
83
84 CFParamSetterT(Params* v)
85 : ICFParamSetter(v)
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>::
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 // Checks that the current 'begin' is greater than the previous one.
194 if (nb_param != 0 && id > 0) {
195 Type previous_value = asType(param(id - 1));
196 if (avalue < previous_value)
198 }
199
200 // Checks that the current 'begin' is less than the next one.
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
219 typedef UniqueArray<SmallVariant> Params;
220
221 public:
222
223 Impl(CaseTable::eParamType type);
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; //!< List of values
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 // Normally we should do a fatal error, but for reasons of
267 // compatibility with existing code, we consider it a 'Real' type parameter.
269 }
270
271 if (type == CaseTable::ParamReal)
272 m_setter = new CFParamSetterT<Real>(&m_param_list);
273 else if (type == CaseTable::ParamInteger)
274 m_setter = new CFParamSetterT<Integer>(&m_param_list);
275 else
276 ARCANE_THROW(NotSupportedException, "Invalid type '{0}'", (int)type);
277
278 m_param_type = type;
279}
280
281/*---------------------------------------------------------------------------*/
282/*---------------------------------------------------------------------------*/
283
284/*---------------------------------------------------------------------------*/
285/*---------------------------------------------------------------------------*/
286
287CaseTableParams::
288CaseTableParams(CaseTable::eParamType v)
289: m_p(new Impl(v))
290{
291}
292
293CaseTableParams::
294~CaseTableParams()
295{
296 delete m_p;
297}
298
299bool CaseTableParams::
300null() const
301{
302 return m_p->m_param_type == CaseTable::ParamUnknown;
303}
304
305Integer CaseTableParams::
306nbElement() const
307{
308 return m_p->m_param_list.size();
309}
310
311void CaseTableParams::
312value(Integer id, Real& v) const
313{
314 m_p->m_setter->value(id, v);
315}
316
317void CaseTableParams::
318value(Integer id, Integer& v) const
319{
320 m_p->m_setter->value(id, v);
321}
322
323CaseTable::eError CaseTableParams::
324appendValue(const String& avalue)
325{
326 return m_p->m_setter->appendValue(avalue);
327}
328
329CaseTable::eError CaseTableParams::
330setValue(Integer id, const String& avalue)
331{
332 return m_p->m_setter->setValue(id, avalue);
333}
334
335CaseTable::eError CaseTableParams::
336setValue(Integer id, Real v)
337{
338 return m_p->m_setter->setValue(id, v);
339}
340
341CaseTable::eError CaseTableParams::
342setValue(Integer id, Integer v)
343{
344 return m_p->m_setter->setValue(id, v);
345}
346
347void CaseTableParams::
348removeValue(Integer id)
349{
350 m_p->m_setter->removeValue(id);
351}
352
353void CaseTableParams::
354toString(Integer id, String& str) const
355{
356 m_p->m_setter->toString(id, str);
357}
358
359void CaseTableParams::
360setType(CaseTable::eParamType new_type)
361{
362 m_p->setType(new_type);
363}
364
365/*---------------------------------------------------------------------------*/
366/*---------------------------------------------------------------------------*/
367
368namespace
369{
370 template <typename T>
371 class Comparer
372 {
373 public:
374
375 bool operator()(const SmallVariant& a, const SmallVariant& b) const
376 {
377 T ta = {};
378 T tb = {};
379 a.value(ta);
380 b.value(tb);
381 return ta < tb;
382 }
383 };
384} // namespace
385
386/*---------------------------------------------------------------------------*/
387/*---------------------------------------------------------------------------*/
388
389template <typename T> void CaseTableParams::
390_getRange(T v, Int32& begin, Int32& end) const
391{
392 // Since the parameter values are sorted, use binary search to find the
393 // index in the parameter array where 'v' is located.
394 const Int32 max_end = nbElement();
395 begin = 0;
396 end = max_end;
397 Comparer<T> comp;
398 SmallVariant v2(v);
399 ConstArrayView<SmallVariant> params = m_p->m_param_list;
400 auto iter = std::lower_bound(params.begin(), params.end(), v2, comp);
401 Int32 pos = static_cast<Int32>(iter - params.begin());
402 // Increase the interval to ensure that boundary cases where the value is
403 // close to a value stored in \a params are handled.
404 begin = pos - 2;
405 end = pos + 2;
406 begin = std::clamp(begin, 0, max_end);
407 end = std::clamp(end, 0, max_end);
408}
409
410/*---------------------------------------------------------------------------*/
411/*---------------------------------------------------------------------------*/
412
413void CaseTableParams::
414getRange(Real v, Int32& begin, Int32& end) const
415{
416 _getRange(v, begin, end);
417}
418
419/*---------------------------------------------------------------------------*/
420/*---------------------------------------------------------------------------*/
421
422void CaseTableParams::
423getRange(Integer v, Int32& begin, Int32& end) const
424{
425 _getRange(v, begin, end);
426}
427
428/*---------------------------------------------------------------------------*/
429/*---------------------------------------------------------------------------*/
430
431template class CFParamSetterT<Real>;
432template class CFParamSetterT<Integer>;
433
434/*---------------------------------------------------------------------------*/
435/*---------------------------------------------------------------------------*/
436
437} // namespace Arcane
438
439/*---------------------------------------------------------------------------*/
440/*---------------------------------------------------------------------------*/
#define ARCANE_THROW(exception_class,...)
Macro for throwing an exception with formatting.
eError
Types of errors returned by the class.
Definition CaseTable.h:48
@ ErrCanNotConvertParamToRightType
Indicates that converting the parameter to the desired type is impossible.
Definition CaseTable.h:53
@ ErrNotGreaterThanPrevious
Indicates that the parameter is not greater than the previous one.
Definition CaseTable.h:57
@ ErrNotLesserThanNext
Indicates that the parameter is not less than the next one.
Definition CaseTable.h:59
eParamType
Type of a function parameter.
@ ParamUnknown
Unknown parameter type.
@ ParamReal
Real type parameter.
@ ParamInteger
Integer type parameter.
Class managing a polymorphic type.
1D data vector with value semantics (STL style).
Integer toInteger(Real r)
Converts a Real to Integer.
double toDouble(Real r)
Converts a Real to double.
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
Int32 Integer
Type representing an integer.
double Real
Type representing a real number.
std::int32_t Int32
Signed integer type of 32 bits.