xo-facet: extend facet gen scope to IFoo_{Xfer,Any}, RFoo
This commit is contained in:
parent
209128d73f
commit
2494aaee8c
6 changed files with 384 additions and 46 deletions
|
|
@ -32,12 +32,23 @@ using Opaque = void *;
|
|||
**/
|
||||
class {{abstract_facet}} {
|
||||
public:
|
||||
{% if using_dox %}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-type-traits **/
|
||||
///@{
|
||||
{% endif %}
|
||||
// types
|
||||
{% for ty in types %}
|
||||
/** {{ty.doc}} **/
|
||||
using {{ty.name}} = {{ty.definition}};
|
||||
{% endfor %}
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
|
||||
{% if using_dox %}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-methods **/
|
||||
///@{
|
||||
{% endif %}
|
||||
// const methods
|
||||
/** RTTI: unique id# for actual runtime data representation **/
|
||||
virtual int32_t _typeseq() const noexcept = 0;
|
||||
|
|
@ -51,6 +62,9 @@ public:
|
|||
/** {{md.doc}} **/
|
||||
virtual {{md.return_type}} {{md.name}}({{md.args | args}}) {{md | qualifiers}} = 0;
|
||||
{% endfor %}
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
}; /*{{abstract_facet}}*/
|
||||
|
||||
/** Implementation {{iface_facet}}_DRepr of {{abstract_facet}} for state DRepr
|
||||
|
|
|
|||
|
|
@ -38,18 +38,36 @@ def format_args_nonames(args):
|
|||
def format_arg_names(args):
|
||||
""" Format argument names, for forwarding
|
||||
"""
|
||||
return ', '.join(p['name'] for p in args)
|
||||
names = [p['name'] for p in args]
|
||||
return ', '.join([f"_dcast({names[0]})"] + names[1:])
|
||||
|
||||
def format_args_nodata(args):
|
||||
""" Format arguments, but exclude data arg
|
||||
"""
|
||||
return format_args(args[1:])
|
||||
|
||||
def format_args_routing(args):
|
||||
""" Format argument names, for routing
|
||||
"""
|
||||
names = [p['name'] for p in args]
|
||||
return ', '.join([f"O::data()"] + names[1:])
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--input', required=True, help='input IDL JSON5 file')
|
||||
parser.add_argument('--output', required=True, help='output directory')
|
||||
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_dir = Path(args.output)
|
||||
output_dir.mkdir(parents=False, exist_ok=True)
|
||||
#
|
||||
output_hpp_dir = Path(args.output_hpp)
|
||||
output_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(__file__).parent
|
||||
|
|
@ -66,11 +84,17 @@ def main():
|
|||
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
|
||||
using_dox = idl['using_doxygen']
|
||||
|
||||
facet_includes = idl['includes']
|
||||
facet_ns1 = idl['namespace1']
|
||||
facet_ns2 = idl['namespace2']
|
||||
facet_name = idl['facet'] # e.g. Sequence
|
||||
facet_name_lc = facet_name.lower()
|
||||
facet_brief = idl['brief']
|
||||
facet_doc = '\n'.join(idl['doc'])
|
||||
|
||||
|
|
@ -95,15 +119,25 @@ def main():
|
|||
iface_facet_impltype = f'{iface_facet}_ImplType'
|
||||
#
|
||||
iface_facet_any = f'{iface_facet}_Any'
|
||||
iface_facet_any_fname = f'{iface_facet_any}.hpp'
|
||||
iface_facet_any_hpp_fname = f'{iface_facet_any}.hpp'
|
||||
iface_facet_any_cpp_fname = f'{iface_facet_any}.cpp'
|
||||
#
|
||||
iface_facet_xfer = f'{iface_facet}_Xfer'
|
||||
iface_facet_xfer_hpp_fname = f'{iface_facet_xfer}.hpp'
|
||||
iface_facet_xfer_cpp_fname = f'{iface_facet_xfer}.cpp'
|
||||
#
|
||||
router_facet = f'R{facet_name}'
|
||||
router_facet_hpp_fname = f'{router_facet}.hpp'
|
||||
|
||||
context = {
|
||||
'genfacet': __file__,
|
||||
'genfacet_input': args.input,
|
||||
'using_dox': using_dox,
|
||||
#
|
||||
'facet_includes': facet_includes,
|
||||
'facet_ns1': facet_ns1,
|
||||
'facet_ns2': facet_ns2,
|
||||
'facet_name_lc': facet_name_lc,
|
||||
#'name': facet_name,
|
||||
'idl_fname': idl_fname,
|
||||
#
|
||||
|
|
@ -117,7 +151,19 @@ def main():
|
|||
#
|
||||
'iface_facet_any': iface_facet_any,
|
||||
'iface_facet_any_hpp_j2': 'iface_facet_any.hpp.j2',
|
||||
'iface_facet_any_fname': iface_facet_any_fname,
|
||||
'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,
|
||||
#
|
||||
|
|
@ -129,18 +175,30 @@ def main():
|
|||
# generate .hpp files
|
||||
|
||||
templates = {}
|
||||
templates[abstract_facet_fname] = context['abstract_facet_hpp_j2']
|
||||
templates[iface_facet_any_fname] = context['iface_facet_any_hpp_j2']
|
||||
templates[abstract_facet_fname] = [output_hpp_dir,
|
||||
context['abstract_facet_hpp_j2']]
|
||||
templates[iface_facet_any_hpp_fname] = [output_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_hpp_dir,
|
||||
context['iface_facet_xfer_hpp_j2']]
|
||||
templates[router_facet_hpp_fname] = [output_hpp_dir,
|
||||
context['router_facet_hpp_j2']]
|
||||
|
||||
for output_file, template_name in templates.items():
|
||||
print(f'output_file: [{output_file}]')
|
||||
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)
|
||||
|
||||
(output_dir / output_file).write_text(content)
|
||||
print(f"Generated {output_dir}/{output_file}")
|
||||
(out_dir / out_file).write_text(content)
|
||||
print(f"Generated {out_dir}/{out_file}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
|||
38
codegen/iface_facet_any.cpp.j2
Normal file
38
codegen/iface_facet_any.cpp.j2
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/** @file {{iface_facet_any_cpp_fname}}
|
||||
*
|
||||
**/
|
||||
|
||||
#include "{{iface_facet_any_hpp_fname}}"
|
||||
#include <iostream>
|
||||
|
||||
namespace {{facet_ns1}} {
|
||||
namespace {{facet_ns2}} {
|
||||
|
||||
using xo::facet::DVariantPlaceholder;
|
||||
using xo::facet::typeseq;
|
||||
using xo::facet::valid_facet_implementation;
|
||||
|
||||
void
|
||||
{{iface_facet_any}}::_fatal()
|
||||
{
|
||||
/* control here on uninitialized IAllocator_Any.
|
||||
* Initialized instance will have specific implementation type
|
||||
*/
|
||||
std::cerr << "fatal"
|
||||
<< ": attempt to call uninitialized"
|
||||
<< " {{iface_facet_any}} method"
|
||||
<< std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
|
||||
int32_t
|
||||
{{iface_facet_any}}::s_typeseq = typeseq::id<DVariantPlaceholder>();
|
||||
|
||||
bool
|
||||
{{iface_facet_any}}::_valid
|
||||
= valid_facet_implementation<{{abstract_facet}}, {{iface_facet_any}}>();
|
||||
|
||||
} /*namespace {{facet_ns2}}*/
|
||||
} /*namespace {{facet_ns1}}*/
|
||||
|
||||
/* end {{iface_facet_any_cpp_fname}} */
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/** @file {{iface_facet_any_fname}}
|
||||
/** @file {{iface_facet_any_hpp_fname}}
|
||||
*
|
||||
* Generated automagically from ingredients:
|
||||
* 1. code generator:
|
||||
|
|
@ -34,39 +34,74 @@ struct FacetImplementation<{{facet_ns1}}::{{facet_ns2}}::{{abstract_facet}},
|
|||
namespace {{facet_ns1}} {
|
||||
namespace {{facet_ns2}} {
|
||||
|
||||
/** @class {{iface_facet_any}}
|
||||
* @brief {{abstract_facet}} implementation for empty variant instance
|
||||
**/
|
||||
class {{iface_facet_any}} : public {{abstract_facet}} {
|
||||
public:
|
||||
{% for ty in types %}
|
||||
using {{ty.name}} = {{abstract_facet}}::{{ty.name}};
|
||||
{% endfor %}
|
||||
/** @class {{iface_facet_any}}
|
||||
* @brief {{abstract_facet}} implementation for empty variant instance
|
||||
**/
|
||||
class {{iface_facet_any}} : public {{abstract_facet}} {
|
||||
public:
|
||||
{% if using_dox %}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-any-type-traits **/
|
||||
///@{
|
||||
{% endif %}
|
||||
|
||||
const {{abstract_facet}} * iface() const { return std::launder(this); }
|
||||
{% for ty in types %}
|
||||
using {{ty.name}} = {{abstract_facet}}::{{ty.name}};
|
||||
{% endfor %}
|
||||
|
||||
// from {{abstract_facet}}
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
{% if using_dox %}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-any-methods **/
|
||||
///@{
|
||||
{% endif %}
|
||||
|
||||
// const methods
|
||||
int32_t _typeseq() const noexcept override { return s_typeseq; }
|
||||
{% for md in const_methods %}
|
||||
[[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatal(); }
|
||||
{% endfor %}
|
||||
const {{abstract_facet}} * iface() const { return std::launder(this); }
|
||||
|
||||
// nonconst methods
|
||||
{% for md in nonconst_methods %}
|
||||
[[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatail(); }
|
||||
{% endfor %}
|
||||
// from {{abstract_facet}}
|
||||
|
||||
private:
|
||||
[[noreturn]] static void _fatal();
|
||||
// const methods
|
||||
int32_t _typeseq() const noexcept override { return s_typeseq; }
|
||||
{% for md in const_methods %}
|
||||
[[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatal(); }
|
||||
{% endfor %}
|
||||
|
||||
public:
|
||||
static int32_t s_typeseq;
|
||||
static bool _valid;
|
||||
};
|
||||
// nonconst methods
|
||||
{% for md in nonconst_methods %}
|
||||
[[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatail(); }
|
||||
{% endfor %}
|
||||
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
|
||||
private:
|
||||
{% if using_dox %}
|
||||
/** @defgraoup {{facet_ns2}}-{{facet_name_lc}}-any-private-methods **/
|
||||
///@{
|
||||
{% endif %}
|
||||
|
||||
[[noreturn]] static void _fatal();
|
||||
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
|
||||
public:
|
||||
{% if using_dox %}
|
||||
/** @defgraoup {{facet_ns2}}-{{facet_name_lc}}-any-member-vars **/
|
||||
///@{
|
||||
{% endif %}
|
||||
|
||||
static int32_t s_typeseq;
|
||||
static bool _valid;
|
||||
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
};
|
||||
|
||||
} /*namespace {{facet_ns2}} */
|
||||
} /*namespace {{facet_ns1}} */
|
||||
|
||||
/* {{iface_facet_any_fname}} */
|
||||
/* {{iface_facet_any_hpp_fname}} */
|
||||
|
|
|
|||
99
codegen/iface_facet_xfer.hpp.j2
Normal file
99
codegen/iface_facet_xfer.hpp.j2
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/** @file {{iface_facet_xfer_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 "{{abstract_facet_fname}}"
|
||||
|
||||
namespace {{facet_ns1}} {
|
||||
namespace {{facet_ns2}} {
|
||||
/** @class {{iface_facet_xfer}}
|
||||
**/
|
||||
template <typename DRepr, typename {{iface_facet}}_DRepr>
|
||||
class {{iface_facet_xfer}} : public {{abstract_facet}} {
|
||||
public:
|
||||
{% if using_dox %}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-xfer-type-traits **/
|
||||
///@{
|
||||
{% endif %}
|
||||
using Impl = {{iface_facet}}_DRepr;
|
||||
{% for ty in types %}
|
||||
using {{ty.name}} = {{abstract_facet}}::{{ty.name}};
|
||||
{% endfor %}
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
|
||||
{% if using_dox %}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-xfer-methods **/
|
||||
///@{
|
||||
{% endif %}
|
||||
|
||||
static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; }
|
||||
static DRepr & _dcast(Opaque d) { return *(DRepr *)d; }
|
||||
|
||||
// from {{abstract_facet}}
|
||||
|
||||
// const methods
|
||||
int32_t _typeseq() const noexcept override { return s_typeseq; }
|
||||
{% for md in const_methods %}
|
||||
{{md.return_type}} {{md.name}}({{md.args | args}}) {{md | qualifiers}} override {
|
||||
return I::{{md.name}}({{md.args | argnames}});
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
// non-const methods
|
||||
{% for md in nonconst_methods %}
|
||||
{{md.return_type}} {{md.name}}({{md.args | args}}) {{md | qualifiers}} override {
|
||||
return I::{{md.name}}({{md.args | argnames}});
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
|
||||
private:
|
||||
using I = Impl;
|
||||
|
||||
public:
|
||||
{% if using_dox %}
|
||||
/** @defgraoup {{facet_ns2}}-{{facet_name_lc}}-xfer-member-vars **/
|
||||
///@{
|
||||
{% endif %}
|
||||
|
||||
/** typeseq for template parameter DRepr **/
|
||||
static int32_t s_typeseq;
|
||||
/** true iff satisfies facet implementation **/
|
||||
static bool _valid;
|
||||
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
};
|
||||
|
||||
template <typename DRepr, typename {{iface_facet}}_DRepr>
|
||||
int32_t
|
||||
{{iface_facet_xfer}}<DRepr, {{iface_facet}}_DRepr>::s_typeseq
|
||||
= xo::facet::typeseq::id<DRepr>();
|
||||
|
||||
template <typename DRepr, typename {{iface_facet}}_DRepr>
|
||||
bool
|
||||
{{iface_facet_xfer}}<DRepr, {{iface_facet}}_DRepr>::_valid
|
||||
= xo::facet::valid_facet_implementation<{{abstract_facet}},
|
||||
{{iface_facet_xfer}}>();
|
||||
|
||||
} /*namespace {{facet_ns2}} */
|
||||
} /*namespace {{facet_ns1}}*/
|
||||
|
||||
/* end {{iface_facet_xfer_hpp_fname}} */
|
||||
94
codegen/router_facet.hpp.j2
Normal file
94
codegen/router_facet.hpp.j2
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
/** @file {{router_facet_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 "{{abstract_facet_fname}}"
|
||||
|
||||
namespace {{facet_ns1}} {
|
||||
namespace {{facet_ns2}} {
|
||||
|
||||
/** @class {{router_facet}}
|
||||
**/
|
||||
template <typename Object>
|
||||
class {{router_facet}} : public Object {
|
||||
private:
|
||||
using O = Object;
|
||||
|
||||
public:
|
||||
{% if using_dox %}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-router-type-traits **/
|
||||
///@{
|
||||
{% endif %}
|
||||
using ObjectType = Object;
|
||||
using DataPtr = Object::DataPtr;
|
||||
{% for ty in types %}
|
||||
using {{ty.name}} = {{abstract_facet}}::{{ty.name}};
|
||||
{% endfor %}
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
|
||||
{% if using_dox %}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-router-ctors **/
|
||||
///@{
|
||||
{% endif %}
|
||||
{{router_facet}}() {}
|
||||
{{router_facet}}(Object::DataPtr data) : Object{std::move(data)} {}
|
||||
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-router-methods **/
|
||||
///@{
|
||||
{% endif %}
|
||||
|
||||
// const methods
|
||||
int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); }
|
||||
{% for md in const_methods %}
|
||||
{{md.return_type}} {{md.name}}({{md.args | argsnodata}}) {{md | qualifiers}} override {
|
||||
return O::iface()->{{md.name}}({{md.args | argrouting}});
|
||||
}
|
||||
{% endfor %}
|
||||
|
||||
// non-const methods
|
||||
// << do something for non-const methods >>
|
||||
//
|
||||
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
/** @defgroup {{facet_ns2}}-{{facet_name_lc}}-member-vars **/
|
||||
///@{
|
||||
{% endif %}
|
||||
|
||||
static bool _valid;
|
||||
|
||||
{% if using_dox %}
|
||||
///@}
|
||||
{% endif %}
|
||||
};
|
||||
|
||||
template <typename Object>
|
||||
bool
|
||||
{{router_facet}}<Object>::_valid = xo::facet::valid_object_router<Object>();
|
||||
|
||||
} /*namespace {{facet_ns2}}*/
|
||||
} /*namespace {{facet_ns1}}*/
|
||||
|
||||
namespace xo { namespace facet {
|
||||
template <typename Object>
|
||||
struct RoutingFor<{{facet_ns1}}::{{facet_ns2}}::{{abstract_facet}}, Object> {
|
||||
using RoutingType = {{facet_ns1}}::{{facet_ns2}}::{{router_facet}}<Object>;
|
||||
};
|
||||
} }
|
||||
|
||||
/* end {{router_facet_hpp_fname}} */
|
||||
Loading…
Add table
Add a link
Reference in a new issue