NCBI C++ ToolKit
data_loader.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef OBJECTS_OBJMGR___DATA_LOADER__HPP
2 #define OBJECTS_OBJMGR___DATA_LOADER__HPP
3 
4 /* $Id: data_loader.hpp 98733 2022-12-28 15:46:44Z vasilche $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Aleksey Grichenko, Michael Kimelman, Eugene Vasilchenko
30 *
31 * File Description:
32 * Data loader base class for object manager
33 *
34 */
35 
36 #include <corelib/ncbiobj.hpp>
37 #include <util/range.hpp>
39 #include <objmgr/annot_name.hpp>
41 #include <objmgr/impl/tse_lock.hpp>
42 #include <objmgr/blob_id.hpp>
43 
45 #include <objects/seq/Seq_inst.hpp>
47 #include <set>
48 #include <map>
49 
52 
53 /** @addtogroup ObjectManagerCore
54  *
55  * @{
56  */
57 
58 
59 // fwd decl
60 class CDataSource;
61 class CTSE_Info;
62 class CTSE_Chunk_Info;
63 class CBioseq_Info;
64 class IEditSaver;
65 struct SAnnotSelector;
66 class CScope_Impl;
67 
68 /////////////////////////////////////////////////////////////////////////////
69 // structure to describe required data set
70 //
71 
73 {
85  };
86  typedef int TAnnotBlobType;
87 
89  : m_NeedSeqMap(TRange::GetEmpty()),
90  m_NeedSeqData(TRange::GetEmpty()),
92  {
93  }
94 
99 };
100 
101 
102 /////////////////////////////////////////////////////////////////////////////
103 // Template for data loader construction.
105 {
106 public:
107  // Virtual method for creating an instance of the data loader
108  virtual CDataLoader* CreateLoader(void) const = 0;
109 
110  virtual ~CLoaderMaker_Base(void) {}
111 
112 protected:
114  string m_Name;
116 
117  friend class CObjectManager;
118 };
119 
120 
121 // Construction of data loaders without arguments
122 template <class TDataLoader>
124 {
125 public:
127  {
128  m_Name = TDataLoader::GetLoaderNameFromArgs();
129  }
130 
131  virtual ~CSimpleLoaderMaker(void) {}
132 
133  virtual CDataLoader* CreateLoader(void) const
134  {
135  return new TDataLoader(m_Name);
136  }
139  {
142  return info;
143  }
144 };
145 
146 
147 // Construction of data loaders with an argument. A structure
148 // may be used to create loaders with multiple arguments.
149 template <class TDataLoader, class TParam>
151 {
152 public:
153  typedef TParam TParamType;
154 public:
155  // TParam should have copy method.
156  CParamLoaderMaker(TParam param)
157  : m_Param(param)
158  {
159  m_Name = TDataLoader::GetLoaderNameFromArgs(param);
160  }
161 
162  virtual ~CParamLoaderMaker(void) {}
163 
164  virtual CDataLoader* CreateLoader(void) const
165  {
166  return new TDataLoader(m_Name, m_Param);
167  }
170  {
173  return info;
174  }
175 protected:
176  TParam m_Param;
177 };
178 
179 
180 ////////////////////////////////////////////////////////////////////
181 //
182 // CDataLoader --
183 //
184 // Load data from different sources
185 //
186 
187 // There are three types of blobs (top-level Seq-entries) related to
188 // any Seq-id:
189 // 1. main (eBioseq/eBioseqCore/eSequence):
190 // Seq-entry containing Bioseq with Seq-id.
191 // 2. external (eExtAnnot):
192 // Seq-entry doesn't contain Bioseq but contains annotations on Seq-id,
193 // provided this data source contain some blob with Bioseq.
194 // 3. orphan (eOrphanAnnot):
195 // Seq-entry contains only annotations and this data source doesn't
196 // contain Bioseq with specified Seq-id at all.
197 
199 {
200 protected:
201  CDataLoader(void);
202  CDataLoader(const string& loader_name);
203 
204 public:
205  virtual ~CDataLoader(void);
206 
207 public:
208  /// main blob is blob with sequence
209  /// all other blobs are external and contain external annotations
210  enum EChoice {
211  eBlob, ///< whole main
212  eBioseq, ///< main blob with complete bioseq
213  eCore, ///< ?only seq-entry core?
214  eBioseqCore, ///< main blob with bioseq core (no seqdata and annots)
215  eSequence, ///< seq data
216  eFeatures, ///< features from main blob
217  eGraph, ///< graph annotations from main blob
218  eAlign, ///< aligns from main blob
219  eAnnot, ///< all annotations from main blob
220  eExtFeatures, ///< external features
221  eExtGraph, ///< external graph annotations
222  eExtAlign, ///< external aligns
223  eExtAnnot, ///< all external annotations
224  eOrphanAnnot, ///< all external annotations if no Bioseq exists
225  eAll ///< all blobs (main and external)
226  };
227 
231  typedef vector<TChunk> TChunkSet;
232 
234  static bool IsRequestedAnyNA(const SAnnotSelector* sel);
235  static bool IsRequestedNA(const string& na, const SAnnotSelector* sel);
236  static bool IsProcessedNA(const string& na, const TProcessedNAs* processed_nas);
237  static void SetProcessedNA(const string& na, TProcessedNAs* processed_nas);
238 
239  /// Request from a datasource using handles and ranges instead of seq-loc
240  /// The TSEs loaded in this call will be added to the tse_set.
241  /// The GetRecords() may throw CBlobStateException if the sequence
242  /// is not available (not known or disabled), and blob state
243  /// is different from minimal fState_no_data.
244  /// The actual blob state can be read from the exception in this case.
245  virtual TTSE_LockSet GetRecords(const CSeq_id_Handle& idh,
246  EChoice choice);
247  /// The same as GetRecords() but always returns empty TSE lock set
248  /// instead of throwing CBlobStateException.
249  TTSE_LockSet GetRecordsNoBlobState(const CSeq_id_Handle& idh,
250  EChoice choice);
251  /// Request from a datasource using handles and ranges instead of seq-loc
252  /// The TSEs loaded in this call will be added to the tse_set.
253  /// Default implementation will call GetRecords().
254  virtual TTSE_LockSet GetDetailedRecords(const CSeq_id_Handle& idh,
255  const SRequestDetails& details);
256  /// Request from a datasource set of blobs with external annotations.
257  /// CDataLoader has reasonable default implementation.
258  virtual TTSE_LockSet GetExternalRecords(const CBioseq_Info& bioseq);
259 
260  /// old Get*AnnotRecords() methods
261  virtual TTSE_LockSet GetOrphanAnnotRecords(const CSeq_id_Handle& idh,
262  const SAnnotSelector* sel);
263  virtual TTSE_LockSet GetExternalAnnotRecords(const CSeq_id_Handle& idh,
264  const SAnnotSelector* sel);
265  virtual TTSE_LockSet GetExternalAnnotRecords(const CBioseq_Info& bioseq,
266  const SAnnotSelector* sel);
267 
269  /// new Get*AnnotRecords() methods
270  virtual TTSE_LockSet GetOrphanAnnotRecordsNA(const CSeq_id_Handle& idh,
271  const SAnnotSelector* sel,
272  TProcessedNAs* processed_nas);
273  virtual TTSE_LockSet GetOrphanAnnotRecordsNA(const TSeq_idSet& ids,
274  const SAnnotSelector* sel,
275  TProcessedNAs* processed_nas);
276  virtual TTSE_LockSet GetExternalAnnotRecordsNA(const CSeq_id_Handle& idh,
277  const SAnnotSelector* sel,
278  TProcessedNAs* processed_nas);
279  virtual TTSE_LockSet GetExternalAnnotRecordsNA(const CBioseq_Info& bioseq,
280  const SAnnotSelector* sel,
281  TProcessedNAs* processed_nas);
282 
283  typedef vector<CSeq_id_Handle> TIds;
284  /// Request for a list of all Seq-ids of a sequence.
285  /// The result container should not change if sequence with requested id
286  /// is not known.
287  /// The result must be non-empty for existing sequences
288  virtual void GetIds(const CSeq_id_Handle& idh, TIds& ids);
289 
290  /// helper function to check if sequence exists, uses GetIds()
291  bool SequenceExists(const CSeq_id_Handle& idh);
292 
293  /// Request for a accession.version Seq-id of a sequence.
294  /// Returns null CSeq_id_Handle if sequence with requested id is not known,
295  /// or if existing sequence doesn't have an accession
296  /// @sa GetAccVerFound()
297  virtual CSeq_id_Handle GetAccVer(const CSeq_id_Handle& idh);
298  /// Better replacement of GetAccVer(), this method should be defined in
299  /// data loaders, GetAccVer() is left for compatibility.
300  /// @sa GetAccVer()
301  struct SAccVerFound {
302  bool sequence_found; // true if the sequence is found by data loader
303  CSeq_id_Handle acc_ver; // may be null even for existing sequence
304  SAccVerFound() : sequence_found(false) {}
305  };
306  virtual SAccVerFound GetAccVerFound(const CSeq_id_Handle& idh);
307 
308  /// Request for a gi of a sequence.
309  /// Returns zero gi if sequence with requested id is not known,
310  /// or if existing sequence doesn't have a gi
311  /// @sa GetGiFound()
312  virtual TGi GetGi(const CSeq_id_Handle& idh);
313  /// Better replacement of GetGi(), this method should be defined in
314  /// data loaders, GetGi() is left for compatibility.
315  /// @sa GetGi()
316  struct SGiFound {
317  bool sequence_found; // true if the sequence is found by data loader
318  TGi gi; // may be 0 even for existing sequence
319  SGiFound() : sequence_found(false), gi(ZERO_GI) {}
320  };
321  virtual SGiFound GetGiFound(const CSeq_id_Handle& idh);
322 
323  /// Request for a label string of a sequence.
324  /// Returns empty string if sequence with requested id is not known.
325  /// The result must be non-empty for existing sequences
326  virtual string GetLabel(const CSeq_id_Handle& idh);
327 
328  /// Request for a taxonomy id of a sequence.
329  /// Returns -1 if sequence with requested id is not known.
330  /// Returns 0 if existing sequence doesn't have TaxID
331  virtual TTaxId GetTaxId(const CSeq_id_Handle& idh);
332 
333  /// Request for a length of a sequence.
334  /// Returns kInvalidSeqPos if sequence with requested id is not known.
335  /// The result must not be kInvalidSeqPos for existing sequences
336  virtual TSeqPos GetSequenceLength(const CSeq_id_Handle& idh);
337 
338  /// Request for a type of a sequence
339  /// Returns CSeq_inst::eMol_not_set if sequence is not known
340  /// @sa GetSequenceTypeFound()
341  virtual CSeq_inst::TMol GetSequenceType(const CSeq_id_Handle& idh);
342  /// Better replacement of GetSequenceType(), this method should be
343  /// defined in data loaders, GetSequenceType() is left for compatibility.
344  /// @sa GetSequenceType()
345  struct STypeFound {
346  bool sequence_found; // true if the sequence is found by data loader
347  CSeq_inst::TMol type; // may be eMol_not_set even for existing sequence
348  STypeFound() : sequence_found(false), type(CSeq_inst::eMol_not_set) {}
349  };
350  virtual STypeFound GetSequenceTypeFound(const CSeq_id_Handle& idh);
351 
352  /// Request for a state of a sequence.
353  /// Returns CBioseq_Handle::fState_not_found|fState_no_data if sequence
354  /// with requested id is not known.
355  /// Result mustn't be fState_not_found|fState_no_data if sequence exists
356  virtual int GetSequenceState(const CSeq_id_Handle& idh);
357 
358  /// Request for a sequence hash.
359  /// Returns 0 if the sequence or its hash is not known.
360  /// @sa GetSequenceHashFound()
361  virtual int GetSequenceHash(const CSeq_id_Handle& idh);
362  /// Better replacement of GetSequenceHash(), this method should be
363  /// defined in data loaders, GetSequenceHash() is left for compatibility.
364  /// @sa GetSequenceHash()
365  struct SHashFound {
366  bool sequence_found; // true if the sequence is found by data loader
367  bool hash_known; // true if sequence exists and hash value is set
368  int hash; // may be 0 even for existing sequence
370  : sequence_found(false),
371  hash_known(false),
372  hash(0)
373  {
374  }
375  };
376  virtual SHashFound GetSequenceHashFound(const CSeq_id_Handle& idh);
377 
378  /// Bulk loading interface for a small pieces of information per id.
379  /// The 'loaded' bit set (in/out) marks ids that already processed.
380  /// If an element in 'loaded' is set on input then bulk methods
381  /// should skip corresponding id, as it's already processed.
382  /// Othewise, if the id is known and processed, the 'loaded' element
383  /// will be set to true.
384  /// Othewise, the 'loaded' element will remain false.
385  typedef vector<bool> TLoaded;
386  typedef vector<TGi> TGis;
387  typedef vector<string> TLabels;
388  typedef vector<TTaxId> TTaxIds;
389  typedef vector<TSeqPos> TSequenceLengths;
390  typedef vector<CSeq_inst::TMol> TSequenceTypes;
391  typedef vector<int> TSequenceStates;
392  typedef vector<int> TSequenceHashes;
393  typedef vector<bool> THashKnown;
395  typedef vector<vector<CSeq_id_Handle>> TSeqIdSets;
396  typedef vector<CTSE_Lock> TCDD_Locks;
397 
398  /// Bulk request for accession.version Seq-ids of a set of sequences.
399  virtual void GetAccVers(const TIds& ids, TLoaded& loaded, TIds& ret);
400  /// Bulk request for gis of a set of sequences.
401  virtual void GetGis(const TIds& ids, TLoaded& loaded, TGis& ret);
402  /// Bulk request for label strings of a set of sequences.
403  virtual void GetLabels(const TIds& ids, TLoaded& loaded, TLabels& ret);
404  /// Bulk request for taxonomy ids of a set of sequences.
405  virtual void GetTaxIds(const TIds& ids, TLoaded& loaded, TTaxIds& ret);
406  /// Bulk request for lengths of a set of sequences.
407  virtual void GetSequenceLengths(const TIds& ids, TLoaded& loaded,
408  TSequenceLengths& ret);
409  /// Bulk request for types of a set of sequences.
410  virtual void GetSequenceTypes(const TIds& ids, TLoaded& loaded,
411  TSequenceTypes& ret);
412  /// Bulk request for states of a set of sequences.
413  virtual void GetSequenceStates(const TIds& ids, TLoaded& loaded,
414  TSequenceStates& ret);
415  /// Bulk request for hashes of a set of sequences.
416  virtual void GetSequenceHashes(const TIds& ids, TLoaded& loaded,
417  TSequenceHashes& ret, THashKnown& known);
418  virtual void GetCDDAnnots(const TSeqIdSets& id_sets, TLoaded& loaded, TCDD_Locks& ret);
419 
420  // Load multiple seq-ids. Same as GetRecords() for multiple ids
421  // with choise set to eBlob. The map should be initialized with
422  // the id handles to be loaded.
423  virtual void GetBlobs(TTSE_LockSets& tse_sets);
424 
425  // blob operations
427  typedef int TBlobVersion;
428  virtual TBlobId GetBlobId(const CSeq_id_Handle& idh);
429  virtual TBlobId GetBlobIdFromString(const string& str) const;
430  virtual TBlobVersion GetBlobVersion(const TBlobId& id);
431 
432  virtual bool CanGetBlobById(void) const;
433  virtual TTSE_Lock GetBlobById(const TBlobId& blob_id);
434 
435  virtual SRequestDetails ChoiceToDetails(EChoice choice) const;
436  virtual EChoice DetailsToChoice(const SRequestDetails::TAnnotSet& annots) const;
437  virtual EChoice DetailsToChoice(const SRequestDetails& details) const;
438 
439  virtual void GetChunk(TChunk chunk_info);
440  virtual void GetChunks(const TChunkSet& chunks);
441 
442  //
443  virtual void DropTSE(CRef<CTSE_Info> tse_info);
444 
445  /// Specify datasource to send loaded data to.
446  void SetTargetDataSource(CDataSource& data_source);
447 
448  string GetName(void) const;
449 
450  /// Resolve TSE conflict
451  /// *select the best TSE from the set of dead TSEs.
452  /// *select the live TSE from the list of live TSEs
453  /// and mark the others one as dead.
454  virtual TTSE_Lock ResolveConflict(const CSeq_id_Handle& id,
455  const TTSE_LockSet& tse_set);
456  virtual void GC(void);
457 
459  virtual TEditSaver GetEditSaver() const;
460 
461  virtual CObjectManager::TPriority GetDefaultPriority(void) const;
462 
463  virtual Uint4 EstimateLoadBytes(const CTSE_Chunk_Info& chunk) const;
464  virtual double EstimateLoadSeconds(const CTSE_Chunk_Info& chunk, Uint4 bytes) const;
465 
466  virtual unsigned GetDefaultBlobCacheSizeLimit() const;
467  virtual bool GetTrackSplitSeq() const;
468 
469 protected:
470  /// Register the loader only if the name is not yet
471  /// registered in the object manager
472  static void RegisterInObjectManager(
474  CLoaderMaker_Base& loader_maker,
475  CObjectManager::EIsDefault is_default,
476  CObjectManager::TPriority priority);
477 
478  void SetName(const string& loader_name);
479  CDataSource* GetDataSource(void) const;
480 
482  friend class CScope_Impl;
483 
484 private:
487 
488  string m_Name;
490 
491  friend class CObjectManager;
492 };
493 
494 
495 /* @} */
496 
498 
500 
501 template<>
503 {
504 public:
506  {
507  CPluginManager_DllResolver* resolver =
510  kEmptyStr,
513 
514  resolver->SetDllNamePrefix("ncbi");
515  return resolver;
516  }
517 };
518 
519 
521 
522 #endif // OBJECTS_OBJMGR___DATA_LOADER__HPP
#define false
Definition: bool.h:36
pair< string, int > GetAccVer(const CAlignModel &a, CScope &scope)
Definition: chainer.cpp:6040
Template function to create dll resolver for interface.
CInterfaceVersion<> –.
CObjectManager –.
CObject –.
Definition: ncbiobj.hpp:180
Service class for DLLs resolution.
Edit Saver Interface.
Definition: edit_saver.hpp:72
Definition: set.hpp:45
IEditSaver * GetEditSaver(const Handle &handle)
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
SStrictId_Tax::TId TTaxId
Taxon id type.
Definition: ncbimisc.hpp:1048
#define ZERO_GI
Definition: ncbimisc.hpp:1088
@ eAutoUnload
Definition: ncbidll.hpp:144
string GetLabel(const CSeq_id &id)
TTaxId GetTaxId(const CBioseq_Handle &handle)
return the tax-id associated with a given sequence.
Definition: sequence.cpp:274
virtual CDataLoader * CreateLoader(void) const
SRegisterLoaderInfo< TDataLoader > TRegisterInfo
CParamLoaderMaker(TParam param)
CDataLoader(const CDataLoader &)
TLoader * GetLoader(void) const
Get pointer to the loader.
CRef< IEditSaver > TEditSaver
set< CSeq_id_Handle > TSeq_idSet
set< SAnnotTypeSelector > TAnnotTypesSet
Definition: data_loader.hpp:75
vector< TSeqPos > TSequenceLengths
CDataLoader & operator=(const CDataLoader &)
vector< CTSE_Lock > TCDD_Locks
virtual CDataLoader * CreateLoader(void) const =0
vector< CSeq_id_Handle > TIds
SRegisterLoaderInfo< TDataLoader > TRegisterInfo
CSeq_inst::TMol type
CBlobIdKey TBlobId
virtual ~CParamLoaderMaker(void)
vector< bool > THashKnown
TRegisterInfo GetRegisterInfo(void)
vector< TGi > TGis
virtual CDataLoader * CreateLoader(void) const
virtual ~CSimpleLoaderMaker(void)
TRange m_NeedSeqData
Definition: data_loader.hpp:96
CRef< CTSE_Chunk_Info > TChunk
EChoice
main blob is blob with sequence all other blobs are external and contain external annotations
CPluginManager_DllResolver * operator()(void)
vector< CSeq_inst::TMol > TSequenceTypes
vector< vector< CSeq_id_Handle > > TSeqIdSets
TRegisterInfo_Base m_RegisterInfo
EIsDefault
Flag defining if the data loader is included in the "default" group.
map< CSeq_id_Handle, TTSE_LockSet > TTSE_LockSets
TRegisterInfo GetRegisterInfo(void)
set< string > TProcessedNAs
TAnnotSet m_NeedAnnots
Definition: data_loader.hpp:97
vector< bool > TLoaded
Bulk loading interface for a small pieces of information per id.
CRange< TSeqPos > TRange
Definition: data_loader.hpp:74
bool IsCreated(void) const
Return true if the loader was just created, false if already registered or if the operation failed.
vector< string > TLabels
TAnnotBlobType m_AnnotBlobType
Definition: data_loader.hpp:98
virtual ~CLoaderMaker_Base(void)
SRegisterLoaderInfo< CDataLoader > TRegisterInfo_Base
NCBI_DECLARE_INTERFACE_VERSION(objects::CDataLoader, "xloader", 8, 0, 0)
map< CAnnotName, TAnnotTypesSet > TAnnotSet
Definition: data_loader.hpp:76
vector< TTaxId > TTaxIds
vector< int > TSequenceStates
vector< int > TSequenceHashes
vector< TChunk > TChunkSet
CDataSource * m_DataSource
CTSE_Lock TTSE_Lock
set< TTSE_Lock > TTSE_LockSet
@ eExtFeatures
external features
@ eExtAnnot
all external annotations
@ eExtAlign
external aligns
@ eSequence
seq data
@ eBlob
whole main
@ eOrphanAnnot
all external annotations if no Bioseq exists
@ eGraph
graph annotations from main blob
@ eCore
?only seq-entry core?
@ eAnnot
all annotations from main blob
@ eBioseq
main blob with complete bioseq
@ eAlign
aligns from main blob
@ eBioseqCore
main blob with bioseq core (no seqdata and annots)
@ eExtGraph
external graph annotations
@ eFeatures
features from main blob
virtual void SetDllNamePrefix(const string &prefix)
Set DLL file name prefix.
uint32_t Uint4
4-byte (32-bit) unsigned integer
Definition: ncbitype.h:103
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
#define kEmptyStr
Definition: ncbistr.hpp:123
#define NCBI_XOBJMGR_EXPORT
Definition: ncbi_export.h:1307
EMol
molecule class in living organism
Definition: Seq_inst_.hpp:108
static MDB_envinfo info
Definition: mdb_load.c:37
Portable reference counted smart and weak pointers using CWeakRef, CRef, CObject and CObjectEx.
The Object manager core.
Plugin manager (using class factory paradigm).
static bool GetIds(const T &d, set< string > &labels, const string name="", bool detect=false, bool found=false)
Uint4 GetSequenceType(const CBioseq_Handle &bsh)
Return a (corrected) set of flags identifying the sequence type.
Definition: sequtils.cpp:42
CRef< objects::CObjectManager > om
static const char * str(char *buf, int n)
Definition: stats.c:84
Better replacement of GetAccVer(), this method should be defined in data loaders, GetAccVer() is left...
Better replacement of GetGi(), this method should be defined in data loaders, GetGi() is left for com...
Better replacement of GetSequenceHash(), this method should be defined in data loaders,...
Better replacement of GetSequenceType(), this method should be defined in data loaders,...
SAnnotSelector –.
Definition: _hash_fun.h:40
Definition: type.c:6
Modified on Thu Nov 30 04:57:05 2023 by modify_doxy.py rev. 669887