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