1.8 Rationale for changes from version 1
All Application Manual Name SummaryHelp

  • Documentation
    • Reference manual
    • Packages
      • A C++ interface to SWI-Prolog
        • A C++ interface to SWI-Prolog
          • Rationale for changes from version 1
            • Implicit constructors and conversion operators
            • Strings

1.8.2 Strings

The version API often used char* for both setting and setting string values. This is not a problem for setting (although encodings can be an issue), but can introduce subtle bugs in the lifetimes of pointers if the buffer stack isn't used properly. PlStringBuffers makes the buffer stack easier to use, but it would be preferable to avoid its use altogether. C++, unlike C, has a standard string that allows easily keeping a copy rather than dealing with a pointer that might become invalid. (Also, C++ strings can contain null characters.)

C++ has default conversion operators from char* to std::string, so some of the API support only std::string, even though this can cause a small inefficiency. If this proves to be a problem, additional overloaded functions and methods can be provided in future (note that some compilers have optimizations that reduce the overheads of using std::string); but for performance-critical code, the C functions can still be used.

Unicode and encodings are handled as follows. std::wstring and wchar_t* carry full Unicode and need no encoding. For interfaces that use std::string or char* the byte encoding is given by an optional PlEncoding argument:

typedef enum class PlEncoding
{ Latin1 = REP_ISO_LATIN_1,
  UTF8   = REP_UTF8,
  Locale = REP_MB,
  RepFn  = REP_FN
} PlEncoding;
static constexpr PlEncoding ENC_INPUT  = PlEncoding::Latin1;
static constexpr PlEncoding ENC_OUTPUT = PlEncoding::Locale;

Methods that construct Prolog text from std::string or char* (the PlAtom, PlTerm_atom, PlTerm_string and PlCompound constructors and the PlTerm::unify_*() methods) default to ENC_INPUT (PlEncoding::Latin1), which is byte-compatible with the pre-encoding API. Methods that return text (PlTerm::as_string(), PlAtom::as_string()) default to ENC_OUTPUT (PlEncoding::Locale). Pass PlEncoding::UTF8 explicitly when the char* or std::string holds UTF-8.

Identifiers that are normally program constants rather than data derived from arbitrarily encoded external input --- the names passed to PlModule and PlPredicate --- are hard-wired to UTF-8, matching the PL_predicate() CĀ API, and therefore take no PlEncoding argument.

The earlier argument order PlAtom(PlEncoding, len, s) and PlAtom(PlEncoding, std::string&) is [[deprecated]] in favour of the trailing-PlEncoding forms.