diff --git a/CMakeLists.txt b/CMakeLists.txt index bef04e3b..8b7eeaf7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -90,8 +90,9 @@ add_subdirectory(xo-ratio) add_subdirectory(xo-unit) add_subdirectory(xo-pyunit) add_subdirectory(xo-callback) +add_subdirectory(xo-printable2) # experiment w/ facet object model add_subdirectory(xo-alloc) -add_subdirectory(xo-alloc2) # experiment w/ sep iface,data +add_subdirectory(xo-alloc2) # experiment w/ facet object model add_subdirectory(xo-gc) add_subdirectory(xo-object) add_subdirectory(xo-object2) # experiment w/ facet object model diff --git a/xo-alloc2/CMakeLists.txt b/xo-alloc2/CMakeLists.txt index 9ce251c7..afe3d225 100644 --- a/xo-alloc2/CMakeLists.txt +++ b/xo-alloc2/CMakeLists.txt @@ -21,7 +21,8 @@ add_definitions(${PROJECT_CXX_FLAGS}) # must complete definition of expression lib before configuring examples add_subdirectory(src/alloc2) add_subdirectory(utest) -#xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) # ---------------------------------------------------------------- # docs targets depend on other library/utest/exec targets above, diff --git a/xo-cmake/cmake/xo_macros/xo_cxx.cmake b/xo-cmake/cmake/xo_macros/xo_cxx.cmake index 182f1599..c872c927 100644 --- a/xo-cmake/cmake/xo_macros/xo_cxx.cmake +++ b/xo-cmake/cmake/xo_macros/xo_cxx.cmake @@ -64,6 +64,11 @@ macro(xo_cxx_toplevel_options2) set_property( TARGET docs_${PROJECT_NAME} PROPERTY targets "") + + add_custom_target(idl_${PROJECT_NAME}) + set_property( + TARGET idl_${PROJECT_NAME} + PROPERTY path ${PROJECT_SOURCE_DIR}/idl) endif() endmacro() @@ -1625,7 +1630,7 @@ endmacro() # for faceted object model # -macro(xo_add_genfacet) +function(xo_add_genfacet) # Parse arguments set(options "") set(oneValueArgs @@ -1638,8 +1643,26 @@ macro(xo_add_genfacet) ) set(multiValueArgs "") + message(STATUS "oneValueArgs=${oneValueArgs}") + cmake_parse_arguments(GF "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + if(NOT DEFINED GF_TARGET) + message(FATAL_ERROR "xo_add_genfacet: TARGET is required") + endif() + if(NOT DEFINED GF_FACET) + message(FATAL_ERROR "xo_add_genfacet: FACET is required") + endif() + if(NOT DEFINED GF_OUTPUT_HPP_DIR) + message(FATAL_ERROR "xo_add_genfacet: OUTPUT_HPP_DIR is required") + endif() + if(NOT DEFINED GF_OUTPUT_IMPL_SUBDIR) + message(FATAL_ERROR "xo_add_genfacet: OUTPUT_IMPL_SUBDIR is required") + endif() + if(NOT DEFINED GF_OUTPUT_CPP_DIR) + message(FATAL_ERROR "xo_add_genfacet: OUTPUT_CPP_DIR is required") + endif() + find_program(GENFACET_EXECUTABLE NAMES genfacet HINTS ${CMAKE_SOURCE_DIR}/xo-facet/codegen DOC "path to xo genfacet code generator" @@ -1647,57 +1670,16 @@ macro(xo_add_genfacet) 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) + ${GF_OUTPUT_HPP_DIR}/${GF_FACET}.hpp + ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/A${GF_FACET}.hpp + ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_Any.hpp + ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_Xfer.hpp + ${GF_OUTPUT_HPP_DIR}/${GF_OUTPUT_IMPL_SUBDIR}/R${GF_FACET}.hpp + ${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_Any.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 - ) + message(STATUS "generatedFiles=${generatedFiles}") - # Create a target for this generation - add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles}) -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) + message(ERROR "epic fail") # Build the genfacet command add_custom_command( @@ -1715,4 +1697,72 @@ macro(xo_add_genfacetimpl) # Create a target for this generation add_custom_target(${GF_TARGET} DEPENDS ${generatedFiles}) -endmacro() +endfunction() + +function(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}) + + if(NOT DEFINED GF_TARGET) + message(FATAL_ERROR "xo_add_genfacetimpl: TARGET is required") + endif() + if(NOT DEFINED GF_FACET) + message(FATAL_ERROR "xo_add_genfacetimpl: FACET is required") + endif() + if(NOT DEFINED GF_REPR) + message(FATAL_ERROR "xo_add_genfacetimpl: REPR is required") + endif() + if(NOT DEFINED GF_INPUT) + message(FATAL_ERROR "xo_add_genfacetimpl: INPUT is required") + endif() + if(NOT DEFINED GF_OUTPUT_HPP_DIR) + message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_HPP_DIR is required") + endif() + if(NOT DEFINED GF_OUTPUT_IMPL_SUBDIR) + message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_IMPL_SUBDIR is required") + endif() + if(NOT DEFINED GF_OUTPUT_CPP_DIR) + message(FATAL_ERROR "xo_add_genfacetimpl: OUTPUT_CPP_DIR is required") + endif() + + 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}/${GF_OUTPUT_IMPL_SUBDIR}/I${GF_FACET}_D${GF_REPR}.hpp + ${GF_OUTPUT_CPP_DIR}/I${GF_FACET}_D${GF_REPR}.cpp) + + # Build the genfacet command. + # But careful: can't have the same generated files in two different rules, + # so need to remove overlaps here + 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}) +endfunction() diff --git a/xo-facet/README.md b/xo-facet/README.md index 67cf5576..f44c3ec4 100644 --- a/xo-facet/README.md +++ b/xo-facet/README.md @@ -1 +1,56 @@ # xo-facet + + +## Codegen + +To scaffold a new facet Foo we need several c++ classes + +* `AFoo` abstract FOMO interface, with opaque data pointer +* `IFoo_Any` variant placeholder, all methods terminate +* `IFoo_Xfer` template, delegates methods to a separate implementation class +* `RFoo` template, inherits from a 2x-wide fat pointer (iface+data). + +These classes all have parallel methods +Can generate these as follows: + +1. write `xo-foo/idl/Foo.json5`. + + Supply attributes: + - mode :: string + - includes :: [string] + - namespace1 :: string + - namespace2 :: string + - facet :: string + - detail_subdir :: string + - brief :: string + - using_doxygen :: bool + - doc :: [string] + - types :: [{name, doc, definition}] + - const_methods :: [{name, doc, return_type, args, const, noexcept, attributes}] + - nonconst_methods :: [{name, doc, return_type, args, const, noexcept, attributes}] + +Example in xo-object2/idl/Sequence.json5 + +2. generate: + +``` +$ cd xo-foo +$ ../xo-facet/codegen/genfacet.py --input ./idl/Foo.json5 --output include/xo/foo2 +``` + +Alternatively in `xo-foo/CMakeLists.txt` + +``` +xo_add_genfacet( + TARGET xo-foo2-facet-foo + FACET Foo + INPUT idl/Foo.json5 + OUTPUT_HTTP_DIR include/xo/foo2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/foo2) +``` + +then generate with: +``` +cmake --build path/to/build -- xo-foo2-facet-foo +``` diff --git a/xo-facet/codegen/abstract_facet.hpp.j2 b/xo-facet/codegen/abstract_facet.hpp.j2 index 59e61270..0861b2aa 100644 --- a/xo-facet/codegen/abstract_facet.hpp.j2 +++ b/xo-facet/codegen/abstract_facet.hpp.j2 @@ -37,6 +37,8 @@ public: ///@{ {% endif %} // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; {% for ty in types %} /** {{ty.doc}} **/ using {{ty.name}} = {{ty.definition}}; @@ -51,7 +53,7 @@ public: {% endif %} // const methods /** RTTI: unique id# for actual runtime data representation **/ - virtual int32_t _typeseq() const noexcept = 0; + virtual typeseq _typeseq() const noexcept = 0; {% for md in const_methods %} /** {{md.doc}} **/ virtual {{md.return_type}} {{md.name}}({{md.args | args}}) {{md | qualifiers}} = 0; diff --git a/xo-facet/codegen/genfacet b/xo-facet/codegen/genfacet index ff809d50..03e6cebf 100755 --- a/xo-facet/codegen/genfacet +++ b/xo-facet/codegen/genfacet @@ -77,9 +77,8 @@ def format_args_impl(args, drepr): def gen_facet(env, idl_fname, idl, - input_json5, output_hpp_dir, - output_impl_hpp_dir, + #output_impl_hpp_subdir, output_cpp_dir): @@ -88,6 +87,8 @@ def gen_facet(env, # extra include files (or perhaps other definitions) facet_includes = idl['includes'] + # detail + facet_detail_subdir = idl['detail_subdir'] facet_ns1 = idl['namespace1'] facet_ns2 = idl['namespace2'] facet_name = idl['facet'] # e.g. Sequence @@ -95,6 +96,8 @@ def gen_facet(env, facet_brief = idl['brief'] facet_doc = '\n'.join(idl['doc']) + output_impl_hpp_dir = output_hpp_dir / facet_detail_subdir + types = idl['types'] for ty in types: ty['doc'] = '\n'.join(ty['doc']) @@ -143,7 +146,7 @@ def gen_facet(env, 'genfacet': __file__, 'genfacet_input': idl_fname, 'using_dox': using_dox, - 'impl_hpp_subdir': output_impl_hpp_subdir, + 'impl_hpp_subdir': facet_detail_subdir, # 'facet_hpp_j2': 'facet.hpp.j2', 'facet_includes': facet_includes, @@ -475,23 +478,23 @@ def main(): 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) + gen_facet(env=env, + idl_fname=idl_fname, + idl=idl, + output_hpp_dir=output_hpp_dir, + #output_impl_hpp_dir=output_impl_hpp_dir, + output_cpp_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) + gen_facet_impl(env=env, + idl_fname=idl_fname, + idl=idl, + facet_idl=facet_idl, + output_hpp_dir=output_hpp_dir, + output_impl_hpp_dir=output_impl_hpp_dir, + output_cpp_dir=output_cpp_dir) if __name__ == '__main__': main() diff --git a/xo-facet/codegen/iface_facet_any.cpp.j2 b/xo-facet/codegen/iface_facet_any.cpp.j2 index 603686c9..0454bb24 100644 --- a/xo-facet/codegen/iface_facet_any.cpp.j2 +++ b/xo-facet/codegen/iface_facet_any.cpp.j2 @@ -25,7 +25,7 @@ void std::terminate(); } -int32_t +typeseq {{iface_facet_any}}::s_typeseq = typeseq::id(); bool diff --git a/xo-facet/codegen/iface_facet_any.hpp.j2 b/xo-facet/codegen/iface_facet_any.hpp.j2 index 70a27a98..cd8b99c4 100644 --- a/xo-facet/codegen/iface_facet_any.hpp.j2 +++ b/xo-facet/codegen/iface_facet_any.hpp.j2 @@ -44,6 +44,8 @@ namespace {{facet_ns2}} { ///@{ {% endif %} + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; {% for ty in types %} using {{ty.name}} = {{abstract_facet}}::{{ty.name}}; {% endfor %} @@ -61,14 +63,14 @@ namespace {{facet_ns2}} { // from {{abstract_facet}} // const methods - int32_t _typeseq() const noexcept override { return s_typeseq; } + typeseq _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 %} // nonconst methods {% for md in nonconst_methods %} - [[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatail(); } + [[noreturn]] {{md.return_type}} {{md.name}}({{md.args | argtypes}}) {{md | qualifiers}} override { _fatal(); } {% endfor %} {% if using_dox %} @@ -89,11 +91,11 @@ namespace {{facet_ns2}} { public: {% if using_dox %} - /** @defgraoup {{facet_ns2}}-{{facet_name_lc}}-any-member-vars **/ + /** @defgroup {{facet_ns2}}-{{facet_name_lc}}-any-member-vars **/ ///@{ {% endif %} - static int32_t s_typeseq; + static typeseq s_typeseq; static bool _valid; {% if using_dox %} diff --git a/xo-facet/codegen/iface_facet_xfer.hpp.j2 b/xo-facet/codegen/iface_facet_xfer.hpp.j2 index bdfd6156..ad65907b 100644 --- a/xo-facet/codegen/iface_facet_xfer.hpp.j2 +++ b/xo-facet/codegen/iface_facet_xfer.hpp.j2 @@ -68,7 +68,7 @@ namespace {{facet_ns2}} { public: {% if using_dox %} - /** @defgraoup {{facet_ns2}}-{{facet_name_lc}}-xfer-member-vars **/ + /** @defgroup {{facet_ns2}}-{{facet_name_lc}}-xfer-member-vars **/ ///@{ {% endif %} diff --git a/xo-gc/CMakeLists.txt b/xo-gc/CMakeLists.txt index 4480a1ad..fbe3bab2 100644 --- a/xo-gc/CMakeLists.txt +++ b/xo-gc/CMakeLists.txt @@ -21,7 +21,8 @@ add_definitions(${PROJECT_CXX_FLAGS}) # must complete definition of expression lib before configuring examples add_subdirectory(src/gc) add_subdirectory(utest) -#xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) # ---------------------------------------------------------------- # docs targets depend on other library/utest/exec targets above, diff --git a/xo-gc/cmake/xo-gcConfig.cmake.in b/xo-gc/cmake/xo_gcConfig.cmake.in similarity index 100% rename from xo-gc/cmake/xo-gcConfig.cmake.in rename to xo-gc/cmake/xo_gcConfig.cmake.in diff --git a/xo-indentlog/include/xo/indentlog/print/ppdetail_atomic.hpp b/xo-indentlog/include/xo/indentlog/print/ppdetail_atomic.hpp index 3f2a3c3f..cc50770a 100644 --- a/xo-indentlog/include/xo/indentlog/print/ppdetail_atomic.hpp +++ b/xo-indentlog/include/xo/indentlog/print/ppdetail_atomic.hpp @@ -1,17 +1,17 @@ -/* ppdetail_atomic.hpp +/** @file ppdetail_atomic.hpp * - * author: Roland Conybeare, Jul 2025 - */ + * @author Roland Conybeare, Jul 2025 + **/ #pragma once +#include "ppindentinfo.hpp" #include #include namespace xo { namespace print { struct ppstate; // see pretty.hpp - struct ppindentinfo; // Defining this means ppdetail_atomic -> ppdetail. // For debugging suppress the #define; causes specialization of ppdetail_atomic to be required for every T @@ -22,28 +22,6 @@ namespace xo { // #define ppdetail_atomic ppdetail - struct ppindentinfo { - ppindentinfo(ppstate * pps, std::uint32_t ci0, std::uint32_t indent_width, bool upto) - : pps_{pps}, ci0_{ci0}, ci1_{ci0 + indent_width}, upto_{upto} {} - - ppstate * pps() const { return pps_; } - std::uint32_t ci0_unused() const { return ci0_; } - std::uint32_t ci1() const { return ci1_; } - bool upto() const { return upto_; } - - private: - ppstate * pps_ = nullptr; - /** current indent **/ - std::uint32_t ci0_ = 0; - /** ci0 +1 indent level **/ - std::uint32_t ci1_ = 0; - /** - * true -> print on remainder of current line, unless past right margin - * false -> pretty across across multiple lines - **/ - bool upto_; - }; - /** @class ppdetail * @brief template for opt-in to pretty-printer * diff --git a/xo-indentlog/include/xo/indentlog/print/ppindentinfo.hpp b/xo-indentlog/include/xo/indentlog/print/ppindentinfo.hpp new file mode 100644 index 00000000..6137e6f9 --- /dev/null +++ b/xo-indentlog/include/xo/indentlog/print/ppindentinfo.hpp @@ -0,0 +1,43 @@ +/** @file ppindentinfo.hpp + * + * @author Roland Conybeare, Jul 2025 + **/ + +#pragma once + +#include + +namespace xo { + namespace print { + struct ppstate; + + /** @class ppindentinfo + * @brief pretty-printing state passed down the stack while traversing object graph + **/ + struct ppindentinfo { + ppindentinfo(ppstate * pps, std::uint32_t ci0, std::uint32_t indent_width, bool upto) + : pps_{pps}, ci0_{ci0}, ci1_{ci0 + indent_width}, upto_{upto} {} + + ppstate * pps() const { return pps_; } + std::uint32_t ci0_unused() const { return ci0_; } + std::uint32_t ci1() const { return ci1_; } + bool upto() const { return upto_; } + + private: + /** pretty-printing state. flyweight. See [xo/indentlog/print/pretty.hpp] **/ + ppstate * pps_ = nullptr; + /** current indent **/ + std::uint32_t ci0_ = 0; + /** ci0 +1 indent level **/ + std::uint32_t ci1_ = 0; + /** + * true -> print on remainder of current line, unless past right margin + * false -> pretty across across multiple lines + **/ + bool upto_; + }; + + } +} + +/* end ppindentinfo.hpp */ diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index bb540b37..fc15ebf9 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -37,12 +37,26 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +get_target_property(xo_printable2_src_dir xo-printable2 xo_srcdir) +message(STATUS "xo_printable2_src_dir=${xo_printable_src_dir}") + +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-printable-float + FACET Printable + REPR Float + INPUT idl/IPrintable_DFloat.json5 + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR . + OUTPUT_CPP_DIR src/object2 +) + # ---------------------------------------------------------------- # must complete definition of expression lib before configuring examples add_subdirectory(src/object2) add_subdirectory(utest) -#xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) # ---------------------------------------------------------------- # docs targets depend on other library/utest/exec targets above, diff --git a/xo-object2/idl/IPrintable_DFloat.json5 b/xo-object2/idl/IPrintable_DFloat.json5 new file mode 100644 index 00000000..31d10dd5 --- /dev/null +++ b/xo-object2/idl/IPrintable_DFloat.json5 @@ -0,0 +1,11 @@ +{ + mode: "implementation", + includes: [], + namespace1: "xo", + namespace2: "print", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DFloat", + using_doxygen: true, + repr: "DFloat", + doc: [ "doc for something or other" ], +} diff --git a/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp b/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp index 06838b36..dc9d73fc 100644 --- a/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp +++ b/xo-object2/include/xo/object2/sequence/ISequence_Any.hpp @@ -66,7 +66,7 @@ namespace scm { ///@} private: - /** @defgraoup scm-sequence-any-private-methods **/ + /** @defgroup scm-sequence-any-private-methods **/ ///@{ [[noreturn]] static void _fatal(); @@ -74,7 +74,7 @@ namespace scm { ///@} public: - /** @defgraoup scm-sequence-any-member-vars **/ + /** @defgroup scm-sequence-any-member-vars **/ ///@{ static typeseq s_typeseq; diff --git a/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp b/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp index 4a679b6c..3bcad3d8 100644 --- a/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp +++ b/xo-object2/include/xo/object2/sequence/ISequence_Xfer.hpp @@ -57,7 +57,7 @@ namespace scm { using I = Impl; public: - /** @defgraoup scm-sequence-xfer-member-vars **/ + /** @defgroup scm-sequence-xfer-member-vars **/ ///@{ /** typeseq for template parameter DRepr **/ diff --git a/xo-object2/src/object2/CMakeLists.txt b/xo-object2/src/object2/CMakeLists.txt index fc66c970..f1359f3b 100644 --- a/xo-object2/src/object2/CMakeLists.txt +++ b/xo-object2/src/object2/CMakeLists.txt @@ -16,4 +16,3 @@ xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 $ # note: deps here must also appear in cmake/xo_alloc2Config.cmake.in xo_dependency(${SELF_LIB} xo_gc) #xo_dependency(${SELF_LIB} indentlog) -#add_dependencies(${SELF_LIB} xo-object2-facetimpl-sequence-list) diff --git a/xo-printable2/CMakeLists.txt b/xo-printable2/CMakeLists.txt new file mode 100644 index 00000000..32034af1 --- /dev/null +++ b/xo-printable2/CMakeLists.txt @@ -0,0 +1,43 @@ +# xo-printable2/CMakeLists.txt + +cmake_minimum_required(VERSION 3.10) + +project(xo_printable2 VERSION 0.1) + +include(GNUInstallDirs) +include(cmake/xo-bootstrap-macros.cmake) + +xo_cxx_toplevel_options3() + +# ---------------------------------------------------------------- +# c++ settings + +set(PROJECT_CXX_FLAGS "") +#set(PROJECT_CXX_FLAGS "-fconcepts-diagnostics-depth=2") # gcc-only! +add_definitions(${PROJECT_CXX_FLAGS}) + +# ---------------------------------------------------------------- + +xo_add_genfacet( + TARGET xo-printable2-facet-printable + FACET Printable + INPUT idl/Printable.json5 + OUTPUT_HPP_DIR include/xo/printable2 + OUTPUT_IMPL_SUBDIR detail + OUTPUT_CPP_DIR src/printable2 +) + +# ---------------------------------------------------------------- + +add_subdirectory(src/printable2) +#add_subdirectory(utest) + +xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) + +# ---------------------------------------------------------------- +# docs targets depend on other library/utest/exec targets above, +# --> must come after them. +# +#add_subdirectory(docs) + +# end CMakeLists.txt diff --git a/xo-printable2/cmake/xo-bootstrap-macros.cmake b/xo-printable2/cmake/xo-bootstrap-macros.cmake new file mode 100644 index 00000000..aba31169 --- /dev/null +++ b/xo-printable2/cmake/xo-bootstrap-macros.cmake @@ -0,0 +1,35 @@ +# ---------------------------------------------------------------- +# for example: +# $ PREFIX=/usr/local # for example +# $ cmake -DCMAKE_MODULE_PATH=prefix -DCMAKE_INSTALL_PREFIX=$PREFIX -B .build +# +# will get +# CMAKE_MODULE_PATH +# from xo-cmake-config --cmake-module-path +# +# and expect .cmake macros in +# CMAKE_MODULE_PATH/xo_macros/xo_cxx.cmake +# ---------------------------------------------------------------- + +find_program(XO_CMAKE_CONFIG_EXECUTABLE NAMES xo-cmake-config REQUIRED) + +if ("${XO_CMAKE_CONFIG_EXECUTABLE}" STREQUAL "XO_CMAKE_CONFIG_EXECUTABLE-NOT_FOUND") + message(FATAL "could not find xo-cmake-config executable") +endif() + +message(STATUS "XO_CMAKE_CONFIG_EXECUTABLE=${XO_CMAKE_CONFIG_EXECUTABLE}") + +if (NOT XO_SUBMODULE_BUILD) + if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) + # default to typical install location for xo-project-macros + execute_process(COMMAND ${XO_CMAKE_CONFIG_EXECUTABLE} --cmake-module-path OUTPUT_VARIABLE CMAKE_MODULE_PATH) + message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") + endif() +endif() + +# needs to have been installed somewhere on CMAKE_MODULE_PATH, +# (e.g. from xo-cmake with the same value for CMAKE_INSTALL_PREFIX) +# +include(xo_macros/xo_cxx) + +xo_cxx_bootstrap_message() diff --git a/xo-printable2/cmake/xo_printable2Config.cmake.in b/xo-printable2/cmake/xo_printable2Config.cmake.in new file mode 100644 index 00000000..985fc324 --- /dev/null +++ b/xo-printable2/cmake/xo_printable2Config.cmake.in @@ -0,0 +1,7 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(indentlog) +find_dependency(xo_facet) +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/xo-printable2/idl/Printable.json5 b/xo-printable2/idl/Printable.json5 new file mode 100644 index 00000000..ee9a1e75 --- /dev/null +++ b/xo-printable2/idl/Printable.json5 @@ -0,0 +1,29 @@ +{ + mode: "facet", + includes: [""], + namespace1: "xo", + namespace2: "print", + facet: "Printable", + detail_subdir: "detail", + brief: "pretty-printable objects", + using_doxygen: true, + doc: [ + "Trait for data types that support pretty-printing" + ], + types: [], + const_methods: [ + // bool pretty(const ppindentinfo & ppii) const + { + name: "pretty", + doc: [ + "Pretty-printing support for this object.", + "See [xo-indentlog/xo/indentlog/pretty.hpp]", + ], + return_type: "bool", + args: [ + {type: "const ppindentinfo &", name: "ppii"}, + ], + }, + ], + nonconst_methods: [], +} diff --git a/xo-printable2/include/xo/printable2/Printable.hpp b/xo-printable2/include/xo/printable2/Printable.hpp new file mode 100644 index 00000000..b5952a7d --- /dev/null +++ b/xo-printable2/include/xo/printable2/Printable.hpp @@ -0,0 +1,21 @@ +/** @file Printable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Printable.json5] + * 2. jinja2 template for facet .hpp file: + * [facet.hpp.j2] + * 3. idl for facet methods + * [idl/Printable.json5] + **/ + +#pragma once + +#include "detail/APrintable.hpp" +#include "detail/IPrintable_Any.hpp" +#include "detail/IPrintable_Xfer.hpp" +#include "detail/RPrintable.hpp" + +/* end Printable.hpp */ \ No newline at end of file diff --git a/xo-printable2/include/xo/printable2/detail/APrintable.hpp b/xo-printable2/include/xo/printable2/detail/APrintable.hpp new file mode 100644 index 00000000..3b734816 --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/APrintable.hpp @@ -0,0 +1,69 @@ +/** @file APrintable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Printable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [abstract_facet.hpp.j2] + * 3. idl for facet methods + * [idl/Printable.json5] + **/ + +#pragma once + +// includes (via {facet_includes}) +#include +#include +#include +#include + +namespace xo { +namespace print { + +using Copaque = const void *; +using Opaque = void *; + +/** +Trait for data types that support pretty-printing +**/ +class APrintable { +public: + /** @defgroup print-printable-type-traits **/ + ///@{ + // types + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + ///@} + + /** @defgroup print-printable-methods **/ + ///@{ + // const methods + /** RTTI: unique id# for actual runtime data representation **/ + virtual typeseq _typeseq() const noexcept = 0; + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + virtual bool pretty(Copaque data, const ppindentinfo & ppii) = 0; + + // nonconst methods + ///@} +}; /*APrintable*/ + +/** Implementation IPrintable_DRepr of APrintable for state DRepr + * should provide a specialization: + * + * template <> + * struct xo::facet::FacetImplementation { + * using Impltype = IPrintable_DRepr; + * }; + * + * then IPrintable_ImplType --> IPrintable_DRepr + **/ +template +using IPrintable_ImplType = xo::facet::FacetImplType; + +} /*namespace print*/ +} /*namespace xo*/ + +/* */ \ No newline at end of file diff --git a/xo-printable2/include/xo/printable2/detail/IPrintable_Any.hpp b/xo-printable2/include/xo/printable2/detail/IPrintable_Any.hpp new file mode 100644 index 00000000..b2c29bf4 --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/IPrintable_Any.hpp @@ -0,0 +1,85 @@ +/** @file IPrintable_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Printable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Printable.json5] + **/ + +#pragma once + +#include "APrintable.hpp" +#include + +namespace xo { namespace print { class IPrintable_Any; } } + +namespace xo { +namespace facet { + +template <> +struct FacetImplementation +{ + using ImplType = xo::print::IPrintable_Any; +}; + +} +} + +namespace xo { +namespace print { + + /** @class IPrintable_Any + * @brief APrintable implementation for empty variant instance + **/ + class IPrintable_Any : public APrintable { + public: + /** @defgroup print-printable-any-type-traits **/ + ///@{ + + /** integer identifying a type **/ + using typeseq = xo::facet::typeseq; + + ///@} + /** @defgroup print-printable-any-methods **/ + ///@{ + + const APrintable * iface() const { return std::launder(this); } + + // from APrintable + + // const methods + typeseq _typeseq() const noexcept override { return s_typeseq; } + [[noreturn]] bool pretty(Copaque, const ppindentinfo &) override { _fatal(); } + + // nonconst methods + + ///@} + + private: + /** @defgraoup print-printable-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgraoup print-printable-any-member-vars **/ + ///@{ + + static typeseq s_typeseq; + static bool _valid; + + ///@} + }; + +} /*namespace print */ +} /*namespace xo */ + +/* IPrintable_Any.hpp */ \ No newline at end of file diff --git a/xo-printable2/include/xo/printable2/detail/IPrintable_Xfer.hpp b/xo-printable2/include/xo/printable2/detail/IPrintable_Xfer.hpp new file mode 100644 index 00000000..d37d8453 --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/IPrintable_Xfer.hpp @@ -0,0 +1,77 @@ +/** @file IPrintable_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Printable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Printable.json5] + **/ + +#pragma once + +#include "APrintable.hpp" + +namespace xo { +namespace print { + /** @class IPrintable_Xfer + **/ + template + class IPrintable_Xfer : public APrintable { + public: + /** @defgroup print-printable-xfer-type-traits **/ + ///@{ + using Impl = IPrintable_DRepr; + ///@} + + /** @defgroup print-printable-xfer-methods **/ + ///@{ + + static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; } + static DRepr & _dcast(Opaque d) { return *(DRepr *)d; } + + // from APrintable + + // const methods + int32_t _typeseq() const noexcept override { return s_typeseq; } + bool pretty(Copaque data, const ppindentinfo & ppii) override { + return I::pretty(_dcast(data), ppii); + } + + // non-const methods + + ///@} + + private: + using I = Impl; + + public: + /** @defgraoup print-printable-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static int32_t s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + int32_t + IPrintable_Xfer::s_typeseq + = xo::facet::typeseq::id(); + + template + bool + IPrintable_Xfer::_valid + = xo::facet::valid_facet_implementation(); + +} /*namespace print */ +} /*namespace xo*/ + +/* end IPrintable_Xfer.hpp */ \ No newline at end of file diff --git a/xo-printable2/include/xo/printable2/detail/RPrintable.hpp b/xo-printable2/include/xo/printable2/detail/RPrintable.hpp new file mode 100644 index 00000000..1d9bd237 --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/RPrintable.hpp @@ -0,0 +1,77 @@ +/** @file RPrintable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/Printable.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/Printable.json5] + **/ + +#pragma once + +#include "APrintable.hpp" + +namespace xo { +namespace print { + +/** @class RPrintable + **/ +template +class RPrintable : public Object { +private: + using O = Object; + +public: + /** @defgroup print-printable-router-type-traits **/ + ///@{ + using ObjectType = Object; + using DataPtr = Object::DataPtr; + ///@} + + /** @defgroup print-printable-router-ctors **/ + ///@{ + RPrintable() {} + RPrintable(Object::DataPtr data) : Object{std::move(data)} {} + + ///@} + /** @defgroup print-printable-router-methods **/ + ///@{ + + // const methods + int32_t _typeseq() const noexcept { return O::iface()->_typeseq(); } + bool pretty(const ppindentinfo & ppii) override { + return O::iface()->pretty(O::data(), ppii); + } + + // non-const methods + // << do something for non-const methods >> + // + + ///@} + /** @defgroup print-printable-member-vars **/ + ///@{ + + static bool _valid; + + ///@} +}; + +template +bool +RPrintable::_valid = xo::facet::valid_object_router(); + +} /*namespace print*/ +} /*namespace xo*/ + +namespace xo { namespace facet { + template + struct RoutingFor { + using RoutingType = xo::print::RPrintable; + }; +} } + +/* end RPrintable.hpp */ \ No newline at end of file diff --git a/xo-printable2/src/printable2/CMakeLists.txt b/xo-printable2/src/printable2/CMakeLists.txt new file mode 100644 index 00000000..101bc8e3 --- /dev/null +++ b/xo-printable2/src/printable2/CMakeLists.txt @@ -0,0 +1,11 @@ +# printable2/CMakeLists.txt + +set(SELF_LIB xo_printable2) +set(SELF_SRCS + IPrintable_Any.cpp +) + +xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) +# note: deps here must coord with cmake/xo_printable2Config.cmake.in +xo_dependency(${SELF_LIB} indentlog) +xo_dependency(${SELF_LIB} xo_facet) diff --git a/xo-printable2/src/printable2/IPrintable_Any.cpp b/xo-printable2/src/printable2/IPrintable_Any.cpp new file mode 100644 index 00000000..ecef6484 --- /dev/null +++ b/xo-printable2/src/printable2/IPrintable_Any.cpp @@ -0,0 +1,38 @@ +/** @file IPrintable_Any.cpp + * + **/ + +#include "detail/IPrintable_Any.hpp" +#include + +namespace xo { +namespace print { + +using xo::facet::DVariantPlaceholder; +using xo::facet::typeseq; +using xo::facet::valid_facet_implementation; + +void +IPrintable_Any::_fatal() +{ + /* control here on uninitialized IAllocator_Any. + * Initialized instance will have specific implementation type + */ + std::cerr << "fatal" + << ": attempt to call uninitialized" + << " IPrintable_Any method" + << std::endl; + std::terminate(); +} + +typeseq +IPrintable_Any::s_typeseq = typeseq::id(); + +bool +IPrintable_Any::_valid + = valid_facet_implementation(); + +} /*namespace print*/ +} /*namespace xo*/ + +/* end IPrintable_Any.cpp */ \ No newline at end of file