Peano 4
Loading...
Searching...
No Matches
Attribute.py
Go to the documentation of this file.
1# This file is part of the DaStGen2 project. For conditions of distribution and
2# use, please see the copyright notice at www.peano-framework.org
3import abc
4from enum import Enum
5from dastgen2.Utils import construct_ifdef_string
6
7
8class Attribute(object):
9 """!
10
11 Represents one attribute.
12
13 This is the superclass of all attributes tied
14
15 """
16
17 class Qualifier(Enum):
18 """!
19 classifies attribute qualifiers.
20 """
21
22 NONE = 0
23 STATIC = 1
24 CONST = 2
25 CONST_STATIC = 3
26 CONSTEXPR = 4
27
29 self,
30 name,
31 ifdefs=[],
32 qualifier=Qualifier.NONE,
33 initval=None,
34 expose_in_header_file=False,
35 ):
36 """
37
38 name: String
39 This is a plain string which has to follow the C++ naming conventions, i.e.
40 it is case-sensitive and may not contain any special characters besides the
41 underscore. If also has to be unique within the enclosing data model.
42 However, this uniqueness is a C++ constraint. A DaStGen model can hold the
43 same attribute multiple times, as long as their ifdefs are different and
44 hence mask them out, i.e. ensure that only version is "active" at any
45 compile run.
46
47 ifdefs: [String]
48 A set of strings which have to hold at compile time to determine if this
49 attribute does exist or not.
50
51 qualifier: self.Qualifier
52 An additional qualifier.
53
54 initval: str or None
55 Initial value. The type depends on underlying type. But you can always pass
56 in a string that evaluates to the correct type.
57
58 expose_in_header_file: Boolean
59 Flag that determines if an attribute's setters and getters should have an
60 implementation within the header or if the generated C++ code should strictly
61 separate declaration and definition and stick the latter into a separate
62 implementation and hence object file.
63
64 """
65 self._name = name
66 self.use_data_store = False
67 self.ifdefs = ifdefs
68 self.qualifier = qualifier
69 self._initval = initval
70 self.expose_in_header_file = expose_in_header_file
71
72 if (
73 self._is_const_static or self._is_constexpr or self._is_const
74 ) and self._initval is None:
75 raise ValueError(
76 "Attribute",
77 self._name,
78 ": You need to provide an initialisation value for a const attribute",
79 )
80
81 @property
82 def _is_static(self):
83 return self.qualifier == self.Qualifier.STATIC
84
85 @property
87 return self.qualifier == self.Qualifier.CONST_STATIC
88
89 @property
90 def _is_const(self):
91 return self.qualifier == self.Qualifier.CONST
92
93 @property
94 def _is_constexpr(self):
95 return self.qualifier == self.Qualifier.CONSTEXPR
96
98 """!
99
100 Return string that is to be embedded into the public part of the class
101 definition. Most attributes don't add anything here, but some (alike
102 enumerations) need to.
103
104 """
105 return ""
106
107 @abc.abstractmethod
108 def get_methods(self, _full_qualified_class_name, for_declaration=True):
109 """!
110
111 Return sequence of methods that are defined for this attribute. Each
112 entry is a tuple. Its first entry is the signature of the function
113 (not including the semicolon), the second entry is the return type.
114
115 for_declaration: Boolean
116 if True, assume we want method names for function declaration, not
117 definition. Some generators might - for example - add additional
118 annotations for the declaration such as Clang attributes. The
119 most frequently used use case for this flag is the static
120 annotation. To make a function a class function, you have to
121 declare it as static. But the definition does not allow you to
122 repeat that static keyword again.
123
124 """
125 return
126
128 """!
129
130 If this routine returns False, the generator will create a copy
131 constructor copying each attribute over via a setter/getter
132 combination.
133
134 """
135 return True
136
138 """!
139
140 Return list of tuple of arguments for the constructor. The first
141 tuple entry is the name, the second one the type. By default,
142 I take them from the plain C attributes, but you can alter
143 this behaviour.
144
145 """
146 return self.get_plain_C_attributes(for_constructor=True)
147
148 @abc.abstractmethod
149 def get_plain_C_attributes(self, for_constructor=False):
150 """!
151
152 Return list of n-tuples. The tuple can either host two, three or
153 four entries. The list itself may contain arbitrary many tuples, as
154 one attribute logically can map onto multiple technical attributes.
155 For example, when declaring an array, also declare an integer variable
156 containing its length.
157
158 for_constructor: bool
159 whether the return value of this function is intended for use
160 in the constructor method of the DataModel. If true, will omit
161 (optionally provided) initialization values in the attribute
162 string.
163
164
165 ### Two entries
166
167 The first triple entry always is the name, the second one the type.
168 Type has to be plain C.
169
170 ### Three entries
171
172 The first triple entry always is the name, the second one the type.
173 Type has to be plain C. The third entry is a C++ attribute, i.e.
174 a string embedded into [[...]].
175
176 ### Four entries
177
178 The first triple entry always is the name, the second one the type.
179 Type has to be plain C. The third entry is a C++ attribute, i.e.
180 a string embedded into [[...]].
181 The fourth attribute is a list of ifdef symbols that have to be
182 defined to use this attribute. The list of
183 symbols is concatenated with an and. You can return an empty list.
184 All symbol definitions can also be expressions such sa DEBUG>0
185 or defined(DEBUG).
186
187 Please note that these latter ifdefs are something completely
188 different than the base class ifdefs. The base class ifdefs are
189 to be used if you want to switch attributes on and off. The
190 attributes here are used to switch between realisation variants.
191
192
193 ## Arrays
194
195 Arrays can be modelled by adding a cardinality ("[15]" for example)
196 to the first triple entry, i.e. the name.
197
198 """
199 assert False, "abstract function should not be called"
200 return
201
203 """!
204
205 For MPI for example, I need to know the first attribute. If you map
206 your attribute onto multiple data types, it is one type that represents the whole thing.
207
208 """
209 return self.get_plain_C_attributes()
210
212 """!
213 Construct the string used for variable declaration using the
214 output of get_plain_C_attributes(self). This is a list of tuples,
215 each tuple containing two, three, or four entries.
216
217 See get_plain_C_attributes(self) for more details.
218 """
219
220 decString = ""
221 decString += construct_ifdef_string(self.ifdefs)
222
223 # one attribute logically can map onto multiple technical attributes
224 # for example, when declaring an array, also declare an integer variable
225 # containing its length
226 for subattribute in self.get_plain_C_attributes(for_constructor=False):
227 if len(subattribute) == 4:
228 decString += construct_ifdef_string(subattribute[3])
229 decString += (
230 " "
231 + subattribute[2]
232 + " "
233 + subattribute[1]
234 + " "
235 + subattribute[0]
236 + ";\n"
237 )
238 decString += "#endif\n"
239 elif len(subattribute) == 3:
240 decString += (
241 " "
242 + subattribute[2]
243 + " "
244 + subattribute[1]
245 + " "
246 + subattribute[0]
247 + ";\n"
248 )
249 elif len(subattribute) == 2:
250 decString += " " + subattribute[1] + " " + subattribute[0] + ";\n"
251 else:
252 raise IndexError("wrong number of attribute tuples")
253
254 if self.ifdefs != []:
255 decString += "#endif \n"
256
257 return decString
258
260 """!
261 Generate the accessor name used throughout dastgen2 to
262 create variables, function names, etc.
263 """
264 accessor_name = self._name[0].capitalize() + self._name[1:]
265 return accessor_name
266
267 @abc.abstractmethod
268 def get_method_body(self, signature):
269 """!
270
271 I hand in the method signature (see get_methods()) and wanna get
272 the whole implementation.
273
274 """
275 assert False, "not implemented"
276 return
277
278 @property
279 def name(self):
280 """!
281
282 I expect that there's at least one setter/getter pair
283
284 """
285 return self._name
286
287 @abc.abstractmethod
289 """!
290
291 Return native (built-in) MPI datatype. Return None if there's no
292 direct mapping. The actual result is not a string only, but a list
293 of tuples from native type to cardinality.
294
295 """
296 return
297
298 @abc.abstractmethod
299 def get_to_string(self):
300 """!
301
302 Return string representation of attribute. Should be something
303 that can be streamed via << into a sstream. So the result has
304 to be of type string.
305
306 """
307 return
308
309 def get_includes(self):
310 return ""
classifies attribute qualifiers.
Definition Attribute.py:17
Represents one attribute.
Definition Attribute.py:8
get_methods(self, _full_qualified_class_name, for_declaration=True)
Return sequence of methods that are defined for this attribute.
Definition Attribute.py:108
get_attribute_declaration_string(self)
Construct the string used for variable declaration using the output of get_plain_C_attributes(self).
Definition Attribute.py:211
get_public_fields(self)
Return string that is to be embedded into the public part of the class definition.
Definition Attribute.py:97
get_constructor_arguments(self)
Return list of tuple of arguments for the constructor.
Definition Attribute.py:137
get_native_MPI_type(self)
Return native (built-in) MPI datatype.
Definition Attribute.py:288
use_default_copy_constructor(self)
If this routine returns False, the generator will create a copy constructor copying each attribute ov...
Definition Attribute.py:127
get_plain_C_attributes(self, for_constructor=False)
Return list of n-tuples.
Definition Attribute.py:149
get_accessor_name(self)
Generate the accessor name used throughout dastgen2 to create variables, function names,...
Definition Attribute.py:259
get_first_plain_C_attribute(self)
For MPI for example, I need to know the first attribute.
Definition Attribute.py:202
get_method_body(self, signature)
I hand in the method signature (see get_methods()) and wanna get the whole implementation.
Definition Attribute.py:268
get_to_string(self)
Return string representation of attribute.
Definition Attribute.py:299
__init__(self, name, ifdefs=[], qualifier=Qualifier.NONE, initval=None, expose_in_header_file=False)
name: String This is a plain string which has to follow the C++ naming conventions,...
Definition Attribute.py:35
name(self)
I expect that there's at least one setter/getter pair.
Definition Attribute.py:279