NCBI C++ ToolKit
enumerated.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: enumerated.cpp 99879 2023-05-18 17:35:50Z vasilche $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Eugene Vasilchenko
27 *
28 * File Description:
29 * !!! PUT YOUR DESCRIPTION HERE !!!
30 */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbistd.hpp>
34 #include <corelib/ncbiutil.hpp>
35 #include <corelib/ncbithr.hpp>
36 #include <serial/enumvalues.hpp>
38 #include <serial/serialutil.hpp>
39 #include <serial/objistr.hpp>
40 #include <serial/objostr.hpp>
41 #include <serial/objcopy.hpp>
42 #include <common/ncbi_sanitizers.h>
43 
44 
46 
48  bool isInteger)
49  : m_Name(name),
50  m_Integer(isInteger),
51  m_IsBitset(false), m_IsInternal(false),
52  m_NameToValue(0),
53  m_ValueToName(0)
54 {
55 }
56 
58  bool isInteger)
59  : m_Name(name),
60  m_Integer(isInteger),
61  m_IsBitset(false), m_IsInternal(false),
62  m_NameToValue(0),
63  m_ValueToName(0)
64 {
65 }
66 
68 {
69  ClearIndexes();
70 }
71 
72 
74 {
75  delete m_ValueToName.exchange(nullptr);
76  delete m_NameToValue.exchange(nullptr);
77 }
78 
79 const string& CEnumeratedTypeValues::GetName(void) const
80 {
81  return IsInternal()? kEmptyStr: m_Name;
82 }
83 
84 const string& CEnumeratedTypeValues::GetModuleName(void) const
85 {
87 }
88 
89 void CEnumeratedTypeValues::SetModuleName(const string& name)
90 {
91  if ( !m_ModuleName.empty() )
92  NCBI_THROW(CSerialException,eFail,"cannot change module name: " + m_ModuleName + " to " + name);
93  m_ModuleName = name;
94 }
95 
96 const string& CEnumeratedTypeValues::GetInternalName(void) const
97 {
98  return !IsInternal()? kEmptyStr: m_Name;
99 }
100 
102 {
103  return !IsInternal()? kEmptyStr: m_ModuleName;
104 }
105 
107 {
108  if ( IsInternal() || !m_Name.empty() || !m_ModuleName.empty() )
109  NCBI_THROW(CSerialException,eFail, "cannot change (internal) name to " + name);
110  m_IsInternal = true;
111  m_Name = name;
112 }
113 
114 const string& CEnumeratedTypeValues::GetAccessName(void) const
115 {
116  return m_Name;
117 }
118 
120 {
121  return m_ModuleName;
122 }
123 
125 {
126  const TNameToValue& m = NameToValue();
128  if ( i == m.end() ) {
129  string name_alt = string(name);
130  name_alt[0] = (char)toupper((unsigned char)name_alt[0]);
131  i = m.find(name_alt);
132  if ( i == m.end() ) {
133  NCBI_THROW(CSerialException,eInvalidData,
134  "invalid value of enumerated type: " + string(name));
135  }
136  }
137  return i->second;
138 }
139 
141 {
142  const TNameToValue& m = NameToValue();
143  return ( m.find(name) != m.end() );
144 }
145 
147  bool allowBadValue) const
148 {
149  const TValueToName& m = ValueToName();
151  if ( i == m.end() ) {
152  if ( allowBadValue ) {
153  return NcbiEmptyString;
154  }
155  else {
156  NCBI_THROW(CSerialException,eInvalidData,
157  "invalid value of enumerated type: " + NStr::NumericToString(value));
158  }
159  }
160  return *i->second;
161 }
162 
164  bool allowBadValue) const
165 {
166  if ((GetValueFlags(value) & eHideName) != 0) {
167  return kEmptyStr;
168  }
169  return FindName( value, allowBadValue);
170 }
171 
173 {
174  string res;
175  if (IsBitset()) {
176  TEnumValueType v = value;
177  const TValueToName& m = ValueToName();
178  TValueToName::const_reverse_iterator i = m.rbegin();
179  for (i = m.rbegin(); i != m.rend(); ++i) {
180  if ((i->first & v) == i->first) {
181  if (!res.empty()) {
182  res.insert(0,",");
183  }
184  res.insert(0,*(i->second));
185  v -= i->first;
186  }
187  }
188  if (v) {
189  if (!res.empty()) {
190  res += ',';
191  }
192  res += NStr::NumericToString(v);
193  }
194 
195  } else {
196  res = FindName(value, true);
197  }
198  if (res.empty()) {
200  }
201  return res;
202 }
203 
204 void CEnumeratedTypeValues::AddValue(const string& name,
206 {
207  if ( name.empty() ) {
208  NCBI_THROW(CSerialException,eInvalidData,
209  "empty enum value name");
210  }
211  m_Values.push_back(make_pair(name, value));
213  ClearIndexes();
214 }
215 
216 
219 {
221  return i != m_ValueFlags.end() ? i->second : eNone;
222 }
223 
224 DEFINE_STATIC_FAST_MUTEX(s_EnumValuesMutex);
225 
228 {
229  TValueToName* m = m_ValueToName.load(memory_order_acquire);
230  if ( !m ) {
231  CFastMutexGuard GUARD(s_EnumValuesMutex);
232  m = m_ValueToName.load(memory_order_acquire);
233  if ( !m ) {
235  unique_ptr<TValueToName> keep(m = new TValueToName);
236  ITERATE ( TValues, i, m_Values ) {
237  (*m)[i->second] = &i->first;
238  }
239  m_ValueToName.store(keep.release(), memory_order_release);
240  }
241  }
242  return *m;
243 }
244 
247 {
248  TNameToValue* m = m_NameToValue.load(memory_order_acquire);
249  if ( !m ) {
250  CFastMutexGuard GUARD(s_EnumValuesMutex);
251  m = m_NameToValue.load(memory_order_acquire);
252  if ( !m ) {
254  unique_ptr<TNameToValue> keep(m = new TNameToValue);
255  ITERATE ( TValues, i, m_Values ) {
256  const string& s = i->first;
257  pair<TNameToValue::iterator, bool> p =
258  m->insert(TNameToValue::value_type(s, i->second));
259  if ( !p.second ) {
260  NCBI_THROW(CSerialException,eInvalidData,
261  "duplicate enum value name: " + s);
262  }
263  }
264  m_NameToValue.store(keep.release(), memory_order_release);
265  }
266  }
267  return *m;
268 }
269 
270 void CEnumeratedTypeValues::AddValue(const char* name,
272 {
273  AddValue(string(name), value, flags);
274 }
275 
277  const CEnumeratedTypeValues* values,
278  bool sign)
279  : CParent(size, values->GetName(), ePrimitiveValueEnum, sign),
280  m_ValueType(CPrimitiveTypeInfo::GetIntegerTypeInfo(size, sign)),
281  m_Values(*values)
282 {
285  if ( values->IsInternal() )
286  SetInternalName(values->GetInternalName());
287  const string& module_name = values->GetAccessModuleName();
288  if ( !module_name.empty() )
289  SetModuleName(module_name);
295 }
296 
298 {
299  return m_ValueType->IsDefault(object);
300 }
301 
303  ESerialRecursionMode how) const
304 {
305  return m_ValueType->Equals(object1, object2, how);
306 }
307 
309 {
310  m_ValueType->SetDefault(dst);
311 }
312 
314  ESerialRecursionMode how) const
315 {
316  m_ValueType->Assign(dst, src, how);
317 }
318 
320 {
321  return m_ValueType->IsSigned();
322 }
323 
325 {
326  return m_ValueType->GetValueInt4(objectPtr);
327 }
328 
330 {
331  return m_ValueType->GetValueUint4(objectPtr);
332 }
333 
335 {
336  if ( !Values().IsInteger() ) {
337  // check value for acceptance
338  _ASSERT(sizeof(TEnumValueType) == sizeof(value));
340  Values().FindName(v, false);
341  }
342  m_ValueType->SetValueInt4(objectPtr, value);
343 }
344 
346  Uint4 value) const
347 {
348  if ( !Values().IsInteger() ) {
349  // check value for acceptance
350  _ASSERT(sizeof(TEnumValueType) == sizeof(value));
352  if ( v < 0 ) {
353  NCBI_THROW(CSerialException,eOverflow,"overflow error");
354  }
355  Values().FindName(v, false);
356  }
357  m_ValueType->SetValueUint4(objectPtr, value);
358 }
359 
361 {
362  return m_ValueType->GetValueInt8(objectPtr);
363 }
364 
366 {
367  return m_ValueType->GetValueUint8(objectPtr);
368 }
369 
371 {
372  if ( !Values().IsInteger() ) {
373  // check value for acceptance
374  _ASSERT(sizeof(TEnumValueType) < sizeof(value));
376  if ( v != value )
377  NCBI_THROW(CSerialException,eOverflow,"overflow error");
378  Values().FindName(v, false);
379  }
380  m_ValueType->SetValueInt8(objectPtr, value);
381 }
382 
384  Uint8 value) const
385 {
386  if ( !Values().IsInteger() ) {
387  // check value for acceptance
388  _ASSERT(sizeof(TEnumValueType) < sizeof(value));
390  if ( v < 0 || Uint8(v) != value )
391  NCBI_THROW(CSerialException,eOverflow,"overflow error");
392  Values().FindName(v, false);
393  }
394  m_ValueType->SetValueUint8(objectPtr, value);
395 }
396 
398  string& value) const
399 {
400  value = Values().FindName(m_ValueType->GetValueInt(objectPtr), false);
401 }
402 
404  const string& value) const
405 {
406  m_ValueType->SetValueInt(objectPtr, Values().FindValue(value));
407 }
408 
410  CObjectMemoryPool* /*memoryPool*/)
411 {
412  const CEnumeratedTypeInfo* enumType =
414  return enumType->m_ValueType->Create();
415 }
416 
418  TTypeInfo objectType,
419  TObjectPtr objectPtr)
420 {
421  const CEnumeratedTypeInfo* enumType =
423  try {
424  enumType->m_ValueType->SetValueInt(objectPtr,
425  in.ReadEnum(enumType->Values()));
426  }
427  catch ( CException& e ) {
428  NCBI_RETHROW_SAME(e,"invalid enum value");
429  }
430  catch ( ... ) {
431  in.ThrowError(in.fInvalidData,"invalid enum value");
432  }
433 }
434 
436  TTypeInfo objectType,
437  TConstObjectPtr objectPtr)
438 {
439  const CEnumeratedTypeInfo* enumType =
441  try {
442  out.WriteEnum(enumType->Values(),
443  enumType->m_ValueType->GetValueInt(objectPtr));
444  }
445  catch ( CException& e ) {
446  NCBI_RETHROW_SAME(e,"invalid enum value");
447  }
448  catch ( ... ) {
449  out.ThrowError(out.fInvalidData,"invalid enum value");
450  }
451 }
452 
454  TTypeInfo objectType)
455 {
456  const CEnumeratedTypeInfo* enumType =
458  try {
459  copier.Out().CopyEnum(enumType->Values(), copier.In());
460  }
461  catch ( CException& e ) {
462  NCBI_RETHROW_SAME(e,"invalid enum value");
463  }
464  catch ( ... ) {
465  copier.ThrowError(CObjectIStream::fInvalidData,"invalid enum value");
466  }
467 }
468 
470  TTypeInfo objectType)
471 {
472  const CEnumeratedTypeInfo* enumType =
474  try {
475  in.ReadEnum(enumType->Values());
476  }
477  catch ( CException& e ) {
478  NCBI_RETHROW_SAME(e,"invalid enum value");
479  }
480  catch ( ... ) {
481  in.ThrowError(in.fInvalidData,"invalid enum value");
482  }
483 }
484 
CObjectIStream –.
Definition: objistr.hpp:93
CObjectOStream –.
Definition: objostr.hpp:83
CObjectStreamCopier –.
Definition: objcopy.hpp:71
Root class for all serialization exceptions.
Definition: exception.hpp:50
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTypeInfo class contains all information about C++ types (both basic and classes): members and layout...
Definition: typeinfo.hpp:76
container_type::const_iterator const_iterator
Definition: map.hpp:53
const_iterator end() const
Definition: map.hpp:152
iterator_bool insert(const value_type &val)
Definition: map.hpp:165
container_type::value_type value_type
Definition: map.hpp:52
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
Include a standard set of the NCBI C++ Toolkit most basic headers.
static uch flags
DEFINE_STATIC_FAST_MUTEX(s_EnumValuesMutex)
std::ofstream out("events_result.xml")
main entry point for tests
#define false
Definition: bool.h:36
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
string
Definition: cgiapp.hpp:687
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
#define NCBI_RETHROW_SAME(prev_exception, message)
Generic macro to re-throw the same exception.
Definition: ncbiexpt.hpp:749
void AddValue(const string &name, TEnumValueType value, TValueFlags flags=eNone)
Add name-value pair.
Definition: enumerated.cpp:204
const string & FindName(TEnumValueType value, bool allowBadValue) const
Find name of the enum by its numeric value.
Definition: enumerated.cpp:146
const string & GetAccessName(void) const
Return internal or regular name.
Definition: enumerated.cpp:114
list< pair< string, TEnumValueType > > TValues
Definition: enumvalues.hpp:54
bool IsInternal(void) const
Check if this enum describes internal unnamed type.
Definition: enumvalues.hpp:81
TValueFlags GetValueFlags(TEnumValueType) const
Definition: enumerated.cpp:218
void SetModuleName(const string &name)
Set ASN.1 module name.
Definition: enumerated.cpp:89
bool IsBitset(void) const
Definition: enumvalues.hpp:147
const string & GetModuleName(void) const
Get ASN.1 module name.
Definition: enumerated.cpp:84
void ClearIndexes(void)
Definition: enumerated.cpp:73
void SetInternalName(const string &name)
Mark this enum as internal.
Definition: enumerated.cpp:106
const TNameToValue & NameToValue(void) const
Get name-to-value map.
Definition: enumerated.cpp:246
atomic< TValueToName * > m_ValueToName
Definition: enumvalues.hpp:164
unsigned int TValueFlags
Binary OR of EValueFlags.
Definition: enumvalues.hpp:62
map< TEnumValueType, TValueFlags > m_ValueFlags
Definition: enumvalues.hpp:162
bool IsValidName(const CTempString &name) const
Check whether enum with this name is defined.
Definition: enumerated.cpp:140
const string & GetInternalModuleName(void) const
Return internal type's owner module name.
Definition: enumerated.cpp:101
TEnumValueType FindValue(const CTempString &name) const
Find numeric value by the name of the enum.
Definition: enumerated.cpp:124
const string & GetName(void) const
Definition: enumerated.cpp:79
const string & GetInternalName(void) const
Return internal type access string e.g. Int-fuzz.lim.
Definition: enumerated.cpp:96
string GetDisplayName(TEnumValueType value) const
Definition: enumerated.cpp:172
const TValueToName & ValueToName(void) const
Get value-to-name map.
Definition: enumerated.cpp:227
const string & FindNameEx(TEnumValueType value, bool allowBadValue) const
Definition: enumerated.cpp:163
const string & GetAccessModuleName(void) const
Return internal or regular module name.
Definition: enumerated.cpp:119
CEnumeratedTypeValues(const char *name, bool isInteger)
Definition: enumerated.cpp:47
atomic< TNameToValue * > m_NameToValue
Definition: enumvalues.hpp:163
ESerialRecursionMode
How to assign and compare child sub-objects of serial objects.
Definition: serialdef.hpp:191
void * TObjectPtr
Definition: serialdef.hpp:55
int TEnumValueType
Definition: serialdef.hpp:232
const void * TConstObjectPtr
Definition: serialdef.hpp:59
static const TObjectType * SafeCast(TTypeInfo type)
Definition: serialutil.hpp:76
@ ePrimitiveValueInteger
(signed|unsigned) (char|short|int|long)
Definition: serialdef.hpp:151
@ ePrimitiveValueEnum
enum
Definition: serialdef.hpp:154
CObjectIStream & In(void) const
CObjectOStream & Out(void) const
virtual void CopyEnum(const CEnumeratedTypeValues &values, CObjectIStream &in)=0
@ fInvalidData
Input data is incorrect (e.g. invalid enum)
Definition: objistr.hpp:381
int32_t Int4
4-byte (32-bit) signed integer
Definition: ncbitype.h:102
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
#define NcbiEmptyString
Definition: ncbistr.hpp:122
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
void SetWriteFunction(TTypeWriteFunction func)
Definition: typeinfo.cpp:487
static void WriteEnum(CObjectOStream &out, TTypeInfo objectType, TConstObjectPtr objectPtr)
Definition: enumerated.cpp:435
virtual void SetValueInt8(TObjectPtr objectPtr, Int8 value) const override
Definition: enumerated.cpp:370
virtual bool Equals(TConstObjectPtr, TConstObjectPtr, ESerialRecursionMode how=eRecursive) const override
Check if both objects contain the same values.
Definition: enumerated.cpp:302
virtual void SetDefault(TObjectPtr dst) const override
Set object to default value.
Definition: enumerated.cpp:308
virtual bool IsSigned(void) const override
Definition: enumerated.cpp:319
void SetValueInt(TObjectPtr objectPtr, int value) const
virtual bool IsDefault(TConstObjectPtr object) const override
Check, whether the object contains default value.
Definition: stdtypes.cpp:383
virtual Uint4 GetValueUint4(TConstObjectPtr objectPtr) const
Definition: stdtypes.cpp:433
virtual bool Equals(TConstObjectPtr, TConstObjectPtr, ESerialRecursionMode how=eRecursive) const override
Check if both objects contain the same values.
Definition: stdtypes.cpp:393
static TObjectPtr CreateEnum(TTypeInfo objectType, CObjectMemoryPool *memoryPool)
Definition: enumerated.cpp:409
virtual void SetDefault(TObjectPtr dst) const override
Set object to default value.
Definition: stdtypes.cpp:388
int GetValueInt(TConstObjectPtr objectPtr) const
virtual void SetValueString(TObjectPtr objectPtr, const string &value) const override
Definition: enumerated.cpp:403
EPrimitiveValueType GetPrimitiveValueType(void) const
virtual Uint4 GetValueUint4(TConstObjectPtr objectPtr) const override
Definition: enumerated.cpp:329
virtual void SetValueInt8(TObjectPtr objectPtr, Int8 value) const
Definition: stdtypes.cpp:451
virtual void SetValueInt4(TObjectPtr objectPtr, Int4 value) const
Definition: stdtypes.cpp:427
CEnumeratedTypeInfo(size_t size, const CEnumeratedTypeValues *values, bool sign=false)
Definition: enumerated.cpp:276
virtual CTypeInfo * SetTag(CAsnBinaryDefs::TLongTag tag, CAsnBinaryDefs::ETagClass tagclass=CAsnBinaryDefs::eUniversal, CAsnBinaryDefs::ETagType tagtype=CAsnBinaryDefs::eAutomatic)
Definition: typeinfo.cpp:172
void SetModuleName(const string &name)
Set module name.
Definition: typeinfo.cpp:259
static void CopyEnum(CObjectStreamCopier &copier, TTypeInfo objectType)
Definition: enumerated.cpp:453
virtual void SetValueUint8(TObjectPtr objectPtr, Uint8 value) const override
Definition: enumerated.cpp:383
const CPrimitiveTypeInfo * m_ValueType
Definition: enumerated.hpp:97
virtual void GetValueString(TConstObjectPtr objectPtr, string &value) const override
Definition: enumerated.cpp:397
virtual Int4 GetValueInt4(TConstObjectPtr objectPtr) const
Definition: stdtypes.cpp:421
virtual Int8 GetValueInt8(TConstObjectPtr objectPtr) const override
Definition: enumerated.cpp:360
void SetInternalName(const string &name)
Mark this type as internal.
Definition: typeinfo.cpp:281
virtual Int4 GetValueInt4(TConstObjectPtr objectPtr) const override
Definition: enumerated.cpp:324
virtual void SetValueUint4(TObjectPtr objectPtr, Uint4 value) const override
Definition: enumerated.cpp:345
virtual void Assign(TObjectPtr dst, TConstObjectPtr src, ESerialRecursionMode how=eRecursive) const override
Set object to copy of another one.
Definition: enumerated.cpp:313
void SetSkipFunction(TTypeSkipFunction func)
Definition: typeinfo.cpp:497
static void ReadEnum(CObjectIStream &in, TTypeInfo objectType, TObjectPtr objectPtr)
Definition: enumerated.cpp:417
virtual void SetValueUint8(TObjectPtr objectPtr, Uint8 value) const
Definition: stdtypes.cpp:463
virtual void SetValueUint4(TObjectPtr objectPtr, Uint4 value) const
Definition: stdtypes.cpp:439
virtual void Assign(TObjectPtr dst, TConstObjectPtr src, ESerialRecursionMode how=eRecursive) const override
Set object to copy of another one.
Definition: stdtypes.cpp:399
virtual bool IsSigned(void) const
void SetCreateFunction(TTypeCreate func)
Definition: typeinfo.cpp:355
virtual Uint8 GetValueUint8(TConstObjectPtr objectPtr) const override
Definition: enumerated.cpp:365
static void SkipEnum(CObjectIStream &in, TTypeInfo objectType)
Definition: enumerated.cpp:469
virtual void SetValueInt4(TObjectPtr objectPtr, Int4 value) const override
Definition: enumerated.cpp:334
virtual bool IsDefault(TConstObjectPtr object) const override
Check, whether the object contains default value.
Definition: enumerated.cpp:297
void SetCopyFunction(TTypeCopyFunction func)
Definition: typeinfo.cpp:492
const CEnumeratedTypeValues & Values(void) const
Definition: enumerated.hpp:57
virtual Int8 GetValueInt8(TConstObjectPtr objectPtr) const
Definition: stdtypes.cpp:445
TObjectPtr Create(CObjectMemoryPool *memoryPool=0) const
Create object of this type on heap (can be deleted by operator delete)
virtual Uint8 GetValueUint8(TConstObjectPtr objectPtr) const
Definition: stdtypes.cpp:457
void SetReadFunction(TTypeReadFunction func)
Definition: typeinfo.cpp:477
int i
const struct ncbi::grid::netcache::search::fields::SIZE size
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
Common macro to detect used sanitizers and suppress memory leaks if run under LeakSanitizer.
#define NCBI_LSAN_DISABLE_GUARD
int toupper(Uchar c)
Definition: ncbictype.hpp:73
Multi-threading – classes, functions, and features.
Useful/utility classes and methods.
std::istream & in(std::istream &in_, double &x_)
#define _ASSERT
Modified on Sat May 18 11:40:18 2024 by modify_doxy.py rev. 669887