Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-2023 The plumed team
3 : (see the PEOPLE file at the root of the distribution for a list of names)
4 :
5 : See http://www.plumed.org for more information.
6 :
7 : This file is part of plumed, version 2.
8 :
9 : plumed is free software: you can redistribute it and/or modify
10 : it under the terms of the GNU Lesser General Public License as published by
11 : the Free Software Foundation, either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : plumed is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU Lesser General Public License for more details.
18 :
19 : You should have received a copy of the GNU Lesser General Public License
20 : along with plumed. If not, see <http://www.gnu.org/licenses/>.
21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
22 : #ifndef __PLUMED_wrapper_Plumed_h
23 : #define __PLUMED_wrapper_Plumed_h
24 :
25 : /*
26 : This header might be included more than once in order to provide
27 : the declarations and the definitions. The guard is thus closed before the end of the file
28 : (match this brace) {
29 : and a new guard is added for the definitions.
30 : */
31 :
32 : /**
33 : \page ReferencePlumedH Reference for interfacing MD codes with PLUMED
34 :
35 : Plumed.h and Plumed.c contain the external plumed interface, which is used to
36 : integrate it with MD engines. This interface is very general, and is expected
37 : not to change across plumed versions. Plumed.c also implements a dummy version
38 : of the interface, so as to allow a code to be fully linked even if the plumed
39 : library is not available yet. These files could be directly included in the official
40 : host MD distribution. In this manner, it will be sufficient to link the plumed
41 : library at link time (on all systems) or directly at runtime (on systems where
42 : dynamic loading is enabled) to include plumed features.
43 :
44 : Notice that in PLUMED 2.5 this interface has been rewritten in order to allow
45 : more debugging features and a better behavior in multithread environments.
46 : The interface is almost perfectly backward compatible, although it implements
47 : a few additional functions. See more details below.
48 :
49 : A further improvement has been made in PLUMED 2.8, where the interface has
50 : been modified to allow dynamic type checking. See more details below.
51 :
52 : Why is Plumed.c written in C and not C++? The reason is that the resulting Plumed.o
53 : needs to be linked with the host MD code immediately (whereas the rest of plumed
54 : could be linked a posteriori). Imagine the MD code is written in FORTRAN: when we
55 : link the Plumed.o file we would like not to need any C++ library linked. In this
56 : manner, we do not need to know which C++ compiler will be used to compile plumed.
57 : The C++ library is only linked to the "rest" of plumed, which actually uses it.
58 : Anyway, Plumed.c is written in such a manner to allow its compilation also in C++
59 : (C++ is a bit stricter than C). This will
60 : allow e.g. MD codes written in C++ to just incorporate Plumed.c (maybe renamed into
61 : Plumed.cpp), without the need of configuring a plain C compiler.
62 :
63 : Plumed interface can be used from C, C++ and FORTRAN. Everything concerning plumed
64 : is hidden inside a single object type, which is described in C by a structure
65 : (struct \ref plumed), in C++ by a class (PLMD::Plumed) and in FORTRAN by a
66 : fixed-length string (CHARACTER(LEN=32)). Obviously C++ can use both struct
67 : and class interfaces, but the second should be preferred since it will automatically take
68 : care of objects constructions and destructions. The reference interface
69 : is the C one, whereas FORTRAN and C++ interfaces are implemented as wrappers
70 : around it.
71 : In the C++ interface, all the routines are implemented as methods of PLMD::Plumed.
72 : In the C and FORTRAN interfaces, all the routines are named plumed_*, to
73 : avoid potential name clashes. Notice that the entire plumed library
74 : is implemented in C++, and it is hidden inside the PLMD namespace.
75 :
76 : Handlers to the plumed object can be converted among different representations,
77 : to allow inter-operability among languages. In C, there are tools to convert
78 : to/from FORTRAN, whereas in C++ there are tools to convert to/from FORTRAN and C.
79 :
80 : These handlers only contain a pointer to the real structure, so that
81 : when a plumed object is brought from one language to another,
82 : it brings a reference to the same environment.
83 :
84 : Moreover, to simplify life in all cases where a single Plumed object is
85 : required for the entire simulation (which covers many of the practical
86 : applications with conventional MD codes) it is possible to take advantage
87 : of a global interface, which is implicitly referring to a unique global instance.
88 : The global object should still be initialized and finalized properly.
89 : This global object is obviously not usable in a multithread context. In addition,
90 : it is difficult to use it in an exception-safe manner, so its usage in C++ is
91 : allowed but discouraged.
92 :
93 : As of PLUMED 2.5, the interface contains a reference counter that allows
94 : for a better control of plumed initializations and deallocations.
95 : This is particularly useful for the C++ interface that now
96 : behaves similarly to a primitive shared pointer and can be thus copied.
97 : In other languages, to use the reference counter correctly it is sufficient to
98 : remember the following rule: for any `plumed_create*` call, there should be a corresponding
99 : `plumed_finalize` call. More examples can be found below.
100 :
101 : Notice that up to PLUMED 2.8 the reference counter was not thread safe. This is fixed
102 : when using PLUMED>=2.9 wrappers with a PLUMED>=2.9 kernel.
103 :
104 : The basic method to send a message to plumed is
105 : \verbatim
106 : (C) plumed_cmd
107 : (C++) PLMD::Plumed::cmd
108 : (FORTRAN) PLUMED_F_CMD
109 : \endverbatim
110 :
111 : To initialize a plumed object, use:
112 : \verbatim
113 : (C) plumed_create
114 : (C++) (constructor of PLMD::Plumed)
115 : (FORTRAN) PLUMED_F_CREATE
116 : \endverbatim
117 :
118 : As of PLUMED 2.5, you can also initialize a plumed object using the following functions,
119 : that load a specific kernel. The function plumed_create_dlopen2 allows to specify options
120 : for dlopen. The C++ version accepts an optional argument to this aim.
121 : \verbatim
122 : (C) plumed_create_dlopen or plumed_create_dlopen2
123 : (C++) PLMD::Plumed::dlopen
124 : (FORTRAN) PLUMED_F_CREATE_DLOPEN
125 : \endverbatim
126 :
127 : As of PLUMED 2.8, you can also initialize a plumed object using the following function,
128 : that loads a kernel from an already loaded shared library. It accepts a handler
129 : returned by `dlopen`:
130 : \verbatim
131 : (C) plumed_create_dlsym
132 : (C++) PLMD::Plumed::dlsym
133 : (FORTRAN not allowed)
134 : \endverbatim
135 :
136 : To finalize a plumed object, use
137 : \verbatim
138 : (C) plumed_finalize
139 : (C++) (destructor of PLMD::Plumed)
140 : (FORTRAN) PLUMED_F_FINALIZE
141 : \endverbatim
142 :
143 : To access to the global-object, use
144 : \verbatim
145 : (C) plumed_gcreate, plumed_gfinalize, plumed_gcmd
146 : (C++) PLMD::Plumed::gcreate, PLMD::Plumed::gfinalize, PLMD::Plumed::gcmd
147 : (FORTRAN) PLUMED_F_GCREATE, PLUMED_F_GFINALIZE, PLUMED_F_GCMD
148 : \endverbatim
149 :
150 : To check if the global object has been initialized, use
151 : \verbatim
152 : (C) plumed_ginitialized
153 : (C++) PLMD::Plumed::ginitialized
154 : (FORTRAN) PLUMED_F_GINITIALIZED
155 : \endverbatim
156 :
157 : Notice that when using runtime binding the plumed library might be not available.
158 : In this case, plumed_create (and plumed_gcreate) will still succeed, but a subsequent
159 : call to plumed_cmd (or plumed_gcmd) would exit. In order to avoid this
160 : unpleasant situation you have two options.
161 :
162 : First, you can check if plumed library is available before actually creating an object
163 : using this function:
164 : \verbatim
165 : (C) plumed_installed
166 : (C++) PLMD::Plumed::installed
167 : (FORTRAN) PLUMED_F_INSTALLED
168 : \endverbatim
169 :
170 : Alternatively, as of PLUMED 2.5, you can interrogate the just created plumed
171 : object using the following function:
172 : \verbatim
173 : (C) plumed_valid
174 : (C++) PLMD::Plumed::valid
175 : (FORTRAN) PLUMED_F_VALID
176 : \endverbatim
177 :
178 : If you want to create on purpose an invalid Plumed object (useful in C++ to postpone
179 : the loading of the library) you can use `Plumed p(Plumed::makeInvalid());`.
180 :
181 : To know if the global object is valid instead you should use the following function:
182 : \verbatim
183 : (C) plumed_gvalid
184 : (C++) PLMD::Plumed::gvalid
185 : (FORTRAN) PLUMED_F_GVALID
186 : \endverbatim
187 :
188 : To convert handlers between different languages, use
189 : \verbatim
190 : (C) plumed_c2f (C to FORTRAN)
191 : (C) plumed_f2c (FORTRAN to C)
192 : (C++) Plumed(plumed) constructor (C to C++)
193 : (C++) operator plumed() cast (C++ to C)
194 : (C++) Plumed(char*) constructor (FORTRAN to C++)
195 : (C++) toFortran(char*) (C++ to FORTRAN)
196 : \endverbatim
197 :
198 : As of PLUMED 2.5, when using C or C++ we allow a user to explicitly store a plumed object as
199 : a void pointer (indeed: that's the only thing contained in a plumed object).
200 : This might be useful in case you do not want to include the Plumed.h header in some
201 : of your headers. In order to convert to/from void pointers you can use the following functions
202 : \verbatim
203 : (C) plumed_v2c (void* to C)
204 : (C) plumed_c2v (C to void*)
205 : (C++) Plumed(void*) constructor (void* to C++)
206 : (C++) toVoid() (C++ to void*)
207 : \endverbatim
208 : Using the functions above is much safer than accessing directly the pointer contained in the \ref plumed struct
209 : since, when compiling with debug options, it will check if the void pointer actually points to a plumed object.
210 :
211 : As of PLUMED 2.5, we added a reference count. It is in practice possible
212 : to create multiple `plumed` objects that refer to the same environment.
213 : This is done using the following functions
214 : \verbatim
215 : (C) plumed_create_reference (from a C object)
216 : (C) plumed_create_reference_f (from a FORTRAN object)
217 : (C) plumed_create_reference_v (from a void pointer)
218 : (FORTRAN) plumed_f_create_reference (from a FORTRAN object)
219 : \endverbatim
220 : In C++ references are managed automatically by constructors and destructor.
221 : In addition, you can manually manage them (with care!) using incref() and decref().
222 :
223 : The interface of the FORTRAN functions is very similar to that of the C functions
224 : and is listed below:
225 :
226 : \verbatim
227 : FORTRAN interface
228 : SUBROUTINE PLUMED_F_CREATE(p)
229 : CHARACTER(LEN=32), INTENT(OUT) :: p
230 : SUBROUTINE PLUMED_F_CREATE_DLOPEN(p,path)
231 : CHARACTER(LEN=32), INTENT(OUT) :: p
232 : CHARACTER(LEN=*), INTENT(IN) :: path
233 : SUBROUTINE PLUMED_F_CREATE_REFERENCE(p,r)
234 : CHARACTER(LEN=32), INTENT(OUT) :: p
235 : CHARACTER(LEN=32), INTENT(IN) :: r
236 : SUBROUTINE PLUMED_F_CREATE_INVALID(p)
237 : CHARACTER(LEN=32), INTENT(OUT) :: p
238 : SUBROUTINE PLUMED_F_CMD(p,key,val)
239 : CHARACTER(LEN=32), INTENT(IN) :: p
240 : CHARACTER(LEN=*), INTENT(IN) :: key
241 : UNSPECIFIED_TYPE, INTENT(INOUT) :: val(*)
242 : SUBROUTINE PLUMED_F_FINALIZE(p)
243 : CHARACTER(LEN=32), INTENT(IN) :: p
244 : SUBROUTINE PLUMED_F_INSTALLED(i)
245 : INTEGER, INTENT(OUT) :: i
246 : SUBROUTINE PLUMED_F_VALID(p,i)
247 : CHARACTER(LEN=32), INTENT(IN) :: p
248 : INTEGER, INTENT(OUT) :: i
249 : SUBROUTINE PLUMED_F_USE_COUNT(p,i)
250 : CHARACTER(LEN=32), INTENT(IN) :: p
251 : INTEGER, INTENT(OUT) :: i
252 : SUBROUTINE PLUMED_F_GLOBAL(p)
253 : CHARACTER(LEN=32), INTENT(OUT) :: p
254 : SUBROUTINE PLUMED_F_GINITIALIZED(i)
255 : INTEGER, INTENT(OUT) :: i
256 : SUBROUTINE PLUMED_F_GCREATE()
257 : SUBROUTINE PLUMED_F_GCMD(key,val)
258 : CHARACTER(LEN=*), INTENT(IN) :: key
259 : UNSPECIFIED_TYPE, INTENT(INOUT) :: val(*)
260 : SUBROUTINE PLUMED_F_GFINALIZE()
261 : SUBROUTINE PLUMED_F_GVALID(i)
262 : INTEGER, INTENT(OUT) :: i
263 : \endverbatim
264 :
265 : Almost all C functions have a corresponding FORTRAN function.
266 : As a simple mnemonic, if you know the name of the C function you can obtain the
267 : corresponding FORTRAN subroutine by adding `F_` after the `PLUMED_` prefix.
268 : In addition, all `plumed` objects are replaced by `CHARACTER(LEN=32)` objects
269 : holding the same information. These pointers basically contain a text representation
270 : of the stored pointer, that is suitable to be contained in a string.
271 : Finally, whenever a C function returns a value,
272 : the corresponding FORTRAN subroutine will have an additional `INTENT(OUT)` parameter
273 : passed as the its last argument.
274 :
275 : When you compile the FORTRAN interface, wrapper functions are added with several possible
276 : name manglings, so you should not experience problems linking the plumed library with a FORTRAN file.
277 :
278 : \section ReferencePlumedH-exceptions Error handling
279 :
280 : In case an error is detected by PLUMED, either because of some user error, some internal bug,
281 : or some mistake in using the library, an exception will be thrown. The behavior is different depending if you use
282 : PLUMED from C/FORTRAN or from C++.
283 :
284 : First of all, notice that access to PLUMED goes through three functions:
285 : - plumed_create: this, as of PLUMED 2.5, is guaranteed not to throw any exception. If there is a problem, it will
286 : just return a plumed object containing a NULL pointer
287 : - plumed_cmd: this function might throw exceptions.
288 : - plumed_finalize: this is a destructor and is guaranteed not to throw any exception.
289 :
290 : The following discussion concerns all the exceptions thrown by plumed_cmd.
291 :
292 : If you use C/FORTRAN, you will basically have no way to intercept the exception and the program will just terminate.
293 :
294 : If you use C++ and you are calling the C++ interface (e.g. \ref Plumed::cmd), as of PLUMED 2.5 we implemented a complete
295 : remapping of the exceptions thrown by PLUMED. This solves both the problems mentioned above. In particular:
296 : - Instead of throwing an exception, PLUMED will return (using a \ref plumed_nothrow_handler) the details about the occurred error.
297 : - An equivalent exception will be thrown within the inline PLUMED interface compiled with your MD code.
298 :
299 : As a consequence, you will be able to combine different compilers and avoid stack unwinding in the C layer.
300 :
301 : If you use C++ but you are calling the C interface (e.g. \ref plumed_cmd), then you might be
302 : able to catch the exceptions thrown by PLUMED. Notice that all the exceptions thrown by PLUMED inherit from std::exception,
303 : so you might want to catch it by reference. By default, as of PLUMED 2.8 \ref plumed_cmd is redefined as a macro and directly calls
304 : the \ref Plumed::cmd interface, and thus behaves in an equivalent manner. With previous versions of this header
305 : one could have encountered problems with stack unwinding performed during exception handling in the C layer.
306 :
307 : Notice that, even if you use \ref Plumed::cmd, if you are loading a kernel <=2.4 any exception generated by PLUMED will
308 : leak through the C layer. This might lead to undefined behavior. If you are lucky (with some compiler it works!) and
309 : the exception arrives to C, PLUMED will catch it and rethrow it as it would do if you were using a kernel >=2.5.
310 :
311 : The remapping of exceptions takes care of all the standard C++ exceptions plus all the exceptions raised within
312 : PLUMED. Unexpected exceptions that are derived from std::exception will be rethrown as std::exception.
313 : Notice that this implies some loss of information, since the original exception might have been of a different type.
314 : However, it also implies that the virtual table of the original exception won't be needed anymore. This allows to
315 : completely decouple the MD code from the PLUMED library.
316 :
317 : \section ReferencePlumedH-typesafe Typesafe interface
318 :
319 : Starting with PLUMED 2.8, the `cmd` function of the C++ interface, and the similar function `gcmd`, can be called
320 : with several interfaces and can perform a typechecking on the passed argument. In particular, the following
321 : forms are now possible:
322 : \verbatim
323 : cmd("string",value); // by value
324 : cmd("string",&value); // by pointer
325 : cmd("string",&value,nelem); // by pointer, specifying the number of elements of the passed array
326 : cmd("string",&value,shape); // by pointer, specifying the shape of the passed array
327 : \endverbati
328 : The `nelem` and `shape` arguments are used by PLUMED to check that the user
329 : provided enough elements. If nelem is provided, the check is done on the flatten array, whereas if shape
330 : is passed a more thorough check is performed controlling each of the dimensions of the array.
331 : In addition to this, the type of the pointer (or of the value) is checked at runtime.
332 :
333 : All these checks are only implemented if the PLUMED library is recent (>=2.8). However, it will still be
334 : possible to load at runtime an older PLUMED library (<=2.7). For this reason, it is still compulsory
335 : to pass the correct types to the `cmd` function, also when the argument is passed by value.
336 : Type conversions are only performed between pointers and only in ways compatible with
337 : what is allowed in C++ (e.g., `const void*` cannot be converted to `void*`, but `void*` can
338 : be converted to `const void*`).
339 :
340 : Type checkes can be disabled in two ways:
341 : - By compiling `Plumed.h` with `-D__PLUMED_WRAPPER_CXX_TYPESAFE=0`
342 : - By setting `export PLUMED_TYPESAFE_IGNORE=yes` at runtime.
343 :
344 : Typechecks are also enabled in the C interface (plumed_cmd). This function is replaced with a macro by default.
345 : In particular:
346 : - If the C interface is used in C++ code, it calls the C++ interface. Can be disabled with `-D__PLUMED_WRAPPER_CXX_BIND_C=0`.
347 : - If the C interface is used in C code and compiled with a C11 compiler, it uses _Generic to pass type information.
348 : Can be disabled using `-D__PLUMED_WRAPPER_C_TYPESAFE=0`.
349 :
350 : \section ReferencePlumedH-2-5 New in PLUMED 2.5
351 :
352 : The wrappers in PLUMED 2.5 have been completely rewritten with several improvements.
353 : The interface is almost perfectly backward compatible, although the behavior of C++ constructors
354 : has been modified slightly.
355 : In addition, a few new functions are introduced (explicitly marked in the documentation).
356 : As a consequence, if your code uses some of the new functions, you will not be able
357 : to link it directly with an older PLUMED library (though you will still be able to load
358 : an older PLUMED library at runtime). In addition, the reference counter changes slightly
359 : the behavior of the C++ methods used to interoperate with C and FORTRAN.
360 :
361 : An important novelty is in the way the runtime loader is implemented.
362 : In particular, the loader works also if the symbols of the main executable are not exported.
363 : The proper functions from the kernel are indeed searched explicitly now using `dlsym`.
364 :
365 : Some additional features can be enabled using suitable environment variables. In particular:
366 : - `PLUMED_LOAD_DEBUG` can be set to report more information about the loading process.
367 : - `PLUMED_LOAD_NAMESPACE` can be set to `LOCAL` to load the PLUMED kernel in a separate
368 : namespace. The default is global namespace, which is the same behavior of PLUMED <=2.4,
369 : and is consistent with what happens when linking PLUMED as a shared library.
370 : - `PLUMED_LOAD_NODEEPBIND` can be set to load the PLUMED kernel in not-deepbind mode. Deepbind
371 : mode implies that the symbols defined in the library are preferred to other symbols with the same name.
372 : Only works on systems supporting `RTLD_DEEPBIND` and is mostly for debugging purposes.
373 :
374 : Another difference is that the implementation of the wrappers is now completely contained in the `Plumed.h`
375 : file. You can see that the `Plumed.c` is much simpler now and just includes `Plumed.h`. With a similar
376 : procedure you could compile the wrappers directly into your code making it unnecessary to link
377 : the libplumedWrapper.a library. The corresponding macros are still subject to change and are not documented here.
378 :
379 : As written above, the plumed object now implements a reference counter. Consider the following example
380 : \verbatim
381 : plumed p=plumed_create();
382 : plumed_cmd(p,"init",NULL);
383 : plumed q=plumed_create_reference(p);
384 : plumed_finalize(p);
385 : // at this stage, object q still exists
386 : plumed_cmd(q,"whatever",NULL);
387 : plumed_finalize(q);
388 : // now plumed has been really finalized
389 : \endverbatim
390 :
391 : In other words, every \ref plumed_create, \ref plumed_create_dlopen, \ref plumed_create_reference,
392 : \ref plumed_create_reference_f, and \ref plumed_create_reference_v call must be matched by a \ref plumed_finalize.
393 : Notice that in C++ whenever an object goes out of scope the reference counter
394 : will be decreased. In addition, consider that conversion from C/FORTRAN/void* to C++ implies calling a C++ constructor, that
395 : is increases the number of references by one. Converting from C++ to C/FORTRAN/void* instead does not call any constructor,
396 : that is the number of references is unchanged.
397 :
398 : The change in the behavior of C++ constructors means that the following code will behave in a backward incompatible manner:
399 : \verbatim
400 : plumed p=plumed_create();
401 : plumed_cmd(p,"init",NULL);
402 : Plumed q(p);
403 : plumed_finalize(p);
404 : // at this stage, object q still exists with PLUMED 2.5
405 : // on the other hand, with PLUMED 2.4 object q refers to an
406 : // already finalized object
407 : q.cmd("whatever",NULL);
408 : \endverbatim
409 :
410 : Another difference is that the value of the variable `PLUMED_KERNEL` is read every time a new
411 : plumed object is instantiated. So, you might even use it to load different plumed versions
412 : simultaneously, although the preferred way to do this is using the function \ref plumed_create_dlopen.
413 : Notice that if you want to load multiple versions simultaneously you should load them in a local namespace.
414 : \ref plumed_create_dlopen does it automatically, whereas loading through env var `PLUMED_KERNEL` only does it if
415 : you also set env var `PLUMED_NAMESPACE=LOCAL`.
416 :
417 : Finally, a few functions have been added, namely:
418 : - Functions to find if a plumed object is valid
419 : (\ref plumed_valid(), \ref plumed_gvalid(), \ref PLMD::Plumed::valid(), and \ref PLMD::Plumed::gvalid()).
420 : - Functions to create a plumed object based on the path of a specific kernel
421 : (\ref plumed_create_dlopen() and \ref PLMD::Plumed::dlopen()).
422 : - Functions to create a plumed object referencing to another one, implementing a reference counter
423 : (\ref plumed_create_reference(), \ref plumed_create_reference_v(), \ref plumed_create_reference_f().
424 :
425 : */
426 :
427 : /* BEGINNING OF DECLARATIONS */
428 :
429 : /* SETTING DEFAULT VALUES FOR CONTROL MACROS */
430 :
431 : /*
432 : 1: make the C wrapper functions extern (default)
433 : 0: make the C wrapper functions static (C) or inline (C++)
434 :
435 : If set to zero, it disables all functions that only make sense as extern, such as
436 : Fortran wrappers, global objects, and plumed_kernel_register.
437 :
438 : It can be set to zero to include multiple copies of the wrapper implementation without worrying
439 : about duplicated symbols.
440 :
441 : Notice that C++ wrappers are always inline. What this function controls is if the C wrappers
442 : (called by the C++ wrappers) is inline or not. Also consider that if this header is compiled
443 : with C++ and inline C wrappers, the C wrappers will be actually compiled with C++ linkage
444 : in the root namespace.
445 :
446 : Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
447 : */
448 :
449 : #ifndef __PLUMED_WRAPPER_EXTERN
450 : #define __PLUMED_WRAPPER_EXTERN 1
451 : #endif
452 :
453 : /*
454 : 1: emit global plumed object and related functions (default)
455 : 0: do not emit global plumed object and related functions
456 :
457 : Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
458 : */
459 :
460 : #ifndef __PLUMED_WRAPPER_GLOBAL
461 : #define __PLUMED_WRAPPER_GLOBAL 1
462 : #endif
463 :
464 : /*
465 : 1: Enable typesafe C interface (default)
466 : 0: Disable typesafe C interface
467 :
468 : Only used in declarations. Requires C11 _Generic and variadic macros, and so it is
469 : disabled by default with C++ and pre C11 compilers.
470 :
471 : https://mort.coffee/home/c-compiler-quirks/
472 : */
473 :
474 : #ifndef __PLUMED_WRAPPER_C_TYPESAFE
475 : # if defined(__STDC_VERSION__)
476 : # if ! defined(__cplusplus) && __STDC_VERSION__ >= 201112L
477 : # if defined(__GNUC__) && !defined(__clang__)
478 : # if (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
479 : # define __PLUMED_WRAPPER_C_TYPESAFE 1
480 : # endif
481 : # else
482 : # define __PLUMED_WRAPPER_C_TYPESAFE 1
483 : # endif
484 : # endif
485 : # endif
486 : # ifndef __PLUMED_WRAPPER_C_TYPESAFE
487 : # define __PLUMED_WRAPPER_C_TYPESAFE 0
488 : # endif
489 : #endif
490 :
491 : /*
492 : 1: Enable RTLD_DEEPBIND when possible (default)
493 : 0: Disable RTLD_DEEPBIND
494 : */
495 :
496 : #ifndef __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
497 : #define __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND 1
498 : #endif
499 :
500 : /*
501 : 1: enable C++ wrapper (default)
502 : 0: disable C++ wrapper
503 :
504 : Only used in declarations, but affects the scope of the C interface also in definitions.
505 : */
506 :
507 : #ifndef __PLUMED_WRAPPER_CXX
508 : #define __PLUMED_WRAPPER_CXX 1
509 : #endif
510 :
511 : /*
512 : 1: new headers such as cstdlib are included in C++ (default)
513 : 0: old headers such as stdlib.h are included in C++
514 :
515 : Should only be set to zero when including the Plumed.h file in a file using the
516 : old (stdlib.h) convention.
517 :
518 : Used both in declarations and definitions.
519 : */
520 :
521 : #ifndef __PLUMED_WRAPPER_CXX_STD
522 : #define __PLUMED_WRAPPER_CXX_STD 1
523 : #endif
524 :
525 : /*
526 : 1: place C++ wrappers in an anonymous namespace
527 : 0: place C++ wrappers in the PLMD namespace (default)
528 :
529 : It will make PLMD::Plumed a different class (though with the same name)
530 : in each of the translation units in which `Plumed.h` is included.
531 :
532 : Can be used to completey separate C++ implementations. However, it will make
533 : it impossible to transfer Plumed objects between different translation units
534 : without converting to a void* or plumed object.
535 :
536 : Only used in declarations, but affects the scope of the C interface also in definitions.
537 : */
538 :
539 : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE
540 : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 0
541 : #endif
542 :
543 :
544 : /*
545 : 1: throw exceptions such as PLMD::Exception
546 : 0: throw exceptions such as PLMD::Plumed::Exception (default)
547 :
548 : This is useful when including Plumed.h within the plumed library
549 : in anonymous mode, to make sure that the exception types from the
550 : library are used.
551 : */
552 : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
553 : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 0
554 : #endif
555 :
556 : /*
557 : 1: make PLMD::Plumed class polymorphic (default)
558 : 0: make PLMD::Plumed class non-polymorphic
559 :
560 : Only used in declarations.
561 : */
562 :
563 : #ifndef __PLUMED_WRAPPER_CXX_POLYMORPHIC
564 : #define __PLUMED_WRAPPER_CXX_POLYMORPHIC 1
565 : #endif
566 :
567 : /*
568 : 1: Enable typesafe interface (default)
569 : 0: Disable typesafe interface
570 :
571 : Only used in declarations.
572 : */
573 :
574 : #ifndef __PLUMED_WRAPPER_CXX_TYPESAFE
575 : #define __PLUMED_WRAPPER_CXX_TYPESAFE 1
576 : #endif
577 :
578 : /*
579 : 1: Define macros plumed_cmd and plumed_gcmd to use the C++ interface (default).
580 : 0: Don't define macros plumed_cmd and plumed_gcmd.
581 :
582 : Only used in declarations.
583 : */
584 :
585 : #ifndef __PLUMED_WRAPPER_CXX_BIND_C
586 : #define __PLUMED_WRAPPER_CXX_BIND_C 1
587 : #endif
588 :
589 : /*
590 : 1: Enable passing long long int
591 : 0: Disable passing long long int
592 :
593 : Only used in declarations. Default is 0 in C++<11 and 1 in C++>=11
594 : */
595 :
596 : #ifndef __PLUMED_WRAPPER_CXX_LONGLONG
597 : #if __cplusplus > 199711L
598 : #define __PLUMED_WRAPPER_CXX_LONGLONG 1
599 : #else
600 : #define __PLUMED_WRAPPER_CXX_LONGLONG 0
601 : #endif
602 : #endif
603 :
604 : /*
605 : 1: make the default constructor create an invalid object
606 : 0: make the default constructor create a valid object
607 :
608 : Only for internal usage.
609 : */
610 : #ifndef __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
611 : #define __PLUMED_WRAPPER_CXX_DEFAULT_INVALID 0
612 : #endif
613 :
614 : /*
615 : Size of a buffer used to store message for exceptions with noexcept constructor.
616 : Should typically hold short messages. Anyway, as long as the stack size stays within the correct
617 : limits it does not seem to affect efficiency. Notice that there cannot be recursive calls of
618 : PLMD::Plumed::cmd, so that it should be in practice irrelevant.
619 : */
620 : #ifndef __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER
621 : #define __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER 512
622 : #endif
623 :
624 : /*
625 : 1: enable nested exceptions (only with C++11) (default)
626 : 0: disable nested exceptions
627 :
628 : For internal testing, used to mimic pre C++11 behavior on
629 : nested exception.
630 :
631 : Only used in declarations.
632 : */
633 :
634 : #ifndef __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
635 : #define __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS 1
636 : #endif
637 :
638 : /*
639 : By default, assume C++11 compliant library is not available.
640 : */
641 :
642 : #ifndef __PLUMED_WRAPPER_LIBCXX11
643 : #define __PLUMED_WRAPPER_LIBCXX11 0
644 : #endif
645 :
646 : /* The following macros are just to define shortcuts */
647 :
648 : /* Simplify addition of extern "C" blocks. */
649 : #ifdef __cplusplus
650 : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN extern "C" {
651 : #define __PLUMED_WRAPPER_EXTERN_C_END }
652 : #else
653 : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN
654 : #define __PLUMED_WRAPPER_EXTERN_C_END
655 : #endif
656 :
657 : /* Without C++, stdlib functions should not be prepended with ::std:: */
658 : #ifndef __cplusplus
659 : #undef __PLUMED_WRAPPER_CXX_STD
660 : #define __PLUMED_WRAPPER_CXX_STD 0
661 : #endif
662 :
663 : /* Set prefix for stdlib functions */
664 : #if __PLUMED_WRAPPER_CXX_STD
665 : #define __PLUMED_WRAPPER_STD ::std::
666 : #else
667 : #define __PLUMED_WRAPPER_STD
668 : #endif
669 :
670 : /* Allow using noexcept, explicit, and override with C++11 compilers */
671 : #ifdef __cplusplus /*{*/
672 : #if __cplusplus > 199711L
673 : #define __PLUMED_WRAPPER_CXX_NOEXCEPT noexcept
674 : #define __PLUMED_WRAPPER_CXX_NORETURN [[ noreturn ]]
675 : #define __PLUMED_WRAPPER_CXX_EXPLICIT explicit
676 : #define __PLUMED_WRAPPER_CXX_OVERRIDE override
677 : #define __PLUMED_WRAPPER_CXX_NULLPTR nullptr
678 : #else
679 : #define __PLUMED_WRAPPER_CXX_NOEXCEPT throw()
680 : #define __PLUMED_WRAPPER_CXX_NORETURN
681 : #define __PLUMED_WRAPPER_CXX_EXPLICIT
682 : #define __PLUMED_WRAPPER_CXX_OVERRIDE
683 : #define __PLUMED_WRAPPER_CXX_NULLPTR NULL
684 : #endif
685 : #else
686 : #define __PLUMED_WRAPPER_CXX_NOEXCEPT
687 : #define __PLUMED_WRAPPER_CXX_NORETURN
688 : #define __PLUMED_WRAPPER_CXX_EXPLICIT
689 : #define __PLUMED_WRAPPER_CXX_OVERRIDE
690 : #define __PLUMED_WRAPPER_CXX_NULLPTR NULL
691 : #endif /*}*/
692 :
693 : /* static inline, for to avoid compiler warnings */
694 : #if defined(__cplusplus) || __STDC_VERSION__>=199901L
695 : #define __PLUMED_WRAPPER_STATIC_INLINE static inline
696 : #else
697 : #define __PLUMED_WRAPPER_STATIC_INLINE static
698 : #endif
699 :
700 : /* Macros for anonymous namespace */
701 : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE && defined(__cplusplus) /*{*/
702 : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN namespace {
703 : #define __PLUMED_WRAPPER_ANONYMOUS_END }
704 : #else
705 : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN
706 : #define __PLUMED_WRAPPER_ANONYMOUS_END
707 : #endif /*}*/
708 :
709 : #if __PLUMED_WRAPPER_EXTERN /*{*/
710 :
711 : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN extern
712 : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_EXTERN_C_END
713 : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN static
714 : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_EXTERN_C_END
715 :
716 : #else
717 :
718 : #ifdef __cplusplus
719 : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_ANONYMOUS_BEGIN inline
720 : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_ANONYMOUS_END
721 : #else
722 : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_STATIC_INLINE
723 : #define __PLUMED_WRAPPER_C_END
724 : #endif
725 :
726 : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_C_BEGIN
727 : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_C_END
728 :
729 : /* with an not-external interface, it does not make sense to define global functions */
730 : #undef __PLUMED_WRAPPER_GLOBAL
731 : #define __PLUMED_WRAPPER_GLOBAL 0
732 :
733 : #endif /*}*/
734 :
735 : #if __PLUMED_WRAPPER_CXX_STD
736 : #include <cstddef> /* size_t */
737 : #include <cstring> /* memcpy */
738 : #include <cstdio> /* fprintf */
739 : #include <cstdlib> /* abort */
740 : #include <cassert> /* assert */
741 : #else
742 : #include <stddef.h>
743 : #include <string.h>
744 : #include <stdio.h> /* FILE and fprintf */
745 : #include <stdlib.h> /* abort */
746 : #include <limits.h> /* CHAR_MIN */
747 : #include <assert.h> /* assert */
748 : #endif
749 :
750 : /**
751 : This is an internal tool, to make sure that all malloc calls inside the
752 : plumed library refer to the same implementation. When compiling with
753 : __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
754 : allocations and deallocations, so as to debug the wrappers.
755 : */
756 : __PLUMED_WRAPPER_C_BEGIN
757 : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size);
758 : __PLUMED_WRAPPER_C_END
759 :
760 : /**
761 : This is an internal tool, to make sure that all free calls inside the
762 : plumed library refer to the same implementation. When compiling with
763 : __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
764 : allocations and deallocations, so as to debug the wrappers.
765 : */
766 : __PLUMED_WRAPPER_C_BEGIN
767 : void plumed_free(void* ptr);
768 : __PLUMED_WRAPPER_C_END
769 :
770 : /**
771 : \brief Main plumed object
772 :
773 : This is an object containing a Plumed instance, which should be used in
774 : the MD engine. It should first be initialized with plumed_create(),
775 : then it communicates with the MD engine using plumed_cmd(). Finally,
776 : before the termination, it should be deallocated with plumed_finalize().
777 : Its interface is very simple and general, and is expected
778 : not to change across plumed versions. See \ref ReferencePlumedH.
779 : */
780 : typedef struct {
781 : /**
782 : \private
783 : \brief Void pointer holding the real PlumedMain structure
784 :
785 : To maintain binary compatibility, we should not add members to this structure.
786 : As of PLUMED 2.5, in order to add new components we do not store the pointer
787 : to \ref PlumedMain here but rather a pointer to an intermediate private structure
788 : that contains all the details.
789 : */
790 : void*p;
791 : } plumed;
792 :
793 : typedef struct {
794 : void* ptr;
795 : void (*handler)(void*,int,const char*,const void*);
796 : } plumed_nothrow_handler;
797 :
798 : /** \relates plumed
799 : \brief Structure holding a typesafe pointer.
800 : */
801 :
802 : typedef struct {
803 : /** Pointer to data */
804 : const void* ptr;
805 : /** Number of elements (in case pointing to an array) */
806 : __PLUMED_WRAPPER_STD size_t nelem;
807 : /** Shape (scanned up to a zero value is found) */
808 : const __PLUMED_WRAPPER_STD size_t* shape;
809 : /**
810 : sum of:
811 : sizeof(pointed data), up to 0x10000 (65536). 0 means size not checked
812 : 0x10000 * data type, up to 0xff (255)
813 : 0 not typechecked
814 : 1 void
815 : 2 nullptr
816 : 3 integral
817 : 4 floating point
818 : 5 FILE (size will not be computed as it might be incomplete)
819 : >5 not typechecked, reserved for future extensions
820 : 0x1000000 * 1 for unsigned (ignored)
821 : 0x2000000 * pointer/const type, up to 8
822 : 0 not typechecked
823 : 1 T (pass-by-value)
824 : 2 T *
825 : 3 T const *
826 : 4 T * *
827 : 5 T * const *
828 : 6 T const * *
829 : 7 T const * const *
830 : 0x10000000 * 1 to forbid pointer copy (pointer copy is also forbidden for pass-by-value)
831 : 0x20000000 and higher bits are ignored, reserved for future extensions
832 : */
833 : __PLUMED_WRAPPER_STD size_t flags;
834 : /** Optional information, not used yet */
835 : const void* opt;
836 : } plumed_safeptr;
837 :
838 : /**
839 : Small structure that is only defined locally to retrieve errors.
840 :
841 : It is supposed to be used in the C11/C++ plumed_cmd interface as follows:
842 : \verbatim
843 : plumed p;
844 : plumed_error error;
845 :
846 : p=plumed_create();
847 :
848 : plumed_cmd(p,"setNatoms",10,&error);
849 : if(error.code) {
850 : fprintf(errors,"%d\n",error.code);
851 : plumed_error_finalize(error); // make sure the error object is finalized!
852 : }
853 : // if no error was raised (error.code==0), it is not necessary to call plumed_error_finalize.
854 : // but doing it is harmless
855 :
856 : // no need to initialize error, it is written in the plumed_cmd function
857 : plumed_cmd(p,"init",&error);
858 : if(error.code) {
859 : fprintf(errors,"%d\n",error.code);
860 : plumed_error_finalize(error); // make sure the error object is finalized!
861 : }
862 : \endverbatim
863 :
864 : The layout of this structure is subject to change, thus all the functions manipulating it
865 : are defined as inline/static functions. In the future, we might reach some form
866 : of ABI stability, and these functions might be moved below to the implementation
867 : file.
868 :
869 : Notice that there is a macro plumed_error() defined in the PLUMED source code
870 : (at tools/Exception.h). There is no conflict with this type since C preprocessor
871 : distinguishes macros and function-like macros.
872 : */
873 : typedef struct plumed_error {
874 : /** code used for translating messages */
875 : int code;
876 : /** error code for system_error */
877 : int error_code;
878 : /** message */
879 : const char* what;
880 : /** the buffer containing the message to be deallocated */
881 : char* what_buffer;
882 : /** pointer to nested exception */
883 : struct plumed_error* nested;
884 : } plumed_error;
885 :
886 : /** Initialize error (for internal usage) */
887 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_init(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
888 : assert(error);
889 14246 : error->code=0;
890 14246 : error->error_code=0;
891 14246 : error->what=__PLUMED_WRAPPER_CXX_NULLPTR;
892 14246 : error->what_buffer=__PLUMED_WRAPPER_CXX_NULLPTR;
893 14246 : error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
894 : }
895 :
896 : /** Finalize error - should be called when an error is raised to avoid leaks */
897 0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_finalize(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
898 0 : if(!error.code) {
899 : return;
900 : }
901 0 : if(error.nested) {
902 0 : plumed_error_finalize(*error.nested);
903 0 : plumed_free(error.nested);
904 : }
905 0 : if(error.what_buffer) {
906 0 : plumed_free(error.what_buffer);
907 : }
908 : }
909 :
910 : /** Access message - more robust than directly accessing what ptr, for future extensibility */
911 : __PLUMED_WRAPPER_STATIC_INLINE const char* plumed_error_what(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
912 : return error.what;
913 : }
914 :
915 : /** Set error to bad_alloc (for internal usage).
916 : At variance with plumed_error_init, it also finalizes the error, possibly
917 : deallocating any buffer.
918 : */
919 0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set_bad_alloc(plumed_error*error) {
920 : assert(error);
921 0 : plumed_error_finalize(*error);
922 : plumed_error_init(error);
923 0 : error->what="[msg erased due to allocation failure]";
924 0 : error->code=11400;
925 0 : }
926 :
927 : /** Recursive merge (for internal usage) */
928 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_recursive_merge(plumed_error* error,char*buffer,const char*join,__PLUMED_WRAPPER_STD size_t*len) __PLUMED_WRAPPER_CXX_NOEXCEPT {
929 : if(error->nested) {
930 : plumed_error_recursive_merge(error->nested,buffer,join,len);
931 : }
932 : __PLUMED_WRAPPER_STD strncat(buffer,plumed_error_what(*error),*len);
933 : *len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
934 : __PLUMED_WRAPPER_STD strncat(buffer,join,*len);
935 : *len -= __PLUMED_WRAPPER_STD strlen(join);
936 : }
937 :
938 : /** Merge with nested exceptions */
939 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_merge_with_nested(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
940 : __PLUMED_WRAPPER_STD size_t len;
941 : __PLUMED_WRAPPER_STD size_t len_join;
942 : /* The is temporarily holding the new message */
943 : char* new_buffer;
944 : /* This is the string used to concatenate messages */
945 : const char* join="\n\nThe above exception was the direct cause of the following exception:\n";
946 : /* This is used to iterate over the linked list of nested exceptions */
947 : plumed_error*e;
948 :
949 : /* If exception is not nested, nothing to do */
950 : if(!error->nested) {
951 : return;
952 : }
953 :
954 : /* Accumulate the total length of the concatenated message */
955 : len_join=__PLUMED_WRAPPER_STD strlen(join);
956 : e=error;
957 : len=__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
958 : while(e->nested) {
959 : e=e->nested;
960 : len+=len_join+__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
961 : }
962 :
963 : /* Allocate the new message */
964 : new_buffer=(char*)plumed_malloc(len+1);
965 : if(new_buffer) {
966 : /* If allocation was successful, merge the messages */
967 : new_buffer[0]='\0';
968 : /* Notice that we have a forward linked list but we need to go through that in backward order
969 : (inner to outer). To do that without allocating an additional array, we use a recursive
970 : function.
971 : */
972 : assert(error->nested);
973 : plumed_error_recursive_merge(error->nested,new_buffer,join,&len);
974 : __PLUMED_WRAPPER_STD strncat(new_buffer,plumed_error_what(*error),len);
975 : len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
976 : /* we keep track of length of buffer for safety */
977 : assert(len==0);
978 : }
979 : error->what=new_buffer;
980 :
981 : /* Deallocate the previous message */
982 : if(error->what_buffer) {
983 : plumed_free(error->what_buffer);
984 : }
985 : error->what_buffer=new_buffer;
986 :
987 : /* Finalize the chain of nested exceptions */
988 : plumed_error_finalize(*error->nested);
989 : plumed_free(error->nested);
990 : error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
991 :
992 : if(!error->what) {
993 : /* If allocation was not successful, reset to bad_alloc */
994 : plumed_error_set_bad_alloc(error);
995 : }
996 : }
997 :
998 : /** Rethrow error (calling abort) */
999 : __PLUMED_WRAPPER_CXX_NORETURN __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_rethrow(plumed_error h) {
1000 : if(h.nested) {
1001 : plumed_error_merge_with_nested(&h);
1002 : }
1003 : __PLUMED_WRAPPER_STD fprintf(stderr,"Terminate due to exception. Code: %d\n%s\n",h.code,plumed_error_what(h));
1004 : __PLUMED_WRAPPER_STD abort();
1005 : }
1006 :
1007 : /** Callback (for internal usage) */
1008 0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set(void*ptr,int code,const char*what,const void* opt) __PLUMED_WRAPPER_CXX_NOEXCEPT {
1009 : plumed_error* error;
1010 : __PLUMED_WRAPPER_STD size_t len;
1011 : void*const* options;
1012 :
1013 : error=(plumed_error*) ptr;
1014 :
1015 0 : error->code=code;
1016 0 : error->error_code=0;
1017 0 : len=__PLUMED_WRAPPER_STD strlen(what);
1018 0 : error->what_buffer=(char*) plumed_malloc(len+1);
1019 0 : if(!error->what_buffer) {
1020 0 : plumed_error_set_bad_alloc(error);
1021 0 : return;
1022 : }
1023 :
1024 : __PLUMED_WRAPPER_STD strncpy(error->what_buffer,what,len+1);
1025 0 : error->what=error->what_buffer;
1026 :
1027 : /* interpret optional arguments */
1028 0 : if(opt) {
1029 : options=(void*const*)opt;
1030 0 : while(*options) {
1031 : /* c: error code */
1032 0 : if(*((const char*)*options)=='c' && *(options+1)) {
1033 0 : error->error_code=*((const int*)*(options+1));
1034 0 : break;
1035 : }
1036 0 : options+=2;
1037 : }
1038 : options=(void*const*)opt;
1039 0 : while(*options) {
1040 : /* n: nested exception */
1041 0 : if(*((const char*)*options)=='n' && *(options+1)) {
1042 : /* notice that once this is allocated it is guaranteed to be deallocated by the recursive destructor */
1043 0 : error->nested=(plumed_error*) plumed_malloc(sizeof(plumed_error));
1044 : /* this is if malloc fails */
1045 0 : if(!error->nested) {
1046 0 : plumed_error_set_bad_alloc(error);
1047 0 : break;
1048 : }
1049 : plumed_error_init((plumed_error*)error->nested);
1050 : /* plumed will make sure to only use this if it is not null */
1051 0 : *(void**)*(options+1)=error->nested;
1052 0 : break;
1053 : }
1054 0 : options+=2;
1055 : }
1056 : }
1057 : }
1058 :
1059 : /** \relates plumed
1060 : \brief Constructor
1061 :
1062 : Constructs a plumed object.
1063 :
1064 : Notice that if you are linking against libplumedWrapper.a, if you are
1065 : using a code patched in runtime mode, or if you are including the `Plumed.c`
1066 : file directly in your code, this constructor might return an invalid plumed
1067 : object. In particular, this could happen if the `PLUMED_KERNEL` environment
1068 : variable is not set or set incorrectly. In order to detect an incorrect
1069 : plumed object you might use \ref plumed_valid() on the resulting object.
1070 : Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
1071 : Also notice that to avoid memory leaks you should call \ref plumed_finalize()
1072 : to finalize a plumed object even if it is invalid:
1073 : \verbatim
1074 : plumed p=plumed_create();
1075 : if(!plumed_valid(p)) {
1076 : // this will happen if the PLUMED_KERNEL variable is not set correctly
1077 : plumed_finalize(p);
1078 : return whatever;
1079 : }
1080 : \endverbatim
1081 :
1082 : \return The constructed plumed object
1083 : */
1084 : __PLUMED_WRAPPER_C_BEGIN
1085 : plumed plumed_create(void);
1086 : __PLUMED_WRAPPER_C_END
1087 :
1088 : /** \relates plumed
1089 : \brief Constructor from path. Available as of PLUMED 2.5
1090 :
1091 : It tries to construct a plumed object loading the kernel located at path.
1092 : Notice that it could leave the resulting object in an invalid state.
1093 : In order to detect an invalid
1094 : plumed object you might use \ref plumed_valid() on the resulting object.
1095 : Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
1096 :
1097 : Also notice that to avoid memory leaks you should call \ref plumed_finalize()
1098 : to finalize a plumed object even if it is invalid.
1099 : \verbatim
1100 : plumed p=plumed_create(path);
1101 : if(!plumed_valid(p)) {
1102 : // this will happen if the path argument is not set correctly
1103 : plumed_finalize(p);
1104 : return whatever;
1105 : }
1106 : \endverbatim
1107 :
1108 : \return The constructed plumed object
1109 : */
1110 : __PLUMED_WRAPPER_C_BEGIN
1111 : plumed plumed_create_dlopen(const char*path);
1112 : __PLUMED_WRAPPER_C_END
1113 :
1114 :
1115 : /**
1116 : \brief Constructor from path. Available as of PLUMED 2.5
1117 :
1118 : Same as \ref plumed_create_dlopen, but also allows to specify the mode for dlopen.
1119 :
1120 : \warning
1121 : Use with care, since not all the possible modes work correctly with PLUMED.
1122 : */
1123 : __PLUMED_WRAPPER_C_BEGIN
1124 : plumed plumed_create_dlopen2(const char*path,int mode);
1125 : __PLUMED_WRAPPER_C_END
1126 :
1127 : /**
1128 : \brief Constructor from dlopen handle. Available as of PLUMED 2.8
1129 :
1130 : Same as \ref plumed_create_dlopen, but it acts on an already loaded library.
1131 : This allows to separate the library loading from the construction of the
1132 : plumed object. By using this function, the caller takes the responsibility
1133 : to later use dlclose on this handle.
1134 : */
1135 : __PLUMED_WRAPPER_C_BEGIN
1136 : plumed plumed_create_dlsym(void* dlhandle);
1137 : __PLUMED_WRAPPER_C_END
1138 :
1139 : /** \relates plumed
1140 : Create a new reference to an existing object, increasing its reference count. Available as of PLUMED 2.5
1141 :
1142 : Use it to increase by one the reference count of a plumed object.
1143 : The resulting pointer might be identical to the one passed as an
1144 : argument, but the reference count will be incremented by one.
1145 : Notice that you should finalize the resulting object.
1146 : \verbatim
1147 : plumed p1;
1148 : plumed p2;
1149 : p1=plumed_create();
1150 : p2=plumed_create_reference(p1);
1151 : plumed_finalize(p1);
1152 : // now you can still use p2
1153 : plumed_cmd(p2,"init",NULL);
1154 : plumed_finalize(p2);
1155 : // now the underlying object is destroyed.
1156 : \endverbatim
1157 :
1158 : If the `p` object is invalid, also the returned object will be invalid.
1159 :
1160 : \param p The plumed object that will be referenced to.
1161 : \return The constructed plumed object
1162 : */
1163 :
1164 : __PLUMED_WRAPPER_C_BEGIN
1165 : plumed plumed_create_reference(plumed p);
1166 : __PLUMED_WRAPPER_C_END
1167 :
1168 : /** \relates plumed
1169 : \brief Create a new reference to an existing object passed as a void pointer, increasing its reference count. Available as of PLUMED 2.5
1170 :
1171 : \return The constructed plumed object
1172 : */
1173 :
1174 : __PLUMED_WRAPPER_C_BEGIN
1175 : plumed plumed_create_reference_v(void*v);
1176 : __PLUMED_WRAPPER_C_END
1177 :
1178 : /** \relates plumed
1179 : \brief Create a new reference to an existing object passed as a fortran string, increasing its reference count. Available as of PLUMED 2.5
1180 :
1181 : \return The constructed plumed object
1182 : */
1183 :
1184 : __PLUMED_WRAPPER_C_BEGIN
1185 : plumed plumed_create_reference_f(const char*f);
1186 : __PLUMED_WRAPPER_C_END
1187 :
1188 : /** \relates plumed
1189 : \brief Constructor as invalid. Available as of PLUMED 2.5
1190 :
1191 : Can be used to create an object in the same state as if it was returned by
1192 : plumed_create_dlopen with an incorrect path (or plumed_create using runtime binding
1193 : and an incorrect PLUMED_KERNEL).
1194 :
1195 : Can be used to initialize a plumed object to a well-defined state without explicitly
1196 : creating it. The resulting object can be checked later with \ref plumed_valid.
1197 : Consider the following example
1198 : \verbatim
1199 : plumed p;
1200 : p=plumed_create_invalid();
1201 : // at this point p is initialized to a well-defined (invalid) state.
1202 : setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
1203 : plumed_finalize(p);
1204 : p=plumed_create();
1205 : \endverbatim
1206 :
1207 : \return The constructed plumed object
1208 : */
1209 :
1210 : __PLUMED_WRAPPER_C_BEGIN
1211 : plumed plumed_create_invalid();
1212 : __PLUMED_WRAPPER_C_END
1213 :
1214 : /** \relates plumed
1215 : \brief Tells p to execute a command.
1216 :
1217 : If the object is not valid (see \ref plumed_valid), this command will exit.
1218 :
1219 : \param p The plumed object on which command is acting
1220 : \param key The name of the command to be executed
1221 : \param val The argument. It is declared as const to allow calls like plumed_cmd(p,"A","B"),
1222 : but for some choice of key it can change the content.
1223 :
1224 : Notice that within PLUMED we use a const_cast to remove any const qualifier from the second
1225 : argument of \ref plumed_cmd.
1226 :
1227 : In some cases val can be omitted: just pass a NULL pointer (in C++, val is optional and can be omitted,
1228 : or you can equivalently pass NULL or nullptr).
1229 : The set of possible keys is the real API of the plumed library, and will be expanded with time.
1230 : New commands will be added, but backward compatibility will be retained as long as possible.
1231 : */
1232 :
1233 : __PLUMED_WRAPPER_C_BEGIN
1234 : void plumed_cmd(plumed p,const char*key,const void*val);
1235 : __PLUMED_WRAPPER_C_END
1236 :
1237 : /**
1238 : \relates plumed
1239 : \brief Same as \ref plumed_cmd, but does not throw exceptions.
1240 :
1241 : This function is meant to be used when errors should be handled explicitly.
1242 : if an exception is raised within PLUMED, the function nothrow.handler() will
1243 : be called with arguments (nothrow.ptr,code,message,opt). This allows the C++ interface
1244 : to correctly rethrow exceptions, but might be used from C as well. opt can be used
1245 : to pass further information (not used yet).
1246 : */
1247 :
1248 : __PLUMED_WRAPPER_C_BEGIN
1249 : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow);
1250 : __PLUMED_WRAPPER_C_END
1251 :
1252 : __PLUMED_WRAPPER_C_BEGIN
1253 : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr,plumed_nothrow_handler nothrow);
1254 : __PLUMED_WRAPPER_C_END
1255 :
1256 : __PLUMED_WRAPPER_C_BEGIN
1257 : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr);
1258 : __PLUMED_WRAPPER_C_END
1259 :
1260 : /** \relates plumed
1261 : \brief Destructor.
1262 :
1263 : It must be used for any object created using \ref plumed_create(),
1264 : even if the created object is not valid.
1265 :
1266 : \param p The plumed object to be deallocated
1267 : */
1268 :
1269 : __PLUMED_WRAPPER_C_BEGIN
1270 : void plumed_finalize(plumed p);
1271 : __PLUMED_WRAPPER_C_END
1272 :
1273 : /** \relates plumed
1274 : \brief Check if plumed is installed (for runtime binding).
1275 :
1276 : Notice that this is equivalent to creating a dummy object and checking if it is valid.
1277 :
1278 : \verbatim
1279 : // this:
1280 : //int a=plumed_installed();
1281 : // is equivalent to this:
1282 :
1283 : plumed p=plumed_create();
1284 : int a=plumed_valid(p);
1285 : plumed_finalize(p);
1286 :
1287 : \endverbatim
1288 :
1289 : This function is mostly provided for compatibility with PLUMED 2.4, where \ref plumed_valid()
1290 : was not available. Using \ref plumed_valid() is now preferred since it creates a single object
1291 : instead of creating a dummy object that is then discarded.
1292 :
1293 : \return 1 if plumed is installed, 0 otherwise
1294 : */
1295 :
1296 : __PLUMED_WRAPPER_C_BEGIN
1297 : int plumed_installed(void);
1298 : __PLUMED_WRAPPER_C_END
1299 :
1300 : /** \relates plumed
1301 : \brief Check if plumed object is valid. Available as of PLUMED 2.5
1302 :
1303 : It might return false if plumed is not available at runtime.
1304 :
1305 : \return 1 if plumed is valid, 0 otherwise
1306 : */
1307 :
1308 : __PLUMED_WRAPPER_C_BEGIN
1309 : int plumed_valid(plumed p);
1310 : __PLUMED_WRAPPER_C_END
1311 :
1312 : /** \relates plumed
1313 : \brief Returns the number of references to the underlying object. Available as of PLUMED 2.5.
1314 : */
1315 :
1316 : __PLUMED_WRAPPER_C_BEGIN
1317 : int plumed_use_count(plumed p);
1318 : __PLUMED_WRAPPER_C_END
1319 :
1320 :
1321 : /* routines to convert char handler from/to plumed objects */
1322 :
1323 : /** \related plumed
1324 : \brief Converts a C handler to a FORTRAN handler
1325 :
1326 : \param p The C handler
1327 : \param c The FORTRAN handler (a char[32])
1328 :
1329 : This function can be used to convert a plumed object created in C to
1330 : a plumed handler that can be used in FORTRAN. Notice that the reference counter
1331 : is not incremented. In other words, the FORTRAN object will be a weak reference.
1332 : If you later finalize the C handler, the FORTRAN handler will be invalid.
1333 : \verbatim
1334 : #include <plumed/wrapper/Plumed.h>
1335 : int main(int argc,char*argv[]){
1336 : plumed p;
1337 : p=plumed_create();
1338 : char fortran_handler[32];
1339 : plumed_c2f(p,fortran_handler);
1340 : printf("DEBUG: this is a string representation for the plumed handler: %s\n",fortran_handler);
1341 : fortran_routine(fortran_handler);
1342 : plumed_finalize(p);
1343 : return 0;
1344 : }
1345 : \endverbatim
1346 : Here `fortran_routine` is a routine implemented in FORTRAN that manipulates the
1347 : fortran_handler.
1348 : */
1349 :
1350 : __PLUMED_WRAPPER_C_BEGIN
1351 : void plumed_c2f(plumed p,char* c);
1352 : __PLUMED_WRAPPER_C_END
1353 :
1354 : /** \related plumed
1355 : \brief Converts a FORTRAN handler to a C handler
1356 : \param c The FORTRAN handler (a char[32])
1357 : \return The C handler
1358 :
1359 : This function can be used to convert a plumed object created in FORTRAN
1360 : to a plumed handler that can be used in C. Notice that the reference counter
1361 : is not incremented. In other words, the C object will be a weak reference.
1362 : If you later finalize the FORTRAN handler, the C handler will be invalid.
1363 : \verbatim
1364 : void c_routine(char handler[32]){
1365 : plumed p;
1366 : p=plumed_f2c(handler);
1367 : plumed_cmd(p,"init",NULL);
1368 : }
1369 : \endverbatim
1370 : Here `c_routine` is a C function that can be called from FORTRAN
1371 : and interact with the provided plumed handler.
1372 : */
1373 :
1374 : __PLUMED_WRAPPER_C_BEGIN
1375 : plumed plumed_f2c(const char* c);
1376 : __PLUMED_WRAPPER_C_END
1377 :
1378 : /** \related plumed
1379 : \brief Converts a plumed object to a void pointer. Available as of PLUMED 2.5.
1380 :
1381 : It returns a void pointer that can be converted back to a plumed object using \ref plumed_v2c.
1382 : When compiling without NDEBUG, it checks if the plumed object was properly created.
1383 : Notice that an invalid object (see \ref plumed_valid) can be converted to void* and back.
1384 :
1385 : Can be used to store a reference to a plumed object without including the Plumed.h header.
1386 : */
1387 :
1388 : __PLUMED_WRAPPER_C_BEGIN
1389 : void* plumed_c2v(plumed p);
1390 : __PLUMED_WRAPPER_C_END
1391 :
1392 :
1393 : /** \related plumed
1394 : \brief Converts a void pointer to a plumed object. Available as of PLUMED 2.5.
1395 :
1396 : It returns a plumed object from a void pointer obtained with \ref plumed_c2v.
1397 : When compiling without NDEBUG, it checks if the plumed object was properly created.
1398 :
1399 : Can be used to store a reference to a plumed object without including the Plumed.h header.
1400 : */
1401 :
1402 : __PLUMED_WRAPPER_C_BEGIN
1403 : plumed plumed_v2c(void*);
1404 : __PLUMED_WRAPPER_C_END
1405 :
1406 : #if ! defined( __cplusplus) /*{*/
1407 :
1408 : #if __PLUMED_WRAPPER_C_TYPESAFE /*{*/
1409 :
1410 : #define __PLUMED_WRAPPER_C_TYPESAFE_INNER(type_,typen_,flags_) \
1411 : static inline void plumed_cmdnse_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, const size_t* shape,plumed_error* error) { \
1412 : plumed_safeptr safe; \
1413 : plumed_nothrow_handler nothrow; \
1414 : safe.ptr=ptr; \
1415 : safe.nelem=nelem; \
1416 : safe.shape=(const size_t*)shape; \
1417 : safe.flags=flags_; \
1418 : safe.opt=NULL; \
1419 : if(error) { \
1420 : plumed_error_init(error); \
1421 : nothrow.ptr=error; \
1422 : nothrow.handler=plumed_error_set; \
1423 : plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
1424 : } else { \
1425 : plumed_cmd_safe(p,key,safe); \
1426 : } \
1427 : } \
1428 : static inline void plumed_cmdne_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, plumed_error* error) { \
1429 : plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,error); \
1430 : } \
1431 : static inline void plumed_cmdse_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape, plumed_error* error) { \
1432 : plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,error); \
1433 : } \
1434 : static inline void plumed_cmdn_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem) { \
1435 : plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,NULL); \
1436 : } \
1437 : static inline void plumed_cmds_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape) { \
1438 : plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,NULL); \
1439 : } \
1440 : static inline void plumed_cmde_ ## typen_(plumed p,const char*key,type_*ptr, plumed_error* error) { \
1441 : plumed_cmdnse_ ## typen_(p,key,ptr,0,NULL,error); \
1442 : }
1443 :
1444 : #define __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,size) \
1445 : __PLUMED_WRAPPER_C_TYPESAFE_INNER(type, type_ ## _p, size | (0x10000*(code)) | (0x2000000*2)) \
1446 : __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const, type_ ## _c, size | (0x10000*(code)) | (0x2000000*3)) \
1447 : __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*, type_ ## _pp, size | (0x10000*(code)) | (0x2000000*4)) \
1448 : __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*const, type_ ## _pc, size | (0x10000*(code)) | (0x2000000*5)) \
1449 : __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*, type_ ## _cp, size | (0x10000*(code)) | (0x2000000*6)) \
1450 : __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*const, type_ ## _cc, size | (0x10000*(code)) | (0x2000000*7))
1451 :
1452 : #define __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(type,type_,code) __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,0)
1453 :
1454 : #define __PLUMED_WRAPPER_C_TYPESAFE_SIZED(type,type_,code) \
1455 : __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,sizeof(type)) \
1456 : static inline void plumed_cmdnse_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, const size_t* shape, plumed_error* error) { \
1457 : plumed_safeptr safe; \
1458 : plumed_nothrow_handler nothrow; \
1459 : (void) nelem; \
1460 : (void) shape; \
1461 : safe.ptr=&val; \
1462 : safe.nelem=1; \
1463 : safe.shape=NULL; \
1464 : safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
1465 : safe.opt=NULL; \
1466 : if(error) { \
1467 : plumed_error_init(error); \
1468 : nothrow.ptr=error; \
1469 : nothrow.handler=plumed_error_set; \
1470 : plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
1471 : } else { \
1472 : plumed_cmd_safe(p,key,safe); \
1473 : } \
1474 : } \
1475 : static inline void plumed_cmdne_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, plumed_error* error) { \
1476 : plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,error); \
1477 : } \
1478 : static inline void plumed_cmdse_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape, plumed_error* error) { \
1479 : plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,error); \
1480 : } \
1481 : static inline void plumed_cmdn_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem) { \
1482 : plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,NULL); \
1483 : } \
1484 : static inline void plumed_cmds_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape) { \
1485 : plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,NULL); \
1486 : } \
1487 : static inline void plumed_cmde_ ## type_ ## _v(plumed p,const char*key,type val, plumed_error* error) { \
1488 : plumed_cmdnse_ ## type_ ## _v(p,key,val,0,NULL,error); \
1489 : }
1490 :
1491 : #define __PLUMED_WRAPPER_C_GENERIC1(flavor,type,typen_) \
1492 : type: plumed_ ## flavor ## _ ## typen_,
1493 :
1494 : #define __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
1495 : __PLUMED_WRAPPER_C_GENERIC1(flavor,type*, type_ ## _p) \
1496 : __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*, type_ ## _c) \
1497 : __PLUMED_WRAPPER_C_GENERIC1(flavor,type**, type_ ## _pp) \
1498 : __PLUMED_WRAPPER_C_GENERIC1(flavor,type*const*, type_ ## _pc) \
1499 : __PLUMED_WRAPPER_C_GENERIC1(flavor,type const**, type_ ## _cp) \
1500 : __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*const*, type_ ## _cc)
1501 :
1502 : #define __PLUMED_WRAPPER_C_GENERIC2(flavor,type,type_) \
1503 : __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
1504 : __PLUMED_WRAPPER_C_GENERIC1(flavor,type, type_ ## _v)
1505 :
1506 : /// Here we create all the required instances
1507 : /// 1: void
1508 : /// 3: integral
1509 : /// 4: floating
1510 : /// 5: FILE
1511 : /// 0x100: unsigned
1512 : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(void,void,1)
1513 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(char,char,(CHAR_MIN==0)*0x100+3)
1514 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned char,unsigned_char,0x100+3)
1515 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(signed char,signed_char,0x100+3)
1516 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(short,short,3)
1517 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned short,unsigned_short,0x100+3)
1518 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(int,int,3)
1519 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned int,unsigned_int,0x100+3)
1520 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long,long,3)
1521 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long,unsigned_long,0x100+3)
1522 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long long,long_long,3)
1523 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long long,unsigned_long_long,0x100+3)
1524 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(float,float,4)
1525 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(double,double,4)
1526 : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long double,long_double,4)
1527 : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(FILE,FILE,5)
1528 :
1529 : static inline void plumed_cmd_null_e(plumed p,const char*key,plumed_error* error,int ignore) {
1530 : (void) ignore;
1531 : plumed_cmde_void_p(p,key,NULL,error);
1532 : }
1533 :
1534 : #define plumed_cmdnse_inner(flavor,val) _Generic((val), \
1535 : __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,void,void) \
1536 : __PLUMED_WRAPPER_C_GENERIC2(flavor,char,char) \
1537 : __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned char,unsigned_char) \
1538 : __PLUMED_WRAPPER_C_GENERIC2(flavor,signed char,signed_char) \
1539 : __PLUMED_WRAPPER_C_GENERIC2(flavor,short,short) \
1540 : __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned short,unsigned_short) \
1541 : __PLUMED_WRAPPER_C_GENERIC2(flavor,int,int) \
1542 : __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned int,unsigned_int) \
1543 : __PLUMED_WRAPPER_C_GENERIC2(flavor,long,long) \
1544 : __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long,unsigned_long) \
1545 : __PLUMED_WRAPPER_C_GENERIC2(flavor,long long,long_long) \
1546 : __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long long,unsigned_long_long) \
1547 : __PLUMED_WRAPPER_C_GENERIC2(flavor,float,float) \
1548 : __PLUMED_WRAPPER_C_GENERIC2(flavor,double,double) \
1549 : __PLUMED_WRAPPER_C_GENERIC2(flavor,long double,long_double) \
1550 : __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,FILE,FILE) \
1551 : default: plumed_ ## flavor ## _void_c)
1552 :
1553 : #define plumed_cmd_2args(p,key) plumed_cmdnse_inner(cmdn,NULL) (p,key,NULL,0)
1554 :
1555 : #define plumed_cmd_3args(p,key,X) _Generic((X), \
1556 : plumed_error*: plumed_cmd_null_e, \
1557 : default: plumed_cmdnse_inner(cmdn,X)) (p,key,X,0)
1558 :
1559 : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
1560 : #define plumed_cmd_4args(p,key,val,X) _Generic(((X)+(size_t)0), \
1561 : const size_t *: plumed_cmdnse_inner(cmds,val), \
1562 : size_t *: plumed_cmdnse_inner(cmds,val), \
1563 : size_t: plumed_cmdnse_inner(cmdn,val), \
1564 : plumed_error*: plumed_cmdnse_inner(cmde,val) \
1565 : ) (p,key,val,X)
1566 :
1567 : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
1568 : #define plumed_cmd_5args(p,key,val,X,error) _Generic(((X)+(size_t)0), \
1569 : const size_t *: plumed_cmdnse_inner(cmdse,val), \
1570 : size_t *: plumed_cmdnse_inner(cmdse,val), \
1571 : size_t: plumed_cmdnse_inner(cmdne,val) \
1572 : ) (p,key,val,X,error)
1573 :
1574 : #define __PLUMED_WRAPPER_C_GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
1575 : #define plumed_cmd_c11(...) __PLUMED_WRAPPER_C_GET_MACRO(__VA_ARGS__, plumed_cmd_5args, plumed_cmd_4args, plumed_cmd_3args, plumed_cmd_2args)(__VA_ARGS__)
1576 :
1577 : #define plumed_gcmd_c11(...) plumed_cmd(plumed_global(),__VA_ARGS__)
1578 :
1579 : #define __PLUMED_WRAPPER_REDEFINE_CMD plumed_cmd_c11
1580 : #define __PLUMED_WRAPPER_REDEFINE_GCMD plumed_gcmd_c11
1581 :
1582 : #endif /*}*/
1583 :
1584 : #endif /*}*/
1585 :
1586 :
1587 : #if __PLUMED_WRAPPER_GLOBAL /*{*/
1588 :
1589 : /* Global C functions are always extern */
1590 : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
1591 :
1592 : /** \relates plumed
1593 : \brief Retrieves an handler to the global structure.
1594 :
1595 : You can use this if you work on a code that uses the global structure and you want to
1596 : pass to a generic routine an handler to the same structure. E.g.
1597 :
1598 : \verbatim
1599 : plumed p=plumed_global();
1600 : some_routine(p);
1601 : \endverbatim
1602 : */
1603 : extern
1604 : plumed plumed_global(void);
1605 :
1606 : /** \relates plumed
1607 : \brief Check if the global interface has been initialized.
1608 :
1609 : \return 1 if plumed has been initialized, 0 otherwise
1610 : */
1611 : extern
1612 : int plumed_ginitialized(void);
1613 :
1614 : /** \relates plumed
1615 : \brief Constructor for the global interface.
1616 :
1617 : \note Equivalent to plumed_create(), but initialize the static global plumed object
1618 : */
1619 : extern
1620 : void plumed_gcreate(void);
1621 :
1622 : /** \relates plumed
1623 : \brief Tells to the global interface to execute a command.
1624 :
1625 : \param key The name of the command to be executed
1626 : \param val The argument. It is declared as const to allow calls like plumed_gcmd("A","B"),
1627 : but for some choice of key it can change the content
1628 :
1629 : `plumed_gcmd(a,b);` is equivalent to `plumed_cmd(plumed_global(),a,b);`.
1630 : */
1631 : extern
1632 : void plumed_gcmd(const char* key,const void* val);
1633 :
1634 : /** \relates plumed
1635 : \brief Tells to the global interface to execute a command.
1636 :
1637 : \param key The name of the command to be executed
1638 : \param safe A safe pointer
1639 :
1640 : `plumed_gcmd_safe(a,b);` is equivalent to `plumed_cmd_safe(plumed_global(),a,b);`.
1641 : */
1642 : extern
1643 : void plumed_gcmd_safe(const char* key,plumed_safeptr);
1644 :
1645 : /** \relates plumed
1646 : \brief Destructor for the global interface.
1647 :
1648 : `plumed_gfinalize(a,b);` is similar to `plumed_finalize(plumed_global(),a,b);`, but not completely
1649 : equivalent. In particular, plumed_gfinalize() also makes sure that the global object
1650 : is reset to its initial status. After calling it, \ref plumed_ginitialized() will thus return 0.
1651 : */
1652 : extern
1653 : void plumed_gfinalize(void);
1654 :
1655 : /** \relates plumed
1656 : \brief Check if global plumed object is valid. Available as of PLUMED 2.5
1657 :
1658 : It might return zero if plumed is not available at runtime.
1659 :
1660 : \return 1 if plumed is valid, 0 otherwise.
1661 : */
1662 : extern
1663 : int plumed_gvalid();
1664 :
1665 : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
1666 :
1667 : #endif /*}*/
1668 :
1669 : #if defined( __cplusplus) && __PLUMED_WRAPPER_CXX /*{*/
1670 :
1671 : #if __PLUMED_WRAPPER_CXX_STD
1672 : #include <cstdlib> /* NULL getenv */
1673 : #include <cstddef> /* nullptr_t */
1674 : #include <cstring> /* strncat strlen */
1675 : #include <cassert> /* assert */
1676 : #include <climits> /* CHAR_MIN */
1677 : #else
1678 : #include <stddef.h>
1679 : #include <stdlib.h>
1680 : #include <string.h>
1681 : #include <assert.h>
1682 : #include <limits.h>
1683 : #endif
1684 :
1685 : #include <exception> /* exception bad_exception */
1686 : #include <stdexcept> /* runtime_error logic_error invalid_argument domain_error length_error out_of_range range_error overflow_error underflow_error */
1687 : #include <string> /* string */
1688 : #include <ios> /* iostream_category (C++11) ios_base::failure (C++11 and C++<11) */
1689 : #include <new> /* bad_alloc bad_array_new_length (C++11) */
1690 : #include <typeinfo> /* bad_typeid bad_cast */
1691 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1692 : #include <system_error> /* system_error generic_category system_category */
1693 : #include <future> /* future_category */
1694 : #include <memory> /* bad_weak_ptr */
1695 : #include <functional> /* bad_function_call */
1696 : #endif
1697 :
1698 : #if __cplusplus > 199711L
1699 : #include <array> /* array */
1700 : #include <initializer_list> /* initializer_list */
1701 : #endif
1702 :
1703 : /* C++ interface is hidden in PLMD namespace (same as plumed library) */
1704 : namespace PLMD {
1705 :
1706 : /* Optionally, it is further hidden in an anonymous namespace */
1707 :
1708 : __PLUMED_WRAPPER_ANONYMOUS_BEGIN /*{*/
1709 :
1710 : /**
1711 : Retrieve PLUMED_EXCEPTIONS_DEBUG (internal utility).
1712 :
1713 : This function should not be used by external programs. It is defined
1714 : as inline static so that it can store a static variable (for quicker access)
1715 : without adding a unique global symbol to a library including this header file.
1716 : */
1717 0 : inline static bool PlumedGetenvExceptionsDebug() __PLUMED_WRAPPER_CXX_NOEXCEPT {
1718 0 : static const char* res=__PLUMED_WRAPPER_STD getenv("PLUMED_EXCEPTIONS_DEBUG");
1719 0 : return res;
1720 : }
1721 :
1722 : /**
1723 : C++ wrapper for \ref plumed.
1724 :
1725 : This class provides a C++ interface to PLUMED.
1726 : It only containts a \ref plumed object, but wraps it with a number of useful methods.
1727 : All methods are inlined so as to avoid the compilation of an extra c++ file.
1728 :
1729 : */
1730 :
1731 : class Plumed {
1732 : /**
1733 : C structure.
1734 : */
1735 : plumed main;
1736 :
1737 : private:
1738 :
1739 : /**
1740 : This is an internal utility to dispatch exceptions based on the plumed_error object.
1741 :
1742 : It takes information about the exception to be thrown by the passed h object
1743 : and use it to call function f() on the resulting exception. Notice that:
1744 : - this function does not consider if the error is nested.
1745 : - f should be a callable object, so that it can store information
1746 : - f operator() should be a template function so as to act based on the
1747 : type of its argument
1748 :
1749 : New exceptions added here should be kept in sync with core/PlumedMainInitializer.cpp
1750 :
1751 : Notice that this function also finalizes in place plumed_error h, so as to avoid
1752 : memory leaks.
1753 : */
1754 : template<typename F>
1755 0 : __PLUMED_WRAPPER_CXX_NORETURN static void exception_dispatch(plumed_error&h,F f) {
1756 : /* this is required to make sure h is finalized when leaving this function */
1757 : finalize_plumed_error finalize(h);
1758 : /* grab the message */
1759 : const char* msg=plumed_error_what(h);
1760 0 : if(h.code==1) {
1761 0 : f(Plumed::Invalid(msg));
1762 : }
1763 : /* logic errors */
1764 0 : if(h.code>=10100 && h.code<10200) {
1765 0 : if(h.code>=10105 && h.code<10110) {
1766 0 : f(::std::invalid_argument(msg));
1767 : }
1768 0 : if(h.code>=10110 && h.code<10115) {
1769 0 : f(::std::domain_error(msg));
1770 : }
1771 0 : if(h.code>=10115 && h.code<10120) {
1772 0 : f(::std::length_error(msg));
1773 : }
1774 0 : if(h.code>=10120 && h.code<10125) {
1775 0 : f(::std::out_of_range(msg));
1776 : }
1777 0 : f(::std::logic_error(msg));
1778 : }
1779 : /* runtime errors */
1780 0 : if(h.code>=10200 && h.code<10300) {
1781 0 : if(h.code>=10205 && h.code<10210) {
1782 0 : f(::std::range_error(msg));
1783 : }
1784 0 : if(h.code>=10210 && h.code<10215) {
1785 0 : f(::std::overflow_error(msg));
1786 : }
1787 0 : if(h.code>=10215 && h.code<10220) {
1788 0 : f(::std::underflow_error(msg));
1789 : }
1790 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1791 : if(h.code==10220) {
1792 : f(::std::system_error(h.error_code,::std::generic_category(),msg));
1793 : }
1794 : if(h.code==10221) {
1795 : f(::std::system_error(h.error_code,::std::system_category(),msg));
1796 : }
1797 : if(h.code==10222) {
1798 : f(::std::system_error(h.error_code,::std::iostream_category(),msg));
1799 : }
1800 : if(h.code==10223) {
1801 : f(::std::system_error(h.error_code,::std::future_category(),msg));
1802 : }
1803 : #endif
1804 0 : if(h.code>=10230 && h.code<10240) {
1805 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1806 : // These cases are probably useless as it looks like this should always be std::iostream_category
1807 : if(h.code==10230) {
1808 : f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::generic_category())));
1809 : }
1810 : if(h.code==10231) {
1811 : f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::system_category())));
1812 : }
1813 : if(h.code==10232) {
1814 : f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::iostream_category())));
1815 : }
1816 : if(h.code==10233) {
1817 : f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::future_category())));
1818 : }
1819 : #endif
1820 0 : f(::std::ios_base::failure(msg));
1821 : }
1822 0 : f(::std::runtime_error(msg));
1823 : }
1824 : /* "bad" errors */
1825 : /* "< ::" space required in C++ < 11 */
1826 0 : if(h.code>=11000 && h.code<11100) {
1827 0 : f(add_buffer_to< ::std::bad_typeid>(msg));
1828 : }
1829 0 : if(h.code>=11100 && h.code<11200) {
1830 0 : f(add_buffer_to< ::std::bad_cast>(msg));
1831 : }
1832 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1833 : if(h.code>=11200 && h.code<11300) {
1834 : f(add_buffer_to< ::std::bad_weak_ptr>(msg));
1835 : }
1836 : if(h.code>=11300 && h.code<11400) {
1837 : f(add_buffer_to< ::std::bad_function_call>(msg));
1838 : }
1839 : #endif
1840 0 : if(h.code>=11400 && h.code<11500) {
1841 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1842 : if(h.code>=11410 && h.code<11420) {
1843 : f(add_buffer_to< ::std::bad_array_new_length>(msg));
1844 : }
1845 : #endif
1846 0 : f(add_buffer_to< ::std::bad_alloc>(msg));
1847 : }
1848 0 : if(h.code>=11500 && h.code<11600) {
1849 0 : f(add_buffer_to< ::std::bad_exception>(msg));
1850 : }
1851 : /* lepton error */
1852 0 : if(h.code>=19900 && h.code<20000) {
1853 0 : f(Plumed::LeptonException(msg));
1854 : }
1855 : /* plumed exceptions */
1856 0 : if(h.code>=20000 && h.code<30000) {
1857 : /* debug - only raised with debug options */
1858 0 : if(h.code>=20100 && h.code<20200) {
1859 0 : f(Plumed::ExceptionDebug(msg));
1860 : }
1861 : /* error - runtime check */
1862 0 : if(h.code>=20200 && h.code<20300) {
1863 0 : f(Plumed::ExceptionError(msg));
1864 : }
1865 : /* error - type error */
1866 0 : if(h.code>=20300 && h.code<20400) {
1867 0 : f(Plumed::ExceptionTypeError(msg));
1868 : }
1869 0 : f(Plumed::Exception(msg));
1870 : }
1871 : /* fallback for any other exception */
1872 0 : f(add_buffer_to< ::std::exception>(msg));
1873 : }
1874 :
1875 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
1876 : /** Internal class used by exception_dispatch. */
1877 : class rethrow_nested {
1878 : public:
1879 : template<typename E>
1880 : __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
1881 0 : std::throw_with_nested(e);
1882 : }
1883 : };
1884 : #endif
1885 :
1886 : /** Internal class used by exception_dispatch. */
1887 : class rethrow_not_nested {
1888 : public:
1889 : template<typename E>
1890 0 : __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
1891 0 : throw e;
1892 : }
1893 : };
1894 :
1895 : /** Internal class to simplify plumed_error finalization */
1896 : class finalize_plumed_error {
1897 : plumed_error&e;
1898 : finalize_plumed_error(const finalize_plumed_error&); //not implemented
1899 : public:
1900 : __PLUMED_WRAPPER_CXX_EXPLICIT finalize_plumed_error(plumed_error&e):
1901 : e(e)
1902 : {}
1903 : ~finalize_plumed_error() {
1904 0 : plumed_error_finalize(e);
1905 0 : e.code=0; // make sure it's not finalized again
1906 : }
1907 : };
1908 :
1909 : /**
1910 : Recursive function that rethrows an exception with all the nested ones.
1911 :
1912 : In order to do so, we start throwing from the first exception that was originally thrown
1913 : and recursively throw the others using throw_with_nested.
1914 :
1915 : plumed_error h is finalized at exit by the exception_dispatch function, to avoid memory leaks
1916 : */
1917 0 : __PLUMED_WRAPPER_CXX_NORETURN static void rethrow(plumed_error&h) {
1918 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
1919 : /*
1920 : When using C++11 nested exceptions, we need to rethrow recursively
1921 : */
1922 : try {
1923 0 : if(h.nested) {
1924 0 : rethrow(*h.nested); /* recursive throw */
1925 : }
1926 0 : } catch(...) {
1927 0 : exception_dispatch(h,rethrow_nested());
1928 0 : }
1929 0 : exception_dispatch(h,rethrow_not_nested());
1930 : #else
1931 : /*
1932 : When using C++<11 exceptions, we merge the message and then throw the resulting exception
1933 : */
1934 : if(h.nested) {
1935 : plumed_error_merge_with_nested(&h);
1936 : }
1937 : exception_dispatch(h,rethrow_not_nested());
1938 : #endif
1939 : }
1940 :
1941 : public:
1942 : /**
1943 : This is a tool to rethrow an error as an exception and finalize the error.
1944 :
1945 : In practice, this makes it possible to write a code like this:
1946 : ```
1947 : Plumed p;
1948 : plumed_error e;
1949 : // store error in e if something wrong happes
1950 : // notice that Plumed (C++) is implicitly converted to plumed (C) when calling plumed_cmd
1951 : plumed_cmd(p,"init",&e);
1952 : // do other things here
1953 : // then throw the exception
1954 : if(e.code) plumed_error_rethrow(e);
1955 :
1956 : It should be used through the macro plumed_error_rethrow.
1957 : ```
1958 : */
1959 : __PLUMED_WRAPPER_CXX_NORETURN static void plumed_error_rethrow_cxx(plumed_error h) {
1960 0 : rethrow(h);
1961 : }
1962 :
1963 : private:
1964 : /**
1965 : Rethrow the current exception.
1966 :
1967 : This is useful in order to handle an exception thrown by a kernel <=2.4.
1968 : Only std exceptions are handled, though some of them are thrown as special
1969 : Plumed exceptions in order to be attached a message.
1970 : */
1971 0 : __PLUMED_WRAPPER_CXX_NORETURN static void rethrow() {
1972 : try {
1973 0 : throw;
1974 0 : } catch(const ::std::bad_exception & e) {
1975 0 : throw add_buffer_to< ::std::bad_exception>(e.what());
1976 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1977 : } catch(const ::std::bad_array_new_length & e) {
1978 : throw add_buffer_to< ::std::bad_array_new_length>(e.what());
1979 : #endif
1980 0 : } catch(const ::std::bad_alloc & e) {
1981 0 : throw add_buffer_to< ::std::bad_alloc>(e.what());
1982 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1983 : } catch(const ::std::bad_function_call & e) {
1984 : throw add_buffer_to< ::std::bad_function_call>(e.what());
1985 : } catch(const ::std::bad_weak_ptr & e) {
1986 : throw add_buffer_to< ::std::bad_weak_ptr>(e.what());
1987 : #endif
1988 0 : } catch(const ::std::bad_cast & e) {
1989 0 : throw add_buffer_to< ::std::bad_cast>(e.what());
1990 0 : } catch(const ::std::bad_typeid & e) {
1991 0 : throw add_buffer_to< ::std::bad_typeid>(e.what());
1992 : // not implemented yet: std::regex_error
1993 : // we do not allow regex yet due to portability problems with gcc 4.8
1994 : // as soon as we transition to using <regex> it should be straightforward to add
1995 0 : } catch(const ::std::ios_base::failure & e) {
1996 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
1997 : throw ::std::ios_base::failure(e.what(),e.code());
1998 : #else
1999 0 : throw ::std::ios_base::failure(e.what());
2000 : #endif
2001 : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
2002 : } catch(const ::std::system_error & e) {
2003 : throw ::std::system_error(e.code(),e.what());
2004 : #endif
2005 0 : } catch(const ::std::underflow_error &e) {
2006 0 : throw ::std::underflow_error(e.what());
2007 0 : } catch(const ::std::overflow_error &e) {
2008 0 : throw ::std::overflow_error(e.what());
2009 0 : } catch(const ::std::range_error &e) {
2010 0 : throw ::std::range_error(e.what());
2011 0 : } catch(const ::std::runtime_error & e) {
2012 0 : throw ::std::runtime_error(e.what());
2013 : // not implemented yet: std::future_error
2014 : // not clear how useful it would be.
2015 0 : } catch(const ::std::out_of_range & e) {
2016 0 : throw ::std::out_of_range(e.what());
2017 0 : } catch(const ::std::length_error & e) {
2018 0 : throw ::std::length_error(e.what());
2019 0 : } catch(const ::std::domain_error & e) {
2020 0 : throw ::std::domain_error(e.what());
2021 0 : } catch(const ::std::invalid_argument & e) {
2022 0 : throw ::std::invalid_argument(e.what());
2023 0 : } catch(const ::std::logic_error & e) {
2024 0 : throw ::std::logic_error(e.what());
2025 0 : } catch(const ::std::exception & e) {
2026 0 : throw add_buffer_to< ::std::exception>(e.what());
2027 0 : } catch(...) {
2028 0 : throw add_buffer_to< ::std::bad_exception>("plumed could not translate exception");
2029 0 : }
2030 : }
2031 :
2032 : public:
2033 :
2034 : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
2035 : using Exception = PLMD::Exception;
2036 : #else
2037 : /**
2038 : Base class used to rethrow PLUMED exceptions.
2039 : */
2040 : class Exception :
2041 : public ::std::exception {
2042 : ::std::string msg;
2043 : public:
2044 0 : __PLUMED_WRAPPER_CXX_EXPLICIT Exception(const char* msg): msg(msg) {}
2045 0 : const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {
2046 0 : return msg.c_str();
2047 : }
2048 : #if ! (__cplusplus > 199711L)
2049 : /* Destructor should be declared in order to have the correct throw() before C++11 */
2050 : /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
2051 : ~Exception() throw() {}
2052 : #endif
2053 : };
2054 : #endif
2055 :
2056 : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
2057 : using ExceptionError = PLMD::ExceptionError;
2058 : #else
2059 : /**
2060 : Used to rethrow a PLMD::ExceptionError
2061 : */
2062 0 : class ExceptionError :
2063 : public Exception {
2064 : public:
2065 0 : __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionError(const char* msg): Exception(msg) {}
2066 : #if ! (__cplusplus > 199711L)
2067 : /* Destructor should be declared in order to have the correct throw() before C++11 */
2068 : /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
2069 : ~ExceptionError() throw() {}
2070 : #endif
2071 : };
2072 : #endif
2073 :
2074 : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
2075 : using ExceptionDebug = PLMD::ExceptionDebug;
2076 : #else
2077 : /**
2078 : Used to rethrow a PLMD::ExceptionDebug
2079 : */
2080 0 : class ExceptionDebug :
2081 : public Exception {
2082 : public:
2083 0 : __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionDebug(const char* msg): Exception(msg) {}
2084 : #if ! (__cplusplus > 199711L)
2085 : /* Destructor should be declared in order to have the correct throw() before C++11 */
2086 : /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
2087 : ~ExceptionDebug() throw() {}
2088 : #endif
2089 : };
2090 : #endif
2091 :
2092 : /**
2093 : Thrown when trying to access an invalid plumed object
2094 : */
2095 :
2096 0 : class Invalid :
2097 : public Exception {
2098 : public:
2099 0 : __PLUMED_WRAPPER_CXX_EXPLICIT Invalid(const char* msg): Exception(msg) {}
2100 : #if ! (__cplusplus > 199711L)
2101 : /* Destructor should be declared in order to have the correct throw() before C++11 */
2102 : /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
2103 : ~Invalid() throw() {}
2104 : #endif
2105 : };
2106 :
2107 : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
2108 : using ExceptionTypeError = PLMD::ExceptionTypeError;
2109 : #else
2110 : /**
2111 : Thrown when a wrong pointer is passed to the PLUMED interface.
2112 : */
2113 0 : class ExceptionTypeError:
2114 : public Exception {
2115 : public:
2116 0 : __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionTypeError(const char* msg): Exception(msg) {}
2117 : #if ! (__cplusplus > 199711L)
2118 : /* Destructor should be declared in order to have the correct throw() before C++11 */
2119 : /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
2120 : ~ExceptionTypeError() throw() {}
2121 : #endif
2122 : };
2123 : #endif
2124 :
2125 : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
2126 : using LeptonException = PLMD::lepton::Exception;
2127 : #else
2128 : /**
2129 : Class used to rethrow Lepton exceptions.
2130 : */
2131 :
2132 : class LeptonException :
2133 : public ::std::exception {
2134 : ::std::string msg;
2135 : public:
2136 0 : __PLUMED_WRAPPER_CXX_EXPLICIT LeptonException(const char* msg): msg(msg) {}
2137 0 : const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {
2138 0 : return msg.c_str();
2139 : }
2140 : #if ! (__cplusplus > 199711L)
2141 : /* Destructor should be declared in order to have the correct throw() before C++11 */
2142 : /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
2143 : ~LeptonException() throw() {}
2144 : #endif
2145 : };
2146 : #endif
2147 :
2148 : private:
2149 : /*
2150 : These exceptions are declared as private as they are not supposed to be
2151 : catched by value. they only exist to allow a buffer to be attached to
2152 : the std::exceptions that do not contain it already.
2153 : Notice that these exceptions are those whose constructor should never throw, and as
2154 : such they use a fixed size buffer.
2155 : */
2156 :
2157 : template<typename T>
2158 0 : class add_buffer_to:
2159 : public T {
2160 : char msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER];
2161 : \
2162 : public:
2163 0 : __PLUMED_WRAPPER_CXX_EXPLICIT add_buffer_to(const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT {
2164 0 : this->msg[0]='\0';
2165 0 : __PLUMED_WRAPPER_STD strncat(this->msg,msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1);
2166 0 : this->msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1]='\0';
2167 0 : if(PlumedGetenvExceptionsDebug() && __PLUMED_WRAPPER_STD strlen(msg) > __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1) {
2168 0 : __PLUMED_WRAPPER_STD fprintf(stderr,"+++ WARNING: message will be truncated\n");
2169 : }
2170 0 : }
2171 0 : add_buffer_to(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT {
2172 0 : msg[0]='\0';
2173 0 : __PLUMED_WRAPPER_STD memcpy(msg,other.msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER);
2174 : }
2175 : add_buffer_to & operator=(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT {
2176 : if(this==&other) {
2177 : return *this;
2178 : }
2179 : msg[0]='\0';
2180 : __PLUMED_WRAPPER_STD memcpy(msg,other.msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER);
2181 : return *this;
2182 : }
2183 0 : const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {
2184 0 : return msg;
2185 : }
2186 : #if ! (__cplusplus > 199711L)
2187 : /* Destructor should be declared in order to have the correct throw() before C++11 */
2188 : /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
2189 : ~add_buffer_to() throw() {}
2190 : #endif
2191 : };
2192 :
2193 : private:
2194 : /// Small class that wraps plumed_safeptr in order to make its initialization easier
2195 : class SafePtr {
2196 : /// non copyable (copy would require managing buffer, could be added in the future if needed)
2197 : SafePtr(const SafePtr&);
2198 : /// non assignable (assignment would require managing buffer, could be added in the future if needed)
2199 : SafePtr& operator=(SafePtr const&);
2200 : public:
2201 : plumed_safeptr safe;
2202 : /// This buffer holds a copy of the data when they are passed by value.
2203 : /// The size is sufficient to hold any primitive type.
2204 : /// Notice that the buffer is required to enable conversions (e.g., passing a class that can be converted to int)
2205 : /// and, at the same time, allow the object to exist after SafePtr constructor has completed.
2206 : /// A perhaps cleaner implementation would require a base class containing
2207 : /// the plumed_safeptr object, derived classes depending on the
2208 : /// argument type as a template parameter, and overloaded functions
2209 : /// returning this derived class.
2210 : char buffer[32];
2211 : /// Default constructor, nullptr
2212 : SafePtr() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2213 : safe.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
2214 : safe.nelem=0;
2215 : safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
2216 : safe.flags=0x10000*2;
2217 : safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
2218 : buffer[0]='\0';
2219 : }
2220 :
2221 222 : __PLUMED_WRAPPER_CXX_EXPLICIT SafePtr(const plumed_safeptr & safe,__PLUMED_WRAPPER_STD size_t nelem=0, const __PLUMED_WRAPPER_STD size_t* shape=__PLUMED_WRAPPER_CXX_NULLPTR) __PLUMED_WRAPPER_CXX_NOEXCEPT {
2222 222 : this->safe=safe;
2223 222 : buffer[0]='\0';
2224 : if(nelem>0) {
2225 : this->safe.nelem=nelem;
2226 : }
2227 : if(shape) {
2228 : this->safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape);
2229 : }
2230 : }
2231 :
2232 : #if __cplusplus > 199711L
2233 : /// Construct from null
2234 : SafePtr(__PLUMED_WRAPPER_STD nullptr_t,__PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) noexcept {
2235 : safe.ptr=nullptr;
2236 : safe.nelem=0;
2237 : safe.shape=nullptr;
2238 : safe.flags=0x10000*2;
2239 : safe.opt=nullptr;
2240 : buffer[0]='\0';
2241 : (void) nelem;
2242 : (void) shape;
2243 : }
2244 : #endif
2245 :
2246 : /// Macro that generate a constructor with given type and flags
2247 : #define __PLUMED_WRAPPER_SAFEPTR_INNER(type_,flags_) \
2248 : SafePtr(type_*ptr, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
2249 : safe.ptr=ptr; \
2250 : safe.nelem=nelem; \
2251 : safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape); \
2252 : safe.flags=flags_; \
2253 : safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
2254 : buffer[0]='\0'; \
2255 : }
2256 :
2257 : /// Macro that uses __PLUMED_WRAPPER_SAFEPTR_INNER to generate constructors with
2258 : /// all possible pointer-const combinations
2259 : #define __PLUMED_WRAPPER_SAFEPTR(type,code,size) \
2260 : __PLUMED_WRAPPER_SAFEPTR_INNER(type, size | (0x10000*(code)) | (0x2000000*2)) \
2261 : __PLUMED_WRAPPER_SAFEPTR_INNER(type const, size | (0x10000*(code)) | (0x2000000*3)) \
2262 : __PLUMED_WRAPPER_SAFEPTR_INNER(type*, size | (0x10000*(code)) | (0x2000000*4)) \
2263 : __PLUMED_WRAPPER_SAFEPTR_INNER(type*const, size | (0x10000*(code)) | (0x2000000*5)) \
2264 : __PLUMED_WRAPPER_SAFEPTR_INNER(type const*, size | (0x10000*(code)) | (0x2000000*6)) \
2265 : __PLUMED_WRAPPER_SAFEPTR_INNER(type const*const, size | (0x10000*(code)) | (0x2000000*7))
2266 :
2267 : /// Macro that generates the constructors from empy types (those of which sizeof cannot be computed)
2268 : #define __PLUMED_WRAPPER_SAFEPTR_EMPTY(type,code) __PLUMED_WRAPPER_SAFEPTR(type,code,0)
2269 :
2270 : /// Macro that generates the constructors from sized types (those of which sizeof can be computed).
2271 : /// In addition to generating constructors with all pointer types, it generates a constructor to
2272 : /// allow pass-by-value
2273 : #define __PLUMED_WRAPPER_SAFEPTR_SIZED(type,code) \
2274 : __PLUMED_WRAPPER_SAFEPTR(type,code,sizeof(type)) \
2275 : SafePtr(type val, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
2276 : assert(sizeof(type)<=32); \
2277 : (void) nelem; \
2278 : (void) shape; \
2279 : safe.ptr=buffer; \
2280 : safe.nelem=1; \
2281 : safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR; \
2282 : safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
2283 : safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
2284 : __PLUMED_WRAPPER_STD memcpy(buffer,&val,sizeof(type)); \
2285 : }
2286 :
2287 : /// Here we create all the required instances
2288 : /// 1: void
2289 : /// 3: integral
2290 : /// 4: floating
2291 : /// 5: FILE
2292 : /// 0x100: unsigned
2293 347 : __PLUMED_WRAPPER_SAFEPTR_EMPTY(void,1)
2294 4559 : __PLUMED_WRAPPER_SAFEPTR_SIZED(char,(CHAR_MIN==0)*0x100+3)
2295 : __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned char,3)
2296 : __PLUMED_WRAPPER_SAFEPTR_SIZED(signed char,0x100+3)
2297 : __PLUMED_WRAPPER_SAFEPTR_SIZED(short,3)
2298 : __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned short,0x100+3)
2299 9118 : __PLUMED_WRAPPER_SAFEPTR_SIZED(int,3)
2300 : __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned int,0x100+3)
2301 : __PLUMED_WRAPPER_SAFEPTR_SIZED(long,3)
2302 : __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long,0x100+3)
2303 : #if __PLUMED_WRAPPER_CXX_LONGLONG
2304 : __PLUMED_WRAPPER_SAFEPTR_SIZED(long long,3)
2305 : __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long long,0x100+3)
2306 : #endif
2307 : __PLUMED_WRAPPER_SAFEPTR_SIZED(float,4)
2308 : __PLUMED_WRAPPER_SAFEPTR_SIZED(double,4)
2309 : __PLUMED_WRAPPER_SAFEPTR_SIZED(long double,4)
2310 : __PLUMED_WRAPPER_SAFEPTR_EMPTY(FILE,5)
2311 :
2312 : /// Return the contained plumed_safeptr
2313 : plumed_safeptr get_safeptr() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
2314 14246 : return safe;
2315 : }
2316 :
2317 : };
2318 :
2319 : public:
2320 :
2321 : /**
2322 : Check if plumed is installed (for runtime binding)
2323 : \return true if plumed is installed, false otherwise
2324 : \note Equivalent to plumed_installed() but returns a bool
2325 : */
2326 : static bool installed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2327 : return plumed_installed();
2328 : }
2329 : /**
2330 : Check if Plumed object is valid. Available as of PLUMED 2.5
2331 : \return true if plumed is valid, false otherwise
2332 : \note Equivalent to plumed_valid() but returns a bool
2333 : */
2334 : bool valid() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
2335 : return plumed_valid(main);
2336 : }
2337 : #if __cplusplus > 199711L
2338 : /**
2339 : Same as \ref valid(). Available as of PLUMED 2.5.
2340 :
2341 : Allow code such as
2342 : \verbatim
2343 : Plumed p;
2344 : if(!p) raise_error();
2345 : p.cmd("init");
2346 : \endverbatim
2347 :
2348 : In order to avoid ambiguous conversions, this is only allowed when compiling with C++11
2349 : where it is marked as explicit.
2350 : */
2351 : explicit
2352 : operator bool() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
2353 : return plumed_valid(main);
2354 : }
2355 : #endif
2356 :
2357 : /**
2358 : Returns the number of references to this object. Available as of PLUMED 2.5.
2359 : \note Equivalent to plumed_use_count()
2360 : */
2361 : int useCount() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
2362 : return plumed_use_count(main);
2363 : }
2364 :
2365 : #if __PLUMED_WRAPPER_GLOBAL /*{*/
2366 : /**
2367 : Check if global-plumed has been initialized
2368 : \return true if global plumed object (see global()) is initialized (i.e. if gcreate() has been
2369 : called), false otherwise.
2370 : \note Equivalent to plumed_ginitialized() but returns a bool
2371 : */
2372 : static bool ginitialized() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2373 : return plumed_ginitialized();
2374 : }
2375 : /**
2376 : Check if global-plumed is valid
2377 : \return true if global plumed object (see global()) is valid.
2378 : \note Equivalent to plumed_gvalid() but returns a bool
2379 : */
2380 : static bool gvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2381 : return plumed_gvalid();
2382 : }
2383 : /**
2384 : Initialize global-plumed.
2385 : \warning Using the global objects in C++ is not recommended since they are difficult to use in
2386 : an exception safe manner. In particular, one should explicitly catch exceptions to
2387 : properly call gfinalize()
2388 : \note Equivalent to plumed_gcreate()
2389 : */
2390 : static void gcreate() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2391 : plumed_gcreate();
2392 : }
2393 : /**
2394 : Send a command to global-plumed
2395 : \param key The name of the command to be executed
2396 : \note Equivalent to plumed_gcmd()
2397 : */
2398 : static void gcmd(const char*key) {
2399 : global().cmd(key);
2400 : }
2401 : /**
2402 : Send a command to global-plumed
2403 : \param key The name of the command to be executed
2404 : \param val The argument.
2405 : \note Equivalent to plumed_gcmd()
2406 : */
2407 : template<typename T>
2408 : static void gcmd(const char*key,T val) {
2409 : global().cmd(key,val);
2410 : }
2411 : /**
2412 : Send a command to global-plumed
2413 : \param key The name of the command to be executed
2414 : \param val The argument.
2415 : \param nelem Number of elements in the passed array, for typechecking.
2416 : \note Equivalent to plumed_gcmd()
2417 : */
2418 : template<typename T>
2419 : static void gcmd(const char*key,T* val,__PLUMED_WRAPPER_STD size_t nelem) {
2420 : global().cmd(key,val,nelem);
2421 : }
2422 :
2423 : /**
2424 : Send a command to global-plumed
2425 : \param key The name of the command to be executed
2426 : \param val The argument.
2427 : \param shape The shape of the argument.
2428 : \note Equivalent to plumed_gcmd()
2429 : */
2430 : template<typename T>
2431 : static void gcmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
2432 : global().cmd(key,val,shape);
2433 : }
2434 :
2435 : #if __cplusplus > 199711L
2436 : /**
2437 : Send a command to global-plumed
2438 : \param key The name of the command to be executed
2439 : \param val The argument.
2440 : \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
2441 : \note Equivalent to plumed_gcmd()
2442 : */
2443 : template<typename T>
2444 : static void gcmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
2445 : global().cmd(key,val,shape);
2446 : }
2447 : #endif
2448 :
2449 : /**
2450 : Finalize global-plumed
2451 : */
2452 : static void gfinalize() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2453 : plumed_gfinalize();
2454 : }
2455 : /**
2456 : Returns the Plumed global object
2457 :
2458 : Notice that the object is copied, thus increasing the reference counter of the
2459 : global object. In this manner, the global object will survive after a call to
2460 : \ref gfinalize() if the resulting object is still in scope.
2461 :
2462 : \return The Plumed global object
2463 : */
2464 : static Plumed global() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2465 : return Plumed(plumed_global());
2466 : }
2467 : #endif /*}*/
2468 : /**
2469 : Constructor.
2470 :
2471 : Notice that when using runtime binding the constructed object might be
2472 : invalid. One might check it using the \ref valid() method.
2473 :
2474 : \note Performs the same task a plumed_create()
2475 : */
2476 4559 : Plumed()__PLUMED_WRAPPER_CXX_NOEXCEPT :
2477 : #if __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
2478 : main(plumed_create_invalid())
2479 : #else
2480 4559 : main(plumed_create())
2481 : #endif
2482 : {
2483 : }
2484 :
2485 : /**
2486 : Clone a Plumed object from a FORTRAN char* handler.
2487 :
2488 : \param c The FORTRAN handler (a char[32]).
2489 :
2490 : The reference counter for the corresponding object will be increased
2491 : to make sure that the object will be available after plumed_f_finalize is called
2492 : if the created object is still in scope.
2493 : */
2494 : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(const char*c)__PLUMED_WRAPPER_CXX_NOEXCEPT :
2495 : main(plumed_create_reference_f(c)) {
2496 : }
2497 :
2498 : /**
2499 : Create a reference from a void* pointer. Available as of PLUMED 2.5.
2500 : */
2501 : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(void*v)__PLUMED_WRAPPER_CXX_NOEXCEPT :
2502 : main(plumed_create_reference_v(v)) {
2503 : }
2504 :
2505 : /**
2506 : Clone a Plumed object from a C plumed structure
2507 :
2508 : \param p The C plumed structure.
2509 :
2510 : The reference counter for the corresponding object will be increased
2511 : to make sure that the object will be available after plumed_finalize is called
2512 : if the created object is still in scope.
2513 : */
2514 : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(plumed p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
2515 : main(plumed_create_reference(p)) {
2516 : }
2517 :
2518 : /** Copy constructor.
2519 :
2520 : Takes a reference, incrementing the reference counter of the corresponding object.
2521 : */
2522 : Plumed(const Plumed& p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
2523 : main(plumed_create_reference(p.main)) {
2524 : }
2525 :
2526 : /** Assignment operator. Available as of PLUMED 2.5.
2527 :
2528 : Takes a reference,incrementing the reference counter of the corresponding object.
2529 : */
2530 : Plumed&operator=(const Plumed&p) __PLUMED_WRAPPER_CXX_NOEXCEPT {
2531 : if(this != &p) {
2532 : // the check is needed to avoid calling plumed_finalize on moved objects
2533 : if(main.p) {
2534 : plumed_finalize(main);
2535 : }
2536 : main=plumed_create_reference(p.main);
2537 : }
2538 : return *this;
2539 : }
2540 :
2541 : /*
2542 : PLUMED >= 2.4 requires a C++11 compiler.
2543 : Anyway, since Plumed.h file might be redistributed with other codes
2544 : and it should be possible to combine it with earlier PLUMED versions,
2545 : we here explicitly check if C+11 is available before enabling move semantics.
2546 : */
2547 : #if __cplusplus > 199711L
2548 : /** Move constructor. Available as of PLUMED 2.5.
2549 : Only if move semantics is enabled.
2550 : */
2551 : Plumed(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
2552 : main(p.main) {
2553 : p.main.p=nullptr;
2554 : }
2555 : /** Move assignment. Available as of PLUMED 2.5.
2556 : Only if move semantics is enabled.
2557 : */
2558 : Plumed& operator=(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT {
2559 : if(this != &p) {
2560 : // the check is needed to avoid calling plumed_finalize on moved objects
2561 : if(main.p) {
2562 : plumed_finalize(main);
2563 : }
2564 : main=p.main;
2565 : p.main.p=nullptr;
2566 : }
2567 : return *this;
2568 : }
2569 : #endif
2570 : /**
2571 : Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
2572 :
2573 : It returns an object created with \ref plumed_create_dlopen. The object is owned and
2574 : is then finalized in the destructor. It can be used as follows:
2575 : \verbatim
2576 : PLMD::Plumed p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
2577 : // or, equivalenty:
2578 : // PLMD::Plumed p(PLMD::Plumed::dlopen("/path/to/libplumedKernel.so"));
2579 : p.cmd("init");
2580 : \endverbatim
2581 : or, equivalently, as
2582 : \verbatim
2583 : auto p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
2584 : p.cmd("init");
2585 : \endverbatim
2586 : */
2587 : static Plumed dlopen(const char* path)__PLUMED_WRAPPER_CXX_NOEXCEPT {
2588 : plumed p=plumed_create_dlopen(path);
2589 : Plumed pp(p);
2590 : plumed_finalize(p);
2591 : return pp;
2592 : }
2593 :
2594 : /**
2595 : Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
2596 :
2597 : Same as \ref dlopen(const char* path), but allows a dlopen mode to be chosen explicitly.
2598 : */
2599 : static Plumed dlopen(const char* path,int mode)__PLUMED_WRAPPER_CXX_NOEXCEPT {
2600 : plumed p=plumed_create_dlopen2(path,mode);
2601 : Plumed pp(p);
2602 : plumed_finalize(p);
2603 : return pp;
2604 : }
2605 : /**
2606 : Create a PLUMED object loading from an already opened shared library. Available as of PLUMED 2.8.
2607 :
2608 : Same as \ref dlopen(const char* path), but searches functions in an already loaded library.
2609 : See \ref plumed_create_dlsym.
2610 : */
2611 : static Plumed dlsym(void* dlhandle)__PLUMED_WRAPPER_CXX_NOEXCEPT {
2612 : plumed p=plumed_create_dlsym(dlhandle);
2613 : Plumed pp(p);
2614 : plumed_finalize(p);
2615 : return pp;
2616 : }
2617 :
2618 : /** Invalid constructor. Available as of PLUMED 2.5.
2619 :
2620 : Can be used to initialize an invalid object. It might be useful to postpone
2621 : the initialization of a Plumed object. Consider the following case
2622 : \verbatim
2623 : Plumed p;
2624 : setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
2625 : p.cmd("init")
2626 : \endverbatim
2627 : Here the `p` object will be initialized *before* the `PLUMED_KERNEL` env var has been set.
2628 : This can be particularly problematic if `p` is stored in some high level class.
2629 : The following case would do the job
2630 : \verbatim
2631 : Plumed p;
2632 : setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
2633 : p=Plumed();
2634 : p.cmd("init")
2635 : \endverbatim
2636 : However, there will be some error reported related to the attempt to load the kernel
2637 : when `p` is initialized. The following solution is the optimal one:
2638 : \verbatim
2639 : Plumed p(Plumed::makeInvalid());
2640 : setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
2641 : p=Plumed();
2642 : p.cmd("init")
2643 : \endverbatim
2644 : */
2645 : static Plumed makeInvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2646 : plumed p=plumed_create_invalid();
2647 : Plumed pp(p);
2648 : plumed_finalize(p);
2649 : return pp;
2650 : }
2651 :
2652 : /**
2653 : Create a valid PLMD::Plumed object.
2654 :
2655 : Can be used to create a valid object e.g. when Plumed.h was compiled with
2656 : `-D__PLUMED_WRAPPER_CXX_DEFAULT_INVALID`. For internal usage.
2657 : */
2658 :
2659 : static Plumed makeValid()__PLUMED_WRAPPER_CXX_NOEXCEPT {
2660 : plumed p=plumed_create();
2661 : Plumed pp(p);
2662 : plumed_finalize(p);
2663 : return pp;
2664 : }
2665 :
2666 :
2667 : /**
2668 : Retrieve the C plumed structure for this object.
2669 :
2670 : Notice that the resulting plumed structure is a weak reference and
2671 : should NOT be finalized, unless a new reference is explicitly added
2672 : \verbatim
2673 : Plumed p;
2674 : plumed c=p;
2675 : plumed_finalize(c); // <- this is wrong
2676 : \endverbatim
2677 : \verbatim
2678 : Plumed p;
2679 : plumed c=plumed_create_reference(p);
2680 : plumed_finalize(c); // <- this is right
2681 : \endverbatim
2682 : */
2683 : operator plumed()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
2684 : return main;
2685 : }
2686 :
2687 : /**
2688 : Retrieve a FORTRAN handler for this object
2689 : \param c The FORTRAN handler (a char[32]).
2690 : Notice that the resulting plumed structure is a weak reference and
2691 : should NOT be finalized, unless a new reference is explicitly added.
2692 : */
2693 : void toFortran(char*c)const __PLUMED_WRAPPER_CXX_NOEXCEPT {
2694 : plumed_c2f(main,c);
2695 : }
2696 :
2697 : /**
2698 : Retrieve a void* handler for this object. Available as of PLUMED 2.5.
2699 : Notice that the resulting plumed structure is a weak reference and
2700 : should NOT be finalized, unless a new reference is explicitly added.
2701 : */
2702 : void* toVoid()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
2703 : return plumed_c2v(main);
2704 : }
2705 :
2706 : /**
2707 : Increase reference counter. Available as of PLUMED 2.5.
2708 :
2709 : Using this method improperly might interfere with correct object construction
2710 : and destruction.
2711 : If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
2712 :
2713 : A possible usage is to transfer the ownership of a temporary
2714 : object when it is converted
2715 : \verbatim
2716 : plumed p=Plumed::dlopen(path).incref()
2717 : // without incref(), the just constructed object will be destroyed
2718 : // when the temporary object is deleted.
2719 : ... do stuff ...
2720 : plumed_finalize(p);
2721 : \endverbatim
2722 :
2723 : */
2724 : Plumed& incref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2725 : plumed_create_reference(main);
2726 : return *this;
2727 : }
2728 :
2729 : /**
2730 : Decrease reference counter. Available as of PLUMED 2.5.
2731 :
2732 : Using this method improperly might interfere with correct object construction
2733 : and destruction.
2734 : If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
2735 : */
2736 : Plumed& decref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2737 : // calling decref on a moved plumed object should give an error, so we do not check if main.p!=NULL here:
2738 : plumed_finalize(main);
2739 : return *this;
2740 : }
2741 :
2742 : private:
2743 :
2744 : /**
2745 : Private version of cmd. It is used here to avoid duplication of code between typesafe and not-typesafe versions
2746 : */
2747 14246 : static void cmd_priv(plumed main,const char*key, SafePtr*safe=__PLUMED_WRAPPER_CXX_NULLPTR, const void* unsafe=__PLUMED_WRAPPER_CXX_NULLPTR,plumed_error*error=__PLUMED_WRAPPER_CXX_NULLPTR) {
2748 :
2749 : plumed_error error_cxx;
2750 : plumed_error_init(&error_cxx);
2751 :
2752 : plumed_nothrow_handler nothrow;
2753 14246 : if(error) {
2754 : plumed_error_init(error);
2755 0 : nothrow.ptr=error;
2756 : } else {
2757 14246 : nothrow.ptr=&error_cxx;
2758 : }
2759 14246 : nothrow.handler=plumed_error_set;
2760 :
2761 : try {
2762 14246 : if(safe) {
2763 14246 : plumed_cmd_safe_nothrow(main,key,safe->get_safeptr(),nothrow);
2764 : } else {
2765 0 : plumed_cmd_nothrow(main,key,unsafe,nothrow);
2766 : }
2767 0 : } catch (...) {
2768 : assert(error_cxx.code==0); /* no need to plumed_error_finalize here */
2769 : /*
2770 : When loading a kernel <=2.4, plumed_cmd_nothrow could throw an exception.
2771 : If the exception is transmitted through the C interface and arrives here,
2772 : we translate it so as to free the virtual tables of the loaded kernel.
2773 : */
2774 0 : rethrow();
2775 0 : }
2776 : /* plumed_error_rethrow is finalizing */
2777 14246 : if(!error && error_cxx.code!=0) {
2778 : plumed_error_rethrow_cxx(error_cxx);
2779 : }
2780 14246 : }
2781 :
2782 : public:
2783 :
2784 : /**
2785 : Send a command to this plumed object
2786 : \param key The name of the command to be executed
2787 : \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
2788 : rethrow any exception raised within PLUMED.
2789 : */
2790 : void cmd(const char*key) {
2791 : plumed_cmd_cxx(main,key);
2792 : }
2793 :
2794 : /**
2795 : Send a command to this plumed object
2796 : \param key The name of the command to be executed
2797 : \param val The argument, passed by value.
2798 : \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
2799 : rethrow any exception raised within PLUMED.
2800 : \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
2801 : the type of the argument is checked.
2802 : */
2803 : template<typename T>
2804 : void cmd(const char*key,T val) {
2805 14024 : plumed_cmd_cxx(main,key,val);
2806 14024 : }
2807 :
2808 : /**
2809 : Send a command to this plumed object
2810 : \param key The name of the command to be executed
2811 : \param val The argument, passed by pointer.
2812 : \param shape A zero-terminated array containing the shape of the data.
2813 : \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
2814 : rethrow any exception raised within PLUMED.
2815 : \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
2816 : the type of the argument is checked. If shape is passed, it is also
2817 : checked that PLUMED access only compatible indexes.
2818 : */
2819 : template<typename T>
2820 : void cmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
2821 : plumed_cmd_cxx(main,key,val,shape);
2822 : }
2823 :
2824 : #if __cplusplus > 199711L
2825 : /**
2826 : Send a command to this plumed object
2827 : \param key The name of the command to be executed
2828 : \param val The argument, passed by pointer.
2829 : \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
2830 : \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
2831 : rethrow any exception raised within PLUMED.
2832 : \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
2833 : the type of the argument is checked. If shape is passed, it is also
2834 : checked that PLUMED access only compatible indexes.
2835 : */
2836 : template<typename T>
2837 : void cmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
2838 : if(shape.size()>4) {
2839 : throw Plumed::ExceptionTypeError("Maximum shape size is 4");
2840 : }
2841 : std::array<std::size_t,5> shape_;
2842 : unsigned j=0;
2843 : for(auto i : shape) {
2844 : shape_[j]=i;
2845 : j++;
2846 : }
2847 : shape_[j]=0;
2848 : plumed_cmd_cxx(main,key,val,&shape_[0]);
2849 : }
2850 : #endif
2851 : /**
2852 : Send a command to this plumed object
2853 : \param key The name of the command to be executed
2854 : \param val The argument, passed by pointer.
2855 : \param nelem The number of elements passed.
2856 : \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
2857 : rethrow any exception raised within PLUMED.
2858 : \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
2859 : the type of the argument is checked. nelem is used to check
2860 : the maximum index interpreting the array as flattened.
2861 : */
2862 : template<typename T>
2863 : void cmd(const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem) {
2864 : plumed_cmd_cxx(main,key,val,nelem);
2865 : }
2866 :
2867 : /**
2868 : Destructor
2869 :
2870 : It calls \ref plumed_finalize(). Notice that this is done also if the
2871 : constructor failed (that is, if it returned an invalid object). This allows
2872 : declaring Plumed objects also if PLUMED is actually not available, provided
2873 : one does not use the \ref cmd method.
2874 :
2875 : Destructor is virtual so as to allow correct inheritance from Plumed object.
2876 : */
2877 : #if __PLUMED_WRAPPER_CXX_POLYMORPHIC
2878 : virtual
2879 : #endif
2880 : ~Plumed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
2881 : // the check is needed to avoid calling plumed_finalize on moved objects
2882 4559 : if(main.p) {
2883 4559 : plumed_finalize(main);
2884 : }
2885 4559 : }
2886 :
2887 : /**
2888 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
2889 : namely implement typechecks and rethrowing exception.
2890 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
2891 : They are also used by the Plumed::cmd functions to avoid code duplication.
2892 : Available as of PLUMED 2.8.
2893 : */
2894 : static void plumed_cmd_cxx(plumed p,const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
2895 : #if __PLUMED_WRAPPER_CXX_TYPESAFE
2896 : SafePtr s;
2897 : cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
2898 : #else
2899 : cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,error);
2900 : #endif
2901 : }
2902 :
2903 : /**
2904 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
2905 : namely implement typechecks and rethrowing exception.
2906 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
2907 : They are also used by the Plumed::cmd functions to avoid code duplication.
2908 : Available as of PLUMED 2.8.
2909 : */
2910 : template<typename T>
2911 222 : static void plumed_cmd_cxx(plumed p,const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
2912 : #if __PLUMED_WRAPPER_CXX_TYPESAFE
2913 : SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
2914 222 : cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
2915 : #else
2916 : cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,&val,error);
2917 : #endif
2918 222 : }
2919 :
2920 : /**
2921 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
2922 : namely implement typechecks and rethrowing exception.
2923 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
2924 : They are also used by the Plumed::cmd functions to avoid code duplication.
2925 : Available as of PLUMED 2.8.
2926 : */
2927 : template<typename T>
2928 14024 : static void plumed_cmd_cxx(plumed p,const char*key,T* val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
2929 : #if __PLUMED_WRAPPER_CXX_TYPESAFE
2930 : SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
2931 14024 : cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
2932 : #else
2933 : cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
2934 : #endif
2935 14024 : }
2936 :
2937 : /**
2938 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
2939 : namely implement typechecks and rethrowing exception.
2940 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
2941 : They are also used by the Plumed::cmd functions to avoid code duplication.
2942 : Available as of PLUMED 2.8.
2943 : */
2944 : template<typename T>
2945 : static void plumed_cmd_cxx(plumed p,const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
2946 : #if __PLUMED_WRAPPER_CXX_TYPESAFE
2947 : SafePtr s(val,nelem,__PLUMED_WRAPPER_CXX_NULLPTR);
2948 : cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
2949 : #else
2950 : cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
2951 : #endif
2952 : }
2953 :
2954 : /**
2955 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
2956 : namely implement typechecks and rethrowing exception.
2957 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
2958 : They are also used by the Plumed::cmd functions to avoid code duplication.
2959 : Available as of PLUMED 2.8.
2960 : */
2961 : template<typename T>
2962 : static void plumed_cmd_cxx(plumed p,const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
2963 : #if __PLUMED_WRAPPER_CXX_TYPESAFE
2964 : SafePtr s(val,0,shape);
2965 : cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
2966 : #else
2967 : cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
2968 : #endif
2969 : }
2970 :
2971 :
2972 : #if __PLUMED_WRAPPER_GLOBAL /*{*/
2973 : /**
2974 : \related Plumed
2975 : This function can be used to make plumed_gcmd behave as the C++ wrapper PLMD::Plumed::gcmd,
2976 : namely implement typechecks and rethrowing exception.
2977 : To be used through the macro plumed_gcmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
2978 : Available as of PLUMED 2.8.
2979 : */
2980 :
2981 : /**
2982 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
2983 : namely implement typechecks and rethrowing exception.
2984 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
2985 : They are also used by the Plumed::cmd functions to avoid code duplication.
2986 : Available as of PLUMED 2.8.
2987 : */
2988 : static void plumed_gcmd_cxx(const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
2989 : plumed_cmd_cxx(plumed_global(),key,error);
2990 : }
2991 :
2992 : /**
2993 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
2994 : namely implement typechecks and rethrowing exception.
2995 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
2996 : They are also used by the Plumed::cmd functions to avoid code duplication.
2997 : Available as of PLUMED 2.8.
2998 : */
2999 : template<typename T>
3000 : static void plumed_gcmd_cxx(const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
3001 : plumed_cmd_cxx(plumed_global(),key,val,error);
3002 : }
3003 :
3004 : /**
3005 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
3006 : namely implement typechecks and rethrowing exception.
3007 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
3008 : They are also used by the Plumed::cmd functions to avoid code duplication.
3009 : Available as of PLUMED 2.8.
3010 : */
3011 : template<typename T>
3012 : static void plumed_gcmd_cxx(const char*key,T val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
3013 : plumed_cmd_cxx(plumed_global(),key,val,nelem,error);
3014 : }
3015 :
3016 : /**
3017 : These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
3018 : namely implement typechecks and rethrowing exception.
3019 : To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
3020 : They are also used by the Plumed::cmd functions to avoid code duplication.
3021 : Available as of PLUMED 2.8.
3022 : */
3023 : template<typename T>
3024 : static void plumed_gcmd_cxx(const char*key,T val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
3025 : plumed_cmd_cxx(plumed_global(),key,val,shape,error);
3026 : }
3027 :
3028 : #endif /*}*/
3029 :
3030 : #if __PLUMED_WRAPPER_CXX_BIND_C /*{*/
3031 :
3032 : #define __PLUMED_WRAPPER_REDEFINE_CMD ::PLMD::Plumed::plumed_cmd_cxx
3033 :
3034 : #if __PLUMED_WRAPPER_GLOBAL /*{*/
3035 : #define __PLUMED_WRAPPER_REDEFINE_GCMD ::PLMD::Plumed::plumed_gcmd_cxx
3036 : #endif /*}*/
3037 :
3038 : #define __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW ::PLMD::Plumed::plumed_error_rethrow_cxx
3039 :
3040 : #endif /*}*/
3041 :
3042 : };
3043 :
3044 : /**
3045 : \related Plumed
3046 : Comparison operator. Available as of PLUMED 2.5.
3047 : */
3048 : inline
3049 : bool operator==(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
3050 : return a.toVoid()==b.toVoid();
3051 : }
3052 :
3053 : /**
3054 : \related Plumed
3055 : Comparison operator. Available as of PLUMED 2.5.
3056 : */
3057 : inline
3058 : bool operator!=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
3059 : return a.toVoid()!=b.toVoid();
3060 : }
3061 :
3062 : /**
3063 : \related Plumed
3064 : Comparison operator. Available as of PLUMED 2.5.
3065 : */
3066 : inline
3067 : bool operator<=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
3068 : return a.toVoid()<=b.toVoid();
3069 : }
3070 :
3071 : /**
3072 : \related Plumed
3073 : Comparison operator. Available as of PLUMED 2.5.
3074 : */
3075 : inline
3076 : bool operator<(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
3077 : return a.toVoid()<b.toVoid();
3078 : }
3079 :
3080 : /**
3081 : \related Plumed
3082 : Comparison operator. Available as of PLUMED 2.5.
3083 : */
3084 : inline
3085 : bool operator>=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
3086 : return a.toVoid()>=b.toVoid();
3087 : }
3088 :
3089 : /**
3090 : \related Plumed
3091 : Comparison operator. Available as of PLUMED 2.5.
3092 : */
3093 : inline
3094 : bool operator>(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
3095 : return a.toVoid()>b.toVoid();
3096 : }
3097 :
3098 : __PLUMED_WRAPPER_ANONYMOUS_END /*}*/
3099 :
3100 : }
3101 :
3102 : #endif /*}*/
3103 :
3104 : #endif /*}*/
3105 :
3106 : /* END OF DECLARATIONS */
3107 :
3108 : /*
3109 :
3110 : 1: emit implementation
3111 : 0: do not emit implementation
3112 :
3113 : Allows an implementation to be emitted together with the declarations.
3114 :
3115 : Used to decide if definitions should be emitted. This macro could have a different
3116 : value when Plumed.h is reincluded. As a consequence, we map it to a local
3117 : macro (__PLUMED_WRAPPER_IMPLEMENTATION_) that is reset at the end of this file.
3118 : */
3119 :
3120 : #ifdef __PLUMED_WRAPPER_IMPLEMENTATION
3121 : #define __PLUMED_WRAPPER_IMPLEMENTATION_ __PLUMED_WRAPPER_IMPLEMENTATION
3122 : #else
3123 : #define __PLUMED_WRAPPER_IMPLEMENTATION_ 0
3124 : #endif
3125 :
3126 : /* BEGINNING OF DEFINITIONS */
3127 :
3128 : #if __PLUMED_WRAPPER_IMPLEMENTATION_ /*{*/
3129 : #ifndef __PLUMED_wrapper_Plumed_implementation /*{*/
3130 : #define __PLUMED_wrapper_Plumed_implementation
3131 :
3132 : /*
3133 : the following macros only control the implementation
3134 : */
3135 :
3136 : /*
3137 : 1: enable the definition of plumed_symbol_table_reexport
3138 : 0: does not enable the definition of plumed_symbol_table_reexport
3139 :
3140 : This is only needed in the official plumed library to make
3141 : the symbol table available. This is a hack to reexport the function table
3142 : and is only needed when creating the library libplumed.so.
3143 : */
3144 :
3145 : #ifndef __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
3146 : #define __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE 0
3147 : #endif
3148 :
3149 : /*
3150 : 1: write on stderr changes in reference counters
3151 : 0: do not write changes in reference counters
3152 :
3153 : Used for debugging.
3154 :
3155 : Only used in definitions.
3156 : */
3157 :
3158 : #ifndef __PLUMED_WRAPPER_DEBUG_REFCOUNT
3159 : #define __PLUMED_WRAPPER_DEBUG_REFCOUNT 0
3160 : #endif
3161 :
3162 : /*
3163 : 1: emit plumed_kernel_register function (default)
3164 : 0: do not emit plumed_kernel_register function
3165 :
3166 : This function is only needed to avoid an extra warning when loading old (<=2.4) kernels.
3167 : We might change its default in the future.
3168 :
3169 : Used only in definitions.
3170 : */
3171 :
3172 : #ifndef __PLUMED_WRAPPER_KERNEL_REGISTER
3173 : #define __PLUMED_WRAPPER_KERNEL_REGISTER 1
3174 : #endif
3175 :
3176 : /*
3177 : 1: emit Fortran wrappers
3178 : 0: do not emit Fortran wrappers (default)
3179 :
3180 : Used only in definitions.
3181 : */
3182 :
3183 : #ifndef __PLUMED_WRAPPER_FORTRAN
3184 : #define __PLUMED_WRAPPER_FORTRAN 0
3185 : #endif
3186 :
3187 : /*
3188 : With internal interface, it does not make sense to emit kernel register or fortran interfaces
3189 : */
3190 :
3191 : #if ! __PLUMED_WRAPPER_EXTERN /*{*/
3192 : #undef __PLUMED_WRAPPER_KERNEL_REGISTER
3193 : #define __PLUMED_WRAPPER_KERNEL_REGISTER 0
3194 : #undef __PLUMED_WRAPPER_FORTRAN
3195 : #define __PLUMED_WRAPPER_FORTRAN 0
3196 : #endif /*}*/
3197 :
3198 : #ifdef __PLUMED_HAS_DLOPEN
3199 : #include <dlfcn.h> /* dlopen dlerror dlsym */
3200 : #endif
3201 :
3202 : #if __PLUMED_WRAPPER_CXX_STD
3203 : #include <cstdio> /* fprintf */
3204 : #include <cstring> /* memcpy strlen strncpy memcmp memmove strcmp memcpy */
3205 : #include <cassert> /* assert */
3206 : #include <cstdlib> /* getenv malloc free abort */
3207 : #include <climits> /* CHAR_BIT */
3208 : #else
3209 : #include <stdio.h>
3210 : #include <string.h>
3211 : #include <assert.h>
3212 : #include <stdlib.h>
3213 : #include <limits.h>
3214 : #endif
3215 :
3216 : /**
3217 : Function pointer to plumed_create
3218 : */
3219 :
3220 : typedef void*(*plumed_create_pointer)(void);
3221 : /**
3222 : Function pointer to plumed_cmd
3223 : */
3224 : typedef void(*plumed_cmd_pointer)(void*,const char*,const void*);
3225 :
3226 : /**
3227 : Function pointer to plumed_finalize
3228 : */
3229 : typedef void(*plumed_finalize_pointer)(void*);
3230 :
3231 : /**
3232 : Holder for plumedmain function pointers.
3233 : */
3234 : typedef struct {
3235 : plumed_create_pointer create;
3236 : plumed_cmd_pointer cmd;
3237 : plumed_finalize_pointer finalize;
3238 : } plumed_plumedmain_function_holder;
3239 :
3240 : /**
3241 : Holder for plumed symbol table.
3242 :
3243 : The table contains pointers to function exported from plumed. Functions can be added increasing the version number.
3244 : Notice that the default way to extend functionalities is by adding cmd strings. This is a last resort, and all new
3245 : functions should be explicitly motivated. Here's the addition:
3246 :
3247 : version=2, cmd_nothrow.
3248 :
3249 : This function accepts an extra argument `plumed_nothrow_handler*handler`.
3250 : In case an exception is thrown within plumed, it just calls `handler->handler(handler->ptr,code,message,opt)` and return.
3251 : An alternative would have been to install an error handler (with a call to cmd("setErrorHandler")). However, the cost
3252 : of doing it everytime Plumed::cmd is called is too high. On the other hand, installing it only at object construction
3253 : is very risky since and object created in that way would not report any error if manipulated from the C interface.
3254 : So, it looks like this is the only possibility.
3255 :
3256 : version=3, cmd_safe and cmd_safe_nothrow
3257 :
3258 : These are functions that accept a plumed_safeptr object, which can carry information about the passed type and size.
3259 : Since new information should be passed at every cmd call, this can only be obtained by adding new cmd calls.
3260 :
3261 : version=4, thread-safe reference counter
3262 :
3263 : These functions allow to access a thread-safe reference counter that is stored within the PlumedMain object.
3264 : This allows avoiding to enable atomic access also the C compiler used build Plumed.c. It's added here and not as a new
3265 : cmd since this is a very low-level functionality.
3266 : */
3267 : typedef struct {
3268 : /**
3269 : Version number.
3270 :
3271 : Minimum value is 1.
3272 : */
3273 : int version;
3274 : /**
3275 : Pointers to standard plumed functions (create/cmd/finalize).
3276 :
3277 : Always available.
3278 : */
3279 : plumed_plumedmain_function_holder functions;
3280 : /**
3281 : Pointer to a cmd function guaranteed not to throw exceptions.
3282 :
3283 : Available with version>=2.
3284 : */
3285 : void (*cmd_nothrow)(void*plumed,const char*key,const void*val,plumed_nothrow_handler);
3286 : /**
3287 : Pointer to a cmd function that accepts typeinfos.
3288 :
3289 : Available with version>=3.
3290 : */
3291 : void (*cmd_safe)(void*plumed,const char*key,plumed_safeptr);
3292 :
3293 : /**
3294 : Pointer to a cmd function guaranteed not to throw exceptions and that accepts typeinfos.
3295 :
3296 : Available with version>=3.
3297 : */
3298 : void (*cmd_safe_nothrow)(void*plumed,const char*key,plumed_safeptr,plumed_nothrow_handler);
3299 :
3300 : /**
3301 : Pointer to a function that increments the internal reference counter.
3302 :
3303 : Available with version>=4.
3304 : */
3305 : unsigned (*create_reference)(void*);
3306 : /**
3307 : Pointer to a function that decrements the internal reference counter.
3308 :
3309 : Available with version>=4.
3310 : */
3311 : unsigned (*delete_reference)(void*);
3312 : /**
3313 : Pointer to a function that returns the internal reference counter.
3314 :
3315 : Available with version>=4.
3316 : */
3317 : unsigned (*use_count)(void*);
3318 : } plumed_symbol_table_type;
3319 :
3320 : /* Utility to convert function pointers to pointers, just for the sake of printing them */
3321 : #define __PLUMED_CONVERT_FPTR(ptr,fptr) { ptr=__PLUMED_WRAPPER_CXX_NULLPTR; __PLUMED_WRAPPER_STD memcpy(&ptr,&fptr,(sizeof(fptr)>sizeof(ptr)?sizeof(ptr):sizeof(fptr))); }
3322 :
3323 : #define __PLUMED_GETENV __PLUMED_WRAPPER_STD getenv
3324 : #define __PLUMED_FPRINTF __PLUMED_WRAPPER_STD fprintf
3325 :
3326 : /**
3327 : Historically (PLUMED<=2.4) register for plumedmain function pointers.
3328 : As of PLUMED>=2.5, this function does not do anything except for reporting the attempt to register
3329 : something. It always returns NULL. The function should be here anyway to allow an incomplete
3330 : libplumedKernel (<=2.4), expecting this function to be present, to be loaded correctly.
3331 : */
3332 : #if __PLUMED_WRAPPER_KERNEL_REGISTER
3333 : /* Since it is only called from outside, it must be hardcoded to be extern */
3334 : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
3335 : extern plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder*);
3336 13 : plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder* f) {
3337 : void* tmpptr;
3338 13 : if(f) {
3339 13 : if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) {
3340 0 : __PLUMED_FPRINTF(stderr,"+++ Ignoring registration at %p (",(const void*)f);
3341 : __PLUMED_CONVERT_FPTR(tmpptr,f->create);
3342 0 : __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
3343 : __PLUMED_CONVERT_FPTR(tmpptr,f->cmd);
3344 0 : __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
3345 : __PLUMED_CONVERT_FPTR(tmpptr,f->finalize);
3346 0 : __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
3347 : }
3348 : }
3349 13 : return __PLUMED_WRAPPER_CXX_NULLPTR;
3350 : }
3351 : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
3352 : #endif
3353 :
3354 : #if defined( __PLUMED_HAS_DLOPEN) /*{*/
3355 : /**
3356 : Try to dlopen a path with a given mode.
3357 : If the dlopen command fails, it tries to strip the `Kernel` part of the name.
3358 :
3359 : This function is declared static (internal linkage) so that it is not visible from outside.
3360 : It is first declared then defined to make sure it is a regular C static function.
3361 : */
3362 :
3363 : __PLUMED_WRAPPER_INTERNALS_BEGIN
3364 9 : void* plumed_attempt_dlopen(const char*path,int mode) {
3365 : char* pathcopy;
3366 : void* p;
3367 : char* pc;
3368 : __PLUMED_WRAPPER_STD size_t strlenpath;
3369 : FILE* fp;
3370 : pathcopy=__PLUMED_WRAPPER_CXX_NULLPTR;
3371 : p=__PLUMED_WRAPPER_CXX_NULLPTR;
3372 : pc=__PLUMED_WRAPPER_CXX_NULLPTR;
3373 : strlenpath=0;
3374 9 : fp=__PLUMED_WRAPPER_STD fopen(path,"r");
3375 9 : if(!fp) {
3376 0 : __PLUMED_FPRINTF(stderr,"+++ File %s does not exist or cannot be read\n",path);
3377 0 : return __PLUMED_WRAPPER_CXX_NULLPTR;
3378 : }
3379 9 : __PLUMED_WRAPPER_STD fclose(fp);
3380 9 : dlerror();
3381 9 : p=dlopen(path,mode);
3382 9 : if(!p) {
3383 : /*
3384 : Something went wrong. We try to remove "Kernel" string from the PLUMED_KERNEL variable
3385 : and load directly the shared library. Notice that this particular path is only expected
3386 : to be necessary when using PLUMED<=2.4 and the symbols in the main executable are
3387 : not visible. All the other cases (either PLUMED>=2.5 or symbols in the main executable visible)
3388 : should work correctly without entering here.
3389 : */
3390 0 : __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
3391 0 : strlenpath=__PLUMED_WRAPPER_STD strlen(path);
3392 0 : pathcopy=(char*) plumed_malloc(strlenpath+1);
3393 0 : if(!pathcopy) {
3394 0 : __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
3395 0 : __PLUMED_WRAPPER_STD abort();
3396 : }
3397 : __PLUMED_WRAPPER_STD strncpy(pathcopy,path,strlenpath+1);
3398 0 : pc=pathcopy+strlenpath-6;
3399 0 : while(pc>=pathcopy && __PLUMED_WRAPPER_STD memcmp(pc,"Kernel",6)) {
3400 0 : pc--;
3401 : }
3402 0 : if(pc>=pathcopy) {
3403 0 : __PLUMED_WRAPPER_STD memmove(pc, pc+6, __PLUMED_WRAPPER_STD strlen(pc)-5);
3404 0 : __PLUMED_FPRINTF(stderr,"+++ This error is expected if you are trying to load a kernel <=2.4\n");
3405 0 : __PLUMED_FPRINTF(stderr,"+++ Trying %s +++\n",pathcopy);
3406 0 : fp=__PLUMED_WRAPPER_STD fopen(path,"r");
3407 0 : if(!fp) {
3408 0 : __PLUMED_FPRINTF(stderr,"+++ File %s does not exist or cannot be read\n",pathcopy);
3409 0 : plumed_free(pathcopy);
3410 0 : return __PLUMED_WRAPPER_CXX_NULLPTR;
3411 : }
3412 0 : __PLUMED_WRAPPER_STD fclose(fp);
3413 0 : dlerror();
3414 0 : p=dlopen(pathcopy,mode);
3415 0 : if(!p) {
3416 0 : __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
3417 : }
3418 : }
3419 0 : plumed_free(pathcopy);
3420 : }
3421 : return p;
3422 : }
3423 : __PLUMED_WRAPPER_INTERNALS_END
3424 :
3425 : /**
3426 : Utility to search for a function.
3427 : */
3428 : #define __PLUMED_SEARCH_FUNCTION(tmpptr,handle,func,name,debug) \
3429 : if(!func) { \
3430 : tmpptr=dlsym(handle,name); \
3431 : if(tmpptr) { \
3432 : *(void **)(&func)=tmpptr; \
3433 : if(debug) __PLUMED_FPRINTF(stderr,"+++ %s found at %p +++\n",name,tmpptr); \
3434 : } else { \
3435 : if(debug) __PLUMED_FPRINTF(stderr,"+++ Function %s not found\n",name); \
3436 : } \
3437 : }
3438 :
3439 : /**
3440 : Search symbols in a dlopened library.
3441 :
3442 : This function is declared static (internal linkage) so that it is not visible from outside.
3443 : */
3444 : __PLUMED_WRAPPER_INTERNALS_BEGIN
3445 9 : void plumed_search_symbols(void* handle, plumed_plumedmain_function_holder* f,plumed_symbol_table_type** table) {
3446 : plumed_plumedmain_function_holder functions;
3447 : plumed_symbol_table_type* table_ptr;
3448 : void* tmpptr;
3449 : char* debug;
3450 : functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
3451 : functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
3452 : functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
3453 : table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
3454 9 : tmpptr=__PLUMED_WRAPPER_CXX_NULLPTR;
3455 : /*
3456 : Notice that as of PLUMED 2.5 we ignore self registrations.
3457 : Pointers are searched in the form of a single pointer to a structure, which
3458 : is the standard way in PLUMED 2.5, as well as using alternative names used in
3459 : PLUMED 2.0 to 2.4 (e.g. plumedmain_create) and in some intermediate versions between
3460 : PLUMED 2.4 and 2.5 (e.g. plumed_plumedmain_create). The last chance is probably
3461 : unnecessary and might be removed at some point.
3462 : */
3463 9 : debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
3464 9 : table_ptr=(plumed_symbol_table_type*) dlsym(handle,"plumed_symbol_table");
3465 9 : if(table_ptr) {
3466 9 : functions=table_ptr->functions;
3467 : }
3468 9 : if(debug) {
3469 0 : if(table_ptr) {
3470 0 : __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table version %i found at %p +++\n",table_ptr->version,(void*)table_ptr);
3471 0 : __PLUMED_FPRINTF(stderr,"+++ plumed_function_pointers found at %p (",(void*)&table_ptr->functions);
3472 : __PLUMED_CONVERT_FPTR(tmpptr,functions.create);
3473 0 : __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
3474 : __PLUMED_CONVERT_FPTR(tmpptr,functions.cmd);
3475 0 : __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
3476 : __PLUMED_CONVERT_FPTR(tmpptr,functions.finalize);
3477 0 : __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
3478 : } else {
3479 0 : __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table (available in PLUMED>=2.5) not found, perhaps kernel is older +++\n");
3480 : }
3481 : }
3482 : /* only searches if they were not found already */
3483 9 : __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumedmain_create",debug);
3484 9 : __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumed_plumedmain_create",debug);
3485 9 : __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumedmain_cmd",debug);
3486 9 : __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumed_plumedmain_cmd",debug);
3487 9 : __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumedmain_finalize",debug);
3488 9 : __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumed_plumedmain_finalize",debug);
3489 9 : if(functions.create && functions.cmd && functions.finalize) {
3490 9 : if(debug) {
3491 0 : __PLUMED_FPRINTF(stderr,"+++ PLUMED was loaded correctly +++\n");
3492 : }
3493 9 : *f=functions;
3494 9 : if(table) {
3495 9 : *table=table_ptr;
3496 : }
3497 : } else {
3498 0 : if(!functions.create) {
3499 0 : __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_create not found +++\n");
3500 : }
3501 0 : if(!functions.cmd) {
3502 0 : __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_cmd not found +++\n");
3503 : }
3504 0 : if(!functions.finalize) {
3505 0 : __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_finalize not found +++\n");
3506 : }
3507 0 : f->create=__PLUMED_WRAPPER_CXX_NULLPTR;
3508 0 : f->cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
3509 0 : f->finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
3510 0 : if(table) {
3511 0 : *table=__PLUMED_WRAPPER_CXX_NULLPTR;
3512 : }
3513 : }
3514 9 : }
3515 : __PLUMED_WRAPPER_INTERNALS_END
3516 :
3517 : #endif /*}*/
3518 :
3519 :
3520 : #if __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
3521 :
3522 : /*
3523 : Here is the case where plumed_symbol_table is
3524 : visible as extern. We first declare it (together with plumed_symbol_table_init) ...
3525 : */
3526 :
3527 : __PLUMED_WRAPPER_EXTERN_C_BEGIN
3528 : extern
3529 : plumed_symbol_table_type plumed_symbol_table;
3530 : __PLUMED_WRAPPER_EXTERN_C_END
3531 : __PLUMED_WRAPPER_EXTERN_C_BEGIN
3532 : extern
3533 : void plumed_symbol_table_init(void);
3534 : __PLUMED_WRAPPER_EXTERN_C_END
3535 :
3536 : /*
3537 : ... and then make available a function that returns the address
3538 : of the symbol table.
3539 : */
3540 : __PLUMED_WRAPPER_C_BEGIN
3541 699152 : plumed_symbol_table_type* plumed_symbol_table_reexport() {
3542 : /* make sure the table is initialized */
3543 699152 : plumed_symbol_table_init();
3544 709737 : return &plumed_symbol_table;
3545 : }
3546 : __PLUMED_WRAPPER_C_END
3547 :
3548 : #else
3549 :
3550 : /*
3551 : Here is the case where plumed_symbol_table is not
3552 : visible as extern. We thus assume that plumed_symbol_table_reexport is
3553 : available.
3554 : */
3555 :
3556 : __PLUMED_WRAPPER_EXTERN_C_BEGIN
3557 : extern plumed_symbol_table_type* plumed_symbol_table_reexport();
3558 : __PLUMED_WRAPPER_EXTERN_C_END
3559 : #endif
3560 :
3561 :
3562 : /*
3563 : Returns the global pointers, either those available at link time or those
3564 : found in the library loaded at PLUMED_KERNEL env var.
3565 : If plumed_symbol_table_ptr is not NULL, it is used to return a pointer to the symbol table
3566 : (if available).
3567 : Notice that problems can be detected checking if the functions have a NULL ptr.
3568 : On the other hand, the symbol table pointer might be NULL just because the plumed version is <=2.4.
3569 : If handle is not NULL, it is used to return a dlopen handle that could be subsequently dlclosed.
3570 : */
3571 : __PLUMED_WRAPPER_INTERNALS_BEGIN
3572 700939 : void plumed_retrieve_functions(plumed_plumedmain_function_holder* functions, plumed_symbol_table_type** plumed_symbol_table_ptr,void** handle) {
3573 : #if ! __PLUMED_WRAPPER_LINK_RUNTIME
3574 : /*
3575 : Real interface, constructed using the symbol table obtained with plumed_symbol_table_reexport.
3576 : This makes the symbols hardcoded and independent of a mis-set PLUMED_KERNEL variable.
3577 : */
3578 700939 : plumed_symbol_table_type* ptr=plumed_symbol_table_reexport();
3579 712173 : if(plumed_symbol_table_ptr) {
3580 712173 : *plumed_symbol_table_ptr=ptr;
3581 : }
3582 712173 : if(handle) {
3583 712173 : *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
3584 : }
3585 712173 : if(functions) {
3586 712173 : *functions=ptr->functions;
3587 : }
3588 : #elif ! defined(__PLUMED_HAS_DLOPEN)
3589 : /*
3590 : When dlopen is not available, we hard code them to NULL
3591 : */
3592 : __PLUMED_FPRINTF(stderr,"+++ PLUMED has been compiled without dlopen and without a static kernel +++\n");
3593 : plumed_plumedmain_function_holder g= {__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR};
3594 : if(plumed_symbol_table_ptr) {
3595 : *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
3596 : }
3597 : if(handle) {
3598 : *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
3599 : }
3600 : if(functions) {
3601 : *functions=g;
3602 : }
3603 : #else
3604 : /*
3605 : On the other hand, for runtime binding, we use dlsym to find the relevant functions.
3606 : */
3607 : plumed_plumedmain_function_holder g;
3608 : /* search is done once and only once */
3609 : const char* path;
3610 : void* p;
3611 : char* debug;
3612 : int dlopenmode;
3613 : g.create=__PLUMED_WRAPPER_CXX_NULLPTR;
3614 : g.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
3615 : g.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
3616 : path=__PLUMED_GETENV("PLUMED_KERNEL");
3617 : p=__PLUMED_WRAPPER_CXX_NULLPTR;
3618 : debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
3619 : dlopenmode=0;
3620 : if(plumed_symbol_table_ptr) {
3621 : *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
3622 : }
3623 : if(handle) {
3624 : *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
3625 : }
3626 : #ifdef __PLUMED_DEFAULT_KERNEL
3627 : /*
3628 : This variable allows a default path for the kernel to be hardcoded.
3629 : Can be useful for hardcoding the predefined plumed location
3630 : still allowing the user to override this choice setting PLUMED_KERNEL.
3631 : The path should be chosen at compile time adding e.g.
3632 : -D__PLUMED_DEFAULT_KERNEL=/opt/local/lib/libplumed.dylib
3633 : */
3634 : /* This is required to add quotes */
3635 : #define PLUMED_QUOTE_DIRECT(name) #name
3636 : #define PLUMED_QUOTE(macro) PLUMED_QUOTE_DIRECT(macro)
3637 : if(! (path && (*path) )) {
3638 : path=PLUMED_QUOTE(__PLUMED_DEFAULT_KERNEL);
3639 : }
3640 : #endif
3641 : if(path && (*path)) {
3642 : __PLUMED_FPRINTF(stderr,"+++ Loading the PLUMED kernel runtime +++\n");
3643 : __PLUMED_FPRINTF(stderr,"+++ PLUMED_KERNEL=\"%s\" +++\n",path);
3644 : if(debug) {
3645 : __PLUMED_FPRINTF(stderr,"+++ Loading with mode RTLD_NOW");
3646 : }
3647 : dlopenmode=RTLD_NOW;
3648 : if(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE"),"LOCAL")) {
3649 : dlopenmode=dlopenmode|RTLD_LOCAL;
3650 : if(debug) {
3651 : __PLUMED_FPRINTF(stderr,"|RTLD_LOCAL");
3652 : }
3653 : } else {
3654 : dlopenmode=dlopenmode|RTLD_GLOBAL;
3655 : if(debug) {
3656 : __PLUMED_FPRINTF(stderr,"|RTLD_GLOBAL");
3657 : }
3658 : }
3659 : #ifdef RTLD_DEEPBIND
3660 : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
3661 : if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) {
3662 : dlopenmode=dlopenmode|RTLD_DEEPBIND;
3663 : if(debug) {
3664 : __PLUMED_FPRINTF(stderr,"|RTLD_DEEPBIND");
3665 : }
3666 : }
3667 : #endif
3668 : #endif
3669 : if(debug) {
3670 : __PLUMED_FPRINTF(stderr," +++\n");
3671 : }
3672 : p=plumed_attempt_dlopen(path,dlopenmode);
3673 : if(p) {
3674 : plumed_search_symbols(p,&g,plumed_symbol_table_ptr);
3675 : }
3676 : }
3677 : if(handle) {
3678 : *handle=p;
3679 : }
3680 : if(functions) {
3681 : *functions=g;
3682 : }
3683 : #endif
3684 712173 : }
3685 : __PLUMED_WRAPPER_INTERNALS_END
3686 :
3687 : /**
3688 : Implementation.
3689 : Small object used to store pointers directly into the plumed object defined in Plumed.h.
3690 : This allows avoiding the extra function call to plumed_retrieve_functions at every cmd,
3691 : at the cost of an extra indirection.
3692 : */
3693 : typedef struct {
3694 : /* allows errors with pointers to be found when debugging */
3695 : char magic[6];
3696 : /* reference count. this is only used with PLUMED<=2.8. Later versions have an internal thread-safe reference counter. */
3697 : int refcount;
3698 : /* handler to dlopened library. NULL if there was no library opened */
3699 : void* dlhandle;
3700 : /* non zero if, upon destruction, the library should be dlclosed */
3701 : int dlclose;
3702 : /* 1 if path to kernel was taken from PLUMED_KERNEL var, 0 otherwise */
3703 : int used_plumed_kernel;
3704 : /* function pointers */
3705 : plumed_plumedmain_function_holder functions;
3706 : /* pointer to the symbol table. NULL if kernel <=2.4 */
3707 : plumed_symbol_table_type* table;
3708 : /* pointer to plumed object */
3709 : void* p;
3710 : } plumed_implementation;
3711 :
3712 : __PLUMED_WRAPPER_INTERNALS_BEGIN
3713 710310 : plumed_implementation* plumed_malloc_pimpl() {
3714 : plumed_implementation* pimpl;
3715 : /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
3716 710309 : pimpl=(plumed_implementation*) plumed_malloc(sizeof(plumed_implementation));
3717 728936 : if(!pimpl) {
3718 0 : __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
3719 0 : __PLUMED_WRAPPER_STD abort();
3720 : }
3721 728936 : __PLUMED_WRAPPER_STD memcpy(pimpl->magic,"pLuMEd",6);
3722 728936 : pimpl->refcount=1;
3723 : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
3724 : __PLUMED_FPRINTF(stderr,"refcount: new at %p\n",(void*)pimpl);
3725 : #endif
3726 728936 : pimpl->dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
3727 728936 : pimpl->dlclose=0;
3728 728936 : pimpl->used_plumed_kernel=0;
3729 728936 : pimpl->functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
3730 728936 : pimpl->functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
3731 728936 : pimpl->functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
3732 728936 : pimpl->table=__PLUMED_WRAPPER_CXX_NULLPTR;
3733 728936 : pimpl->p=__PLUMED_WRAPPER_CXX_NULLPTR;
3734 728936 : return pimpl;
3735 : }
3736 : __PLUMED_WRAPPER_INTERNALS_END
3737 :
3738 : #ifndef NDEBUG
3739 :
3740 : __PLUMED_WRAPPER_INTERNALS_BEGIN
3741 : int plumed_check_pimpl(plumed_implementation*pimpl) {
3742 : if(!pimpl) {
3743 : return 0;
3744 : }
3745 : if(__PLUMED_WRAPPER_STD memcmp(pimpl->magic,"pLuMEd",6)) {
3746 : return 0;
3747 : }
3748 : return 1;
3749 : }
3750 : __PLUMED_WRAPPER_INTERNALS_END
3751 : #endif
3752 :
3753 : /* C wrappers: */
3754 :
3755 : __PLUMED_WRAPPER_C_BEGIN
3756 737661 : plumed plumed_create(void) {
3757 : /* returned object */
3758 : plumed p;
3759 : /* pointer to implementation */
3760 : plumed_implementation* pimpl;
3761 : /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
3762 737661 : pimpl=plumed_malloc_pimpl();
3763 : /* store pointers in pimpl */
3764 725279 : plumed_retrieve_functions(&pimpl->functions,&pimpl->table,&pimpl->dlhandle);
3765 : #if __PLUMED_WRAPPER_LINK_RUNTIME
3766 : /* note if PLUMED_KERNEL variable was used */
3767 : pimpl->used_plumed_kernel=1;
3768 : #endif
3769 : /* note if handle should not be dlclosed */
3770 739355 : pimpl->dlclose=1;
3771 739355 : if(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE"),"no")) {
3772 0 : pimpl->dlclose=0;
3773 : }
3774 : /* in case of failure, return */
3775 : /* the resulting object should be plumed_finalized, though you cannot use plumed_cmd */
3776 781938 : if(!pimpl->functions.create) {
3777 : /* store pimpl in returned object */
3778 : p.p=pimpl;
3779 0 : return p;
3780 : }
3781 : assert(pimpl->functions.cmd);
3782 : assert(pimpl->functions.finalize);
3783 : /* obtain object */
3784 781938 : pimpl->p=(*(pimpl->functions.create))();
3785 : /* notice: we do not assert pimpl->p since in principle it might be nullptr */
3786 : /* user might identify this using plumed_valid() */
3787 : /* store pimpl in returned object */
3788 : p.p=pimpl;
3789 774110 : return p;
3790 : }
3791 : __PLUMED_WRAPPER_C_END
3792 :
3793 : __PLUMED_WRAPPER_C_BEGIN
3794 9 : plumed plumed_create_dlopen(const char*path) {
3795 : int dlopenmode;
3796 : /* plumed_create_dlopen always uses RTLD_LOCAL and, when possible, RTLD_DEEPBIND to allow multiple versions */
3797 : #ifdef __PLUMED_HAS_DLOPEN
3798 : dlopenmode=RTLD_NOW|RTLD_LOCAL;
3799 : #ifdef RTLD_DEEPBIND
3800 : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
3801 9 : if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) {
3802 : dlopenmode=dlopenmode|RTLD_DEEPBIND;
3803 : }
3804 : #endif
3805 : #endif
3806 : #else
3807 : dlopenmode=0;
3808 : #endif
3809 9 : return plumed_create_dlopen2(path,dlopenmode);
3810 : }
3811 : __PLUMED_WRAPPER_C_END
3812 :
3813 : __PLUMED_WRAPPER_C_BEGIN
3814 9 : plumed plumed_create_dlsym(void* dlhandle) {
3815 : /* returned object */
3816 : plumed p;
3817 : /* pointer to implementation */
3818 : plumed_implementation* pimpl;
3819 : /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
3820 9 : pimpl=plumed_malloc_pimpl();
3821 : #ifdef __PLUMED_HAS_DLOPEN
3822 9 : pimpl->dlhandle=dlhandle;
3823 9 : plumed_search_symbols(pimpl->dlhandle,&pimpl->functions,&pimpl->table);
3824 : #endif
3825 9 : if(!pimpl->functions.create) {
3826 : p.p=pimpl;
3827 0 : return p;
3828 : }
3829 : assert(pimpl->functions.cmd);
3830 : assert(pimpl->functions.finalize);
3831 : /* obtain object */
3832 9 : pimpl->p=(*(pimpl->functions.create))();
3833 : /* notice: we do not assert pimpl->p since in principle it might be nullptr */
3834 : /* user might identify this using plumed_valid() */
3835 : /* store pimpl in returned object */
3836 : p.p=pimpl;
3837 9 : return p;
3838 : }
3839 : __PLUMED_WRAPPER_C_END
3840 :
3841 : __PLUMED_WRAPPER_C_BEGIN
3842 9 : plumed plumed_create_dlopen2(const char*path,int mode) {
3843 : #ifdef __PLUMED_HAS_DLOPEN
3844 : /* returned object */
3845 : plumed p;
3846 : /* pointer to implementation */
3847 : plumed_implementation* pimpl;
3848 : /* handler */
3849 : void* dlhandle;
3850 : dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
3851 9 : if(path) {
3852 9 : dlhandle=plumed_attempt_dlopen(path,mode);
3853 : }
3854 : /* a NULL handle implies the file could not be loaded */
3855 9 : if(dlhandle) {
3856 9 : p=plumed_create_dlsym(dlhandle);
3857 : /* obtain pimpl */
3858 9 : pimpl=(plumed_implementation*) p.p;
3859 : /* make sure the handler is closed when plumed is finalized */
3860 9 : pimpl->dlclose=1;
3861 9 : return p;
3862 : }
3863 : #else
3864 : (void) path;
3865 : (void) mode;
3866 : #endif
3867 0 : return plumed_create_invalid();
3868 : }
3869 : __PLUMED_WRAPPER_C_END
3870 :
3871 : __PLUMED_WRAPPER_C_BEGIN
3872 7593703 : plumed plumed_create_reference(plumed p) {
3873 : plumed_implementation* pimpl;
3874 : /* obtain pimpl */
3875 7593703 : pimpl=(plumed_implementation*) p.p;
3876 : assert(plumed_check_pimpl(pimpl));
3877 : /* increase reference count */
3878 : /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
3879 7593703 : if(pimpl->p && pimpl->table && pimpl->table->version>3) {
3880 7553522 : pimpl->table->create_reference(pimpl->p);
3881 : } else {
3882 40181 : pimpl->refcount++;
3883 : }
3884 : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
3885 : __PLUMED_FPRINTF(stderr,"refcount: increase at %p\n",(void*)pimpl);
3886 : #endif
3887 7547322 : return p;
3888 : }
3889 : __PLUMED_WRAPPER_C_END
3890 :
3891 : __PLUMED_WRAPPER_C_BEGIN
3892 2 : plumed plumed_create_reference_v(void*v) {
3893 2 : return plumed_create_reference(plumed_v2c(v));
3894 : }
3895 : __PLUMED_WRAPPER_C_END
3896 :
3897 : __PLUMED_WRAPPER_C_BEGIN
3898 8 : plumed plumed_create_reference_f(const char*f) {
3899 8 : return plumed_create_reference(plumed_f2c(f));
3900 : }
3901 : __PLUMED_WRAPPER_C_END
3902 :
3903 : __PLUMED_WRAPPER_C_BEGIN
3904 2 : plumed plumed_create_invalid() {
3905 : plumed p;
3906 : plumed_implementation* pimpl;
3907 2 : pimpl=plumed_malloc_pimpl();
3908 : p.p=pimpl;
3909 2 : return p;
3910 : }
3911 : __PLUMED_WRAPPER_C_END
3912 :
3913 : __PLUMED_WRAPPER_C_BEGIN
3914 369 : void plumed_cmd(plumed p,const char*key,const void*val) {
3915 : plumed_implementation* pimpl;
3916 : /* obtain pimpl */
3917 369 : pimpl=(plumed_implementation*) p.p;
3918 : assert(plumed_check_pimpl(pimpl));
3919 369 : if(!pimpl->p) {
3920 0 : __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
3921 0 : if(pimpl->used_plumed_kernel) {
3922 0 : __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
3923 : }
3924 0 : __PLUMED_WRAPPER_STD abort();
3925 : }
3926 : assert(pimpl->functions.create);
3927 : assert(pimpl->functions.cmd);
3928 : assert(pimpl->functions.finalize);
3929 : /* execute */
3930 369 : (*(pimpl->functions.cmd))(pimpl->p,key,val);
3931 369 : }
3932 : __PLUMED_WRAPPER_C_END
3933 :
3934 : __PLUMED_WRAPPER_C_BEGIN
3935 15583 : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr safe,plumed_nothrow_handler nothrow) {
3936 : plumed_implementation* pimpl;
3937 : /* This is to allow caller to use a null handler to imply that handling is not done */
3938 15583 : if(!nothrow.handler) {
3939 37 : plumed_cmd_safe(p,key,safe);
3940 37 : return;
3941 : }
3942 : /* obtain pimpl */
3943 15546 : pimpl=(plumed_implementation*) p.p;
3944 : assert(plumed_check_pimpl(pimpl));
3945 15546 : if(!pimpl->p) {
3946 0 : if(pimpl->used_plumed_kernel) {
3947 0 : nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.\nCheck your PLUMED_KERNEL environment variable.",__PLUMED_WRAPPER_CXX_NULLPTR);
3948 : } else {
3949 0 : nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.",__PLUMED_WRAPPER_CXX_NULLPTR);
3950 : }
3951 0 : return;
3952 : }
3953 : assert(pimpl->functions.create);
3954 : assert(pimpl->functions.cmd);
3955 : assert(pimpl->functions.finalize);
3956 : /* execute */
3957 15546 : if(pimpl->table && pimpl->table->version>2) {
3958 15546 : (*(pimpl->table->cmd_safe_nothrow))(pimpl->p,key,safe,nothrow);
3959 0 : } else if(pimpl->table && pimpl->table->version>1) {
3960 0 : (*(pimpl->table->cmd_nothrow))(pimpl->p,key,safe.ptr,nothrow);
3961 : } else {
3962 0 : (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
3963 : }
3964 : }
3965 : __PLUMED_WRAPPER_C_END
3966 :
3967 : __PLUMED_WRAPPER_C_BEGIN
3968 0 : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow) {
3969 : plumed_safeptr safe;
3970 0 : safe.ptr=val;
3971 0 : safe.flags=0;
3972 0 : safe.nelem=0;
3973 0 : safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
3974 0 : safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
3975 0 : plumed_cmd_safe_nothrow(p,key,safe,nothrow);
3976 0 : }
3977 : __PLUMED_WRAPPER_C_END
3978 :
3979 : __PLUMED_WRAPPER_C_BEGIN
3980 107 : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr safe) {
3981 : plumed_implementation* pimpl;
3982 : /* obtain pimpl */
3983 107 : pimpl=(plumed_implementation*) p.p;
3984 : assert(plumed_check_pimpl(pimpl));
3985 107 : if(!pimpl->p) {
3986 0 : __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
3987 0 : if(pimpl->used_plumed_kernel) {
3988 0 : __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
3989 : }
3990 0 : __PLUMED_WRAPPER_STD abort();
3991 : }
3992 : assert(pimpl->functions.create);
3993 : assert(pimpl->functions.cmd);
3994 : assert(pimpl->functions.finalize);
3995 : /* execute */
3996 107 : if(pimpl->table && pimpl->table->version>2) {
3997 107 : (*(pimpl->table->cmd_safe))(pimpl->p,key,safe);
3998 : } else {
3999 0 : (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
4000 : }
4001 107 : }
4002 : __PLUMED_WRAPPER_C_END
4003 :
4004 :
4005 : __PLUMED_WRAPPER_C_BEGIN
4006 8512435 : void plumed_finalize(plumed p) {
4007 : plumed_implementation* pimpl;
4008 : /* obtain pimpl */
4009 8512435 : pimpl=(plumed_implementation*) p.p;
4010 : assert(plumed_check_pimpl(pimpl));
4011 : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
4012 : __PLUMED_FPRINTF(stderr,"refcount: decrease at %p\n",(void*)pimpl);
4013 : #endif
4014 : /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
4015 8512435 : if(pimpl->p && pimpl->table && pimpl->table->version>3) {
4016 8445099 : if(pimpl->table->delete_reference(pimpl->p)>0) {
4017 : return;
4018 : }
4019 : } else {
4020 67336 : if(--pimpl->refcount>0) {
4021 : return;
4022 : }
4023 : }
4024 : /* to allow finalizing an invalid plumed object, we only call
4025 : finalize if the object is valid */
4026 772332 : if(pimpl->p) {
4027 : assert(pimpl->functions.create);
4028 : assert(pimpl->functions.cmd);
4029 : assert(pimpl->functions.finalize);
4030 : /* finalize */
4031 772330 : (*(pimpl->functions.finalize))(pimpl->p);
4032 : }
4033 : #ifdef __PLUMED_HAS_DLOPEN
4034 : /* dlclose library */
4035 767723 : if(pimpl->dlhandle && pimpl->dlclose) {
4036 9 : if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) {
4037 0 : __PLUMED_FPRINTF(stderr,"+++ Unloading library\n");
4038 : }
4039 9 : dlclose(pimpl->dlhandle);
4040 : }
4041 : #endif
4042 : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
4043 : __PLUMED_FPRINTF(stderr,"refcount: delete at %p\n",(void*)pimpl);
4044 : #endif
4045 : /* free pimpl space */
4046 767722 : plumed_free(pimpl);
4047 : }
4048 : __PLUMED_WRAPPER_C_END
4049 :
4050 : __PLUMED_WRAPPER_C_BEGIN
4051 23 : int plumed_valid(plumed p) {
4052 : plumed_implementation* pimpl;
4053 : /* obtain pimpl */
4054 23 : pimpl=(plumed_implementation*) p.p;
4055 : assert(plumed_check_pimpl(pimpl));
4056 24 : if(pimpl->p) {
4057 : return 1;
4058 : } else {
4059 2 : return 0;
4060 : }
4061 : }
4062 : __PLUMED_WRAPPER_C_END
4063 :
4064 : __PLUMED_WRAPPER_C_BEGIN
4065 42 : int plumed_use_count(plumed p) {
4066 : plumed_implementation* pimpl;
4067 : /* obtain pimpl */
4068 42 : pimpl=(plumed_implementation*) p.p;
4069 : assert(plumed_check_pimpl(pimpl));
4070 : /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
4071 42 : if(pimpl->p && pimpl->table && pimpl->table->version>3) {
4072 42 : return pimpl->table->use_count(pimpl->p);
4073 : } else {
4074 0 : return pimpl->refcount;
4075 : }
4076 : }
4077 : __PLUMED_WRAPPER_C_END
4078 :
4079 : __PLUMED_WRAPPER_C_BEGIN
4080 9 : int plumed_installed(void) {
4081 : plumed p;
4082 : int result;
4083 9 : p=plumed_create();
4084 9 : result=plumed_valid(p);
4085 9 : plumed_finalize(p);
4086 9 : return result;
4087 : }
4088 : __PLUMED_WRAPPER_C_END
4089 :
4090 : __PLUMED_WRAPPER_C_BEGIN
4091 710847 : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size) {
4092 : void* ptr;
4093 710848 : ptr=__PLUMED_WRAPPER_STD malloc(size);
4094 : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
4095 : if(ptr) {
4096 : fprintf(stderr,"plumed_malloc: %p\n",ptr);
4097 : }
4098 : #endif
4099 710847 : return ptr;
4100 : }
4101 : __PLUMED_WRAPPER_C_END
4102 :
4103 : __PLUMED_WRAPPER_C_BEGIN
4104 756938 : void plumed_free(void* ptr) {
4105 756938 : __PLUMED_WRAPPER_STD free(ptr);
4106 : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
4107 : fprintf(stderr,"plumed_free: %p\n",ptr);
4108 : #endif
4109 756939 : }
4110 : __PLUMED_WRAPPER_C_END
4111 :
4112 : #if __PLUMED_WRAPPER_GLOBAL /*{*/
4113 :
4114 : __PLUMED_WRAPPER_EXTERN_C_BEGIN
4115 :
4116 : /* we declare a Plumed_g_main object here, in such a way that it is always available */
4117 :
4118 : static plumed plumed_gmain= {__PLUMED_WRAPPER_CXX_NULLPTR};
4119 :
4120 41 : plumed plumed_global(void) {
4121 41 : return plumed_gmain;
4122 : }
4123 :
4124 24 : void plumed_gcreate(void) {
4125 : /* should be created once */
4126 : assert(plumed_gmain.p==__PLUMED_WRAPPER_CXX_NULLPTR);
4127 24 : plumed_gmain=plumed_create();
4128 24 : }
4129 :
4130 90 : void plumed_gcmd(const char*key,const void*val) {
4131 90 : plumed_cmd(plumed_gmain,key,val);
4132 90 : }
4133 :
4134 : /* cppcheck-suppress passedByValue */
4135 0 : void plumed_gcmd_safe(const char*key,plumed_safeptr safe) {
4136 0 : plumed_cmd_safe(plumed_gmain,key,safe);
4137 0 : }
4138 :
4139 24 : void plumed_gfinalize(void) {
4140 24 : plumed_finalize(plumed_gmain);
4141 24 : plumed_gmain.p=__PLUMED_WRAPPER_CXX_NULLPTR;
4142 24 : }
4143 :
4144 24 : int plumed_ginitialized(void) {
4145 24 : if(plumed_gmain.p) {
4146 : return 1;
4147 : } else {
4148 16 : return 0;
4149 : }
4150 : }
4151 :
4152 8 : int plumed_gvalid() {
4153 : assert(plumed_gmain.p);
4154 8 : return plumed_valid(plumed_gmain);
4155 : }
4156 :
4157 : __PLUMED_WRAPPER_EXTERN_C_END
4158 :
4159 : #endif /*}*/
4160 :
4161 : __PLUMED_WRAPPER_C_BEGIN
4162 68 : void plumed_c2f(plumed p,char*c) {
4163 : unsigned i;
4164 : unsigned char* cc;
4165 : /*
4166 : Convert the address stored in p.p into a proper FORTRAN string
4167 : made of only ASCII characters. For this to work, the two following
4168 : assertions should be satisfied:
4169 : */
4170 : assert(CHAR_BIT<=12);
4171 : assert(sizeof(p.p)<=16);
4172 :
4173 : assert(c);
4174 : cc=(unsigned char*)&p.p;
4175 612 : for(i=0; i<sizeof(p.p); i++) {
4176 : /*
4177 : characters will range between '0' (ASCII 48) and 'o' (ASCII 111=48+63)
4178 : */
4179 544 : c[2*i]=cc[i]/64+48;
4180 544 : c[2*i+1]=cc[i]%64+48;
4181 : }
4182 612 : for(; i<16; i++) {
4183 544 : c[2*i]=' ';
4184 544 : c[2*i+1]=' ';
4185 : }
4186 68 : }
4187 : __PLUMED_WRAPPER_C_END
4188 :
4189 : __PLUMED_WRAPPER_C_BEGIN
4190 385 : plumed plumed_f2c(const char*c) {
4191 : plumed p;
4192 : unsigned i;
4193 : unsigned char* cc;
4194 :
4195 : assert(CHAR_BIT<=12);
4196 : assert(sizeof(p.p)<=16);
4197 :
4198 : assert(c);
4199 :
4200 : /*
4201 : needed to avoid cppcheck warning on uninitialized p
4202 : */
4203 385 : p.p=__PLUMED_WRAPPER_CXX_NULLPTR;
4204 : cc=(unsigned char*)&p.p;
4205 3465 : for(i=0; i<sizeof(p.p); i++) {
4206 : assert(c[2*i]>=48 && c[2*i]<48+64);
4207 : assert(c[2*i+1]>=48 && c[2*i+1]<48+64);
4208 : /*
4209 : perform the reversed transform
4210 : */
4211 3080 : cc[i]=(c[2*i]-48)*64 + (c[2*i+1]-48);
4212 : }
4213 3465 : for(; i<16; i++) {
4214 : assert(c[2*i]==' ');
4215 : assert(c[2*i+1]==' ');
4216 : }
4217 385 : return p;
4218 : }
4219 : __PLUMED_WRAPPER_C_END
4220 :
4221 : __PLUMED_WRAPPER_C_BEGIN
4222 2 : void* plumed_c2v(plumed p) {
4223 : assert(plumed_check_pimpl((plumed_implementation*)p.p));
4224 2 : return p.p;
4225 : }
4226 : __PLUMED_WRAPPER_C_END
4227 :
4228 : __PLUMED_WRAPPER_C_BEGIN
4229 2 : plumed plumed_v2c(void* v) {
4230 : assert(plumed_check_pimpl((plumed_implementation*)v));
4231 : plumed p;
4232 : p.p=v;
4233 2 : return p;
4234 : }
4235 : __PLUMED_WRAPPER_C_END
4236 :
4237 : #if __PLUMED_WRAPPER_FORTRAN /*{*/
4238 :
4239 : /*
4240 : Fortran wrappers
4241 : These are just like the global C wrappers. They are
4242 : just defined here and not declared since they
4243 : should not be used from c/c++ anyway.
4244 :
4245 : We use a macro that does the following:
4246 : - declare a static function named NAME_static
4247 : - declare a number of functions named NAME_ etc, with all possible
4248 : fortran mangling schemes (zero, one, or two underscores, lower and upper case)
4249 : - define the NAME_static function.
4250 :
4251 : The static function is used basically as an inline function in a C-compatible manner.
4252 : */
4253 :
4254 : #define __PLUMED_IMPLEMENT_FORTRAN(lower,upper,arg1,arg2) \
4255 : static void lower ## _static arg1; \
4256 : extern void lower arg1 {lower ## _static arg2;} \
4257 : extern void lower ##_ arg1 {lower ## _static arg2;} \
4258 : extern void lower ##__ arg1 {lower ## _static arg2;} \
4259 : extern void upper arg1 {lower ## _static arg2;} \
4260 : extern void upper ##_ arg1 {lower ## _static arg2;} \
4261 : extern void upper ##__ arg1 {lower ## _static arg2;} \
4262 : static void lower ## _static arg1
4263 :
4264 : /* FORTRAN wrappers would only make sense as extern "C" */
4265 :
4266 : __PLUMED_WRAPPER_EXTERN_C_BEGIN
4267 :
4268 36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create,PLUMED_F_CREATE,(char*c),(c)) {
4269 18 : plumed_c2f(plumed_create(),c);
4270 18 : }
4271 :
4272 12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_dlopen,PLUMED_F_CREATE_DLOPEN,(char*path,char*c),(path,c)) {
4273 6 : plumed_c2f(plumed_create_dlopen(path),c);
4274 6 : }
4275 :
4276 12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_reference,PLUMED_F_CREATE_REFERENCE,(char* r,char*c),(r,c)) {
4277 6 : plumed_c2f(plumed_create_reference_f(r),c);
4278 6 : }
4279 :
4280 0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_invalid,PLUMED_F_CREATE_INVALID,(char* c),(c)) {
4281 0 : plumed_c2f(plumed_create_invalid(),c);
4282 0 : }
4283 :
4284 558 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_cmd,PLUMED_F_CMD,(char*c,char*key,void*val),(c,key,val)) {
4285 279 : plumed_cmd(plumed_f2c(c),key,val);
4286 279 : }
4287 :
4288 60 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_finalize,PLUMED_F_FINALIZE,(char*c),(c)) {
4289 30 : plumed_finalize(plumed_f2c(c));
4290 30 : }
4291 :
4292 12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_installed,PLUMED_F_INSTALLED,(int*i),(i)) {
4293 : assert(i);
4294 6 : *i=plumed_installed();
4295 6 : }
4296 :
4297 : /* New in PLUMED 2.5 */
4298 0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_valid,PLUMED_F_VALID,(char*c,int*i),(c,i)) {
4299 : assert(i);
4300 0 : *i=plumed_valid(plumed_f2c(c));
4301 0 : }
4302 :
4303 36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_use_count,PLUMED_F_USE_COUNT,(char*c,int*i),(c,i)) {
4304 : assert(i);
4305 18 : *i=plumed_use_count(plumed_f2c(c));
4306 18 : }
4307 :
4308 : /* New in PLUMED 2.8 */
4309 :
4310 : /* note: flags & (~0x1ffffff) removes bits that are set here (code and size) */
4311 :
4312 : #define __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,suffix) \
4313 : plumed_safeptr plumed_f_safeptr_ ## type_ ## suffix(void*val,__PLUMED_WRAPPER_STD size_t nelem,__PLUMED_WRAPPER_STD size_t*shape,__PLUMED_WRAPPER_STD size_t flags,void*opt) {\
4314 : plumed_safeptr safe; \
4315 : safe.ptr=val; \
4316 : safe.nelem=nelem; \
4317 : safe.shape=shape; \
4318 : safe.flags= (flags & (~0x1ffffffu)) + 0x10000*code + size; \
4319 : safe.opt=opt; \
4320 : return safe; \
4321 : }
4322 :
4323 : #define __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,size,code) \
4324 : __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,) \
4325 : __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,_scalar)
4326 :
4327 : #define __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(type,type_,code) \
4328 : __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,0,code)
4329 :
4330 : #define __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(type,type_,code) \
4331 : __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,sizeof(type),code)
4332 :
4333 24 : __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(void,ptr,0)
4334 1 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(float,float,4)
4335 24 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(double,double,4)
4336 0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long double,long_double,4)
4337 25 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(int,int,3)
4338 0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(short,short,3)
4339 0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long,long,3)
4340 21 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(char,char,3)
4341 :
4342 : #if __PLUMED_WRAPPER_GLOBAL /*{*/
4343 :
4344 72 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_global,PLUMED_F_GLOBAL,(char*c),(c)) {
4345 36 : plumed_c2f(plumed_gmain,c);
4346 36 : }
4347 :
4348 36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_ginitialized,PLUMED_F_GINITIALIZED,(int*i),(i)) {
4349 : assert(i);
4350 18 : *i=plumed_ginitialized();
4351 18 : }
4352 :
4353 32 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcreate,PLUMED_F_GCREATE,(void),()) {
4354 16 : plumed_gcreate();
4355 16 : }
4356 :
4357 180 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcmd,PLUMED_F_GCMD,(char*key,void*val),(key,val)) {
4358 90 : plumed_gcmd(key,val);
4359 90 : }
4360 :
4361 32 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gfinalize,PLUMED_F_GFINALIZE,(void),()) {
4362 16 : plumed_gfinalize();
4363 16 : }
4364 :
4365 : /* New in PLUMED 2.5 */
4366 12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gvalid,PLUMED_F_GVALID,(int*i),(i)) {
4367 : assert(i);
4368 6 : *i=plumed_gvalid();
4369 6 : }
4370 :
4371 : #endif /*}*/
4372 :
4373 : __PLUMED_WRAPPER_EXTERN_C_END
4374 :
4375 : #endif /*}*/
4376 :
4377 : #endif /*}*/
4378 :
4379 : #endif /*}*/
4380 :
4381 : /* END OF DEFINITIONS */
4382 :
4383 : /* reset variable to allow it to be redefined upon re-inclusion */
4384 :
4385 : #undef __PLUMED_WRAPPER_IMPLEMENTATION_
4386 :
4387 : /* this macro is set in declarations */
4388 : #ifdef __PLUMED_WRAPPER_REDEFINE_CMD
4389 : #if defined(plumed_cmd)
4390 : #undef plumed_cmd
4391 : #endif
4392 : #define plumed_cmd __PLUMED_WRAPPER_REDEFINE_CMD
4393 : #endif
4394 :
4395 : /* this macro is set in declarations */
4396 : #ifdef __PLUMED_WRAPPER_REDEFINE_GCMD
4397 : #if defined(plumed_gcmd)
4398 : #undef plumed_gcmd
4399 : #endif
4400 : #define plumed_gcmd __PLUMED_WRAPPER_REDEFINE_GCMD
4401 : #endif
4402 :
4403 : /* this macro is set in declarations */
4404 : #ifdef __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
4405 : #if defined(plumed_error_rethrow)
4406 : #undef plumed_error_rethrow
4407 : #endif
4408 : #define plumed_error_rethrow __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
4409 : #endif
|