texlive[64038] Master/texmf-dist: lt3rawobjects (3aug22)

commits+karl at tug.org commits+karl at tug.org
Wed Aug 3 22:34:02 CEST 2022


Revision: 64038
          http://tug.org/svn/texlive?view=revision&revision=64038
Author:   karl
Date:     2022-08-03 22:34:01 +0200 (Wed, 03 Aug 2022)
Log Message:
-----------
lt3rawobjects (3aug22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/lt3rawobjects/lt3rawobjects.pdf
    trunk/Master/texmf-dist/source/latex/lt3rawobjects/lt3rawobjects.dtx
    trunk/Master/texmf-dist/tex/latex/lt3rawobjects/lt3rawobjects.sty

Modified: trunk/Master/texmf-dist/doc/latex/lt3rawobjects/lt3rawobjects.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/lt3rawobjects/lt3rawobjects.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/lt3rawobjects/lt3rawobjects.dtx	2022-08-03 20:33:48 UTC (rev 64037)
+++ trunk/Master/texmf-dist/source/latex/lt3rawobjects/lt3rawobjects.dtx	2022-08-03 20:34:01 UTC (rev 64038)
@@ -22,11 +22,11 @@
 %
 % \iffalse
 %<*driver>
-\ProvidesFile{lt3rawobjects.dtx}[2022/07/11 1.1.1 Objects and proxies in LaTeX3]
+\ProvidesFile{lt3rawobjects.dtx}[2022/08/03 2.0 Objects and proxies in LaTeX3]
 %</driver>
 %<package>\NeedsTeXFormat{LaTeX2e}
 %<package>\RequirePackage{expl3}[2022-04-10]
-%<package>\ProvidesExplPackage{lt3rawobjects}{2022/07/11}{ 1.1.1 }{Objects and proxies in LaTeX3}
+%<package>\ProvidesExplPackage{lt3rawobjects}{2022/08/03}{ 2.0 }{Objects and proxies in LaTeX3}
 %<*driver>
 \documentclass[full]{l3doc}
 \usepackage{lt3rawobjects}
@@ -38,13 +38,13 @@
 % \fi
 %
 % \NewDocumentCommand{\thpkg}{}{\pkg{lt3rawobjects}}
-% \NewDocumentCommand{\thvsn}{}{1.1.1}
-% \NewDocumentCommand{\thdta}{}{2022/07/11}
+% \NewDocumentCommand{\thvsn}{}{2.0}
+% \NewDocumentCommand{\thdta}{}{2022/08/03}
 % \NewDocumentCommand{\fromV}{ m }{{\ttfamily From: #1}}
 %
 % \title{The \pkg{lt3rawobjects} package}
 %   \author{Paolo De Donato}
-%   \date{Released \thdta\ Version \thvsn}
+%   \date{Released on \thdta\ Version \thvsn}
 %
 % \maketitle
 %
@@ -55,56 +55,48 @@
 % \section{Introduction}
 % First to all notice that \thpkg\ means ``raw object(s)'', indeed \thpkg\ introduces a new mechanism to create objects like the well known C structures. The functions exported by this package are quite low level, and many important mechanisms like member protection and name resolution aren't already defined and should be introduced by intermediate packages.
 %
+% This packages follows the \href{https://semver.org/}{SemVer} specification (\texttt{https://semver.org/}). In particular any major version update (for example from \texttt{1.2} to \texttt{2.0}) may introduce imcompatible changes and so it's not advisable to work with different packages that require different major versions of \thpkg. Instead changes introduced in minor and patch version updates are always backward compatible, and any withdrawn function is declared deprecated instead of being removed.
+%
 % \section{To do}
 % \begin{itemize}
-%   \item Introduce member functions in objects and member function specifications in proxies;
 %   \item Uniform declarations for templated proxies;
-%   \item Introduce constant objects.
+%   \item Constant objects.
 % \end{itemize}
 %
 % \section{Objects and proxies}
-% Usually an object in programming languages can be seen as a collection of variables (organized in different ways depending on the chosen language) treated as part of a single entity. Also in \thpkg\ objects are collections of variables, called member variables, which can be retrieved from a string representing that object. Such string is the \emph{address} of the object and act like the address of a structure in C.
+% Usually an object in programming languages can be seen as a collection of variables (organized in different ways depending on the chosen language) treated as part of a single entity. In \thpkg\ objects are collections of
+% \begin{itemize}
+%   \item \LaTeX3 variables, called \emph{members};
+%   \item \LaTeX3 functions, called \emph{methods}.
+% \end{itemize}
+% Both members and methods can be retrieved from a string representing the container object, that is the \emph{address} of the object and act like the address of a structure in C.
 %
-% An address is composed of two parts, the \emph{module} in which variables are created and an \emph{identifier} that identify uniquely the object inside its module. It's up to the caller that two different objects have different identifiers. The address of an object can be obtained with the \cs{object_address} function. Identifiers and module names should not contain numbers, |#| and |_| characters in order to avoid conflicts with automatically generated addresses.
+% An address is composed of two parts: the \emph{module} in which variables are created and an \emph{identifier} that identify uniquely the object inside its module. It's up to the caller that two different objects have different identifiers. The address of an object can be obtained with the \cs{object_address} function. Identifiers and module names should not contain numbers, |#|, |:| and |_| characters in order to avoid conflicts with hidden auxiliary commands. However you can use non letter characters like |-| in order to organize your members and methods.
 %
-% In C each object/structure has a \emph{type} that tells the compiler how each object should be organized and instantiated in the memory. So if you need to create objects with the same structure you should first create a new \verb|struct| entity and then create object with such type.
+% Moreover normal control sequences have an address too, but it's simply any token list for which a |c| expansion retrieves the original control sequence. We impose also that any |x| or |e| fully expansion will be a string representing the control sequence's name, for this reason inside an address |#| characters and \cs{exp_not} functions aren't allowed.
 %
-% In \thpkg\ objects are created from an existing object with a particular structure that holds all the needed informations to organize their variables. Such objects that can be used to instantiate new objects are calles \emph{proxies} and the proxy object used to instantiate an object is its \emph{generator}. In order to create new objects with a specified proxy you can use the \cs{object_create} functions.
+% In \thpkg\ objects are created from an existing object that have a suitable inner structure. These objects that can be used to create other objects are called \emph{proxy}. Every object is generated from a particular proxy object, called \emph{generator}, and new objects can be created from a specified proxy with the \cs{object_create} functions.
 %
 % Since proxies are themself objects we need a proxy to instantiate user defined proxies, you can use the |proxy| object in the |rawobjects| module to create you own proxy, which address is held by the \cs{c_proxy_address_str} variable. Proxies must be created from the |proxy| object otherwise they won't be recognized as proxies. Instead of using \cs{object_create} to create proxies you can directly use the function \cs{proxy_create}.
 %
-% Once you've created you proxy object you should specify its member variables that will be created in each object initialized with such proxy. You can add a variable specification with the \cs{proxy_push_member} function. Once you've added all yor variables specifications you can use your proxy to create objects. You should never modify a proxy once you've used it to create at least one object, since these modifications won't be updated on already created objects, leading to hidden errors in subsequential code.
+% Each member or method inside an object belongs to one of these categories:
+% \begin{enumerate}
+%   \item \emph{mutables};
+%   \item \emph{near constants};
+%   \item \emph{remote constants}.
+% \end{enumerate}
+% \textbf{Warning}: Currently only members (variables) can be mutables, not methods. Mutable members can be added in future releases if they'll be needed.
 %
-% When you create a new variable specification with the \cs{proxy_push_member} you can notice the presence of \meta{type} parameter. It represents the type of such variable and can be a standard type (like |tl|, |str|, |int|, |seq|, ...) or user defined types if the following functions are defined:
+% Members declared as mutables works as normal variables: you can modify their value and retrieve it at any time. Instead members and methods declared as near constant works as constants: when you create them you must specify their initial value (or function body for methods) and you won't be allowed to modify it later. Remote constants for an object are simply near constants defined in its generator: all near constants defined inside a proxy are automatically visible as remote constants to every object generated from that proxy. Usually functions involving near constants have |nc| inside their name, and |rc| if instead they use remote constants.
 %
-% \begin{description}
-%  \item[] \cs{\meta{type}_new:N} and \verb|c| variant;
-%  \item[] \cs{\meta{type}_set_eq:NN} and \verb|cN|, \verb|Nc|, \verb|cc| variants.
-% \end{description}
+% Instead of creating mutable members in each of your objects you can push their specifications inside the generating proxy via \cs{proxy_push_member}. In this way either object created from such proxy will have the specified members. Specify mutable members in this way allows you to omit that member type in some functions as \cs{object_member_adr} for example, their member type will be deduced automatically from its specification inside generating proxy.
 %
-% Every object, and so proxies too, is characterized by the following parameters:
-% \begin{itemize}
-%  \item the \emph{module} in which it has been created;
-%  \item the address of the proxy generator;
-%  \item a parameter saying if the object is \emph{local} or \emph{global};
-%  \item a parameter saying if the object is \emph{public} or \emph{private};
-%  \item zero or more member variables.
-% \end{itemize}
-% In a local/global/public/private object every member variable is declared local/global/public/private. Address of a member variable can be obtained with the \cs{object_member_adr} function, and you can instantiate new members that haven't been specified in its generator with the function \cs{object_new_member}. members created in this way aren't described by generator proxy, so its type can't be deduced and should be always specified in functions like \cs{object_member_adr} or \cs{object_member_use}.
+% Objects can be declared public, private and local, global. In a public/private object every nonconstant member and method is declared public/private, but inside local/global object only assignation to mutable members is performed locally/globally since allocation is always performed globally via \cs{\meta{type}_new:Nn} functions (nevertheless members will be accordingly declared |g_| or |l_|). This is intentional in order to follow the \LaTeX3 guidelines about variables managment, for additional motivations you can see \href{https://github.com/latex3/latex3/issues/410}{this thread} in the \LaTeX3 repository.
 %
-% \section{Constants}
-% This feature is available only from version 1.1 of \thpkg. There're two different kinds of constants you can define on a object:
-% \begin{enumerate}
-%   \item \emph{near constants} are constants defined directly inside the associated object;
-%   \item \emph{remote constants} are constants that are defined instead on the generator proxy and so every object generated with that proxy can access the constant.
-% \end{enumerate}
-% Currently it's possible to define only public constants, if you need private constants use member variables instead.
+% Address of members/methods can be obtained with functions in the form \cs{object_\meta{category}\meta{item}_adr} where \meta{item} is |member| or |method| and \meta{category} is empty for mutable members, |nc| for near constants and |rc| for remote constants. For example \cs{object_rcmethod_adr} retrieves the address of specified remote constant method.
 %
-% Notice that all near constants declared on a proxy are automatically remote constants for every generated object, but remote constants for a proxy aren't directly accessible by generated objects.
-%
-% You can retrieve the address of a near constant with the \cs{object_nconst_adr} function and of a remote constant with \cs{object_rconst_adr}.
-%
 % \section{Library functions}
+% \label{sec:lib}
 %  \subsection{Base object functions}
 %
 % \begin{function}[EXP]{\object_address:nn}
@@ -165,7 +157,7 @@
 % \fromV{1.0}
 % \end{function}
 %
-%  \subsection{Operating with member variables and constants}
+%  \subsection{Members}
 %
 % \begin{function}[EXP]{\object_member_adr:nnn, \object_member_adr:Vnn, \object_member_adr:nnv, \object_member_adr:nn, \object_member_adr:Vn}
 %  \begin{syntax}
@@ -177,6 +169,18 @@
 % \fromV{1.0}
 % \end{function}
 %
+% \begin{function}[pTF]{\object_member_if_exist:nnn, \object_member_if_exist:Vnn, \object_member_if_exist:nn, \object_member_if_exist:Vn}
+%  \begin{syntax}
+%   \cs{object_member_if_exist_p:nnn} \marg{address} \marg{member name} \marg{member type}
+%   \cs{object_member_if_exist:nnnTF} \marg{address} \marg{member name} \marg{member type} \Arg{true code} \Arg{false code}
+%   \cs{object_member_if_exist_p:nn} \Arg{address} \Arg{member name}
+%   \cs{object_member_if_exist:nnTF} \Arg{address} \Arg{member name} \Arg{true code} \Arg{false code}
+%  \end{syntax}
+%  Tests if the specified member exist.
+%
+% \fromV{2.0}
+% \end{function}
+%
 % \begin{function}[EXP]{\object_member_type:nn, \object_member_type:Vn}
 %  \begin{syntax}
 %   \cs{object_member_type:nn} \marg{address} \marg{member name}
@@ -215,27 +219,81 @@
 % \fromV{1.0}
 % \end{function}
 %
-% \begin{function}[EXP]{\object_nconst_adr:nnn, \object_nconst_adr:Vnn, \object_nconst_adr:vnn, \object_rconst_adr:nnn, \object_rconst_adr:Vnn}
+% \begin{function}[EXP]{\object_ncmember_adr:nnn, \object_ncmember_adr:Vnn, \object_ncmember_adr:vnn, \object_rcmember_adr:nnn, \object_rcmember_adr:Vnn}
 %  \begin{syntax}
-%   \cs{object_nconst_adr:nnn} \Arg{address} \Arg{member name} \Arg{member type}
+%   \cs{object_ncmember_adr:nnn} \Arg{address} \Arg{member name} \Arg{member type}
 %  \end{syntax}
-%  Fully expands to the address of specified near/remote constant.
+%  Fully expands to the address of specified near/remote constant member.
 %
-% \fromV{1.1}
+% \fromV{2.0}
 % \end{function}
 %
-% \begin{function}[EXP]{\object_nconst_use:nnn, \object_nconst_use:Vnn, \object_rconst_use:nnn, \object_rconst_use:Vnn}
+% \begin{function}[pTF]{\object_ncmember_if_exist:nnn, \object_ncmember_if_exist:Vnn, \object_rcmember_if_exist:nnn, \object_rcmember_if_exist:Vnn}
 %  \begin{syntax}
-%   \cs{object_nconst_use:nnn} \Arg{address} \Arg{member name} \Arg{member type}
+%   \cs{object_ncmember_if_exist_p:nnn} \marg{address} \marg{member name} \marg{member type}
+%   \cs{object_ncmember_if_exist:nnnTF} \marg{address} \marg{member name} \marg{member type} \Arg{true code} \Arg{false code}
 %  \end{syntax}
-%  Uses the specified near/remote constant.
+%  Tests if the specified member constant exist.
 %
-% \fromV{1.1}
+% \fromV{2.0}
 % \end{function}
 %
-% \subsection{Constant creation}
-% Unlike normal variables, constants in \LaTeX3 are created in different ways depending on the specified type. So we dedicate a new section only to collect some of these fuinctions readapted for near constants (remote constants are simply near constants created on the generator proxy).
+% \begin{function}[EXP]{\object_ncmember_use:nnn, \object_ncmember_use:Vnn, \object_rcmember_use:nnn, \object_rcmember_use:Vnn}
+%  \begin{syntax}
+%   \cs{object_ncmember_use:nnn} \Arg{address} \Arg{member name} \Arg{member type}
+%  \end{syntax}
+%  Uses the specified near/remote constant member.
 %
+% \fromV{2.0}
+% \end{function}
+%
+% \subsection{Methods}
+% Currentlu only constant methods (near and remote) are implemented in \thpkg\ as explained before.
+%
+% \begin{function}[EXP]{\object_ncmethod_adr:nnn, \object_ncmethod_adr:Vnn, \object_ncmethod_adr:vnn, \object_rcmethod_adr:nnn, \object_rcmethod_adr:Vnn}
+%  \begin{syntax}
+%   \cs{object_ncmethod_adr:nnn} \Arg{address} \Arg{method name} \Arg{method variant}
+%  \end{syntax}
+%  Fully expands to the address of the specified
+%  \begin{itemize}
+%    \item near constant method if \cs{object_ncmethod_adr} is used;
+%    \item remote constant method if \cs{object_rcmethod_adr} is used.
+%  \end{itemize}
+%
+% \fromV{2.0}
+% \end{function}
+%
+% \begin{function}[pTF]{\object_ncmethod_if_exist:nnn, \object_ncmethod_if_exist:Vnn, \object_rcmethod_if_exist:nnn, \object_rcmethod_if_exist:Vnn}
+%  \begin{syntax}
+%   \cs{object_ncmethod_if_exist_p:nnn} \marg{address} \marg{method name} \marg{method variant}
+%   \cs{object_ncmethod_if_exist:nnnTF} \marg{address} \marg{method name} \marg{method variant} \Arg{true code} \Arg{false code}
+%  \end{syntax}
+%  Tests if the specified method constant exist.
+%
+% \fromV{2.0}
+% \end{function}
+%
+% \begin{function}{\object_new_cmethod:nnnn, \object_new_cmethod:Vnnn}
+%  \begin{syntax}
+%   \cs{object_new_cmethod:nnnn} \Arg{address} \Arg{method name} \Arg{method arguments} \Arg{code}
+%  \end{syntax}
+%  Creates a new method with specified name and argument types. The \marg{method arguments} should be a string composed only by |n| and |N| characters that are passed to \cs{cs_new:Nn}.
+%
+% \fromV{2.0}
+% \end{function}
+%
+% \begin{function}[EXP]{\object_ncmethod_call:nnn, \object_ncmethod_call:Vnn, \object_rcmethod_call:nnn, \object_rcmethod_call:Vnn}
+%  \begin{syntax}
+%   \cs{object_ncmethod_call:nnn} \marg{address} \marg{method name} \marg{method variant}
+%  \end{syntax}
+%  Calls the specified method. This function is expandable if and only if the specified method was not declared |protected|.
+%
+% \fromV{2.0}
+% \end{function}
+%
+% \subsection{Constant member creation}
+% Unlike normal variables, constant variables in \LaTeX3 are created in different ways depending on the specified type. So we dedicate a new section only to collect some of these fuinctions readapted for near constants (remote constants are simply near constants created on the generator proxy).
+%
 % \begin{function}{\object_newconst_tl:nnn, \object_newconst_tl:Vnn, \object_newconst_str:nnn, \object_newconst_str:Vnn, \object_newconst_int:nnn, \object_newconst_int:Vnn, \object_newconst_clist:nnn, \object_newconst_clist:Vnn, \object_newconst_dim:nnn, \object_newconst_dim:Vnn, \object_newconst_skip:nnn, \object_newconst_skip:Vnn, \object_newconst_fp:nnn, \object_newconst_fp:Vnn}
 %  \begin{syntax}
 %   \cs{object_newconst_\meta{type}:nnn} \Arg{address} \Arg{constant name} \Arg{value}
@@ -278,6 +336,30 @@
 % \fromV{1.0}
 % \end{function}
 %
+% \begin{function}[pTF]{\object_test_proxy:nn, \object_test_proxy:Vn}
+%  \begin{syntax}
+%   \cs{object_test_proxy_p:nn} \Arg{object address} \Arg{proxy address}
+%   \cs{object_test_proxy:nnTF} \Arg{object address} \Arg{proxy address} \Arg{true code} \Arg{false code}
+%  \end{syntax}
+%  Test if the specified object is generated by the selected proxy, where \meta{proxy variable} is a string variable holding the proxy address.
+%
+% \begin{texnote}
+% Remember that this command uses internally an |e| expansion so in older engines (any different from Lua\LaTeX\ before 2019) it'll require slow processing. Don't use it in speed critical parts, instead use \cs{object_test_proxy:nN}.
+% \end{texnote}
+%
+% \fromV{2.0}
+% \end{function}
+%
+% \begin{function}[pTF]{\object_test_proxy:nN, \object_test_proxy:VN}
+%  \begin{syntax}
+%   \cs{object_test_proxy_p:nN} \Arg{object address} \meta{proxy variable}
+%   \cs{object_test_proxy:nNTF} \Arg{object address} \meta{proxy variable} \Arg{true code} \Arg{false code}
+%  \end{syntax}
+%  Test if the specified object is generated by the selected proxy, where \meta{proxy variable} is a string variable holding the proxy address. The |:nN| variant don't use |e| expansion, instead of |:nn| command, so it can be safetly used with older compilers. 
+%
+% \fromV{2.0}
+% \end{function}
+%
 % \begin{variable}{\c_proxy_address_str}
 %  The address of the |proxy| object in the |rawobjects| module.
 %
@@ -305,7 +387,7 @@
 % \fromV{1.0}
 % \end{variable}
 %
-% \begin{function}{\object_create_set:NnnnNN, \object_create_set:NVnnNN, \object_create_gset:NnnnNN, \object_create_gset:NVnnNN}
+% \begin{function}{\object_create_set:NnnnNN, \object_create_set:NVnnNN, \object_create_set:NnnfNN, \object_create_gset:NnnnNN, \object_create_gset:NVnnNN, \object_create_gset:NnnfNN}
 %  \begin{syntax}
 %   \cs{object_create_set:NnnnNN} \meta{str var} \marg{proxy address} \marg{module} \marg{id} \meta{scope} \meta{visibility}
 %  \end{syntax}
@@ -587,35 +669,38 @@
 
 \prg_new_conditional:Nnn \object_if_global:n {p, T, F, TF}
 {
-  \str_if_eq:cNTF { \@@_object_scovar:n {#1} } \c_object_global_str
-  {
-    \prg_return_true:
-  }
-  {
-    \prg_return_false:
-  }
+  \str_if_eq:cNTF { \@@_object_scovar:n {#1} }
+    \c_object_global_str
+    {
+      \prg_return_true:
+    }
+    {
+      \prg_return_false:
+    }
 }
 
 \prg_new_conditional:Nnn \object_if_public:n {p, T, F, TF}
 {
-  \str_if_eq:cNTF { \@@_object_visvar:n { #1 } } \c_object_public_str
-  {
-    \prg_return_true:
-  }
-  {
-    \prg_return_false:
-  }
+  \str_if_eq:cNTF { \@@_object_visvar:n { #1 } }
+    \c_object_public_str
+    {
+      \prg_return_true:
+    }
+    {
+      \prg_return_false:
+    }
 }
 
 \prg_new_conditional:Nnn \object_if_private:n {p, T, F, TF}
 {
-  \str_if_eq:cNTF { \@@_object_visvar:n {#1} } \c_object_private_str
-  {
-    \prg_return_true:
-  }
-  {
-    \prg_return_false:
-  }
+  \str_if_eq:cNTF { \@@_object_visvar:n {#1} }
+    \c_object_private_str
+    {
+      \prg_return_true:
+    }
+    {
+      \prg_return_false:
+    }
 }
 
 \prg_generate_conditional_variant:Nnn \object_if_local:n { V }
@@ -636,9 +721,9 @@
 
 \cs_new:Nn \@@_scope:n
   {
-    \object_if_global:nTF { #1 }
+    \object_if_local:nTF { #1 }
       {
-        g
+        l
       }
       {
         \str_if_eq:cNTF { \@@_object_scovar:n { #1 } }
@@ -647,14 +732,19 @@
             c
           }
           {
-            l
+            g
           }
       }
   }
 
-\cs_new:Nn \object_member_adr:nnn
+\cs_new:Nn \@@_scope_pfx:n
   {
-    \@@_scope:n { #1 }
+    \object_if_local:nF { #1 }
+      { g }
+  }
+
+\cs_new:Nn \@@_vis_var:n
+  {
     \object_if_private:nTF { #1 }
       {
         __
@@ -662,6 +752,20 @@
       {
         _
       }
+  }
+
+\cs_new:Nn \@@_vis_fun:n
+  {
+    \object_if_private:nT { #1 }
+      {
+        __
+      }
+  }
+
+\cs_new:Nn \object_member_adr:nnn
+  {
+    \@@_scope:n { #1 }
+    \@@_vis_var:n { #1 }
     #1 \tl_to_str:n { _ MEMBER _ #2 _ #3 }
   }
 
@@ -671,7 +775,7 @@
   {
     \object_member_adr:nnv { #1 }{ #2 }
       {
-        \object_member_adr:vnn { \@@_object_pxyvar:n { #1 } }
+        \object_rcmember_adr:nnn { #1 }
           { #2 _ type }{ str }
       }
   }
@@ -686,7 +790,7 @@
 
 \cs_new:Nn \object_member_type:nn
   {
-    \object_member_use:vnn { \@@_object_pxyvar:n { #1 } }
+    \object_rcmember_use:nnn { #1 }
       { #2 _ type }{ str }
   }
 
@@ -714,6 +818,46 @@
 
 %    \end{macrocode}
 %
+% \begin{macro}[pTF]{\object_member_if_exist:nnn, \object_member_if_exist:nn}
+% Tests if the specified member exists
+%    \begin{macrocode}
+
+\prg_new_conditional:Nnn \object_member_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_member_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_new_conditional:Nnn \object_member_if_exist:nn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_member_adr:nn { #1 }{ #2 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_generate_conditional_variant:Nnn \object_member_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+\prg_generate_conditional_variant:Nnn \object_member_if_exist:nn
+  { Vn }{ p, T, F, TF }
+
+%    \end{macrocode}
+% \end{macro}
+
 %\begin{macro}{\object_new_member:nnn}
 %Creates a new member variable
 %    \begin{macrocode}
@@ -748,7 +892,7 @@
   {
     \object_member_use:nnv { #1 }{ #2 }
       {
-        \object_member_adr:vnn { \@@_object_pxyvar:n { #1 } }
+        \object_rcmember_adr:nnn { #1 }
           { #2 _ type }{ str }
       }
   }
@@ -768,7 +912,7 @@
     \@@_force_scope:n { #1 }
     \cs_if_exist_use:cT
       {
-        #3 _ \object_if_global:nT { #1 }{ g } set _ eq:cN
+        #3 _ \@@_scope_pfx:n { #1 } set _ eq:cN
       }
       {
         { \object_member_adr:nnn { #1 }{ #2 }{ #3 } } #4
@@ -781,7 +925,7 @@
   {
     \object_member_set_eq:nnvN { #1 }{ #2 }
       {
-        \object_member_adr:vnn { \@@_object_pxyvar:n { #1 } }
+        \object_rcmember_adr:nnn { #1 }
           { #2 _ type }{ str }
       } #3
   }
@@ -791,49 +935,89 @@
 %    \end{macrocode}
 %\end{macro}
 %
-%\begin{macro}{\object_nconst_adr:nnn, \object_rconst_adr:nnn}
+%\begin{macro}{\object_ncmember_adr:nnn, \object_rcmember_adr:nnn}
 % Get the address of a near/remote constant.
 %    \begin{macrocode}
 
-\cs_new:Nn \object_nconst_adr:nnn
+\cs_new:Nn \object_ncmember_adr:nnn
   {
     c _ #1 \tl_to_str:n { _ CONST _ #2 _ #3 }
   }
 
-\cs_generate_variant:Nn \object_member_adr:nnn { Vnn, vnn }
+\cs_generate_variant:Nn \object_ncmember_adr:nnn { Vnn, vnn }
 
-\cs_new:Nn \object_rconst_adr:nnn
+\cs_new:Nn \object_rcmember_adr:nnn
   {
-    \object_nconst_adr:vnn { \@@_object_pxyvar:n { #1 } }
+    \object_ncmember_adr:vnn { \@@_object_pxyvar:n { #1 } }
       { #2 }{ #3 }
   }
 
-\cs_generate_variant:Nn \object_member_adr:nnn { Vnn }
+\cs_generate_variant:Nn \object_rcmember_adr:nnn { Vnn }
 %    \end{macrocode}
 %\end{macro}
 %
-%\begin{macro}{\object_nconst_use:nnn, \object_rconst_use:nnn}
+% \begin{macro}[pTF]{\object_ncmember_if_exist:nnn, \object_rcmember_if_exist:nnn}
+% Tests if the specified member constant exists.
+%    \begin{macrocode}
+
+\prg_new_conditional:Nnn \object_ncmember_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_ncmember_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_new_conditional:Nnn \object_rcmember_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_rcmember_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_generate_conditional_variant:Nnn \object_ncmember_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+\prg_generate_conditional_variant:Nnn \object_rcmember_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+
+%    \end{macrocode}
+% \end{macro}
+%
+%\begin{macro}{\object_ncmember_use:nnn, \object_rcmember_use:nnn}
 % Uses a near/remote constant.
 %    \begin{macrocode}
 
-\cs_new:Nn \object_nconst_use:nnn
+\cs_new:Nn \object_ncmember_use:nnn
   {
     \cs_if_exist_use:cT { #3 _ use:c }
       {
-        { \object_nconst_adr:nnn { #1 }{ #2 }{ #3 } }
+        { \object_ncmember_adr:nnn { #1 }{ #2 }{ #3 } }
       }
   }
 
-\cs_new:Nn \object_rconst_use:nnn
+\cs_new:Nn \object_rcmember_use:nnn
   {
     \cs_if_exist_use:cT { #3 _ use:c }
       {
-        { \object_rconst_adr:nnn { #1 }{ #2 }{ #3 } }
+        { \object_rcmember_adr:nnn { #1 }{ #2 }{ #3 } }
       }
   }
 
-\cs_generate_variant:Nn \object_nconst_use:nnn { Vnn }
-\cs_generate_variant:Nn \object_rconst_use:nnn { Vnn }
+\cs_generate_variant:Nn \object_ncmember_use:nnn { Vnn }
+\cs_generate_variant:Nn \object_rcmember_use:nnn { Vnn }
 
 %    \end{macrocode}
 %\end{macro}
@@ -847,7 +1031,7 @@
   {
     \use:c { #1 _ const:cn }
       {
-        \object_nconst_adr:nnn { #2 }{ #3 }{ #1 }
+        \object_ncmember_adr:nnn { #2 }{ #3 }{ #1 }
       }
       { #4 }
   }
@@ -900,7 +1084,7 @@
   {
     \seq_const_from_clist:cn
       {
-        \object_nconst_adr:nnn { #1 }{ #2 }{ seq }
+        \object_ncmember_adr:nnn { #1 }{ #2 }{ seq }
       }
       { #3 }
   }
@@ -918,7 +1102,7 @@
   {
     \prop_const_from_keyval:cn
       {
-        \object_nconst_adr:nnn { #1 }{ #2 }{ prop }
+        \object_ncmember_adr:nnn { #1 }{ #2 }{ prop }
       }
       { #3 }
   }
@@ -929,7 +1113,118 @@
 %\end{macro}
 %
 %
+% \begin{macro}{\object_ncmethod_adr:nnn, \object_rcmethod_adr:nnn}
+% Fully expands to the method address.
+%    \begin{macrocode}
+
+\cs_new:Nn \object_ncmethod_adr:nnn
+  {
+    #1 \tl_to_str:n { _ CMETHOD _ #2 : #3 }
+  }
+
+\cs_generate_variant:Nn \object_ncmethod_adr:nnn { Vnn , vnn }
+
+\cs_new:Nn \object_rcmethod_adr:nnn
+  {
+    \object_ncmethod_adr:vnn
+      {
+        \@@_object_pxyvar:n { #1 }
+      }
+      { #2 }{ #3 }
+  }
+
+\cs_generate_variant:Nn \object_ncmethod_adr:nnn { Vnn , vnn }
+\cs_generate_variant:Nn \object_rcmethod_adr:nnn { Vnn }
+
+%    \end{macrocode}
+% \end{macro}
 %
+% \begin{macro}[pTF]{\object_ncmethod_if_exist:nnn, \object_rcmethod_if_exist:nnn}
+% Tests if the specified member constant exists.
+%    \begin{macrocode}
+
+\prg_new_conditional:Nnn \object_ncmethod_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_ncmethod_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_new_conditional:Nnn \object_rcmethod_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_rcmethodr_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_generate_conditional_variant:Nnn \object_ncmethod_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+\prg_generate_conditional_variant:Nnn \object_rcmethod_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\object_new_cmethod:nnnn}
+% Creates a new method
+%    \begin{macrocode}
+
+\cs_new_protected:Nn \object_new_cmethod:nnnn
+  {
+    \cs_new:cn
+	  {
+	    \object_ncmethod_adr:nnn { #1 }{ #2 }{ #3 }
+	  }
+	  { #4 }
+  }
+  
+\cs_generate_variant:Nn \object_new_cmethod:nnnn { Vnnn }
+
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\object_ncmethod_call:nnn, \object_rcmethod_call:nnn}
+% Calls the specified method.
+%    \begin{macrocode}
+
+\cs_new:Nn \object_ncmethod_call:nnn
+  {
+    \use:c
+	  {
+	    \object_ncmethod_adr:nnn { #1 }{ #2 }{ #3 }
+	  }
+  }
+
+\cs_new:Nn \object_rcmethod_call:nnn
+  {
+    \use:c
+	  {
+	    \object_rcmethod_adr:nnn { #1 }{ #2 }{ #3 }
+	  }
+  }
+  
+\cs_generate_variant:Nn \object_ncmethod_call:nnn { Vnn }
+\cs_generate_variant:Nn \object_rcmethod_call:nnn { Vnn }
+
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
 %\begin{variable}{\c_proxy_address_str}
 %The address of the \verb|proxy| object.
 %    \begin{macrocode}
@@ -950,8 +1245,6 @@
 \str_const:cV { \@@_object_visvar:V \c_proxy_address_str }
   \c_object_public_str
 
-\cs_generate_variant:Nn \seq_const_from_clist:Nn { cx }
-
 \seq_const_from_clist:cn
   {
     \object_member_adr:Vnn \c_proxy_address_str { varlist }{ seq }
@@ -958,11 +1251,8 @@
   }
   { varlist }
 
-\str_const:cn
-  {
-    \object_member_adr:Vnn \c_proxy_address_str { varlist_type }{ str }
-  }
-  { seq }
+\object_newconst_str:Vnn \c_proxy_address_str { varlist_type }{ seq }
+
 %    \end{macrocode}
 %
 %\begin{macro}[pTF]{\object_if_proxy:n}
@@ -971,7 +1261,7 @@
 
 \prg_new_conditional:Nnn \object_if_proxy:n {p, T, F, TF}
   {
-    \str_if_eq:cNTF { \@@_object_pxyvar:n { #1 } } 
+    \object_test_proxy:nNTF { #1 } 
 	  \c_proxy_address_str
       {
         \prg_return_true:
@@ -984,10 +1274,48 @@
 %    \end{macrocode}
 %\end{macro}
 %
-%\begin{macro}{\object_create:nnnNN, \object_create_set:NnnnNN, \object_create_gset:NnnnNN}
-%Creates an object from a proxy
+%\begin{macro}[pTF]{\object_test_proxy:nn, \object_test_proxy:nN}
+%Test if an object is generated from selected proxy.
 %    \begin{macrocode}
 
+\prg_generate_conditional_variant:Nnn \str_if_eq:nn { ve }{ TF }
+
+\prg_new_conditional:Nnn \object_test_proxy:nn {p, T, F, TF}
+  {
+    \str_if_eq:veTF { \@@_object_pxyvar:n { #1 } } 
+	  { #2 }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_new_conditional:Nnn \object_test_proxy:nN {p, T, F, TF}
+  {
+    \str_if_eq:cNTF { \@@_object_pxyvar:n { #1 } } 
+	  #2
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+  
+\prg_generate_conditional_variant:Nnn \object_test_proxy:nn
+  { Vn }{p, T, F, TF}
+\prg_generate_conditional_variant:Nnn \object_test_proxy:nN
+  { VN }{p, T, F, TF}
+
+%    \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\object_create:nnnNN, \object_create_set:NnnnNN, \object_create_gset:NnnnNN}
+% Creates an object from a proxy
+%    \begin{macrocode}
+
 \msg_new:nnn { aa }{ mess }{ #1 }
 
 \msg_new:nnnn { rawobjects }{ notproxy }{ Fake ~ proxy }
@@ -1020,7 +1348,7 @@
       {
         \object_new_member:nnv { #2 }{ ##1 }
           {
-            \object_member_adr:nnn { #1 }{ ##1 _ type }{ str }
+            \object_ncmember_adr:nnn { #1 }{ ##1 _ type }{ str }
           }
       }
   }
@@ -1044,8 +1372,8 @@
   }
 
 \cs_generate_variant:Nn \object_create:nnnNN { VnnNN }
-\cs_generate_variant:Nn \object_create_set:NnnnNN { NVnnNN }
-\cs_generate_variant:Nn \object_create_gset:NnnnNN { NVnnNN }
+\cs_generate_variant:Nn \object_create_set:NnnnNN { NVnnNN, NnnfNN }
+\cs_generate_variant:Nn \object_create_gset:NnnnNN { NVnnNN, NnnfNN }
 
 %    \end{macrocode}
 %\end{macro}
@@ -1054,18 +1382,26 @@
 % Create an address and use it to instantiate an object
 %    \begin{macrocode}
 
-\cs_new:Nn \@@_combine:nn
+\cs_new:Nn \@@_combine_aux:nnn
   {
-    anon . #2 . #1
+    anon . #3 . #2 . #1
   }
+  
+\cs_generate_variant:Nn \@@_combine_aux:nnn { Vnf }
 
-\cs_generate_variant:Nn \@@_combine:nn { Vn }
+\cs_new:Nn \@@_combine:Nn
+  {
+    \@@_combine_aux:Vnf #1 { #2 }
+	  {
+	    \cs_to_str:N #1
+	  }
+  }
 
 \cs_new_protected:Nn \object_allocate_incr:NNnnNN
   {
-    \object_create_set:NnnnNN #1 { #3 }{ #4 }
+    \object_create_set:NnnfNN #1 { #3 }{ #4 }
       {
-        \@@_combine:Vn #2 { #3 }
+        \@@_combine:Nn #2 { #3 }
       }
       #5 #6
 
@@ -1074,9 +1410,9 @@
 
 \cs_new_protected:Nn \object_gallocate_incr:NNnnNN
   {
-    \object_create_gset:NnnnNN #1 { #3 }{ #4 }
+    \object_create_gset:NnnfNN #1 { #3 }{ #4 }
       {
-        \@@_combine:Vn #2 { #3 }
+        \@@_combine:Nn #2 { #3 }
       }
       #5 #6
 
@@ -1089,9 +1425,9 @@
 
 \cs_new_protected:Nn \object_allocate_gincr:NNnnNN
   {
-    \object_create_set:NnnnNN #1 { #3 }{ #4 }
+    \object_create_set:NnnfNN #1 { #3 }{ #4 }
       {
-        \@@_combine:Vn #2 { #3 }
+        \@@_combine:Nn #2 { #3 }
       }
       #5 #6
 
@@ -1100,9 +1436,9 @@
 
 \cs_new_protected:Nn \object_gallocate_gincr:NNnnNN
   {
-    \object_create_gset:NnnnNN #1 { #3 }{ #4 }
+    \object_create_gset:NnnfNN #1 { #3 }{ #4 }
       {
-        \@@_combine:Vn #2 { #3 }
+        \@@_combine:Nn #2 { #3 }
       }
       #5 #6
 
@@ -1147,12 +1483,7 @@
 \cs_new_protected:Nn \proxy_push_member:nnn
   {
     \@@_force_scope:n { #1 }
-    \object_new_member:nnn { #1 }{ #2 _ type }{ str }
-    \str_set:cn
-      {
-        \object_member_adr:nnn { #1 }{ #2 _ type }{ str }
-      }
-      { #3 }
+    \object_newconst_str:nnn { #1 }{ #2 _ type }{ #3 }
     \seq_gput_left:cn
       {
         \object_member_adr:nnn { #1 }{ varlist }{ seq }

Modified: trunk/Master/texmf-dist/tex/latex/lt3rawobjects/lt3rawobjects.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/lt3rawobjects/lt3rawobjects.sty	2022-08-03 20:33:48 UTC (rev 64037)
+++ trunk/Master/texmf-dist/tex/latex/lt3rawobjects/lt3rawobjects.sty	2022-08-03 20:34:01 UTC (rev 64038)
@@ -26,7 +26,7 @@
 %% 
 \NeedsTeXFormat{LaTeX2e}
 \RequirePackage{expl3}[2022-04-10]
-\ProvidesExplPackage{lt3rawobjects}{2022/07/11}{ 1.1.1 }{Objects and proxies in LaTeX3}
+\ProvidesExplPackage{lt3rawobjects}{2022/08/03}{ 2.0 }{Objects and proxies in LaTeX3}
 \str_const:Nn \c_object_local_str {loc}
 \str_const:Nn \c_object_global_str {glo}
 \str_const:Nn \c_object_public_str {pub}
@@ -107,35 +107,38 @@
 
 \prg_new_conditional:Nnn \object_if_global:n {p, T, F, TF}
 {
-  \str_if_eq:cNTF { \__rawobjects_object_scovar:n {#1} } \c_object_global_str
-  {
-    \prg_return_true:
-  }
-  {
-    \prg_return_false:
-  }
+  \str_if_eq:cNTF { \__rawobjects_object_scovar:n {#1} }
+    \c_object_global_str
+    {
+      \prg_return_true:
+    }
+    {
+      \prg_return_false:
+    }
 }
 
 \prg_new_conditional:Nnn \object_if_public:n {p, T, F, TF}
 {
-  \str_if_eq:cNTF { \__rawobjects_object_visvar:n { #1 } } \c_object_public_str
-  {
-    \prg_return_true:
-  }
-  {
-    \prg_return_false:
-  }
+  \str_if_eq:cNTF { \__rawobjects_object_visvar:n { #1 } }
+    \c_object_public_str
+    {
+      \prg_return_true:
+    }
+    {
+      \prg_return_false:
+    }
 }
 
 \prg_new_conditional:Nnn \object_if_private:n {p, T, F, TF}
 {
-  \str_if_eq:cNTF { \__rawobjects_object_visvar:n {#1} } \c_object_private_str
-  {
-    \prg_return_true:
-  }
-  {
-    \prg_return_false:
-  }
+  \str_if_eq:cNTF { \__rawobjects_object_visvar:n {#1} }
+    \c_object_private_str
+    {
+      \prg_return_true:
+    }
+    {
+      \prg_return_false:
+    }
 }
 
 \prg_generate_conditional_variant:Nnn \object_if_local:n { V }
@@ -149,9 +152,9 @@
 
 \cs_new:Nn \__rawobjects_scope:n
   {
-    \object_if_global:nTF { #1 }
+    \object_if_local:nTF { #1 }
       {
-        g
+        l
       }
       {
         \str_if_eq:cNTF { \__rawobjects_object_scovar:n { #1 } }
@@ -160,14 +163,19 @@
             c
           }
           {
-            l
+            g
           }
       }
   }
 
-\cs_new:Nn \object_member_adr:nnn
+\cs_new:Nn \__rawobjects_scope_pfx:n
   {
-    \__rawobjects_scope:n { #1 }
+    \object_if_local:nF { #1 }
+      { g }
+  }
+
+\cs_new:Nn \__rawobjects_vis_var:n
+  {
     \object_if_private:nTF { #1 }
       {
         __
@@ -175,6 +183,20 @@
       {
         _
       }
+  }
+
+\cs_new:Nn \__rawobjects_vis_fun:n
+  {
+    \object_if_private:nT { #1 }
+      {
+        __
+      }
+  }
+
+\cs_new:Nn \object_member_adr:nnn
+  {
+    \__rawobjects_scope:n { #1 }
+    \__rawobjects_vis_var:n { #1 }
     #1 \tl_to_str:n { _ MEMBER _ #2 _ #3 }
   }
 
@@ -184,7 +206,7 @@
   {
     \object_member_adr:nnv { #1 }{ #2 }
       {
-        \object_member_adr:vnn { \__rawobjects_object_pxyvar:n { #1 } }
+        \object_rcmember_adr:nnn { #1 }
           { #2 _ type }{ str }
       }
   }
@@ -193,7 +215,7 @@
 
 \cs_new:Nn \object_member_type:nn
   {
-    \object_member_use:vnn { \__rawobjects_object_pxyvar:n { #1 } }
+    \object_rcmember_use:nnn { #1 }
       { #2 _ type }{ str }
   }
 
@@ -216,6 +238,41 @@
   }
 
 
+\prg_new_conditional:Nnn \object_member_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_member_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_new_conditional:Nnn \object_member_if_exist:nn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_member_adr:nn { #1 }{ #2 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_generate_conditional_variant:Nnn \object_member_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+\prg_generate_conditional_variant:Nnn \object_member_if_exist:nn
+  { Vn }{ p, T, F, TF }
+
+
+
 \cs_new_protected:Nn \object_new_member:nnn
   {
     \__rawobjects_force_scope:n { #1 }
@@ -240,7 +297,7 @@
   {
     \object_member_use:nnv { #1 }{ #2 }
       {
-        \object_member_adr:vnn { \__rawobjects_object_pxyvar:n { #1 } }
+        \object_rcmember_adr:nnn { #1 }
           { #2 _ type }{ str }
       }
   }
@@ -254,7 +311,7 @@
     \__rawobjects_force_scope:n { #1 }
     \cs_if_exist_use:cT
       {
-        #3 _ \object_if_global:nT { #1 }{ g } set _ eq:cN
+        #3 _ \__rawobjects_scope_pfx:n { #1 } set _ eq:cN
       }
       {
         { \object_member_adr:nnn { #1 }{ #2 }{ #3 } } #4
@@ -267,7 +324,7 @@
   {
     \object_member_set_eq:nnvN { #1 }{ #2 }
       {
-        \object_member_adr:vnn { \__rawobjects_object_pxyvar:n { #1 } }
+        \object_rcmember_adr:nnn { #1 }
           { #2 _ type }{ str }
       } #3
   }
@@ -275,39 +332,73 @@
 \cs_generate_variant:Nn \object_member_set_eq:nnN { VnN, nnc, Vnc }
 
 
-\cs_new:Nn \object_nconst_adr:nnn
+\cs_new:Nn \object_ncmember_adr:nnn
   {
     c _ #1 \tl_to_str:n { _ CONST _ #2 _ #3 }
   }
 
-\cs_generate_variant:Nn \object_member_adr:nnn { Vnn, vnn }
+\cs_generate_variant:Nn \object_ncmember_adr:nnn { Vnn, vnn }
 
-\cs_new:Nn \object_rconst_adr:nnn
+\cs_new:Nn \object_rcmember_adr:nnn
   {
-    \object_nconst_adr:vnn { \__rawobjects_object_pxyvar:n { #1 } }
+    \object_ncmember_adr:vnn { \__rawobjects_object_pxyvar:n { #1 } }
       { #2 }{ #3 }
   }
 
-\cs_generate_variant:Nn \object_member_adr:nnn { Vnn }
+\cs_generate_variant:Nn \object_rcmember_adr:nnn { Vnn }
 
-\cs_new:Nn \object_nconst_use:nnn
+\prg_new_conditional:Nnn \object_ncmember_if_exist:nnn {p, T, F, TF }
   {
+    \cs_if_exist:cTF
+      {
+        \object_ncmember_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_new_conditional:Nnn \object_rcmember_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_rcmember_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_generate_conditional_variant:Nnn \object_ncmember_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+\prg_generate_conditional_variant:Nnn \object_rcmember_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+
+
+\cs_new:Nn \object_ncmember_use:nnn
+  {
     \cs_if_exist_use:cT { #3 _ use:c }
       {
-        { \object_nconst_adr:nnn { #1 }{ #2 }{ #3 } }
+        { \object_ncmember_adr:nnn { #1 }{ #2 }{ #3 } }
       }
   }
 
-\cs_new:Nn \object_rconst_use:nnn
+\cs_new:Nn \object_rcmember_use:nnn
   {
     \cs_if_exist_use:cT { #3 _ use:c }
       {
-        { \object_rconst_adr:nnn { #1 }{ #2 }{ #3 } }
+        { \object_rcmember_adr:nnn { #1 }{ #2 }{ #3 } }
       }
   }
 
-\cs_generate_variant:Nn \object_nconst_use:nnn { Vnn }
-\cs_generate_variant:Nn \object_rconst_use:nnn { Vnn }
+\cs_generate_variant:Nn \object_ncmember_use:nnn { Vnn }
+\cs_generate_variant:Nn \object_rcmember_use:nnn { Vnn }
 
 
 \cs_new_protected:Nn \__rawobjects_const_create:nnnn
@@ -314,7 +405,7 @@
   {
     \use:c { #1 _ const:cn }
       {
-        \object_nconst_adr:nnn { #2 }{ #3 }{ #1 }
+        \object_ncmember_adr:nnn { #2 }{ #3 }{ #1 }
       }
       { #4 }
   }
@@ -361,7 +452,7 @@
   {
     \seq_const_from_clist:cn
       {
-        \object_nconst_adr:nnn { #1 }{ #2 }{ seq }
+        \object_ncmember_adr:nnn { #1 }{ #2 }{ seq }
       }
       { #3 }
   }
@@ -373,7 +464,7 @@
   {
     \prop_const_from_keyval:cn
       {
-        \object_nconst_adr:nnn { #1 }{ #2 }{ prop }
+        \object_ncmember_adr:nnn { #1 }{ #2 }{ prop }
       }
       { #3 }
   }
@@ -380,6 +471,92 @@
 
 \cs_generate_variant:Nn \object_newconst_prop_from_keyval:nnn { Vnn }
 
+
+\cs_new:Nn \object_ncmethod_adr:nnn
+  {
+    #1 \tl_to_str:n { _ CMETHOD _ #2 : #3 }
+  }
+
+\cs_generate_variant:Nn \object_ncmethod_adr:nnn { Vnn , vnn }
+
+\cs_new:Nn \object_rcmethod_adr:nnn
+  {
+    \object_ncmethod_adr:vnn
+      {
+        \__rawobjects_object_pxyvar:n { #1 }
+      }
+      { #2 }{ #3 }
+  }
+
+\cs_generate_variant:Nn \object_ncmethod_adr:nnn { Vnn , vnn }
+\cs_generate_variant:Nn \object_rcmethod_adr:nnn { Vnn }
+
+
+\prg_new_conditional:Nnn \object_ncmethod_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_ncmethod_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_new_conditional:Nnn \object_rcmethod_if_exist:nnn {p, T, F, TF }
+  {
+    \cs_if_exist:cTF
+      {
+        \object_rcmethodr_adr:nnn { #1 }{ #2 }{ #3 }
+      }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_generate_conditional_variant:Nnn \object_ncmethod_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+\prg_generate_conditional_variant:Nnn \object_rcmethod_if_exist:nnn
+  { Vnn }{ p, T, F, TF }
+
+
+\cs_new_protected:Nn \object_new_cmethod:nnnn
+  {
+    \cs_new:cn
+  {
+    \object_ncmethod_adr:nnn { #1 }{ #2 }{ #3 }
+  }
+  { #4 }
+  }
+
+\cs_generate_variant:Nn \object_new_cmethod:nnnn { Vnnn }
+
+
+\cs_new:Nn \object_ncmethod_call:nnn
+  {
+    \use:c
+  {
+    \object_ncmethod_adr:nnn { #1 }{ #2 }{ #3 }
+  }
+  }
+
+\cs_new:Nn \object_rcmethod_call:nnn
+  {
+    \use:c
+  {
+    \object_rcmethod_adr:nnn { #1 }{ #2 }{ #3 }
+  }
+  }
+
+\cs_generate_variant:Nn \object_ncmethod_call:nnn { Vnn }
+\cs_generate_variant:Nn \object_rcmethod_call:nnn { Vnn }
+
 \str_const:Nx \c_proxy_address_str
   { \object_address:nn { rawobjects }{ proxy } }
 \str_const:cn { \__rawobjects_object_modvar:V \c_proxy_address_str }
@@ -391,8 +568,6 @@
 \str_const:cV { \__rawobjects_object_visvar:V \c_proxy_address_str }
   \c_object_public_str
 
-\cs_generate_variant:Nn \seq_const_from_clist:Nn { cx }
-
 \seq_const_from_clist:cn
   {
     \object_member_adr:Vnn \c_proxy_address_str { varlist }{ seq }
@@ -399,16 +574,40 @@
   }
   { varlist }
 
-\str_const:cn
+\object_newconst_str:Vnn \c_proxy_address_str { varlist_type }{ seq }
+
+
+\prg_new_conditional:Nnn \object_if_proxy:n {p, T, F, TF}
   {
-    \object_member_adr:Vnn \c_proxy_address_str { varlist_type }{ str }
+    \object_test_proxy:nNTF { #1 }
+  \c_proxy_address_str
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
   }
-  { seq }
 
-\prg_new_conditional:Nnn \object_if_proxy:n {p, T, F, TF}
+
+\prg_generate_conditional_variant:Nnn \str_if_eq:nn { ve }{ TF }
+
+\prg_new_conditional:Nnn \object_test_proxy:nn {p, T, F, TF}
   {
+    \str_if_eq:veTF { \__rawobjects_object_pxyvar:n { #1 } }
+  { #2 }
+      {
+        \prg_return_true:
+      }
+      {
+        \prg_return_false:
+      }
+  }
+
+\prg_new_conditional:Nnn \object_test_proxy:nN {p, T, F, TF}
+  {
     \str_if_eq:cNTF { \__rawobjects_object_pxyvar:n { #1 } }
-  \c_proxy_address_str
+  #2
       {
         \prg_return_true:
       }
@@ -417,7 +616,12 @@
       }
   }
 
+\prg_generate_conditional_variant:Nnn \object_test_proxy:nn
+  { Vn }{p, T, F, TF}
+\prg_generate_conditional_variant:Nnn \object_test_proxy:nN
+  { VN }{p, T, F, TF}
 
+
 \msg_new:nnn { aa }{ mess }{ #1 }
 
 \msg_new:nnnn { rawobjects }{ notproxy }{ Fake ~ proxy }
@@ -450,7 +654,7 @@
       {
         \object_new_member:nnv { #2 }{ ##1 }
           {
-            \object_member_adr:nnn { #1 }{ ##1 _ type }{ str }
+            \object_ncmember_adr:nnn { #1 }{ ##1 _ type }{ str }
           }
       }
   }
@@ -474,22 +678,30 @@
   }
 
 \cs_generate_variant:Nn \object_create:nnnNN { VnnNN }
-\cs_generate_variant:Nn \object_create_set:NnnnNN { NVnnNN }
-\cs_generate_variant:Nn \object_create_gset:NnnnNN { NVnnNN }
+\cs_generate_variant:Nn \object_create_set:NnnnNN { NVnnNN, NnnfNN }
+\cs_generate_variant:Nn \object_create_gset:NnnnNN { NVnnNN, NnnfNN }
 
 
-\cs_new:Nn \__rawobjects_combine:nn
+\cs_new:Nn \__rawobjects_combine_aux:nnn
   {
-    anon . #2 . #1
+    anon . #3 . #2 . #1
   }
 
-\cs_generate_variant:Nn \__rawobjects_combine:nn { Vn }
+\cs_generate_variant:Nn \__rawobjects_combine_aux:nnn { Vnf }
 
+\cs_new:Nn \__rawobjects_combine:Nn
+  {
+    \__rawobjects_combine_aux:Vnf #1 { #2 }
+  {
+    \cs_to_str:N #1
+  }
+  }
+
 \cs_new_protected:Nn \object_allocate_incr:NNnnNN
   {
-    \object_create_set:NnnnNN #1 { #3 }{ #4 }
+    \object_create_set:NnnfNN #1 { #3 }{ #4 }
       {
-        \__rawobjects_combine:Vn #2 { #3 }
+        \__rawobjects_combine:Nn #2 { #3 }
       }
       #5 #6
 
@@ -498,9 +710,9 @@
 
 \cs_new_protected:Nn \object_gallocate_incr:NNnnNN
   {
-    \object_create_gset:NnnnNN #1 { #3 }{ #4 }
+    \object_create_gset:NnnfNN #1 { #3 }{ #4 }
       {
-        \__rawobjects_combine:Vn #2 { #3 }
+        \__rawobjects_combine:Nn #2 { #3 }
       }
       #5 #6
 
@@ -513,9 +725,9 @@
 
 \cs_new_protected:Nn \object_allocate_gincr:NNnnNN
   {
-    \object_create_set:NnnnNN #1 { #3 }{ #4 }
+    \object_create_set:NnnfNN #1 { #3 }{ #4 }
       {
-        \__rawobjects_combine:Vn #2 { #3 }
+        \__rawobjects_combine:Nn #2 { #3 }
       }
       #5 #6
 
@@ -524,9 +736,9 @@
 
 \cs_new_protected:Nn \object_gallocate_gincr:NNnnNN
   {
-    \object_create_gset:NnnnNN #1 { #3 }{ #4 }
+    \object_create_gset:NnnfNN #1 { #3 }{ #4 }
       {
-        \__rawobjects_combine:Vn #2 { #3 }
+        \__rawobjects_combine:Nn #2 { #3 }
       }
       #5 #6
 
@@ -559,12 +771,7 @@
 \cs_new_protected:Nn \proxy_push_member:nnn
   {
     \__rawobjects_force_scope:n { #1 }
-    \object_new_member:nnn { #1 }{ #2 _ type }{ str }
-    \str_set:cn
-      {
-        \object_member_adr:nnn { #1 }{ #2 _ type }{ str }
-      }
-      { #3 }
+    \object_newconst_str:nnn { #1 }{ #2 _ type }{ #3 }
     \seq_gput_left:cn
       {
         \object_member_adr:nnn { #1 }{ varlist }{ seq }



More information about the tex-live-commits mailing list.