xo-gc xo-object2 xo-facet: builds w/ ISequence,Dlist
This commit is contained in:
parent
519df04e34
commit
afc44e71fa
26 changed files with 717 additions and 75 deletions
|
|
@ -1646,14 +1646,17 @@ macro(xo_add_genfacet)
|
||||||
REQUIRED)
|
REQUIRED)
|
||||||
message(STATUS "GENFACET_EXECUTABLE=${GENFACET_EXECUTABLE}")
|
message(STATUS "GENFACET_EXECUTABLE=${GENFACET_EXECUTABLE}")
|
||||||
|
|
||||||
|
set(generatedFiles
|
||||||
|
${GF_OUTPUT_HPP_DIR}/${FACET}.hpp
|
||||||
|
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/A${FACET}.hpp
|
||||||
|
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${FACET}_Any.hpp
|
||||||
|
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${FACET}_Xfer.hpp
|
||||||
|
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/R${FACET}.hpp
|
||||||
|
${GF_OUTPUT_CPP_DIR}/I${FACET}_Any.cpp)
|
||||||
|
|
||||||
# Build the genfacet command
|
# Build the genfacet command
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${GF_OUTPUT_HPP_DIR}/${FACET}.hpp
|
OUTPUT $generatedFiles
|
||||||
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/A${FACET}.hpp
|
|
||||||
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${FACET}_Any.hpp
|
|
||||||
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${FACET}_Xfer.hpp
|
|
||||||
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/R${FACET}.hpp
|
|
||||||
${GF_OUTPUT_CPP_DIR}/I${FACET}_Any.cpp
|
|
||||||
COMMAND ${GENFACET_EXECUTABLE}
|
COMMAND ${GENFACET_EXECUTABLE}
|
||||||
--input ${GF_INPUT}
|
--input ${GF_INPUT}
|
||||||
--output-hpp ${GF_OUTPUT_HPP_DIR}
|
--output-hpp ${GF_OUTPUT_HPP_DIR}
|
||||||
|
|
@ -1666,7 +1669,50 @@ macro(xo_add_genfacet)
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create a target for this generation
|
# Create a target for this generation
|
||||||
add_custom_target(${GF_TARGET}
|
add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles})
|
||||||
DEPENDS ${GF_GENERATED_FILES}
|
endmacro()
|
||||||
)
|
|
||||||
|
macro(xo_add_genfacetimpl)
|
||||||
|
# Parse arguments
|
||||||
|
set(options "")
|
||||||
|
set(oneValueArgs
|
||||||
|
TARGET # Name for this generation target
|
||||||
|
FACET # facet name
|
||||||
|
REPR # representation name
|
||||||
|
INPUT # Input .json5 file
|
||||||
|
OUTPUT_HPP_DIR # Directory for .hpp files
|
||||||
|
OUTPUT_IMPL_SUBDIR # Subdirectory name for impl headers
|
||||||
|
OUTPUT_CPP_DIR # Directory for .cpp files
|
||||||
|
)
|
||||||
|
set(multiValueArgs "")
|
||||||
|
|
||||||
|
cmake_parse_arguments(GF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
|
||||||
|
|
||||||
|
find_program(GENFACET_EXECUTABLE NAMES genfacet
|
||||||
|
HINTS ${CMAKE_SOURCE_DIR}/xo-facet/codegen
|
||||||
|
DOC "path to xo genfacet code generator"
|
||||||
|
REQUIRED)
|
||||||
|
message(STATUS "GENFACET_EXECUTABLE=${GENFACET_EXECUTABLE}")
|
||||||
|
|
||||||
|
set(generatedFiles
|
||||||
|
${GF_OUTPUT_HPP_DIR}/${FACET}.hpp
|
||||||
|
${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${FACET}_D${REPR}.hpp
|
||||||
|
${GF_OUTPUT_CPP_DIR}/I${FACET}_D${REPR}.cpp)
|
||||||
|
|
||||||
|
# Build the genfacet command
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${generatedFiles}
|
||||||
|
COMMAND ${GENFACET_EXECUTABLE}
|
||||||
|
--input ${GF_INPUT}
|
||||||
|
--output-hpp ${GF_OUTPUT_HPP_DIR}
|
||||||
|
--output-impl-hpp ${GF_OUTPUT_IMPL_SUBDIR}
|
||||||
|
--output-cpp ${GF_OUTPUT_CPP_DIR}
|
||||||
|
DEPENDS ${GF_INPUT}
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
COMMENT "Generating facet source files from ${GF_INPUT}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a target for this generation
|
||||||
|
add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles})
|
||||||
endmacro()
|
endmacro()
|
||||||
|
|
|
||||||
|
|
@ -15,12 +15,22 @@ def format_method_qualifiers(method):
|
||||||
"""
|
"""
|
||||||
quals = []
|
quals = []
|
||||||
if method.get('const', False):
|
if method.get('const', False):
|
||||||
quals.append('const')
|
quals.append(' const')
|
||||||
if method.get('noexcept', False):
|
if method.get('noexcept', False):
|
||||||
quals.append('noexcept')
|
quals.append(' noexcept')
|
||||||
|
|
||||||
return ' '.join(quals)
|
return ' '.join(quals)
|
||||||
|
|
||||||
|
def format_method_staticqual(method):
|
||||||
|
""" Build qualifier string for a static method: noexcet
|
||||||
|
"""
|
||||||
|
quals = []
|
||||||
|
if method.get('noexcept', False):
|
||||||
|
quals.append(' noexcept')
|
||||||
|
|
||||||
|
return ' '.join(quals)
|
||||||
|
|
||||||
|
|
||||||
def format_args(args, include_names=True):
|
def format_args(args, include_names=True):
|
||||||
""" Format argument list for a method
|
""" Format argument list for a method
|
||||||
"""
|
"""
|
||||||
|
|
@ -40,6 +50,12 @@ def format_arg_names(args):
|
||||||
names = [p['name'] for p in args]
|
names = [p['name'] for p in args]
|
||||||
return ', '.join([f"_dcast({names[0]})"] + names[1:])
|
return ', '.join([f"_dcast({names[0]})"] + names[1:])
|
||||||
|
|
||||||
|
def format_arg_names_nodata(args):
|
||||||
|
""" Format argument names for forwarding, omit data ('self') arg
|
||||||
|
"""
|
||||||
|
names = [p['name'] for p in args[1:]]
|
||||||
|
return ', '.join(names)
|
||||||
|
|
||||||
def format_args_nodata(args):
|
def format_args_nodata(args):
|
||||||
""" Format arguments, but exclude data arg
|
""" Format arguments, but exclude data arg
|
||||||
"""
|
"""
|
||||||
|
|
@ -51,46 +67,21 @@ def format_args_routing(args):
|
||||||
names = [p['name'] for p in args]
|
names = [p['name'] for p in args]
|
||||||
return ', '.join([f"O::data()"] + names[1:])
|
return ', '.join([f"O::data()"] + names[1:])
|
||||||
|
|
||||||
def main():
|
def format_args_impl(args, drepr):
|
||||||
parser = argparse.ArgumentParser()
|
""" Format argument names, for implementation (IFoo_DRepr)
|
||||||
parser.add_argument('--input', required=True, help='input IDL JSON5 file')
|
"""
|
||||||
parser.add_argument('--output-impl-hpp', required=True, help='.hpp detail subdir')
|
names = [f"{p['type']} {p['name']}" for p in args]
|
||||||
parser.add_argument('--output-hpp', required=True, help='.hpp output directory')
|
return ', '.join([f"const {drepr} & self"] + names[1:])
|
||||||
parser.add_argument('--output-cpp', required=True, help='.cpp output directory')
|
|
||||||
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
idl_fname = args.input
|
def gen_facet(env,
|
||||||
idl = load_idl(idl_fname)
|
idl_fname,
|
||||||
#
|
idl,
|
||||||
output_hpp_dir = Path(args.output_hpp)
|
input_json5,
|
||||||
output_hpp_dir.mkdir(parents=False, exist_ok=True)
|
output_hpp_dir,
|
||||||
#
|
output_impl_hpp_dir,
|
||||||
output_impl_hpp_subdir = Path(args.output_impl_hpp)
|
output_cpp_dir):
|
||||||
output_impl_hpp_dir = Path(args.output_hpp) / output_impl_hpp_subdir
|
|
||||||
output_impl_hpp_dir.mkdir(parents=False, exist_ok=True)
|
|
||||||
#
|
|
||||||
output_cpp_dir = Path(args.output_cpp)
|
|
||||||
output_cpp_dir.mkdir(parents=False, exist_ok=True)
|
|
||||||
|
|
||||||
# setup jinja2
|
|
||||||
#template_dir = Path(args.templates)
|
|
||||||
template_dir = Path(__file__).parent
|
|
||||||
#template_dir = Path(__file__).parent / 'codegen'
|
|
||||||
|
|
||||||
print(f'template_dir: [{template_dir}]')
|
|
||||||
|
|
||||||
env = Environment(loader = FileSystemLoader(template_dir),
|
|
||||||
trim_blocks = True,
|
|
||||||
lstrip_blocks = True)
|
|
||||||
|
|
||||||
# custom filters
|
|
||||||
env.filters['qualifiers'] = format_method_qualifiers
|
|
||||||
env.filters['args'] = format_args
|
|
||||||
env.filters['argtypes'] = format_args_nonames
|
|
||||||
env.filters['argnames'] = format_arg_names
|
|
||||||
env.filters['argsnodata'] = format_args_nodata
|
|
||||||
env.filters['argrouting'] = format_args_routing
|
|
||||||
|
|
||||||
# true to insert doxygen markup in generated .hpp/.cpp files
|
# true to insert doxygen markup in generated .hpp/.cpp files
|
||||||
using_dox = idl['using_doxygen']
|
using_dox = idl['using_doxygen']
|
||||||
|
|
@ -150,7 +141,7 @@ def main():
|
||||||
|
|
||||||
context = {
|
context = {
|
||||||
'genfacet': __file__,
|
'genfacet': __file__,
|
||||||
'genfacet_input': args.input,
|
'genfacet_input': idl_fname,
|
||||||
'using_dox': using_dox,
|
'using_dox': using_dox,
|
||||||
'impl_hpp_subdir': output_impl_hpp_subdir,
|
'impl_hpp_subdir': output_impl_hpp_subdir,
|
||||||
#
|
#
|
||||||
|
|
@ -225,5 +216,282 @@ def main():
|
||||||
print(f"Generated {out_dir}/{out_file}")
|
print(f"Generated {out_dir}/{out_file}")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def gen_facet_impl(env,
|
||||||
|
idl_fname,
|
||||||
|
idl,
|
||||||
|
facet_idl,
|
||||||
|
output_hpp_dir,
|
||||||
|
output_impl_hpp_subdir,
|
||||||
|
output_cpp_dir):
|
||||||
|
|
||||||
|
|
||||||
|
# true to insert doxygen markup in generated .hpp/.cpp files
|
||||||
|
using_dox = idl['using_doxygen']
|
||||||
|
|
||||||
|
# extra include files (or perhaps other definitions)
|
||||||
|
|
||||||
|
# facet_includes: include section for AFoo.hpp:
|
||||||
|
# <xo/gc/GCObject.hpp>
|
||||||
|
facet_includes = facet_idl['includes']
|
||||||
|
# sequence
|
||||||
|
facet_detail_subdir = facet_idl['detail_subdir']
|
||||||
|
# xo - facet_ns1: outer namespace for facet [e.g. xo]
|
||||||
|
facet_ns1 = facet_idl['namespace1']
|
||||||
|
# scm - facet_ns2: nested namespace for facet [e.g. scm]
|
||||||
|
facet_ns2 = facet_idl['namespace2']
|
||||||
|
|
||||||
|
# Sequence - facet_name: facet name
|
||||||
|
facet_name = facet_idl['facet']
|
||||||
|
# sequence - facet_name_lc: lower case [e.g. sequence]
|
||||||
|
facet_name_lc = facet_name.lower()
|
||||||
|
# brief doc for facet
|
||||||
|
facet_brief = idl['brief']
|
||||||
|
# doc section for facet
|
||||||
|
facet_doc = '\n'.join(idl['doc'])
|
||||||
|
|
||||||
|
types = facet_idl['types']
|
||||||
|
for ty in types:
|
||||||
|
ty['doc'] = '\n'.join(ty['doc'])
|
||||||
|
|
||||||
|
const_methods = facet_idl['const_methods']
|
||||||
|
for md in const_methods:
|
||||||
|
md['args'] = [{'type': "Copaque",
|
||||||
|
'name': "data"}] + md['args']
|
||||||
|
md['doc'] = '\n'.join(md['doc'])
|
||||||
|
|
||||||
|
nonconst_methods = facet_idl['nonconst_methods']
|
||||||
|
for md in nonconst_methods:
|
||||||
|
md['args'] = [{'type': "Opaque",
|
||||||
|
'name': "data"}] + md['args']
|
||||||
|
md['doc'] = '\n'.join(md['doc'])
|
||||||
|
|
||||||
|
# Foo.hpp
|
||||||
|
facet_hpp_fname = f'{facet_name}.hpp'
|
||||||
|
# AFoo
|
||||||
|
abstract_facet = f'A{facet_name}'
|
||||||
|
# AFoo.hpp
|
||||||
|
abstract_facet_fname = f'{abstract_facet}.hpp'
|
||||||
|
# IFoo
|
||||||
|
iface_facet = f'I{facet_name}'
|
||||||
|
# IFoo_ImplType
|
||||||
|
iface_facet_impltype = f'{iface_facet}_ImplType'
|
||||||
|
#
|
||||||
|
# IFoo_Any
|
||||||
|
iface_facet_any = f'{iface_facet}_Any'
|
||||||
|
# IFoo_Any.hpp
|
||||||
|
iface_facet_any_hpp_fname = f'{iface_facet_any}.hpp'
|
||||||
|
# IFoo_Any.cpp
|
||||||
|
iface_facet_any_cpp_fname = f'{iface_facet_any}.cpp'
|
||||||
|
#
|
||||||
|
# IFoo_Xfer
|
||||||
|
iface_facet_xfer = f'{iface_facet}_Xfer'
|
||||||
|
# IFoo_Xfer.hpp
|
||||||
|
iface_facet_xfer_hpp_fname = f'{iface_facet_xfer}.hpp'
|
||||||
|
# IFoo_Xfer.cpp
|
||||||
|
iface_facet_xfer_cpp_fname = f'{iface_facet_xfer}.cpp'
|
||||||
|
#
|
||||||
|
# RFoo
|
||||||
|
router_facet = f'R{facet_name}'
|
||||||
|
# RFoo.hpp
|
||||||
|
router_facet_hpp_fname = f'{router_facet}.hpp'
|
||||||
|
|
||||||
|
# ================================================================
|
||||||
|
# vars for IFacet_DRepr
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
# DList
|
||||||
|
data_repr = idl['repr']
|
||||||
|
# dlist
|
||||||
|
data_repr_lc = data_repr.lower()
|
||||||
|
# DList.hpp
|
||||||
|
data_repr_hpp_fname = f'{data_repr}.hpp'
|
||||||
|
|
||||||
|
# repr_ns1: outer namespace for repr [e.g. xo].
|
||||||
|
# (need not match facet)
|
||||||
|
repr_ns1 = idl['namespace1']
|
||||||
|
# repr_ns2: nested namespace for repr [e.g. scm].
|
||||||
|
repr_ns2 = idl['namespace2']
|
||||||
|
|
||||||
|
|
||||||
|
# iface_facet_repr: IFoo_DRepr
|
||||||
|
iface_facet_repr = f'{iface_facet}_{data_repr}'
|
||||||
|
# iface_facet_repr_hpp_fname: IFoo_DRepr.hpp
|
||||||
|
iface_facet_repr_hpp_fname = f'{iface_facet_repr}.hpp'
|
||||||
|
# iface_facet_repr_cpp_fname: IFoo_DRepr.cpp
|
||||||
|
iface_facet_repr_cpp_fname = f'{iface_facet_repr}.cpp'
|
||||||
|
|
||||||
|
# ================================================================
|
||||||
|
|
||||||
|
context = {
|
||||||
|
'genfacet': __file__,
|
||||||
|
'genfacet_input': idl_fname,
|
||||||
|
'using_dox': using_dox,
|
||||||
|
'impl_hpp_subdir': output_impl_hpp_subdir,
|
||||||
|
#
|
||||||
|
'facet_hpp_j2': 'facet.hpp.j2',
|
||||||
|
'facet_includes': facet_includes,
|
||||||
|
'facet_detail_subdir': facet_detail_subdir,
|
||||||
|
'facet_ns1': facet_ns1,
|
||||||
|
'facet_ns2': facet_ns2,
|
||||||
|
'facet_name': facet_name,
|
||||||
|
'facet_name_lc': facet_name_lc,
|
||||||
|
'facet_hpp_fname': facet_hpp_fname,
|
||||||
|
#'name': facet_name,
|
||||||
|
'idl_fname': idl_fname,
|
||||||
|
#
|
||||||
|
'abstract_facet_hpp_j2': 'abstract_facet.hpp.j2',
|
||||||
|
'abstract_facet': abstract_facet,
|
||||||
|
'abstract_facet_fname': abstract_facet_fname,
|
||||||
|
'abstract_facet_doc': facet_doc,
|
||||||
|
#
|
||||||
|
'iface_facet': iface_facet,
|
||||||
|
'iface_facet_impltype': iface_facet_impltype,
|
||||||
|
#
|
||||||
|
'iface_facet_any': iface_facet_any,
|
||||||
|
'iface_facet_any_hpp_j2': 'iface_facet_any.hpp.j2',
|
||||||
|
'iface_facet_any_cpp_j2': 'iface_facet_any.cpp.j2',
|
||||||
|
'iface_facet_any_hpp_fname': iface_facet_any_hpp_fname,
|
||||||
|
'iface_facet_any_cpp_fname': iface_facet_any_cpp_fname,
|
||||||
|
#
|
||||||
|
'iface_facet_xfer': iface_facet_xfer,
|
||||||
|
'iface_facet_xfer_hpp_j2': 'iface_facet_xfer.hpp.j2',
|
||||||
|
'iface_facet_xfer_cpp_j2': 'iface_facet_xfer.cpp.j2',
|
||||||
|
'iface_facet_xfer_hpp_fname': iface_facet_xfer_hpp_fname,
|
||||||
|
'iface_facet_xfer_cpp_fname': iface_facet_xfer_cpp_fname,
|
||||||
|
#
|
||||||
|
'router_facet': router_facet,
|
||||||
|
'router_facet_hpp_j2': 'router_facet.hpp.j2',
|
||||||
|
'router_facet_hpp_fname': router_facet_hpp_fname,
|
||||||
|
#
|
||||||
|
'types': types,
|
||||||
|
#
|
||||||
|
'const_methods': const_methods,
|
||||||
|
#
|
||||||
|
'nonconst_methods': nonconst_methods,
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
# vars for IFacet_DRepr
|
||||||
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
|
'repr_ns1': repr_ns1,
|
||||||
|
'repr_ns2': repr_ns2,
|
||||||
|
#
|
||||||
|
'data_repr': data_repr,
|
||||||
|
'data_repr_lc': data_repr_lc,
|
||||||
|
'data_repr_hpp_fname': data_repr_hpp_fname,
|
||||||
|
#
|
||||||
|
'iface_facet_repr': iface_facet_repr,
|
||||||
|
'iface_facet_repr_hpp_j2': 'iface_facet_repr.hpp.j2',
|
||||||
|
'iface_facet_repr_hpp_fname': iface_facet_repr_hpp_fname,
|
||||||
|
'iface_facet_repr_cpp_j2': 'iface_facet_repr.cpp.j2',
|
||||||
|
'iface_facet_repr_cpp_fname': iface_facet_repr_cpp_fname,
|
||||||
|
#
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# generate .hpp files
|
||||||
|
|
||||||
|
templates = {}
|
||||||
|
templates[iface_facet_repr_hpp_fname] = [output_hpp_dir,
|
||||||
|
context['iface_facet_repr_hpp_j2']]
|
||||||
|
templates[iface_facet_repr_cpp_fname] = [output_cpp_dir,
|
||||||
|
context['iface_facet_repr_cpp_j2']]
|
||||||
|
|
||||||
|
# templates[facet_hpp_fname] = [output_hpp_dir,
|
||||||
|
# context['facet_hpp_j2']]
|
||||||
|
# templates[abstract_facet_fname] = [output_impl_hpp_dir,
|
||||||
|
# context['abstract_facet_hpp_j2']]
|
||||||
|
# templates[iface_facet_any_hpp_fname] = [output_impl_hpp_dir,
|
||||||
|
# context['iface_facet_any_hpp_j2']]
|
||||||
|
# templates[iface_facet_any_cpp_fname] = [output_cpp_dir,
|
||||||
|
# context['iface_facet_any_cpp_j2']]
|
||||||
|
# templates[iface_facet_xfer_hpp_fname] = [output_impl_hpp_dir,
|
||||||
|
# context['iface_facet_xfer_hpp_j2']]
|
||||||
|
# templates[router_facet_hpp_fname] = [output_impl_hpp_dir,
|
||||||
|
# context['router_facet_hpp_j2']]
|
||||||
|
|
||||||
|
for out_file, record in templates.items():
|
||||||
|
out_dir = record[0]
|
||||||
|
template_name = record[1]
|
||||||
|
|
||||||
|
print(f'out_dir: [{out_dir}]')
|
||||||
|
print(f'out_file: [{out_file}]')
|
||||||
|
print(f'template_name: [{template_name}]')
|
||||||
|
|
||||||
|
template = env.get_template(template_name)
|
||||||
|
content = template.render(**context)
|
||||||
|
|
||||||
|
(out_dir / out_file).write_text(content)
|
||||||
|
print(f"Generated {out_dir}/{out_file}")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('--input', required=True, help='input IDL JSON5 file')
|
||||||
|
# --output-impl-hpp: putting this in .json5, will be able to drop this.
|
||||||
|
parser.add_argument('--output-impl-hpp', required=True, help='.hpp detail subdir')
|
||||||
|
parser.add_argument('--output-hpp', required=True, help='.hpp output directory')
|
||||||
|
parser.add_argument('--output-cpp', required=True, help='.cpp output directory')
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
idl_fname = args.input
|
||||||
|
idl = load_idl(idl_fname)
|
||||||
|
|
||||||
|
output_hpp_dir = Path(args.output_hpp)
|
||||||
|
output_hpp_dir.mkdir(parents=False, exist_ok=True)
|
||||||
|
|
||||||
|
# TODO: output_impl_hpp_subdir: use idl['detail_subdir'] instead
|
||||||
|
output_impl_hpp_subdir = Path(args.output_impl_hpp)
|
||||||
|
output_impl_hpp_dir = Path(args.output_hpp) / output_impl_hpp_subdir
|
||||||
|
output_impl_hpp_dir.mkdir(parents=False, exist_ok=True)
|
||||||
|
|
||||||
|
output_cpp_dir = Path(args.output_cpp)
|
||||||
|
output_cpp_dir.mkdir(parents=False, exist_ok=True)
|
||||||
|
|
||||||
|
# setup jinja2
|
||||||
|
#template_dir = Path(args.templates)
|
||||||
|
template_dir = Path(__file__).parent
|
||||||
|
#template_dir = Path(__file__).parent / 'codegen'
|
||||||
|
|
||||||
|
print(f'template_dir: [{template_dir}]')
|
||||||
|
|
||||||
|
env = Environment(loader = FileSystemLoader(template_dir),
|
||||||
|
trim_blocks = True,
|
||||||
|
lstrip_blocks = True)
|
||||||
|
|
||||||
|
# custom filters.
|
||||||
|
# A filter 'foo' provides ability to write '{{var | foo}}' to expand
|
||||||
|
# j2 variable 'var' to 'filters[foo](var)'
|
||||||
|
#
|
||||||
|
env.filters['qualifiers'] = format_method_qualifiers
|
||||||
|
env.filters['staticqual'] = format_method_staticqual
|
||||||
|
env.filters['args'] = format_args
|
||||||
|
env.filters['argtypes'] = format_args_nonames
|
||||||
|
env.filters['argnames'] = format_arg_names
|
||||||
|
env.filters['argnamesnodata'] = format_arg_names_nodata
|
||||||
|
env.filters['argsnodata'] = format_args_nodata
|
||||||
|
env.filters['argrouting'] = format_args_routing
|
||||||
|
env.filters['argimpl'] = format_args_impl
|
||||||
|
|
||||||
|
if idl['mode'] == 'facet':
|
||||||
|
gen_facet(env,
|
||||||
|
idl_fname,
|
||||||
|
idl,
|
||||||
|
output_hpp_dir,
|
||||||
|
output_impl_hpp_dir,
|
||||||
|
output_cpp_dir)
|
||||||
|
elif idl['mode'] == 'implementation':
|
||||||
|
facet_idl_fname = idl['facet_idl']
|
||||||
|
facet_idl = load_idl(facet_idl_fname)
|
||||||
|
|
||||||
|
gen_facet_impl(env,
|
||||||
|
idl_fname,
|
||||||
|
idl,
|
||||||
|
facet_idl,
|
||||||
|
output_hpp_dir,
|
||||||
|
output_impl_hpp_dir,
|
||||||
|
output_cpp_dir)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
||||||
34
xo-facet/codegen/iface_facet_repr.cpp.j2
Normal file
34
xo-facet/codegen/iface_facet_repr.cpp.j2
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
/** @file {{iface_facet_repr_cpp_fname}}
|
||||||
|
*
|
||||||
|
* Generated automagically from ingredients:
|
||||||
|
* 1. code generator:
|
||||||
|
* [{{genfacet}}]
|
||||||
|
* arguments:
|
||||||
|
* --input [{{genfacet_input}}]
|
||||||
|
* 2. jinja2 template for abstract facet .hpp file:
|
||||||
|
* [{{ iface_facet_any_hpp_j2 }}]
|
||||||
|
* 3. idl for facet methods
|
||||||
|
* [{{ idl_fname }}]
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "{{iface_facet_repr_hpp_fname}}"
|
||||||
|
|
||||||
|
namespace {{repr_ns1}} {
|
||||||
|
namespace {{repr_ns2}} {
|
||||||
|
{% for md in const_methods %}
|
||||||
|
auto
|
||||||
|
{{iface_facet_repr}}::{{md.name}}({{md.args | argimpl(data_repr)}}){{md | staticqual}} -> {{md.return_type}}
|
||||||
|
{
|
||||||
|
{% if md.return_type == "void" %}
|
||||||
|
self.{{md.name}}({{md.args | argnamesnodata}});
|
||||||
|
{% else %}
|
||||||
|
return self.{{md.name}}({{md.args | argnamesnodata}});
|
||||||
|
{% endif %}
|
||||||
|
}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
} /*namespace {{repr_ns2}}*/
|
||||||
|
} /*namespace {{repr_ns1}}*/
|
||||||
|
|
||||||
|
/* end {{iface_facet_repr_cpp_fname}} */
|
||||||
70
xo-facet/codegen/iface_facet_repr.hpp.j2
Normal file
70
xo-facet/codegen/iface_facet_repr.hpp.j2
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
/** @file {{iface_facet_repr_hpp_fname}}
|
||||||
|
*
|
||||||
|
* Generated automagically from ingredients:
|
||||||
|
* 1. code generator:
|
||||||
|
* [{{genfacet}}]
|
||||||
|
* arguments:
|
||||||
|
* --input [{{genfacet_input}}]
|
||||||
|
* 2. jinja2 template for abstract facet .hpp file:
|
||||||
|
* [{{ iface_facet_any_hpp_j2 }}]
|
||||||
|
* 3. idl for facet methods
|
||||||
|
* [{{ idl_fname }}]
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "{{facet_hpp_fname}}"
|
||||||
|
#include "{{facet_detail_subdir}}/{{iface_facet_xfer_hpp_fname}}"
|
||||||
|
#include "{{data_repr_hpp_fname}}"
|
||||||
|
|
||||||
|
namespace {{repr_ns1}} { namespace {{repr_ns2}} { class {{iface_facet_repr}}; } }
|
||||||
|
|
||||||
|
namespace xo {
|
||||||
|
namespace facet {
|
||||||
|
template <>
|
||||||
|
struct FacetImplementation<{{facet_ns1}}::{{facet_ns2}}::{{abstract_facet}},
|
||||||
|
{{repr_ns1}}::{{repr_ns2}}::{{data_repr}}>
|
||||||
|
{
|
||||||
|
using ImplType = {{facet_ns1}}::{{facet_ns2}}::{{iface_facet_xfer}}
|
||||||
|
<{{repr_ns1}}::{{repr_ns2}}::{{data_repr}},
|
||||||
|
{{repr_ns1}}::{{repr_ns2}}::{{iface_facet_repr}}>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {{repr_ns1}} {
|
||||||
|
namespace {{repr_ns2}} {
|
||||||
|
/** @class {{iface_facet_repr}}
|
||||||
|
**/
|
||||||
|
class {{iface_facet_repr}} {
|
||||||
|
public:
|
||||||
|
{% if using_dox %}
|
||||||
|
/** @defgroup {{repr_ns2}}-{{facet_name_lc}}-{{data_repr_lc}}-type-traits **/
|
||||||
|
///@{
|
||||||
|
{% endif %}
|
||||||
|
{% for ty in types %}
|
||||||
|
using {{ty.name}} = {{abstract_facet}}::{{ty.name}};
|
||||||
|
{% endfor %}
|
||||||
|
{% if using_dox %}
|
||||||
|
///@}
|
||||||
|
/** @defgroup {{repr_ns2}}-{{facet_name_lc}}-{{data_repr_lc}}-methods **/
|
||||||
|
///@{
|
||||||
|
{% endif %}
|
||||||
|
{% for md in const_methods %}
|
||||||
|
/** {{md.doc}} **/
|
||||||
|
static {{md.return_type}} {{md.name}}({{md.args | argimpl(data_repr)}}){{md | staticqual}};
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for md in methods %}
|
||||||
|
/** {{md.doc}} **/
|
||||||
|
static {{md.return_type}} {{md.name}}({{md.args | argimpl(data_repr)}}){{md | staticqual}};
|
||||||
|
{% endfor %}
|
||||||
|
{% if using_dox %}
|
||||||
|
///@}
|
||||||
|
{% endif %}
|
||||||
|
};
|
||||||
|
|
||||||
|
} /*namespace {{repr_ns2}}*/
|
||||||
|
} /*namespace {{repr_ns1}}*/
|
||||||
|
|
||||||
|
/* end */
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "IGCObject_Any.hpp"
|
//#include "IGCObject_Any.hpp"
|
||||||
|
|
||||||
#include <xo/facet/facet_implementation.hpp>
|
#include <xo/facet/facet_implementation.hpp>
|
||||||
#include <xo/facet/typeseq.hpp>
|
#include <xo/facet/typeseq.hpp>
|
||||||
|
|
@ -22,6 +22,7 @@ namespace xo {
|
||||||
using Copaque = const void *;
|
using Copaque = const void *;
|
||||||
using Opaque = void *;
|
using Opaque = void *;
|
||||||
|
|
||||||
|
struct AGCObject;
|
||||||
struct IGCObject_Any; // see IGCObject_Any.hpp
|
struct IGCObject_Any; // see IGCObject_Any.hpp
|
||||||
|
|
||||||
/** @class ACollector
|
/** @class ACollector
|
||||||
|
|
@ -53,10 +54,12 @@ namespace xo {
|
||||||
virtual void install_type(Opaque d, int32_t tseq, IGCObject_Any & iface) = 0;
|
virtual void install_type(Opaque d, int32_t tseq, IGCObject_Any & iface) = 0;
|
||||||
virtual void add_gc_root(Opaque d, int32_t tseq, Opaque * root) = 0;
|
virtual void add_gc_root(Opaque d, int32_t tseq, Opaque * root) = 0;
|
||||||
|
|
||||||
/** evacuate @p *lhs to to-space and replace with forwarding pointer
|
/** evacuate @p *lhs, that refers to state with interface @p lhs_iface,
|
||||||
|
* to collector @p d's to-space. Replace *lhs_data with forwarding pointer
|
||||||
|
*
|
||||||
* Require: gc in progress
|
* Require: gc in progress
|
||||||
**/
|
**/
|
||||||
virtual void forward_inplace(Opaque d, obj<AGCObject> * lhs) = 0;
|
virtual void forward_inplace(Opaque d, AGCObject * lhs_iface, void ** lhs_data) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,8 @@ namespace xo {
|
||||||
using Copaque = const void *;
|
using Copaque = const void *;
|
||||||
using Opaque = void *;
|
using Opaque = void *;
|
||||||
|
|
||||||
|
struct ACollector;
|
||||||
|
|
||||||
/** @class AObject
|
/** @class AObject
|
||||||
* @brief Abstract facet for collector-eligible data
|
* @brief Abstract facet for collector-eligible data
|
||||||
*
|
*
|
||||||
|
|
@ -30,9 +32,10 @@ namespace xo {
|
||||||
virtual int32_t _typeseq() const noexcept = 0;
|
virtual int32_t _typeseq() const noexcept = 0;
|
||||||
|
|
||||||
virtual size_type shallow_size(Copaque d) const noexcept = 0;
|
virtual size_type shallow_size(Copaque d) const noexcept = 0;
|
||||||
virtual Opaque * shallow_copy(Copaque d,
|
virtual Opaque shallow_copy(Copaque d,
|
||||||
obj<AAllocator> mm) const noexcept = 0;
|
obj<AAllocator> mm) const noexcept = 0;
|
||||||
virtual size_type forward_children(Opaque d) const noexcept = 0;
|
virtual size_type forward_children(Opaque d,
|
||||||
|
obj<ACollector>) const noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// implementation IGCObject_DRepr of AGCObject for state DRepr
|
// implementation IGCObject_DRepr of AGCObject for state DRepr
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ namespace xo {
|
||||||
// non-const methods
|
// non-const methods
|
||||||
[[noreturn]] void install_type(Opaque, int32_t, IGCObject_Any &) noexcept override { _fatal(); }
|
[[noreturn]] void install_type(Opaque, int32_t, IGCObject_Any &) noexcept override { _fatal(); }
|
||||||
[[noreturn]] void add_gc_root(Opaque, int32_t, Opaque *) override { _fatal(); }
|
[[noreturn]] void add_gc_root(Opaque, int32_t, Opaque *) override { _fatal(); }
|
||||||
[[noreturn]] void forward_inplace(Opaque, obj<AGCObject> *) override { _fatal(); }
|
[[noreturn]] void forward_inplace(Opaque, AGCObject *, void **) override { _fatal(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[noreturn]] static void _fatal();
|
[[noreturn]] static void _fatal();
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ namespace xo {
|
||||||
static void install_type(DX1Collector & d,
|
static void install_type(DX1Collector & d,
|
||||||
int32_t seq, IGCObject_Any & iface);
|
int32_t seq, IGCObject_Any & iface);
|
||||||
static void add_gc_root(DX1Collector & d, int32_t tseq, Opaque * root);
|
static void add_gc_root(DX1Collector & d, int32_t tseq, Opaque * root);
|
||||||
static void forward_inplace(DX1Collector & d, obj<AGCObject> * lhs);
|
static void forward_inplace(DX1Collector & d, AGCObject * lhs_iface, void ** lhs_data);
|
||||||
|
|
||||||
static int32_t s_typeseq;
|
static int32_t s_typeseq;
|
||||||
static bool _valid;
|
static bool _valid;
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,8 @@ namespace xo {
|
||||||
void add_gc_root(Opaque d, int32_t tseq, Opaque * root) override {
|
void add_gc_root(Opaque d, int32_t tseq, Opaque * root) override {
|
||||||
I::add_gc_root(_dcast(d), tseq, root);
|
I::add_gc_root(_dcast(d), tseq, root);
|
||||||
}
|
}
|
||||||
void forward_inplace(Opaque d, obj<AGCObject> * lhs) override {
|
void forward_inplace(Opaque d, AGCObject * lhs_iface, void ** lhs_data) override {
|
||||||
I::forward_inplace(_dcast(d), lhs);
|
I::forward_inplace(_dcast(d), lhs_iface, lhs_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AGCObject.hpp"
|
#include "AGCObject.hpp"
|
||||||
|
#include "Collector.hpp"
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
|
|
@ -31,9 +32,10 @@ namespace xo {
|
||||||
int32_t _typeseq() const noexcept override { return s_typeseq; }
|
int32_t _typeseq() const noexcept override { return s_typeseq; }
|
||||||
|
|
||||||
[[noreturn]] size_type shallow_size(Copaque) const noexcept override { _fatal(); }
|
[[noreturn]] size_type shallow_size(Copaque) const noexcept override { _fatal(); }
|
||||||
[[noreturn]] Opaque * shallow_copy(Copaque,
|
[[noreturn]] Opaque shallow_copy(Copaque,
|
||||||
obj<AAllocator>) const noexcept override { _fatal(); }
|
obj<AAllocator>) const noexcept override { _fatal(); }
|
||||||
[[noreturn]] size_type forward_children(Opaque) const noexcept override { _fatal(); }
|
[[noreturn]] size_type forward_children(Opaque,
|
||||||
|
obj<ACollector>) const noexcept override { _fatal(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
[[noreturn]] static void _fatal();
|
[[noreturn]] static void _fatal();
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "AGCObject.hpp"
|
#include "AGCObject.hpp"
|
||||||
|
#include "ACollector.hpp"
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
namespace mm {
|
namespace mm {
|
||||||
|
|
@ -28,16 +29,17 @@ namespace xo {
|
||||||
|
|
||||||
int32_t _typeseq() const noexcept override { return s_typeseq; }
|
int32_t _typeseq() const noexcept override { return s_typeseq; }
|
||||||
size_type shallow_size(Copaque d) const noexcept override {
|
size_type shallow_size(Copaque d) const noexcept override {
|
||||||
return I::shallow_copy(_dcast(d));
|
return I::shallow_size(_dcast(d));
|
||||||
}
|
}
|
||||||
Opaque * shallow_copy(Copaque d, obj<AAllocator> mm) const noexcept override {
|
Opaque shallow_copy(Copaque d, obj<AAllocator> mm) const noexcept override {
|
||||||
return I::shallow_size(_dcast(d), mm);
|
return I::shallow_copy(_dcast(d), mm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// non-const methods
|
// non-const methods
|
||||||
|
|
||||||
size_type forward_children(Opaque d) const noexcept override {
|
size_type forward_children(Opaque d,
|
||||||
return I::forward_children(d);
|
obj<ACollector> gc) const noexcept override {
|
||||||
|
return I::forward_children(_dcast(d), gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ namespace xo {
|
||||||
void install_type(int32_t tseq, IGCObject_Any & iface) { return O::iface()->install_type(O::data(), tseq, iface); }
|
void install_type(int32_t tseq, IGCObject_Any & iface) { return O::iface()->install_type(O::data(), tseq, iface); }
|
||||||
void add_gc_root(int32_t tseq, Opaque * root) { O::iface()->add_gc_root(O::data(), tseq, root); }
|
void add_gc_root(int32_t tseq, Opaque * root) { O::iface()->add_gc_root(O::data(), tseq, root); }
|
||||||
|
|
||||||
void forward_inplace(obj<AGCObject> * lhs) { O::iface()->forward_inplace(O::data(), lhs); }
|
void forward_inplace(AGCObject * lhs_iface, void ** lhs_data) { O::iface()->forward_inplace(O::data(), lhs_iface, lhs_data); }
|
||||||
|
|
||||||
static bool _valid;
|
static bool _valid;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ namespace xo {
|
||||||
|
|
||||||
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
||||||
size_type shallow_size() const noexcept { O::iface()->shallow_size(O::data()); }
|
size_type shallow_size() const noexcept { O::iface()->shallow_size(O::data()); }
|
||||||
Opaque * shallow_copy(obj<AAllocator> mm) const noexcept { O::iface()->shallow_copy(O::data(), mm); }
|
Opaque shallow_copy(obj<AAllocator> mm) const noexcept { O::iface()->shallow_copy(O::data(), mm); }
|
||||||
size_type forward_children() noexcept { O::iface()->forward_children(O::data()); }
|
size_type forward_children() noexcept { O::iface()->forward_children(O::data()); }
|
||||||
|
|
||||||
static bool _valid;
|
static bool _valid;
|
||||||
|
|
|
||||||
|
|
@ -73,8 +73,10 @@ namespace xo {
|
||||||
|
|
||||||
void
|
void
|
||||||
ICollector_DX1Collector::forward_inplace(DX1Collector & d,
|
ICollector_DX1Collector::forward_inplace(DX1Collector & d,
|
||||||
obj<AGCObject> * lhs)
|
AGCObject * lhs_iface,
|
||||||
|
void ** lhs_data)
|
||||||
{
|
{
|
||||||
|
(void)lhs_iface;
|
||||||
assert(d.runstate_.is_running());
|
assert(d.runstate_.is_running());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -90,7 +92,7 @@ namespace xo {
|
||||||
* +----------+
|
* +----------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void * object_data = (byte *)(*lhs).opaque_data();
|
void * object_data = (byte *)lhs_data;
|
||||||
|
|
||||||
if (!d.contains(role::from_space(), object_data)) {
|
if (!d.contains(role::from_space(), object_data)) {
|
||||||
/* *lhs isn't in GC-allocated space.
|
/* *lhs isn't in GC-allocated space.
|
||||||
|
|
@ -143,7 +145,7 @@ namespace xo {
|
||||||
void * dest = *(void**)object_data;
|
void * dest = *(void**)object_data;
|
||||||
|
|
||||||
/* update *lhs in-place */
|
/* update *lhs in-place */
|
||||||
(*lhs).reset_opaque(dest);
|
*lhs_data = dest;
|
||||||
} else if (check_move_policy(d, alloc_hdr, object_data)) {
|
} else if (check_move_policy(d, alloc_hdr, object_data)) {
|
||||||
/* copy object *lhs + replace with forwarding pointer */
|
/* copy object *lhs + replace with forwarding pointer */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,16 @@ xo_add_genfacet(
|
||||||
OUTPUT_CPP_DIR src/object2
|
OUTPUT_CPP_DIR src/object2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
xo_add_genfacetimpl(
|
||||||
|
TARGET xo-object2-facetimpl-sequence-list
|
||||||
|
FACET Sequence
|
||||||
|
REPR List
|
||||||
|
INPUT idl/ISequence_DList.json5
|
||||||
|
OUTPUT_HPP_DIR include/xo/object2
|
||||||
|
OUTPUT_IMPL_SUBDIR sequence
|
||||||
|
OUTPUT_CPP_DIR src/object2
|
||||||
|
)
|
||||||
|
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|
||||||
# must complete definition of expression lib before configuring examples
|
# must complete definition of expression lib before configuring examples
|
||||||
|
|
|
||||||
12
xo-object2/idl/ISequence_DList.json5
Normal file
12
xo-object2/idl/ISequence_DList.json5
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
mode: "implementation",
|
||||||
|
includes: [],
|
||||||
|
namespace1: "xo",
|
||||||
|
namespace2: "scm",
|
||||||
|
facet_idl: "idl/Sequence.json5",
|
||||||
|
brief: "provide ASequence interface for DList state",
|
||||||
|
using_doxygen: true,
|
||||||
|
repr: "DList",
|
||||||
|
doc: [ "doc for something or other"
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
{
|
{
|
||||||
|
mode: "facet",
|
||||||
includes: ["<xo/gc/GCObject.hpp>"],
|
includes: ["<xo/gc/GCObject.hpp>"],
|
||||||
namespace1: "xo",
|
namespace1: "xo",
|
||||||
namespace2: "scm",
|
namespace2: "scm",
|
||||||
facet: "Sequence",
|
facet: "Sequence",
|
||||||
|
detail_subdir: "sequence",
|
||||||
brief: "an ordered collection of variants",
|
brief: "an ordered collection of variants",
|
||||||
using_doxygen: true,
|
using_doxygen: true,
|
||||||
doc: [
|
doc: [
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,23 @@ namespace xo {
|
||||||
namespace scm {
|
namespace scm {
|
||||||
|
|
||||||
struct DList {
|
struct DList {
|
||||||
|
using size_type = std::size_t;
|
||||||
using AGCObject = xo::mm::AGCObject;
|
using AGCObject = xo::mm::AGCObject;
|
||||||
|
|
||||||
DList(xo::obj<AGCObject> h,
|
DList(xo::obj<AGCObject> h,
|
||||||
xo::obj<AGCObject> r) : head_{h}, rest_{r} {}
|
DList * r) : head_{h}, rest_{r} {}
|
||||||
|
|
||||||
|
/** DList length is at least 1 **/
|
||||||
|
bool is_empty() const noexcept { return false; };
|
||||||
|
/** DList models a finite sequence **/
|
||||||
|
bool is_finite() const noexcept { return true; };
|
||||||
|
/** return number of elements in this DList **/
|
||||||
|
size_type size() const noexcept;
|
||||||
|
/** return element at 0-based index @p ix **/
|
||||||
|
obj<AGCObject> at(size_type ix) const;
|
||||||
|
|
||||||
obj<AGCObject> head_;
|
obj<AGCObject> head_;
|
||||||
obj<AGCObject> rest_;
|
DList * rest_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} /*namespace scm*/
|
} /*namespace scm*/
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <xo/gc/Collector.hpp>
|
||||||
#include <xo/alloc2/alloc/AAllocator.hpp>
|
#include <xo/alloc2/alloc/AAllocator.hpp>
|
||||||
#include <xo/gc/detail/AGCObject.hpp>
|
#include <xo/gc/detail/AGCObject.hpp>
|
||||||
#include <xo/gc/detail/IGCObject_Xfer.hpp>
|
#include <xo/gc/detail/IGCObject_Xfer.hpp>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <xo/gc/Collector.hpp>
|
||||||
#include "xo/alloc2/alloc/AAllocator.hpp"
|
#include "xo/alloc2/alloc/AAllocator.hpp"
|
||||||
#include <xo/gc/detail/AGCObject.hpp>
|
#include <xo/gc/detail/AGCObject.hpp>
|
||||||
#include <xo/gc/detail/IGCObject_Xfer.hpp>
|
#include <xo/gc/detail/IGCObject_Xfer.hpp>
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,19 @@
|
||||||
#include "DList.hpp"
|
#include "DList.hpp"
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
|
namespace scm { struct IGCObject_DList; }
|
||||||
|
|
||||||
|
namespace facet {
|
||||||
|
template <>
|
||||||
|
struct FacetImplementation<xo::mm::AGCObject,
|
||||||
|
xo::scm::DList>
|
||||||
|
{
|
||||||
|
using ImplType = xo::mm::IGCObject_Xfer
|
||||||
|
<xo::scm::DList,
|
||||||
|
xo::scm::IGCObject_DList>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
namespace scm {
|
namespace scm {
|
||||||
/* changes here coordinate with:
|
/* changes here coordinate with:
|
||||||
* IGCObject_XFer
|
* IGCObject_XFer
|
||||||
|
|
|
||||||
61
xo-object2/include/xo/object2/ISequence_DList.hpp
Normal file
61
xo-object2/include/xo/object2/ISequence_DList.hpp
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
/** @file ISequence_DList.hpp
|
||||||
|
*
|
||||||
|
* Generated automagically from ingredients:
|
||||||
|
* 1. code generator:
|
||||||
|
* [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
|
||||||
|
* arguments:
|
||||||
|
* --input [idl/ISequence_DList.json5]
|
||||||
|
* 2. jinja2 template for abstract facet .hpp file:
|
||||||
|
* [iface_facet_any.hpp.j2]
|
||||||
|
* 3. idl for facet methods
|
||||||
|
* [idl/ISequence_DList.json5]
|
||||||
|
**/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Sequence.hpp"
|
||||||
|
#include "sequence/ISequence_Xfer.hpp"
|
||||||
|
#include "DList.hpp"
|
||||||
|
|
||||||
|
namespace xo { namespace scm { class ISequence_DList; } }
|
||||||
|
|
||||||
|
namespace xo {
|
||||||
|
namespace facet {
|
||||||
|
template <>
|
||||||
|
struct FacetImplementation<xo::scm::ASequence,
|
||||||
|
xo::scm::DList>
|
||||||
|
{
|
||||||
|
using ImplType = xo::scm::ISequence_Xfer
|
||||||
|
<xo::scm::DList,
|
||||||
|
xo::scm::ISequence_DList>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace xo {
|
||||||
|
namespace scm {
|
||||||
|
/** @class ISequence_DList
|
||||||
|
**/
|
||||||
|
class ISequence_DList {
|
||||||
|
public:
|
||||||
|
/** @defgroup scm-sequence-dlist-type-traits **/
|
||||||
|
///@{
|
||||||
|
using size_type = ASequence::size_type;
|
||||||
|
using AGCObject = ASequence::AGCObject;
|
||||||
|
///@}
|
||||||
|
/** @defgroup scm-sequence-dlist-methods **/
|
||||||
|
///@{
|
||||||
|
/** true iff sequence is empty **/
|
||||||
|
static bool is_empty(const DList & self) noexcept;
|
||||||
|
/** true iff sequence is finite **/
|
||||||
|
static bool is_finite(const DList & self) noexcept;
|
||||||
|
/** return element @p index of this sequence **/
|
||||||
|
static obj<AGCObject> at(const DList & self, size_type index);
|
||||||
|
|
||||||
|
///@}
|
||||||
|
};
|
||||||
|
|
||||||
|
} /*namespace scm*/
|
||||||
|
} /*namespace xo*/
|
||||||
|
|
||||||
|
/* end */
|
||||||
|
|
@ -6,9 +6,12 @@ set(SELF_SRCS
|
||||||
IGCObject_DInteger.cpp
|
IGCObject_DInteger.cpp
|
||||||
IGCObject_DList.cpp
|
IGCObject_DList.cpp
|
||||||
ISequence_Any.cpp
|
ISequence_Any.cpp
|
||||||
|
ISequence_DList.cpp
|
||||||
|
DList.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
|
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
|
||||||
# note: deps here must also appear in cmake/xo_alloc2Config.cmake.in
|
# note: deps here must also appear in cmake/xo_alloc2Config.cmake.in
|
||||||
xo_dependency(${SELF_LIB} xo_gc)
|
xo_dependency(${SELF_LIB} xo_gc)
|
||||||
#xo_dependency(${SELF_LIB} indentlog)
|
#xo_dependency(${SELF_LIB} indentlog)
|
||||||
|
#add_dependencies(${SELF_LIB} xo-object2-facetimpl-sequence-list)
|
||||||
|
|
|
||||||
54
xo-object2/src/object2/DList.cpp
Normal file
54
xo-object2/src/object2/DList.cpp
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
/** @file DList.cpp
|
||||||
|
*
|
||||||
|
* @author Roland Conybeare, Dec 2025
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "DList.hpp"
|
||||||
|
#include <xo/indentlog/print/tag.hpp>
|
||||||
|
|
||||||
|
namespace xo {
|
||||||
|
namespace scm {
|
||||||
|
auto
|
||||||
|
DList::size() const noexcept -> size_type
|
||||||
|
{
|
||||||
|
const DList * l = this;
|
||||||
|
|
||||||
|
size_type z = 0;
|
||||||
|
|
||||||
|
while (l) {
|
||||||
|
++z;
|
||||||
|
l = l->rest_;
|
||||||
|
}
|
||||||
|
|
||||||
|
return z;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto
|
||||||
|
DList::at(size_type index) const -> obj<AGCObject>
|
||||||
|
{
|
||||||
|
size_type ix = index;
|
||||||
|
const DList * l = this;
|
||||||
|
|
||||||
|
while (l->rest_ && (ix > 0)) {
|
||||||
|
--ix;
|
||||||
|
l = l->rest_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ix > 0) {
|
||||||
|
assert(l == nullptr);
|
||||||
|
|
||||||
|
throw std::runtime_error
|
||||||
|
(tostr("DList::at: out-of-range index where [0..z) expected",
|
||||||
|
xtag("index", index),
|
||||||
|
xtag("z", this->size())));
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(l);
|
||||||
|
|
||||||
|
return l->head_;
|
||||||
|
}
|
||||||
|
|
||||||
|
} /*namespace scm*/
|
||||||
|
} /*namespace xo*/
|
||||||
|
|
||||||
|
/* end DList.cpp */
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
#include "IGCObject_DList.hpp"
|
#include "IGCObject_DList.hpp"
|
||||||
|
|
||||||
namespace xo {
|
namespace xo {
|
||||||
|
using xo::mm::AGCObject;
|
||||||
using xo::mm::AAllocator;
|
using xo::mm::AAllocator;
|
||||||
|
using xo::facet::with_facet;
|
||||||
using xo::facet::obj;
|
using xo::facet::obj;
|
||||||
using std::size_t;
|
using std::size_t;
|
||||||
|
|
||||||
|
|
@ -33,8 +35,11 @@ namespace xo {
|
||||||
IGCObject_DList::forward_children(DList & src,
|
IGCObject_DList::forward_children(DList & src,
|
||||||
obj<ACollector> gc) noexcept
|
obj<ACollector> gc) noexcept
|
||||||
{
|
{
|
||||||
gc.forward_inplace(&src.head_);
|
gc.forward_inplace(src.head_.iface(), (void **)&(src.head_.data_));
|
||||||
gc.forward_inplace(&src.rest_);
|
|
||||||
|
//auto rest = with_facet<AGCObject>::mkobj(src.rest_);
|
||||||
|
xo::facet::FacetImplementation<xo::mm::AGCObject, DList>::ImplType iface;
|
||||||
|
gc.forward_inplace(&iface, (void **)(&src.rest_));
|
||||||
|
|
||||||
return shallow_size(src);
|
return shallow_size(src);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
40
xo-object2/src/object2/ISequence_DList.cpp
Normal file
40
xo-object2/src/object2/ISequence_DList.cpp
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
/** @file ISequence_DList.cpp
|
||||||
|
*
|
||||||
|
* Generated automagically from ingredients:
|
||||||
|
* 1. code generator:
|
||||||
|
* [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet]
|
||||||
|
* arguments:
|
||||||
|
* --input [idl/ISequence_DList.json5]
|
||||||
|
* 2. jinja2 template for abstract facet .hpp file:
|
||||||
|
* [iface_facet_any.hpp.j2]
|
||||||
|
* 3. idl for facet methods
|
||||||
|
* [idl/ISequence_DList.json5]
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "ISequence_DList.hpp"
|
||||||
|
|
||||||
|
namespace xo {
|
||||||
|
namespace scm {
|
||||||
|
auto
|
||||||
|
ISequence_DList::is_empty(const DList & self) noexcept -> bool
|
||||||
|
{
|
||||||
|
return self.is_empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto
|
||||||
|
ISequence_DList::is_finite(const DList & self) noexcept -> bool
|
||||||
|
{
|
||||||
|
return self.is_finite();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto
|
||||||
|
ISequence_DList::at(const DList & self, size_type index) -> obj<AGCObject>
|
||||||
|
{
|
||||||
|
return self.at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} /*namespace scm*/
|
||||||
|
} /*namespace xo*/
|
||||||
|
|
||||||
|
/* end ISequence_DList.cpp */
|
||||||
Loading…
Add table
Add a link
Reference in a new issue