diff --git a/xo-printable2/.gitrepo b/xo-printable2/.gitrepo new file mode 100644 index 00000000..75cec007 --- /dev/null +++ b/xo-printable2/.gitrepo @@ -0,0 +1,12 @@ +; DO NOT EDIT (unless you know what you are doing) +; +; This subdirectory is a git "subrepo", and this file is maintained by the +; git-subrepo command. See https://github.com/ingydotnet/git-subrepo#readme +; +[subrepo] + remote = git@github.com:Rconybea/xo-printable2.git + branch = main + commit = 48f6dfaa20ac6eab44425324d7c10a5480c6bec0 + parent = 6fc83036026aed83cae0421fa3f3272ca182ab3a + method = merge + cmdver = 0.4.9 diff --git a/xo-printable2/CMakeLists.txt b/xo-printable2/CMakeLists.txt new file mode 100644 index 00000000..602fce5e --- /dev/null +++ b/xo-printable2/CMakeLists.txt @@ -0,0 +1,46 @@ +# 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 +) + +# ---------------------------------------------------------------- + +add_subdirectory(src/printable2) +#add_subdirectory(utest) + +install(DIRECTORY idl/ + DESTINATION share/${PROJECT_NAME}/idl + FILES_MATCHING PATTERN "*.json5") + +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/README.md b/xo-printable2/README.md new file mode 100644 index 00000000..1bac1c02 --- /dev/null +++ b/xo-printable2/README.md @@ -0,0 +1 @@ +# xo-printable2 diff --git a/xo-printable2/cmake/xo-bootstrap-macros.cmake b/xo-printable2/cmake/xo-bootstrap-macros.cmake new file mode 100644 index 00000000..592272c0 --- /dev/null +++ b/xo-printable2/cmake/xo-bootstrap-macros.cmake @@ -0,0 +1,41 @@ +# ---------------------------------------------------------------- +# 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 (XO_SUBMODULE_BUILD) + if (("${CMAKE_MODULE_PATH}" STREQUAL "") OR ("${CMAKE_MODULE_PATH}" STREQUAL prefix)) + # local version of xo-cmake macros + set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/xo-cmake/cmake") + message(STATUS "CMAKE_MODULE_PATH=${CMAKE_MODULE_PATH}") + endif() +else() + 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..3bcd63df --- /dev/null +++ b/xo-printable2/cmake/xo_printable2Config.cmake.in @@ -0,0 +1,8 @@ +@PACKAGE_INIT@ + +include(CMakeFindDependencyMacro) +find_dependency(indentlog) +find_dependency(xo_facet) +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Share.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..9926e73e --- /dev/null +++ b/xo-printable2/idl/Printable.json5 @@ -0,0 +1,45 @@ +{ + mode: "facet", + output_cpp_dir: "src/printable2", + output_hpp_dir: "include/xo/printable2", + output_impl_subdir: "detail", + includes: [""], + // extra includes in Printable.hpp + user_hpp_includes: ["\"detail/ppdetail_Printable.hpp\""], + namespace1: "xo", + namespace2: "print", + // text after includes, before APrintable + pretext: [ "// {pretext} here" ], + facet: "Printable", + detail_subdir: "detail", + brief: "pretty-printable objects", + using_doxygen: true, + doc: [ + "Trait for data types that support pretty-printing" + ], + types: [ + // using ppindentinfo = xo::print::ppindentinfo + { + name: "ppindentinfo", + doc: ["dynamic pretty-printing state during layout"], + definition: "xo::print::ppindentinfo", + }, + ], + 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"}, + ], + const: true, + }, + ], + nonconst_methods: [], + router_facet_explicit_content: [], +} diff --git a/xo-printable2/include/xo/printable2/Printable.hpp b/xo-printable2/include/xo/printable2/Printable.hpp new file mode 100644 index 00000000..cec3bc34 --- /dev/null +++ b/xo-printable2/include/xo/printable2/Printable.hpp @@ -0,0 +1,25 @@ +/** @file Printable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/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" + +#include "detail/ppdetail_Printable.hpp" + +#include + +/* end Printable.hpp */ 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..e5b757de --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/APrintable.hpp @@ -0,0 +1,74 @@ +/** @file APrintable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/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; + using Copaque = const void *; + using Opaque = void *; + /** dynamic pretty-printing state during layout **/ + using ppindentinfo = xo::print::ppindentinfo; + ///@} + + /** @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) const = 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*/ + +/* APrintable.hpp */ \ 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..ae3faf0f --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/IPrintable_Any.hpp @@ -0,0 +1,86 @@ +/** @file IPrintable_Any.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/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; + using ppindentinfo = APrintable::ppindentinfo; + + ///@} + /** @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 &) const override { _fatal(); } + + // nonconst methods + + ///@} + + private: + /** @defgraoup print-printable-any-private-methods **/ + ///@{ + + [[noreturn]] static void _fatal(); + + ///@} + + public: + /** @defgroup 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..78de7e43 --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/IPrintable_Xfer.hpp @@ -0,0 +1,81 @@ +/** @file IPrintable_Xfer.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/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 + +namespace xo { +namespace print { + /** @class IPrintable_Xfer + **/ + template + class IPrintable_Xfer : public APrintable { + public: + /** @defgroup print-printable-xfer-type-traits **/ + ///@{ + /** actual implementation (not generated; often delegates to DRepr) **/ + using Impl = IPrintable_DRepr; + /** integer identifying a type **/ + using typeseq = APrintable::typeseq; + using ppindentinfo = APrintable::ppindentinfo; + ///@} + + /** @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 + typeseq _typeseq() const noexcept override { return s_typeseq; } + bool pretty(Copaque data, const ppindentinfo & ppii) const override { + return I::pretty(_dcast(data), ppii); + } + + // non-const methods + + ///@} + + private: + using I = Impl; + + public: + /** @defgroup print-printable-xfer-member-vars **/ + ///@{ + + /** typeseq for template parameter DRepr **/ + static typeseq s_typeseq; + /** true iff satisfies facet implementation **/ + static bool _valid; + + ///@} + }; + + template + xo::facet::typeseq + 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..8d24b17a --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/RPrintable.hpp @@ -0,0 +1,80 @@ +/** @file RPrintable.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/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; + using typeseq = xo::reflect::typeseq; + using ppindentinfo = APrintable::ppindentinfo; + ///@} + + /** @defgroup print-printable-router-ctors **/ + ///@{ + RPrintable() {} + RPrintable(Object::DataPtr data) : Object{std::move(data)} {} + RPrintable(const APrintable * iface, void * data) + requires std::is_same_v + : Object(iface, data) {} + + ///@} + /** @defgroup print-printable-router-methods **/ + ///@{ + + // const methods + typeseq _typeseq() const noexcept { return O::iface()->_typeseq(); } + bool pretty(const ppindentinfo & ppii) const { + return O::iface()->pretty(O::data(), ppii); + } + + // non-const methods (still const in router!) + + ///@} + /** @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/include/xo/printable2/detail/ppdetail_Printable.hpp b/xo-printable2/include/xo/printable2/detail/ppdetail_Printable.hpp new file mode 100644 index 00000000..ba7a3d82 --- /dev/null +++ b/xo-printable2/include/xo/printable2/detail/ppdetail_Printable.hpp @@ -0,0 +1,21 @@ +/** @file ppdetail_Printable.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#include +#include "Printable.hpp" + +namespace xo { + namespace print { + template + struct ppdetail> { + static bool print_pretty(const ppindentinfo & ppii, + const xo::facet::obj & x) { + return x.pretty(ppii); + } + }; + } +} /*namespace xo*/ + +/* end ppdetail_Printable.hpp */ 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..46b0bddc --- /dev/null +++ b/xo-printable2/src/printable2/IPrintable_Any.cpp @@ -0,0 +1,42 @@ +/** @file IPrintable_Any.cpp + * + **/ + +#include "detail/IPrintable_Any.hpp" +#include +#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(); + +// nonconst methods + + +} /*namespace print*/ +} /*namespace xo*/ + +/* end IPrintable_Any.cpp */