|Did you know ...||Search Documentation:|
|Summary of changes between Versions 1 and 2|
Version 1 is in
SWI-cpp.h; version 2 is in
The overall structure of the API has been retained - that is, it is a
thin layer on top of the interface provided by
SWI-Prolog.h. Based on experience with the API, most of the
conversion operators and some of the comparison operators have been
removed or deprecated, and replaced by "getter" methods; the overloaded
constructors have been replaced by subclasses for the various types.
Some changes were also made to ensure that the
doesn't cause unexpected implicit conversions.
2If there is an implicit
conversion operator from
char*, then the
operator is ambiguous if
f is overloaded to accept a
char* in the code
PlTerm t=...; f(t)
Prolog exceptions are now converted to C++ exceptions (which contain
the exception term rather being a subclass of
PlTerm as in
version 1), where they can be caught and thrown using the usual C++
mechanisms; and the subclasses that create exceptions have been changed
to functions. In addition, an exception type
been added, together with PlCheckFail(), to allow more compact code by
"short circuit" return to Prolog on failure.
A convenience class for creating blobs has been added, so that an existing structure can be converted to a blob with only a few lines of code.
SWI-cpp2.cpphas been added, containing the implementation of some functions. This is included by default from
SWI-cpp2.hor can be compiled separately.
SWI-Prolog.h, and have the same names with the “PL'' replaced by “Plx''.3 “Pl'' is used throughout the
SWI-cpp2.hinterface, and the “x'' is for “eXtended with eXception handling.'' Where appropriate, these check return codes and throw a C++ exception (created from the Prolog error). See section 2.5.4. Many of these wrapper functions are also methods in the
PlTermclasses, with the arguments changed from
PlTerm. These wrappers are available if you include
SWI-cpp2.h(they are in a separate
SWI-cpp2-plx.hfile for ease of maintenance).
falsefrom a foreign predicate to indicate failure, you can use
throw PlFail(). The convenience function PlCheckFail(rc) can be used to throw PlFail() if
falseis returned from a function in
SWI-Prolog.h. If the wrapper functions or class methods are used, Prolog errors result in a C++
PlExceptionexception.4If a “Plx_'' wrapper is used to call a
SWI-Prolog.hfunction, a Prolog error will have already resulted in throwing
PlException; PlCheckFail(rc) is used to additionally throw
PlFail, similar to returning
falsefrom the top-level of a foreign predicate - Prolog will check for an error and call throw/1 if appropriate.
PlExceptionclass is a subclass of
std::exceptionand encapsulates a Prolog error. Prolog errors are converted into
throw PlException(...). If the user code does not catch the
PlException, the PREDICATE() macro converts the error to a Prolog error upon return to the Prolog caller.
static_cast<char*>(t)) have been deprecated, replaced by "getters" (e.g.,
std::string, comparison operators. The as_string() method allows specifying the encoding to use whereas the
and similar operators do not allow for this.
char*have been replaced by methods that return
std::stringto ensure that lifetime issues don't cause subtle bugs.5If you want to return a
char*from a function, you should not do
return t.as_string().c_str()because that will return a pointer to local or stack memory. Instead, you should change your interface to return a
std::stringand apply the
c_str()method to it. These lifetime errors can sometimes be caught by specifying the Gnu C++ or Clang options
-Wreturn-local-addr- as of 2023-04, Clang seems to do a better analysis.
wchar_t*arguments also accept
std::wstringarguments. Where possible, encoding information can also be specified.
PlStringhas been renamed to
PlTerm_stringto make it clear that it's a term that contains a Prolog string.
PL_...(term_t, ...)methods have been added to
PL_...(atom_t, ...)methods have been added to
PlAtom. Where appropriate, the arguments use
PlAtom, etc. instead of
intfor true/false now return a C++
atom_t, etc.) have been renamed from
ref, etc. to
C_.6This is done by subclassing from
Wrapped<atom_t>, etc., which define the field
C_, standard constructors, the methods is_null(), not_null(), reset(), reset(v), reset_wrapped(v), plus the constant
null. This value can be accessed by the unwrap() and unwrap_as_ptr() methods. There is also a "friend" function PlUnwrapAsPtr().
PlStringBuffersprovides a simpler interface for allocating strings on the stack than PL_STRINGS_MARK() and PL_STRINGS_RELEASE(). See section 220.127.116.11.
PlStreamprovides a simpler interface for streams than PL_get_stream(), PL_acquire_stream(), and PL_release_stream(). See section 18.104.22.168.
record_thave been added. The
PlRecordExternalCopyclass contains the opaque handle, as a convenience.
control_thas been added and the PREDICATE_NONDET() has been modified to use it.