%%
%% This is file `lt3rawobjects.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% lt3rawobjects.dtx  (with options: `package')
%% 
%% This is a generated file.
%% 
%% lt3rawobjects Object oriented programming in LaTeX3
%% Copyright (C) 2022  Paolo De Donato <dedonato95@hotmail.it>
%% 
%% lt3rawobjects is free software: you can redistribute it and/or modify
%% it under the terms of the GNU General Public License as published by
%% the Free Software Foundation, either version 3 of the License, or
%% (at your option) any later version.
%% 
%% lt3rawobjects is distributed in the hope that it will be useful,
%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
%% GNU General Public License for more details.
%% 
%% You should have received a copy of the GNU General Public License
%% along with lt3rawobjects.  If not, see <https://www.gnu.org/licenses/>.
%% 
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3}[2022-04-10]
\ProvidesExplPackage{lt3rawobjects}{2023/03/17}{ 2.3 }{Objects and proxies in LaTeX3}

\msg_new:nnn { rawobjects }{ deprecate }
  {
    Command ~ #1 ~ is ~ deprecated. ~ Use ~ instead ~ #2
  }

\cs_new_protected:Nn \__rawobjects_launch_deprecate:NN
  {
    \msg_warning:nnnn{ rawobjects }{ deprecate }{ #1 }{ #2 }
  }


\cs_new:Nn \rwobj_address_f:n
  {
    \exp_args:Nc \cs_to_str:N { #1 }
  }

\str_const:Nn \c_object_local_str {l}
\str_const:Nn \c_object_global_str {g}
\str_const:Nn \c_object_public_str {_}
\str_const:Nn \c_object_private_str {__}

\cs_new:Nn \__rawobjects_scope:N
  {
    \str_use:N #1
  }

\cs_new:Nn \__rawobjects_scope_pfx:N
  {
    \str_if_eq:NNF #1 \c_object_local_str
      { g }
  }

\cs_generate_variant:Nn \__rawobjects_scope_pfx:N { c }

\cs_new:Nn \__rawobjects_scope_pfx_cl:n
  {
    \__rawobjects_scope_pfx:c{
  \object_ncmember_adr:nnn
    {
  \object_embedded_adr:nn { #1  }{ /_I_/ }
}
{ S }{ str }
}
  }

\cs_new:Nn \__rawobjects_vis_var:N
  {
    \str_use:N #1
  }

\cs_new:Nn \__rawobjects_vis_fun:N
  {
    \str_if_eq:NNT #1 \c_object_private_str
      {
        __
      }
  }

\cs_new:Nn \object_address:nn {
  \tl_to_str:n { #1  _  #2 }
}

\cs_new:Nn \object_embedded_adr:nn
  {
    #1 \tl_to_str:n{ _SUB_ #2 }
  }

\cs_generate_variant:Nn \object_embedded_adr:nn{ Vn }


\cs_new_protected:Nn \object_address_set:Nnn {
  \str_set:Nn #1 { #2  _  #3 }
}

\cs_new_protected:Nn \object_address_gset:Nnn {
  \str_gset:Nn #1 { #2  _  #3 }
}


\prg_new_conditional:Nnn \object_if_exist:n { p, T, F, TF }
  {
    \cs_if_exist:cTF
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { S }{ str }
      }
      {
        \prg_return_true:
      }
      {
        \prg_return_false:
      }
  }

\prg_generate_conditional_variant:Nnn \object_if_exist:n { V }
  { p, T, F, TF }

\cs_new:Nn \object_get_module:n {
  \object_ncmember_use:nnn
  {
    \object_embedded_adr:nn{ #1 }{ /_I_/ }
  }
  { M }{ str }
}
\cs_new:Nn \object_get_proxy_adr:n {
  \object_ncmember_use:nnn
  {
    \object_embedded_adr:nn{ #1 }{ /_I_/ }
  }
  { P }{ str }
}

\cs_generate_variant:Nn \object_get_module:n { V }
\cs_generate_variant:Nn \object_get_proxy_adr:n { V }
\prg_new_conditional:Nnn \object_if_local:n {p, T, F, TF}
{
  \str_if_eq:cNTF
    {
      \object_ncmember_adr:nnn
        {
          \object_embedded_adr:nn{ #1 }{ /_I_/ }
        }
        { S }{ str }
    }
    \c_object_local_str
    {
      \prg_return_true:
    }
    {
      \prg_return_false:
    }
}

\prg_new_conditional:Nnn \object_if_global:n {p, T, F, TF}
{
  \str_if_eq:cNTF
    {
      \object_ncmember_adr:nnn
        {
          \object_embedded_adr:nn{ #1 }{ /_I_/ }
        }
        { S }{ str }
    }
    \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_ncmember_adr:nnn
        {
          \object_embedded_adr:nn{ #1 }{ /_I_/ }
        }
        { V }{ str }
    }
    \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_ncmember_adr:nnn
        {
          \object_embedded_adr:nn{ #1 }{ /_I_/ }
        }
        { V }{ str }
    }
    \c_object_private_str
    {
      \prg_return_true:
    }
    {
      \prg_return_false:
    }
}

\prg_generate_conditional_variant:Nnn \object_if_local:n { V }
  { p, T, F, TF }
\prg_generate_conditional_variant:Nnn \object_if_global:n { V }
  { p, T, F, TF }
\prg_generate_conditional_variant:Nnn \object_if_public:n { V }
  { p, T, F, TF }
\prg_generate_conditional_variant:Nnn \object_if_private:n { V }
  { p, T, F, TF }

\cs_new:Nn \object_macro_adr:nn
  {
    #1 \tl_to_str:n{ _MACRO_ #2 }
  }

\cs_generate_variant:Nn \object_macro_adr:nn{ Vn }

\cs_new:Nn \object_macro_use:nn
  {
    \use:c
      {
        \object_macro_adr:nn{ #1 }{ #2 }
      }
  }

\cs_generate_variant:Nn \object_macro_use:nn{ Vn }


\cs_new:Nn \__rawobjects_member_adr:nnnNN
  {
    \__rawobjects_scope:N #4
    \__rawobjects_vis_var:N #5
    #1 \tl_to_str:n { _ MEMBER _ #2 _ #3 }
  }

\cs_generate_variant:Nn \__rawobjects_member_adr:nnnNN { VnnNN, nnncc }


\cs_new:Nn \object_member_adr:nnn
  {
    \__rawobjects_member_adr:nnncc { #1 }{ #2 }{ #3 }
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { S }{ str }
      }
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { V }{ str }
      }
  }

\cs_generate_variant:Nn \object_member_adr:nnn { Vnn, vnn, nnv, nnf }


\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_generate_conditional_variant:Nnn \object_member_if_exist:nnn
  { Vnn }{ p, T, F, TF }


\prg_new_conditional:Nnn \object_member_if_tracked:nn {p, T, F, TF }
  {
    \cs_if_exist:cTF
      {
        \object_rcmember_adr:nnn
          { #1 }{ #2 _ type }{ str }
      }
      {
        \prg_return_true:
      }
      {
        \cs_if_exist:cTF
          {
            \object_ncmember_adr:nnn
              {
                \object_embedded_adr:nn { #1 }{ /_T_/ }
              }
              { #2 _ type }{ str }
          }
          {
            \prg_return_true:
          }
          {
            \prg_return_false:
          }
      }
  }

\prg_generate_conditional_variant:Nnn \object_member_if_tracked:nn
  { Vn }{ p, T, F, TF }

\prg_new_eq_conditional:NNn \object_member_if_exist:nn
  \object_member_if_tracked:nn { p, T, F, TF }
\prg_new_eq_conditional:NNn \object_member_if_exist:Vn
  \object_member_if_tracked:Vn { p, T, F, TF }


\cs_new:Nn \object_member_type:nn
  {
    \cs_if_exist:cTF
      {
        \object_rcmember_adr:nnn
          { #1 }{ #2 _ type }{ str }
      }
      {
        \object_rcmember_use:nnn
          { #1 }{ #2 _ type }{ str }
      }
      {
        \cs_if_exist:cT
          {
            \object_ncmember_adr:nnn
              {
                \object_embedded_adr:nn { #1 }{ /_T_/ }
              }
              { #2 _ type }{ str }
          }
          {
            \object_ncmember_use:nnn
              {
                \object_embedded_adr:nn { #1 }{ /_T_/ }
              }
              { #2 _ type }{ str }
          }
      }
  }


\cs_new:Nn \object_member_adr:nn
  {
    \object_member_adr:nnf { #1 }{ #2 }
      {
        \object_member_type:nn { #1 }{ #2 }
      }
  }

\cs_generate_variant:Nn \object_member_adr:nn { Vn }


\cs_new:Nn \__rawobjects_par_trans:N
  {
    \str_case:nnF { #1 }
      {
        { N }{ N }
        { V }{ N }
        { n }{ n }
        { v }{ n }
        { f }{ n }
        { x }{ n }
        { e }{ n }
        { o }{ n }
        { ~ }{}
      }
      { #1 }
  }

\cs_new:Nn \__rawobjects_par_trans:n
  {
    \str_map_function:nN { #1 } \__rawobjects_par_trans:N
  }

\str_new:N \l__rawobjects_tmp_fa_str

\cs_new_protected:Nn \__rawobjects_save_dat:n
  {
    \str_set:Nx \l__rawobjects_tmp_fa_str
      { \str_tail:n{ #1 } }
  }
\cs_new_protected:Nn \__rawobjects_save_dat:nnN
  {
    \str_set:Nx \l__rawobjects_tmp_fa_str
      { \str_tail:n{ #2 } }
  }
\cs_new_protected:Nn \__rawobjects_save_dat_aux:n
  {
    \__rawobjects_save_dat:nnN #1
  }
\cs_generate_variant:Nn \__rawobjects_save_dat_aux:n { f }

\cs_new_protected:Nn \__rawobjects_save_fun:N
  {
    \__rawobjects_save_dat_aux:f { \cs_split_function:N #1 }
  }

\cs_new:Nn \__rawobjects_use_dat:nn
  {
    #1 : #2 \str_use:N \l__rawobjects_tmp_fa_str
  }


\cs_new_protected:Nn \__rawobjects_mgen:nN
  {
    \__rawobjects_save_fun:N #2
    \cs_new:cpn { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        #2
          {
            \object_member_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
    \cs_new:cpn { #1 : nn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2
      {
        #2
          {
            \object_member_adr:nn{ ##1 }{ ##2 }
          }
      }
  }
\cs_new_protected:Nn \__rawobjects_mgen_pr:nN
  {
    \__rawobjects_save_fun:N #2
    \cs_new_protected:cpn
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        #2
          {
            \object_member_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
    \cs_new_protected:cpn
      { #1 : nn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2
      {
        #2
          {
            \object_member_adr:nn{ ##1 }{ ##2 }
          }
      }
  }

\cs_new_protected:Nn \__rawobjects_mgen:nnn
  {
    \__rawobjects_save_dat:n { #3 }

    \cs_new:cpn { __rawobjects_auxfun_#1 :nn } ##1##2
      {
        \use:c{ #2 : #3 }
      }
    \cs_generate_variant:cn { __rawobjects_auxfun_#1 :nn }{ nf, ff }

    \cs_new:cpn { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        \use:c { __rawobjects_auxfun_#1 :nf }
          { ##3 }
          {
            \__rawobjects_scope_pfx_cl:n{ ##1 }
          }
          {
            \object_member_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
    \cs_new:cpn { #1 : nn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2
      {
        \use:c { __rawobjects_auxfun_#1 :ff }
          {
            \object_member_type:nn { ##1 }{ ##2 }
          }
          {
            \__rawobjects_scope_pfx_cl:n{ ##1 }
          }
          {
            \object_member_adr:nn{ ##1 }{ ##2 }
          }
      }
  }
\cs_new_protected:Nn \__rawobjects_mgen_pr:nnn
  {
    \__rawobjects_save_dat:n { #3 }

    \cs_new:cpn { __rawobjects_auxfun_#1 :nn } ##1##2
      {
        \use:c{ #2 : #3 }
      }
    \cs_generate_variant:cn { __rawobjects_auxfun_#1 :nn }{ nf, ff }

    \cs_new_protected:cpn
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        \use:c { __rawobjects_auxfun_#1 :nf }
          { ##3 }
          {
            \__rawobjects_scope_pfx_cl:n{ ##1 }
          }
          {
            \object_member_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
    \cs_new_protected:cpn
      { #1 : nn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2
      {
        \use:c { __rawobjects_auxfun_#1 :ff }
          {
            \object_member_type:nn { ##1 }{ ##2 }
          }
          {
            \__rawobjects_scope_pfx_cl:n{ ##1 }
          }
          {
            \object_member_adr:nn{ ##1 }{ ##2 }
          }
      }
  }

\cs_generate_variant:Nn \__rawobjects_mgen:nN { fN }
\cs_generate_variant:Nn \__rawobjects_mgen:nnn { fnn }
\cs_generate_variant:Nn \__rawobjects_mgen_pr:nN { fN }
\cs_generate_variant:Nn \__rawobjects_mgen_pr:nnn { fnn }

\cs_new_protected:Nn \object_member_generate:NN
  {
    \__rawobjects_mgen:fN { \cs_to_str:N #1 } #2
  }

\cs_new_protected:Nn \object_member_generate_inline:Nnn
  {
    \__rawobjects_mgen:fnn { \cs_to_str:N #1 }{ #2 }{ #3 }
  }
\cs_new_protected:Nn \object_member_generate_protected:NN
  {
    \__rawobjects_mgen_pr:fN { \cs_to_str:N #1 } #2
  }

\cs_new_protected:Nn \object_member_generate_protected_inline:Nnn
  {
    \__rawobjects_mgen_pr:fnn { \cs_to_str:N #1 }{ #2 }{ #3 }
  }


\cs_new_protected:Nn \__rawobjects_ncgen:nN
  {
    \__rawobjects_save_fun:N #2
    \cs_new:cpn { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        #2
          {
            \object_ncmember_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
  }
\cs_new_protected:Nn \__rawobjects_ncgen_pr:nN
  {
    \__rawobjects_save_fun:N #2
    \cs_new_protected:cpn
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        #2
          {
            \object_ncmember_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
  }

\cs_new_protected:Nn \__rawobjects_ncgen:nnn
  {
    \__rawobjects_save_dat:n { #3 }

    \cs_new:cpn { __rawobjects_auxfun_#1 :nn } ##1##2
      {
        \use:c{ #2 : #3 }
      }
    \cs_generate_variant:cn { __rawobjects_auxfun_#1 :nn }{ nf }

    \cs_new:cpn { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        \use:c { __rawobjects_auxfun_#1 :nf }
          { ##3 }
          {
            \__rawobjects_scope_pfx_cl:n{ ##1 }
          }
          {
            \object_ncmember_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
  }
\cs_new_protected:Nn \__rawobjects_ncgen_pr:nnn
  {
    \__rawobjects_save_dat:n { #3 }

    \cs_new:cpn { __rawobjects_auxfun_#1 :nn } ##1##2
      {
        \use:c{ #2 : #3 }
      }
    \cs_generate_variant:cn { __rawobjects_auxfun_#1 :nn }{ nf }

    \cs_new_protected:cpn
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        \use:c { __rawobjects_auxfun_#1 :nf }
          { ##3 }
          {
            \__rawobjects_scope_pfx_cl:n{ ##1 }
          }
          {
            \object_ncmember_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
  }

\cs_generate_variant:Nn \__rawobjects_ncgen:nN { fN }
\cs_generate_variant:Nn \__rawobjects_ncgen:nnn { fnn }
\cs_generate_variant:Nn \__rawobjects_ncgen_pr:nN { fN }
\cs_generate_variant:Nn \__rawobjects_ncgen_pr:nnn { fnn }

\cs_new_protected:Nn \object_ncmember_generate:NN
  {
    \__rawobjects_ncgen:fN { \cs_to_str:N #1 } #2
  }

\cs_new_protected:Nn \object_ncmember_generate_inline:Nnn
  {
    \__rawobjects_ncgen:fnn { \cs_to_str:N #1 }{ #2 }{ #3 }
  }
\cs_new_protected:Nn \object_ncmember_generate_protected:NN
  {
    \__rawobjects_ncgen_pr:fN { \cs_to_str:N #1 } #2
  }

\cs_new_protected:Nn \object_ncmember_generate_protected_inline:Nnn
  {
    \__rawobjects_ncgen_pr:fnn { \cs_to_str:N #1 }{ #2 }{ #3 }
  }


\cs_new_protected:Nn \__rawobjects_rcgen:nN
  {
    \__rawobjects_save_fun:N #2
    \cs_new:cpn { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        #2
          {
            \object_rcmember_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
  }
\cs_new_protected:Nn \__rawobjects_rcgen_pr:nN
  {
    \__rawobjects_save_fun:N #2
    \cs_new_protected:cpn
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        #2
          {
            \object_rcmember_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
  }

\cs_new_protected:Nn \__rawobjects_rcgen:nnn
  {
    \__rawobjects_save_dat:n { #3 }

    \cs_new:cpn { __rawobjects_auxfun_#1 :nn } ##1##2
      {
        \use:c{ #2 : #3 }
      }
    \cs_generate_variant:cn { __rawobjects_auxfun_#1 :nn }{ nf }

    \cs_new:cpn { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        \use:c { __rawobjects_auxfun_#1 :nf }
          { ##3 }
          {
            \__rawobjects_scope_pfx_cl:n{ ##1 }
          }
          {
            \object_rcmember_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
  }
\cs_new_protected:Nn \__rawobjects_rcgen_pr:nnn
  {
    \__rawobjects_save_dat:n { #3 }

    \cs_new:cpn { __rawobjects_auxfun_#1 :nn } ##1##2
      {
        \use:c{ #2 : #3 }
      }
    \cs_generate_variant:cn { __rawobjects_auxfun_#1 :nn }{ nf }

    \cs_new_protected:cpn
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str } ##1##2##3
      {
        \use:c { __rawobjects_auxfun_#1 :nf }
          { ##3 }
          {
            \__rawobjects_scope_pfx_cl:n{ ##1 }
          }
          {
            \object_rcmember_adr:nnn{ ##1 }{ ##2 }{ ##3 }
          }
      }
  }

\cs_generate_variant:Nn \__rawobjects_rcgen:nN { fN }
\cs_generate_variant:Nn \__rawobjects_rcgen:nnn { fnn }
\cs_generate_variant:Nn \__rawobjects_rcgen_pr:nN { fN }
\cs_generate_variant:Nn \__rawobjects_rcgen_pr:nnn { fnn }

\cs_new_protected:Nn \object_rcmember_generate:NN
  {
    \__rawobjects_rcgen:fN { \cs_to_str:N #1 } #2
  }

\cs_new_protected:Nn \object_rcmember_generate_inline:Nnn
  {
    \__rawobjects_rcgen:fnn { \cs_to_str:N #1 }{ #2 }{ #3 }
  }
\cs_new_protected:Nn \object_rcmember_generate_protected:NN
  {
    \__rawobjects_rcgen_pr:fN { \cs_to_str:N #1 } #2
  }

\cs_new_protected:Nn \object_rcmember_generate_protected_inline:Nnn
  {
    \__rawobjects_rcgen_pr:fnn { \cs_to_str:N #1 }{ #2 }{ #3 }
  }


\cs_generate_variant:Nn \cs_generate_variant:Nn { cx }

\cs_new_protected:Nn \__rawobjects_genmem_int:nnn
  {
    \__rawobjects_mgen:nnn { #1 }{ #2 }{ #3 }
    \cs_generate_variant:cx
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str }
      { Vnn \str_use:N \l__rawobjects_tmp_fa_str, nnv \str_use:N \l__rawobjects_tmp_fa_str }
    \cs_generate_variant:cx
      { #1 : nn \str_use:N \l__rawobjects_tmp_fa_str }
      { Vn \str_use:N \l__rawobjects_tmp_fa_str }
  }
\cs_new_protected:Nn \__rawobjects_genmem_pr_int:nnn
  {
    \__rawobjects_mgen_pr:nnn { #1 }{ #2 }{ #3 }
    \cs_generate_variant:cx
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str }
      { Vnn \str_use:N \l__rawobjects_tmp_fa_str, nnv \str_use:N \l__rawobjects_tmp_fa_str }
    \cs_generate_variant:cx
      { #1 : nn \str_use:N \l__rawobjects_tmp_fa_str }
      { Vn \str_use:N \l__rawobjects_tmp_fa_str }
  }

\cs_new_protected:Nn \__rawobjects_genncm_int:nnn
  {
    \__rawobjects_ncgen:nnn { #1 }{ #2 }{ #3 }
    \cs_generate_variant:cx
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str }
      { Vnn \str_use:N \l__rawobjects_tmp_fa_str }
  }
\cs_new_protected:Nn \__rawobjects_genncm_pr_int:nnn
  {
    \__rawobjects_ncgen_pr:nnn { #1 }{ #2 }{ #3 }
    \cs_generate_variant:cx
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str }
      { Vnn \str_use:N \l__rawobjects_tmp_fa_str }
  }

\cs_new_protected:Nn \__rawobjects_genrcm_int:nnn
  {
    \__rawobjects_rcgen:nnn { #1 }{ #2 }{ #3 }
    \cs_generate_variant:cx
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str }
      { Vnn \str_use:N \l__rawobjects_tmp_fa_str }
  }
\cs_new_protected:Nn \__rawobjects_genrcm_pr_int:nnn
  {
    \__rawobjects_rcgen_pr:nnn { #1 }{ #2 }{ #3 }
    \cs_generate_variant:cx
      { #1 : nnn \str_use:N \l__rawobjects_tmp_fa_str }
      { Vnn \str_use:N \l__rawobjects_tmp_fa_str }
  }


\msg_new:nnnn { rawobjects }{ noerr }{ Unspecified ~ scope }
  {
    Object ~ #1 ~ hasn't ~ a ~ scope ~ variable
  }


\__rawobjects_genmem_pr_int:nnn { object_new_member }{ #1 _ new }{ c }

\cs_new_protected:Nn \object_new_member_tracked:nnn
  {
    \object_new_member:nnn { #1 }{ #2 }{ #3 }

    \str_const:cn
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn { #1 }{ /_T_/ }
          }
          { #2 _ type }{ str }
      }
      { #3 }
  }

\cs_generate_variant:Nn \object_new_member_tracked:nnn { Vnn, nnv }


\__rawobjects_genmem_int:nnn {object_member_use}{ #1_use }{c}

\cs_generate_variant:Nn \object_member_use:nnn {vnn}


\__rawobjects_genmem_pr_int:nnn {object_member_set}{ #1_#2 set }{ cn }


\__rawobjects_genmem_pr_int:nnn { object_member_set_eq }{ #1 _ #2 set_eq }{ cN }

\cs_generate_variant:Nn \object_member_set_eq:nnnN { nnnc, Vnnc }

\cs_generate_variant:Nn \object_member_set_eq:nnN { nnc, Vnc }


\cs_new:Nn \object_ncmember_adr:nnn
  {
    \tl_to_str:n{ c _ } #1 \tl_to_str:n { _ CONST _ #2 _ #3 }
  }

\cs_generate_variant:Nn \object_ncmember_adr:nnn { Vnn, vnn }


\cs_new:Nn \object_rcmember_adr:nnn
  {
    \object_ncmember_adr:vnn
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { P }{ str }
      }
      { #2 }{ #3 }
  }

\cs_generate_variant:Nn \object_rcmember_adr:nnn { Vnn }

\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 }


\__rawobjects_genncm_int:nnn { object_ncmember_use }{ #1_use}{ c }

\__rawobjects_genrcm_int:nnn { object_rcmember_use }{ #1_use}{ c }


\__rawobjects_genncm_pr_int:nnn { object_newconst }{ #1 _ const }{ cn }


\cs_new_protected:Nn \object_newconst_tl:nnn
  {
    \object_newconst:nnnn { #1 }{ #2 }{ tl }{ #3 }
  }
\cs_new_protected:Nn \object_newconst_str:nnn
  {
    \object_newconst:nnnn { #1 }{ #2 }{ str }{ #3 }
  }
\cs_new_protected:Nn \object_newconst_int:nnn
  {
    \object_newconst:nnnn { #1 }{ #2 }{ int }{ #3 }
  }
\cs_new_protected:Nn \object_newconst_clist:nnn
  {
    \object_newconst:nnnn { #1 }{ #2 }{ clist }{ #3 }
  }
\cs_new_protected:Nn \object_newconst_dim:nnn
  {
    \object_newconst:nnnn { #1 }{ #2 }{ dim }{ #3 }
  }
\cs_new_protected:Nn \object_newconst_skip:nnn
  {
    \object_newconst:nnnn { #1 }{ #2 }{ skip }{ #3 }
  }
\cs_new_protected:Nn \object_newconst_fp:nnn
  {
    \object_newconst:nnnn { #1 }{ #2 }{ fp }{ #3 }
  }

\cs_generate_variant:Nn \object_newconst_tl:nnn { Vnn }
\cs_generate_variant:Nn \object_newconst_str:nnn { Vnn }
\cs_generate_variant:Nn \object_newconst_int:nnn { Vnn }
\cs_generate_variant:Nn \object_newconst_clist:nnn { Vnn }
\cs_generate_variant:Nn \object_newconst_dim:nnn { Vnn }
\cs_generate_variant:Nn \object_newconst_skip:nnn { Vnn }
\cs_generate_variant:Nn \object_newconst_fp:nnn { Vnn }

\cs_generate_variant:Nn \object_newconst_str:nnn { nnx }
\cs_generate_variant:Nn \object_newconst_str:nnn { nnV }


\cs_new_protected:Nn \object_newconst_seq_from_clist:nnn
  {
    \seq_const_from_clist:cn
      {
        \object_ncmember_adr:nnn { #1 }{ #2 }{ seq }
      }
      { #3 }
  }

\cs_generate_variant:Nn \object_newconst_seq_from_clist:nnn { Vnn }


\cs_new_protected:Nn \object_newconst_prop_from_keyval:nnn
  {
    \prop_const_from_keyval:cn
      {
        \object_ncmember_adr:nnn { #1 }{ #2 }{ prop }
      }
      { #3 }
  }

\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
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { P }{ str }
      }
      { #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 }


\cs_new_protected:Nn \__rawobjects_initproxy:nnn
  {
    \object_newconst:nnnn
      {
        \object_embedded_adr:nn{ #3 }{ /_I_/ }
      }
      { ifprox }{ bool }{ \c_true_bool }
  }
\cs_generate_variant:Nn \__rawobjects_initproxy:nnn { VnV }


\cs_new:Nn \__rawobjects_bol_com:N
  {
    \cs_if_exist_p:N #1 && \bool_if_p:N #1
  }

\cs_generate_variant:Nn \__rawobjects_bol_com:N { c }

\prg_new_conditional:Nnn \object_if_proxy:n {p, T, F, TF}
  {
    \cs_if_exist:cTF
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { ifprox }{ bool }
      }
      {
        \bool_if:cTF
          {
            \object_ncmember_adr:nnn
              {
                \object_embedded_adr:nn{ #1 }{ /_I_/ }
              }
              { ifprox }{ bool }
          }
          {
            \prg_return_true:
          }
          {
            \prg_return_false:
          }
      }
      {
        \prg_return_false:
      }
  }


\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_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { P }{ str }
      }
  { #2 }
      {
        \prg_return_true:
      }
      {
        \prg_return_false:
      }
  }

\prg_new_conditional:Nnn \object_test_proxy:nN {p, T, F, TF}
  {
    \str_if_eq:cNTF
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { P }{ str }
      }
  #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}


\msg_new:nnnn { rawobjects }{ notproxy }{ Fake ~ proxy }
  {
    Object ~ #1 ~ is ~ not ~ a ~ proxy.
  }

\cs_new_protected:Nn \__rawobjects_force_proxy:n
  {
    \object_if_proxy:nF { #1 }
      {
        \msg_error:nnn { rawobjects }{ notproxy }{ #1 }
      }
  }

\cs_new_protected:Nn \__rawobjects_create_anon:nnnNN
  {
    \tl_if_empty:nF{ #1 }
    {

    \__rawobjects_force_proxy:n { #1 }

    \object_newconst_str:nnn
      {
        \object_embedded_adr:nn{ #3 }{ /_I_/ }
      }
      { M }{ #2 }
    \object_newconst_str:nnn
      {
        \object_embedded_adr:nn{ #3 }{ /_I_/ }
      }
      { P }{ #1 }
    \object_newconst_str:nnV
      {
        \object_embedded_adr:nn{ #3 }{ /_I_/ }
      }
      { S } #4
    \object_newconst_str:nnV
      {
        \object_embedded_adr:nn{ #3 }{ /_I_/ }
      }
      { V } #5

    \seq_map_inline:cn
      {
        \object_member_adr:nnn { #1 }{ varlist }{ seq }
      }
      {
        \object_new_member:nnv { #3 }{ ##1 }
          {
            \object_ncmember_adr:nnn { #1 }{ ##1 _ type }{ str }
          }
      }

    \seq_map_inline:cn
      {
        \object_member_adr:nnn { #1 }{ objlist }{ seq }
      }
      {
        \embedded_create:nvn
          { #3 }
          {
            \object_ncmember_adr:nnn { #1 }{ ##1 _ proxy }{ str }
          }
          { ##1 }
      }

    \tl_map_inline:cn
      {
        \object_member_adr:nnn { #1 }{ init }{ tl }
      }
      {
        ##1 { #1 }{ #2 }{ #3 }
      }

    }
  }

\cs_generate_variant:Nn \__rawobjects_create_anon:nnnNN { xnxNN, xvxcc }

\cs_new_protected:Nn \object_create:nnnNN
  {
    \__rawobjects_create_anon:xnxNN { #1 }{ #2 }
      { \object_address:nn { #2 }{ #3 } }
      #4 #5
  }

\cs_generate_variant:Nn \object_create:nnnNN { VnnNN }

\cs_new_protected:Nn \object_create_set:NnnnNN
  {
    \object_create:nnnNN { #2 }{ #3 }{ #4 } #5 #6
    \str_set:Nx #1 { \object_address:nn { #3 }{ #4 } }
  }

\cs_new_protected:Nn \object_create_gset:NnnnNN
  {
    \object_create:nnnNN { #2 }{ #3 }{ #4 } #5 #6
    \str_gset:Nx #1 { \object_address:nn { #3 }{ #4 } }
  }

\cs_generate_variant:Nn \object_create_set:NnnnNN { NVnnNN, NnnfNN }
\cs_generate_variant:Nn \object_create_gset:NnnnNN { NVnnNN, NnnfNN }

\cs_new_protected:Nn \object_create:nnnN
  {
    \object_create:nnnNN { #1 }{ #2 }{ #3 } #4 \c_object_public_str
  }

\cs_generate_variant:Nn \object_create:nnnN { VnnN }

\cs_new_protected:Nn \object_create_set:NnnnN
  {
    \object_create_set:NnnnNN #1 { #2 }{ #3 }{ #4 } #5 \c_object_public_str
  }

\cs_new_protected:Nn \object_create_gset:NnnnN
  {
    \object_create_gset:NnnnNN #1 { #2 }{ #3 }{ #4 } #5 \c_object_public_str
  }

\cs_generate_variant:Nn \object_create_set:NnnnN { NVnnN }
\cs_generate_variant:Nn \object_create_gset:NnnnN { NVnnN }

\cs_new_protected:Nn \object_create:nnn
  {
    \object_create:nnnNN { #1 }{ #2 }{ #3 }
      \c_object_global_str \c_object_public_str
  }

\cs_generate_variant:Nn \object_create:nnn { Vnn }

\cs_new_protected:Nn \object_create_set:Nnnn
  {
    \object_create_set:NnnnNN #1 { #2 }{ #3 }{ #4 }
      \c_object_global_str \c_object_public_str
  }

\cs_new_protected:Nn \object_create_gset:Nnnn
  {
    \object_create_gset:NnnnNN #1 { #2 }{ #3 }{ #4 }
      \c_object_global_str \c_object_public_str
  }

\cs_generate_variant:Nn \object_create_set:Nnnn { NVnn }
\cs_generate_variant:Nn \object_create_gset:Nnnn { NVnn }

\cs_new_protected:Nn \embedded_create:nnn
  {
    \__rawobjects_create_anon:xvxcc { #2 }
  {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { M }{ str }
      }
      {
        \object_embedded_adr:nn
          { #1 }{ #3 }
      }
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { S }{ str }
      }
      {
        \object_ncmember_adr:nnn
          {
            \object_embedded_adr:nn{ #1 }{ /_I_/ }
          }
          { V }{ str }
      }
  }

\cs_generate_variant:Nn \embedded_create:nnn { nvn, Vnn }


\cs_new_protected:Nn \proxy_create:nn
  {
    \object_create:VnnNN \c_proxy_address_str { #1 }{ #2 }
      \c_object_global_str \c_object_public_str
  }

\cs_new_protected:Nn \proxy_create_set:Nnn
  {
    \object_create_set:NVnnNN #1 \c_proxy_address_str { #2 }{ #3 }
      \c_object_global_str \c_object_public_str
  }

\cs_new_protected:Nn \proxy_create_gset:Nnn
  {
    \object_create_gset:NVnnNN #1 \c_proxy_address_str { #2 }{ #3 }
      \c_object_global_str \c_object_public_str
  }

\cs_new_protected:Nn \proxy_create:nnN
  {
    \__rawobjects_launch_deprecate:NN \proxy_create:nnN \proxy_create:nn
    \object_create:VnnNN \c_proxy_address_str { #1 }{ #2 }
      \c_object_global_str #3
  }

\cs_new_protected:Nn \proxy_create_set:NnnN
  {
    \__rawobjects_launch_deprecate:NN \proxy_create_set:NnnN \proxy_create_set:Nnn
    \object_create_set:NVnnNN #1 \c_proxy_address_str { #2 }{ #3 }
      \c_object_global_str #4
  }

\cs_new_protected:Nn \proxy_create_gset:NnnN
  {
    \__rawobjects_launch_deprecate:NN \proxy_create_gset:NnnN \proxy_create_gset:Nnn
    \object_create_gset:NVnnNN #1 \c_proxy_address_str { #2 }{ #3 }
      \c_object_global_str #4
  }


\cs_new_protected:Nn \proxy_push_member:nnn
  {
    \object_newconst_str:nnn { #1 }{ #2 _ type }{ #3 }
    \seq_gput_left:cn
      {
        \object_member_adr:nnn { #1 }{ varlist }{ seq }
      }
      { #2 }
  }

\cs_generate_variant:Nn \proxy_push_member:nnn { Vnn }


\cs_new_protected:Nn \proxy_push_embedded:nnn
  {
    \object_newconst_str:nnx { #1 }{ #2 _ proxy }{ #3 }
    \seq_gput_left:cn
      {
        \object_member_adr:nnn { #1 }{ objlist }{ seq }
      }
      { #2 }
  }

\cs_generate_variant:Nn \proxy_push_embedded:nnn { Vnn }


\cs_new_protected:Nn \proxy_add_initializer:nN
  {
    \tl_gput_right:cn
      {
        \object_member_adr:nnn { #1 }{ init }{ tl }
      }
      { #2 }
  }

\cs_generate_variant:Nn \proxy_add_initializer:nN { VN }


\str_const:Nx \c_proxy_address_str
  { \object_address:nn { rawobjects }{ proxy } }

\object_newconst_str:nnn
  {
    \object_embedded_adr:Vn \c_proxy_address_str { /_I_/ }
  }
  { M }{ rawobjects }

\object_newconst_str:nnV
  {
    \object_embedded_adr:Vn \c_proxy_address_str { /_I_/ }
  }
  { P } \c_proxy_address_str

\object_newconst_str:nnV
  {
    \object_embedded_adr:Vn \c_proxy_address_str { /_I_/ }
  }
  { S } \c_object_global_str

\object_newconst_str:nnV
  {
    \object_embedded_adr:Vn \c_proxy_address_str { /_I_/ }
  }
  { V } \c_object_public_str

\__rawobjects_initproxy:VnV \c_proxy_address_str { rawobjects } \c_proxy_address_str

\object_new_member:Vnn \c_proxy_address_str { init }{ tl }

\object_new_member:Vnn \c_proxy_address_str { varlist }{ seq }

\object_new_member:Vnn \c_proxy_address_str { objlist }{ seq }

\proxy_push_member:Vnn \c_proxy_address_str
  { init }{ tl }
\proxy_push_member:Vnn \c_proxy_address_str
  { varlist }{ seq }
\proxy_push_member:Vnn \c_proxy_address_str
  { objlist }{ seq }

\proxy_add_initializer:VN \c_proxy_address_str
  \__rawobjects_initproxy:nnn


\cs_new:Nn \__rawobjects_combine_aux:nnn
  {
    anon . #3 . #2 . #1
  }

\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:NnnfNN #1 { #3 }{ #4 }
      {
        \__rawobjects_combine:Nn #2 { #3 }
      }
      #5 #6

      \int_incr:N #2
  }

\cs_new_protected:Nn \object_gallocate_incr:NNnnNN
  {
    \object_create_gset:NnnfNN #1 { #3 }{ #4 }
      {
        \__rawobjects_combine:Nn #2 { #3 }
      }
      #5 #6

      \int_incr:N #2
  }

\cs_generate_variant:Nn \object_allocate_incr:NNnnNN { NNVnNN }

\cs_generate_variant:Nn \object_gallocate_incr:NNnnNN { NNVnNN }

\cs_new_protected:Nn \object_allocate_gincr:NNnnNN
  {
    \object_create_set:NnnfNN #1 { #3 }{ #4 }
      {
        \__rawobjects_combine:Nn #2 { #3 }
      }
      #5 #6

      \int_gincr:N #2
  }

\cs_new_protected:Nn \object_gallocate_gincr:NNnnNN
  {
    \object_create_gset:NnnfNN #1 { #3 }{ #4 }
      {
        \__rawobjects_combine:Nn #2 { #3 }
      }
      #5 #6

      \int_gincr:N #2
  }

\cs_generate_variant:Nn \object_allocate_gincr:NNnnNN { NNVnNN }

\cs_generate_variant:Nn \object_gallocate_gincr:NNnnNN { NNVnNN }

\cs_new_protected:Nn \object_assign:nn
  {
    \seq_map_inline:cn
      {
        \object_member_adr:vnn
          {
            \object_ncmember_adr:nnn
              {
                \object_embedded_adr:nn{ #1 }{ /_I_/ }
              }
              { P }{ str }
          }
          { varlist }{ seq }
      }
      {
        \object_member_set_eq:nnc { #1 }{ ##1 }
          {
            \object_member_adr:nn{ #2 }{ ##1 }
          }
      }
  }

\cs_generate_variant:Nn \object_assign:nn { nV, Vn, VV }

\endinput
%%
%% End of file `lt3rawobjects.sty'.
