Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions SWI-cpp2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -722,8 +722,8 @@ PlCompound::PlCompound(const std::wstring& text)
}

_SWI_CPP2_CPP_inline
PlCompound::PlCompound(const char *functor, const PlTermv& args)
{ functor_t f = Plx_new_functor(Plx_new_atom(functor), args.size());
PlCompound::PlCompound(const char *functor, const PlTermv& args, PlEncoding rep)
{ functor_t f = Plx_new_functor(Plx_new_atom_mbchars(static_cast<int>(rep), static_cast<size_t>(-1), functor), args.size());
PlEx<bool>(f != (functor_t)0);
Plx_cons_functor_v(unwrap(), f, args.termv());
}
Expand All @@ -736,8 +736,8 @@ PlCompound::PlCompound(const wchar_t *functor, const PlTermv& args)
}

_SWI_CPP2_CPP_inline
PlCompound::PlCompound(const std::string& functor, const PlTermv& args)
{ functor_t f = Plx_new_functor(Plx_new_atom_nchars(functor.size(), functor.data()), args.size());
PlCompound::PlCompound(const std::string& functor, const PlTermv& args, PlEncoding rep)
{ functor_t f = Plx_new_functor(Plx_new_atom_mbchars(static_cast<int>(rep), functor.size(), functor.data()), args.size());
Plx_cons_functor_v(unwrap(), f, args.termv());
}

Expand Down Expand Up @@ -863,8 +863,8 @@ PlException::as_string(PlEncoding enc) const
// allocating the std::string) even though we specify "throw()" -
// telling the truth "noexcept(false)" results in a compilation
// error.
(void)enc; // TODO: use this
const_cast<PlException*>(this)->set_what_str();
(void)enc; // TODO: use this (MG: see next line
const_cast<PlException*>(this)->set_what_str(/* enc? */);
return what_str_;
}

Expand Down
84 changes: 52 additions & 32 deletions SWI-cpp2.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,22 +293,25 @@ class PlAtom : public WrappedC<atom_t>
public:
explicit PlAtom(atom_t v)
: WrappedC<atom_t>(v) { }
explicit PlAtom(const std::string& text)
: WrappedC<atom_t>(Plx_new_atom_nchars(text.size(), text.data()))
explicit PlAtom(const std::string& text, PlEncoding rep=ENC_INPUT)
: WrappedC<atom_t>(Plx_new_atom_mbchars(static_cast<int>(rep), text.size(), text.data()))
{ }
explicit PlAtom(const std::wstring& text)
: WrappedC<atom_t>(Plx_new_atom_wchars(text.size(), text.data()))
{ }
explicit PlAtom(const pl_wchar_t *text)
: WrappedC<atom_t>(Plx_new_atom_wchars(static_cast<size_t>(-1), text))
{ }
explicit PlAtom(const char *text)
: WrappedC<atom_t>(Plx_new_atom_nchars(static_cast<size_t>(-1), text))
explicit PlAtom(const char *text, PlEncoding rep=ENC_INPUT)
: WrappedC<atom_t>(Plx_new_atom_mbchars(static_cast<int>(rep), static_cast<size_t>(-1), text))
{ }
explicit PlAtom(PlEncoding rep, size_t len, const char *s)
explicit PlAtom(size_t len, const char *s, PlEncoding rep=ENC_INPUT)
: WrappedC<atom_t>(Plx_new_atom_mbchars(static_cast<int>(rep), len, s))
{ }
[[deprecated("use PlAtom(size_t, const char*, PlEncoding)")]] explicit PlAtom(PlEncoding rep, size_t len, const char *s)
: WrappedC<atom_t>(Plx_new_atom_mbchars(static_cast<int>(rep), len, s))
{ }
explicit PlAtom(PlEncoding rep, std::string& text) // TODO: rep as optional with default ENC_INPUT
[[deprecated("use PlAtom(std::string&, PlEncoding)")]] explicit PlAtom(PlEncoding rep, std::string& text)
: WrappedC<atom_t>(Plx_new_atom_mbchars(static_cast<int>(rep), text.size(), text.data()))
{ }

Expand Down Expand Up @@ -342,7 +345,6 @@ class PlAtom : public WrappedC<atom_t>
[[deprecated("use PlAtom instead of atom_t")]] bool operator !=(atom_t to) const { return unwrap() != to; }

// TODO: when C++17 becomes standard, rename register_ref() to register().

void register_ref() const
{ Plx_register_atom(unwrap());
}
Expand Down Expand Up @@ -386,16 +388,16 @@ class PlFunctor : public WrappedC<functor_t>
: WrappedC<functor_t>(v) { }

// PlFunctor(const char*) is handled by std::string constructor
// MG: hmm. Couldn't we deprecate and remove all const char* initializers then?

// TODO: add encoding to string
explicit PlFunctor(const std::string& name, size_t arity)
explicit PlFunctor(const std::string& name, size_t arity, PlEncoding rep=ENC_INPUT)
: WrappedC<functor_t>(null)
{ PlAtom a(name);
{ PlAtom a(name, rep);
reset_wrapped(Plx_new_functor(a.unwrap(), arity));
Plx_unregister_atom(a.unwrap());
}

explicit PlFunctor(const std::wstring& name, size_t arity)
explicit PlFunctor(const std::wstring& name, size_t arity, PlEncoding rep=ENC_INPUT)
: WrappedC<functor_t>(null)
{ PlAtom a(name);
reset_wrapped(Plx_new_functor(a.unwrap(), arity));
Expand All @@ -405,8 +407,8 @@ class PlFunctor : public WrappedC<functor_t>
explicit PlFunctor(PlAtom name, size_t arity)
: WrappedC<functor_t>(Plx_new_functor(name.unwrap(), arity)) { }

[[deprecated("use PlPredicate")]] predicate_t pred(module_t m) const {
predicate_t p = Plx_pred(unwrap(), m);
[[deprecated("use PlPredicate")]] predicate_t pred(module_t m) const
{ predicate_t p = Plx_pred(unwrap(), m);
return p;
}

Expand All @@ -419,9 +421,10 @@ class PlModule : public WrappedC<module_t>
{
public:
explicit PlModule(module_t m = 0)
: WrappedC<module_t>(m) { }
explicit PlModule(const std::string& name)
: WrappedC<module_t>(Plx_new_module(PlAtom(name).unwrap()))
: WrappedC<module_t>(m)
{ }
explicit PlModule(const std::string& name, PlEncoding rep=ENC_INPUT)
: WrappedC<module_t>(Plx_new_module(PlAtom(name, rep).unwrap()))
Copy link
Copy Markdown
Member

@kamahen kamahen Apr 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You would need to add a Plx_new_module with the additional parameter (which should also default).

{ }
explicit PlModule(PlAtom name)
: WrappedC<module_t>(Plx_new_module(name.unwrap()))
Expand Down Expand Up @@ -686,10 +689,14 @@ class PlTerm : public WrappedC<term_t>
// All the unify_*() methods check for an exception (and throw), so
// the return code is whether the unification succeeded or not.
// TODO: replace PL_unify_*() with PL_unify_string() and flags, where appropriate
// TODO: encodings for char*, std::string
// TODO: encodings for char*, std::string (MG: see below)
[[nodiscard]] bool unify_term(PlTerm t2) const { return Plx_unify(unwrap(), t2.unwrap()); }
[[nodiscard]] bool unify_atom(PlAtom a) const { return Plx_unify_atom(unwrap(), a.unwrap()); }
[[nodiscard]] bool unify_chars(int flags, size_t len, const char *s) const { return Plx_unify_chars(unwrap(), flags, len, s); }
// MG: The line above would read as
// unify_chars(int flags, size_t len, const char *s, PlEncoding rep=ENC_INPUT) const
// { return Plx_unify_chars(unwrap(), flags | rep, len, s); }
// Do we need this? I tend to yes, because rep can be set as the default
[[nodiscard]] bool unify_chars(int flags, const std::string& s) const { return Plx_unify_chars(unwrap(), flags, s.size(), s.data()); }
[[nodiscard]] bool unify_atom(const char* v) const { return Plx_unify_atom_chars(unwrap(), v); }
[[nodiscard]] bool unify_atom(const wchar_t* v) const { return Plx_unify_wchars(unwrap(), PL_ATOM, static_cast<size_t>(-1), v); }
Expand Down Expand Up @@ -780,7 +787,7 @@ class PlTerm : public WrappedC<term_t>
};


// PlTermScoped is an *experimental* inteface, which may change
// PlTermScoped is an *experimental* interface, which may change
// in the future. It implements a PlTerm that is automatically
// freed when it goes out of scope. The API is similar to
// std::unique_ptr.
Expand Down Expand Up @@ -888,9 +895,11 @@ class PlTerm_atom : public PlTerm
// For now, these are safe only with ASCII (PlEncoding::Latin1):
explicit PlTerm_atom(atom_t a) { Plx_put_atom(unwrap(), a); }
explicit PlTerm_atom(PlAtom a) { Plx_put_atom(unwrap(), a.unwrap()); }
explicit PlTerm_atom(const char *text) { Plx_put_atom_chars(unwrap(), text); } // TODO: add encoding
explicit PlTerm_atom(const char *text, PlEncoding rep=ENC_INPUT)
{ Plx_put_chars(unwrap(), PL_ATOM | static_cast<int>(rep), static_cast<size_t>(-1), text); }
explicit PlTerm_atom(const wchar_t *text) { PlEx<bool>(Plx_unify_wchars(unwrap(), PL_ATOM, static_cast<size_t>(-1), text)); }
explicit PlTerm_atom(const std::string& text) { Plx_put_atom_nchars(unwrap(), text.size(), text.data()); } // TODO: add encoding
explicit PlTerm_atom(const std::string& text, PlEncoding rep=ENC_INPUT)
{ Plx_put_chars(unwrap(), PL_ATOM | static_cast<int>(rep), text.size(), text.data()); }
explicit PlTerm_atom(const std::wstring& text) { PlEx<int>(Plx_unify_wchars(unwrap(), PL_ATOM, text.size(), text.data())); }
};

Expand Down Expand Up @@ -960,11 +969,13 @@ class PlPredicate : public WrappedC<predicate_t>
explicit PlPredicate(PlFunctor f, PlModule m)
: WrappedC<predicate_t>(Plx_pred(f.unwrap(), m.unwrap()))
{ }
// MG: Should we add PlEncoding here? I tend to yes.
// Would be something like PlPredicate(PlFunctor(name, arity, rep), module)
explicit PlPredicate(const char *name, int arity, const char *module)
: WrappedC<predicate_t>(Plx_predicate(name, arity, module))
: WrappedC<predicate_t>(Plx_predicate(name, arity, module))
{ }
explicit PlPredicate(const std::string& name, int arity, const std::string& module)
: WrappedC<predicate_t>(Plx_predicate(name.c_str(), arity, module.c_str()))
: WrappedC<predicate_t>(Plx_predicate(name.c_str(), arity, module.c_str()))
{ }
void predicate_info(PlAtom *name, size_t *arity, PlModule *module)
{ atom_t n;
Expand Down Expand Up @@ -1033,33 +1044,41 @@ class PlTermv
class PlCompound : public PlTerm
{
public:
// PlCompound("parent(alex, matthias") or what? Do you want to keep this?
explicit PlCompound(const wchar_t *text);
explicit PlCompound(const std::string& text, PlEncoding enc=ENC_INPUT);
explicit PlCompound(const std::wstring& text);
PlCompound(const char *functor, const PlTermv& args); // TODO: PlEncoding
PlCompound(const char *functor, const PlTermv& args, PlEncoding rep=ENC_INPUT);
PlCompound(const wchar_t *functor, const PlTermv& args);
PlCompound(const std::string& functor, const PlTermv& args); // TODO: PlEncoding
PlCompound(const std::string& functor, const PlTermv& args, PlEncoding rep=ENC_INPUT);
PlCompound(const std::wstring& functor, const PlTermv& args);
};


class PlTerm_string : public PlTerm
{
public:
// TODO: PlEncoding
PlTerm_string(const char *text) { Plx_put_string_chars(unwrap(), text); }
PlTerm_string(const char *text, size_t len) { Plx_put_string_nchars(unwrap(), len, text); }
PlTerm_string(const wchar_t *text) { PlEx<int>(Plx_unify_wchars(unwrap(), PL_STRING, static_cast<size_t>(-1), text)); }
PlTerm_string(const wchar_t *text, size_t len) { PlEx<int>(Plx_unify_wchars(unwrap(), PL_STRING, len, text));}
PlTerm_string(const std::string& text) { Plx_put_string_nchars(unwrap(), text.size(), text.data()); }
PlTerm_string(const std::wstring& text) { PlEx<int>(Plx_unify_wchars(unwrap(), PL_STRING, text.size(), text.data())); }
// Commented out because this does not seem to be necessary (see a few lines below)
// PlTerm_string(const char *text, PlEncoding rep=ENC_INPUT)
// { Plx_put_chars(unwrap(), PL_STRING | static_cast<int>(rep), static_cast<size_t>(-1), text); }
PlTerm_string(const char *text, size_t len, PlEncoding rep=ENC_INPUT)
{ Plx_put_chars(unwrap(), PL_STRING | static_cast<int>(rep), len, text); }
PlTerm_string(const wchar_t *text)
{ PlEx<int>(Plx_unify_wchars(unwrap(), PL_STRING, static_cast<size_t>(-1), text)); }
PlTerm_string(const wchar_t *text, size_t len)
{ PlEx<int>(Plx_unify_wchars(unwrap(), PL_STRING, len, text));}
PlTerm_string(const std::string& text, PlEncoding rep=ENC_INPUT) // here
{ Plx_put_chars(unwrap(), PL_STRING | static_cast<int>(rep), text.size(), text.data()); }
PlTerm_string(const std::wstring& text)
{ PlEx<int>(Plx_unify_wchars(unwrap(), PL_STRING, text.size(), text.data())); }
};


class PlTerm_list_codes : public PlTerm
{
public:
// TODO: PlEncoding + deprecate this interface
// I'll skip that one since it's deprecated
PlTerm_list_codes(const char *text) { Plx_put_list_codes(unwrap(), text); }
PlTerm_list_codes(const wchar_t *text) { PlEx<int>(Plx_unify_wchars(unwrap(), PL_CODE_LIST, static_cast<size_t>(-1), text)); }
};
Expand All @@ -1069,6 +1088,7 @@ class PlTerm_list_chars : public PlTerm
{
public:
// TODO: PlEncoding + deprecate this interface
// skipped that one
PlTerm_list_chars(const char *text) { Plx_put_list_chars(unwrap(), text); }
PlTerm_list_chars(const wchar_t *text) { PlEx<int>(Plx_unify_wchars(unwrap(), PL_CHAR_LIST, static_cast<size_t>(-1), text)); }
};
Expand Down Expand Up @@ -1164,7 +1184,7 @@ class PlRecordExternalCopy
: C_(external)
{ }

PlRecordExternalCopy(const char*external, size_t len)
PlRecordExternalCopy(const char *external, size_t len)
: C_(std::string(external, len))
{ }

Expand Down
20 changes: 20 additions & 0 deletions test_cpp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -715,10 +715,14 @@ PREDICATE(ensure_PlTerm_forward_declarations_are_implemented, 0)
*********************************************************************/
PlTerm_var t_var;
PlTerm_atom t_atom1("abc");
PlTerm_atom t_atom1a("abc", PlEncoding::UTF8);
PlTerm_atom t_atom2(L"ABC");
PlTerm_atom t_atom2a("ABC", PlEncoding::UTF8);
PlTerm_atom t_atom3(PlAtom("an atom"));
PlTerm_atom p_atom4(std::string("abc"));
PlTerm_atom p_atom5(std::wstring(L"世界"));
PlTerm_atom p_atom5a(std::string("世界"), PlEncoding::UTF8);

PlTerm_term_t t_t(Plx_new_term_ref());
PlTerm_term_t t_null(PlTerm::null);
PlTerm t_t2(Plx_new_term_ref());
Expand Down Expand Up @@ -749,6 +753,7 @@ PREDICATE(ensure_PlTerm_forward_declarations_are_implemented, 0)

PlTerm_string t_string1("abc");
PlTerm_string t_string2(L"世界");
PlTerm_string t_string3("世界", PlEncoding::UTF8);
const char codes[] = {81,82,83,0};
PlTerm_list_codes s02(codes);
PlTerm_list_chars s03("mno");
Expand Down Expand Up @@ -776,8 +781,14 @@ PREDICATE(ensure_PlTerm_forward_declarations_are_implemented, 0)

PlAtom atom1("atom1");
PlAtom atom2(L"原子2");
PlAtom atom2a("原子2", PlEncoding::UTF8);
PlAtom atom2b(2, "原子2", PlEncoding::UTF8);
// PlAtom atom2c(PlEncoding::UTF8, 2, "原子2"); // deprecated
PlAtom atom3(std::string("atom3"));
PlAtom atom4(std::wstring(L"原子4"));
PlAtom atom4a(std::string("原子4"), PlEncoding::UTF8);
std::string s4b("原子4");
// PlAtom atom4b(PlEncoding::UTF8, s4b); // deprecated
PlAtom a5a(t_atom1.as_atom());
PlAtom atom_null(PlAtom::null);
// The following are unsafe (the as_string() is deleted in the statement):
Expand Down Expand Up @@ -910,6 +921,15 @@ PREDICATE(ensure_PlTerm_forward_declarations_are_implemented, 0)
// TODO: the rest of the methods
strm.release();

PlFunctor f1(std::string("functor1"), 1, ENC_INPUT);
PlFunctor f2(std::string("世界2"), 2, PlEncoding::UTF8);
PlFunctor f3(std::wstring(L"世界3"), 3);
PlFunctor f4(PlAtom("世界", PlEncoding::UTF8), 4);

PlCompound c5("functor5", PlTermv(t_int1, t_int2), PlEncoding::UTF8);
PlCompound c6(L"世界6", PlTermv(t_int1, t_int2));
PlCompound c7(std::string("世界7"), PlTermv(t_int1, t_int2), PlEncoding::UTF8);
PlCompound c8(std::wstring(L"世界8"), PlTermv(t_int1, t_int2));
return true;
}

Expand Down