Cantera
Install
User Guide
Examples
Reference
Develop
Community
4.0.0a2
Toggle main menu visibility
Loading...
Searching...
No Matches
Cabinet.h
Go to the documentation of this file.
1
/**
2
* @file Cabinet.h
3
*/
4
5
// This file is part of Cantera. See License.txt in the top-level directory or
6
// at https://cantera.org/license.txt for license and copyright information.
7
8
#ifndef CT_CABINET_H
9
#define CT_CABINET_H
10
11
#include "
cantera/base/ctexceptions.h
"
12
#include "
cantera/base/utilities.h
"
13
#include <unordered_map>
14
15
namespace
Cantera
{
16
17
/**
18
* Template for classes to hold pointers to objects. The Cabinet<M> class
19
* maintains a list of pointers to objects of class M (or of subclasses of M). These
20
* classes are used by the 'CLib' interface library functions that provide access to
21
* %Cantera C++ objects from outside C++. To refer to an existing object, the library
22
* functions take an integer argument that specifies the location in the pointer list
23
* maintained by the appropriate Cabinet<M> instance. The pointer is retrieved
24
* from the list by the interface function, the desired method is invoked, and the
25
* result returned to the non-C++ calling procedure. By storing the pointers in a
26
* Cabinet, there is no need to encode them in a string or integer and pass
27
* them out to the non-C++ calling routine, as some other interfacing schemes do.
28
*
29
* The Cabinet<M> class can be used to store pointers to arbitrary objects. In
30
* most cases, class M is a base class with virtual methods, and the base class versions
31
* of the methods throw CanteraError exceptions. The subclasses overload these methods
32
* to implement the desired functionality. Class Cabinet<M> stores only the
33
* base-class pointers, but since the methods are virtual, the method of the appropriate
34
* subclass will be invoked.
35
*
36
* As the Cabinet<M> class uses smart pointers, it is set up to allow deleting
37
* objects in an inherently safe manner. Method 'del' does the following. If called
38
* with n >= 0, it dereferences the object. The original object is only destroyed if the
39
* reference is not shared by other objects. In this way, if it is deleted again
40
* inadvertently nothing happens, and if an attempt is made to reference the object by
41
* its index number, a standard exception is thrown.
42
*
43
* The Cabinet<M> class is implemented as a singleton. The constructor is never
44
* explicitly called; instead, static function Cabinet<M>::Cabinet() is
45
* called to obtain a pointer to the instance. This function calls the constructor on
46
* the first call and stores the pointer to this instance. Subsequent calls simply
47
* return the already-created pointer.
48
*/
49
template
<
class
M>
50
class
Cabinet
51
{
52
public
:
53
typedef
vector<shared_ptr<M>>& dataRef;
54
typedef
std::unordered_map<const M*, set<int>>& lookupRef;
55
56
/**
57
* Constructor.
58
*/
59
Cabinet
() {}
60
61
/**
62
* Add a new object. The index of the object is returned.
63
*/
64
static
int
add
(shared_ptr<M> obj) {
65
dataRef data =
getData
();
66
data.push_back(obj);
67
int
idx =
static_cast<
int
>
(data.size()) - 1;
68
lookupRef lookup =
getLookup
();
69
if
(lookup.count(obj.get())) {
70
lookup[obj.get()].insert(idx);
71
}
else
{
72
lookup[obj.get()] = {idx};
73
}
74
return
idx;
75
}
76
77
/**
78
* Return cabinet size.
79
*/
80
static
int
size
() {
81
return
static_cast<
int
>
(
getData
().size());
82
}
83
84
/**
85
* Delete all objects and erase mapping.
86
*/
87
static
int
reset
() {
88
getData
().clear();
89
getLookup
().clear();
90
return
0;
91
}
92
93
/**
94
* Delete the nth object.
95
*/
96
static
void
del
(
int
n) {
97
dataRef data =
getData
();
98
if
(n >= 0 && n <
len
(data)) {
99
lookupRef lookup =
getLookup
();
100
if
(!lookup.count(data[n].get())) {
101
throw
CanteraError
(
"Cabinet::del"
,
102
"Lookup table does not contain reference to object."
);
103
}
104
if
(lookup[data[n].get()].
size
() == 1) {
105
// set only contains one index
106
lookup.erase(data[n].get());
107
}
else
{
108
// remove index n from the reverse lookup table
109
lookup[data[n].get()].erase(n);
110
}
111
data[n].reset();
112
}
else
{
113
throw
CanteraError
(
"Cabinet::del"
,
114
"Attempt made to delete a non-existing object."
);
115
}
116
}
117
118
/**
119
* Return a shared pointer to object n.
120
*/
121
static
shared_ptr<M>&
at
(
int
n) {
122
dataRef data =
getData
();
123
if
(n < 0 || n >=
len
(data)) {
124
throw
CanteraError
(
"Cabinet::at"
,
"Index {} out of range."
, n);
125
}
126
if
(!data[n]) {
127
throw
CanteraError
(
"Cabinet::at"
,
128
"Object with index {} has been deleted."
, n);
129
}
130
return
data[n];
131
}
132
133
/**
134
* Return object n, cast to the specified type.
135
*/
136
template
<
class
T>
137
static
shared_ptr<T>
as
(
int
n) {
138
auto
obj = std::dynamic_pointer_cast<T>(
at
(n));
139
if
(obj) {
140
return
obj;
141
}
142
throw
CanteraError
(
"Cabinet::as"
,
"Item is not of the correct type."
);
143
}
144
145
private
:
146
/**
147
* Static function that returns a pointer to the data member of
148
* the singleton Cabinet<M> instance. All member functions should
149
* access the data through this function.
150
*/
151
static
dataRef
getData
() {
152
if
(
s_storage
==
nullptr
) {
153
s_storage
=
new
Cabinet<M>
();
154
}
155
return
s_storage
->m_table;
156
}
157
158
/**
159
* Static function that returns a pointer to the reverse lookup table of
160
* the singleton Cabinet<M> instance. All member functions should
161
* access the lookup table through this function.
162
*/
163
static
lookupRef
getLookup
() {
164
if
(
s_storage
==
nullptr
) {
165
s_storage
=
new
Cabinet<M>
();
166
}
167
return
s_storage
->m_lookup;
168
}
169
170
/**
171
* Pointer to the single instance of this class.
172
*/
173
static
Cabinet<M>
*
s_storage
;
174
175
/**
176
* Reverse lookup table for the single instance of this class.
177
*/
178
std::unordered_map<const M*, set<int>>
m_lookup
;
179
180
/**
181
* List to hold pointers to objects.
182
*/
183
vector<shared_ptr<M>>
m_table
;
184
};
185
186
}
187
188
#endif
Cantera::Cabinet::getLookup
static lookupRef getLookup()
Static function that returns a pointer to the reverse lookup table of the singleton Cabinet<M> instan...
Definition
Cabinet.h:163
Cantera::Cabinet::s_storage
static Cabinet< M > * s_storage
Pointer to the single instance of this class.
Definition
Cabinet.h:173
Cantera::Cabinet::at
static shared_ptr< M > & at(int n)
Return a shared pointer to object n.
Definition
Cabinet.h:121
Cantera::Cabinet::reset
static int reset()
Delete all objects and erase mapping.
Definition
Cabinet.h:87
Cantera::Cabinet::m_lookup
std::unordered_map< const M *, set< int > > m_lookup
Reverse lookup table for the single instance of this class.
Definition
Cabinet.h:178
Cantera::Cabinet::del
static void del(int n)
Delete the nth object.
Definition
Cabinet.h:96
Cantera::Cabinet::Cabinet
Cabinet()
Constructor.
Definition
Cabinet.h:59
Cantera::Cabinet::add
static int add(shared_ptr< M > obj)
Add a new object.
Definition
Cabinet.h:64
Cantera::Cabinet::getData
static dataRef getData()
Static function that returns a pointer to the data member of the singleton Cabinet<M> instance.
Definition
Cabinet.h:151
Cantera::Cabinet::as
static shared_ptr< T > as(int n)
Return object n, cast to the specified type.
Definition
Cabinet.h:137
Cantera::Cabinet::size
static int size()
Return cabinet size.
Definition
Cabinet.h:80
Cantera::Cabinet::m_table
vector< shared_ptr< M > > m_table
List to hold pointers to objects.
Definition
Cabinet.h:183
Cantera::CanteraError
Base class for exceptions thrown by Cantera classes.
Definition
ctexceptions.h:66
ctexceptions.h
Definitions for the classes that are thrown when Cantera experiences an error condition (also contain...
Cantera::len
U len(const T &container)
Get the size of a container, cast to a signed integer type.
Definition
utilities.h:231
Cantera
Namespace for the Cantera kernel.
Definition
AnyMap.cpp:595
utilities.h
Various templated functions that carry out common vector and polynomial operations (see Templated Arr...
interfaces
clib
src
Cabinet.h
Generated by
1.17.0