From d4dae460a6d5cd27595f77a2a759f0801ed761dd Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 6 Jun 2026 22:20:07 -0400 Subject: [PATCH] .xo-reflect subrepo tidy --- .../workflows/cmake-single-platform.yml | 117 ---- .xo-reflect/.gitignore | 8 - .xo-reflect/CMakeLists.txt | 29 - .xo-reflect/FILESYSTEM | 1 - .xo-reflect/README.md | 55 -- .xo-reflect/cmake/reflectConfig.cmake.in | 9 - .xo-reflect/cmake/run-external-ctest | 8 - .xo-reflect/cmake/xo-bootstrap-macros.cmake | 41 -- .xo-reflect/include/xo/reflect/CMakeLists.txt | 32 - .../include/xo/reflect/EstablishTypeDescr.hpp | 76 --- .xo-reflect/include/xo/reflect/Metatype.hpp | 41 -- .xo-reflect/include/xo/reflect/Object.hpp | 43 -- .xo-reflect/include/xo/reflect/Reflect.hpp | 421 ------------ .../include/xo/reflect/SelfTagging.hpp | 31 - .../include/xo/reflect/StructReflector.hpp | 165 ----- .xo-reflect/include/xo/reflect/TaggedPtr.hpp | 128 ---- .../include/xo/reflect/TaggedRcptr.hpp | 88 --- .xo-reflect/include/xo/reflect/TypeDescr.hpp | 616 ------------------ .../include/xo/reflect/TypeDescrExtra.hpp | 91 --- .../include/xo/reflect/TypeDrivenMap.hpp | 50 -- .../include/xo/reflect/atomic/AtomicTdx.hpp | 39 -- .../xo/reflect/function/FunctionTdx.hpp | 58 -- .../include/xo/reflect/init_reflect.hpp | 22 - .../include/xo/reflect/pointer/PointerTdx.hpp | 85 --- .../include/xo/reflect/reflect_struct.hpp | 71 -- .../xo/reflect/struct/StructMember.hpp | 236 ------- .../include/xo/reflect/struct/StructTdx.hpp | 98 --- .../include/xo/reflect/vector/VectorTdx.hpp | 123 ---- .xo-reflect/src/reflect/CMakeLists.txt | 19 - .xo-reflect/src/reflect/TaggedRcptr.cpp | 30 - .xo-reflect/src/reflect/TypeDescr.cpp | 383 ----------- .xo-reflect/src/reflect/TypeDescrExtra.cpp | 37 -- .xo-reflect/src/reflect/atomic/AtomicTdx.cpp | 32 - .../src/reflect/function/FunctionTdx.cpp | 54 -- .xo-reflect/src/reflect/init_reflect.cpp | 23 - .../src/reflect/pointer/PointerTdx.cpp | 17 - .../src/reflect/struct/StructMember.cpp | 36 - .xo-reflect/src/reflect/struct/StructTdx.cpp | 67 -- .xo-reflect/src/reflect/vector/VectorTdx.cpp | 20 - .xo-reflect/utest/CMakeLists.txt | 15 - .xo-reflect/utest/FunctionTdx.test.cpp | 40 -- .xo-reflect/utest/StructReflector.test.cpp | 142 ---- .xo-reflect/utest/StructTdx.test.cpp | 57 -- .xo-reflect/utest/VectorTdx.test.cpp | 181 ----- .xo-reflect/utest/reflect_utest_main.cpp | 6 - 45 files changed, 3941 deletions(-) delete mode 100644 .xo-reflect/.github/workflows/cmake-single-platform.yml delete mode 100644 .xo-reflect/.gitignore delete mode 100644 .xo-reflect/CMakeLists.txt delete mode 100644 .xo-reflect/FILESYSTEM delete mode 100644 .xo-reflect/README.md delete mode 100644 .xo-reflect/cmake/reflectConfig.cmake.in delete mode 100755 .xo-reflect/cmake/run-external-ctest delete mode 100644 .xo-reflect/cmake/xo-bootstrap-macros.cmake delete mode 100644 .xo-reflect/include/xo/reflect/CMakeLists.txt delete mode 100644 .xo-reflect/include/xo/reflect/EstablishTypeDescr.hpp delete mode 100644 .xo-reflect/include/xo/reflect/Metatype.hpp delete mode 100644 .xo-reflect/include/xo/reflect/Object.hpp delete mode 100644 .xo-reflect/include/xo/reflect/Reflect.hpp delete mode 100644 .xo-reflect/include/xo/reflect/SelfTagging.hpp delete mode 100644 .xo-reflect/include/xo/reflect/StructReflector.hpp delete mode 100644 .xo-reflect/include/xo/reflect/TaggedPtr.hpp delete mode 100644 .xo-reflect/include/xo/reflect/TaggedRcptr.hpp delete mode 100644 .xo-reflect/include/xo/reflect/TypeDescr.hpp delete mode 100644 .xo-reflect/include/xo/reflect/TypeDescrExtra.hpp delete mode 100644 .xo-reflect/include/xo/reflect/TypeDrivenMap.hpp delete mode 100644 .xo-reflect/include/xo/reflect/atomic/AtomicTdx.hpp delete mode 100644 .xo-reflect/include/xo/reflect/function/FunctionTdx.hpp delete mode 100644 .xo-reflect/include/xo/reflect/init_reflect.hpp delete mode 100644 .xo-reflect/include/xo/reflect/pointer/PointerTdx.hpp delete mode 100644 .xo-reflect/include/xo/reflect/reflect_struct.hpp delete mode 100644 .xo-reflect/include/xo/reflect/struct/StructMember.hpp delete mode 100644 .xo-reflect/include/xo/reflect/struct/StructTdx.hpp delete mode 100644 .xo-reflect/include/xo/reflect/vector/VectorTdx.hpp delete mode 100644 .xo-reflect/src/reflect/CMakeLists.txt delete mode 100644 .xo-reflect/src/reflect/TaggedRcptr.cpp delete mode 100644 .xo-reflect/src/reflect/TypeDescr.cpp delete mode 100644 .xo-reflect/src/reflect/TypeDescrExtra.cpp delete mode 100644 .xo-reflect/src/reflect/atomic/AtomicTdx.cpp delete mode 100644 .xo-reflect/src/reflect/function/FunctionTdx.cpp delete mode 100644 .xo-reflect/src/reflect/init_reflect.cpp delete mode 100644 .xo-reflect/src/reflect/pointer/PointerTdx.cpp delete mode 100644 .xo-reflect/src/reflect/struct/StructMember.cpp delete mode 100644 .xo-reflect/src/reflect/struct/StructTdx.cpp delete mode 100644 .xo-reflect/src/reflect/vector/VectorTdx.cpp delete mode 100644 .xo-reflect/utest/CMakeLists.txt delete mode 100644 .xo-reflect/utest/FunctionTdx.test.cpp delete mode 100644 .xo-reflect/utest/StructReflector.test.cpp delete mode 100644 .xo-reflect/utest/StructTdx.test.cpp delete mode 100644 .xo-reflect/utest/VectorTdx.test.cpp delete mode 100644 .xo-reflect/utest/reflect_utest_main.cpp diff --git a/.xo-reflect/.github/workflows/cmake-single-platform.yml b/.xo-reflect/.github/workflows/cmake-single-platform.yml deleted file mode 100644 index 49c1a81c..00000000 --- a/.xo-reflect/.github/workflows/cmake-single-platform.yml +++ /dev/null @@ -1,117 +0,0 @@ -name: xo-reflect ubuntu build - -on: - push: - branches: [ "main" ] - pull_request: - branches: [ "main" ] - -env: - # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) - BUILD_TYPE: Release - -jobs: - build: - # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac. - # You can convert this to a matrix build if you need cross-platform coverage. - # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix - runs-on: ubuntu-latest - - steps: - - name: checkout source - uses: actions/checkout@v3 - - - name: Install catch2 - # install catch2. see [[https://stackoverflow.com/questions/57982945/how-to-apt-get-install-in-a-github-actions-workflow]] - run: sudo apt-get install -y catch2 - - # ---------------------------------------------------------------- - - - name: Clone xo-cmake - uses: actions/checkout@v3 - with: - repository: Rconybea/xo-cmake - path: repo/xo-cmake - - - name: Configure xo-cmake - run: cmake -B ${{github.workspace}}/build_xo-cmake -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/xo-cmake - - - name: Build xo-cmake (trivial) - run: cmake --build ${{github.workspace}}/build_xo-cmake --config ${{env.BUILD_TYPE}} - - - name: Install xo-cmake - run: cmake --install ${{github.workspace}}/build_xo-cmake - - # ---------------------------------------------------------------- - - - name: Clone indentlog - uses: actions/checkout@v3 - with: - repository: Rconybea/indentlog - path: repo/indentlog - - - name: Configure indentlog - # configure cmake for indentlog in dedicated build directory. - run: cmake -B ${{github.workspace}}/build_indentlog -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/indentlog - - - name: Build indentlog - run: cmake --build ${{github.workspace}}/build_indentlog --config ${{env.BUILD_TYPE}} - - - name: Install indentlog - # install into ${{github.workspace}}/local - run: cmake --install ${{github.workspace}}/build_indentlog - - # ---------------------------------------------------------------- - - - name: Clone subsys - uses: actions/checkout@v3 - with: - repository: Rconybea/subsys - path: repo/subsys - - - name: Configure subsys - # configure cmake for subsys in dedicated build directory. - run: cmake -B ${{github.workspace}}/build_subsys -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/subsys - - - name: Build subsys - run: cmake --build ${{github.workspace}}/build_subsys --config ${{env.BUILD_TYPE}} - - - name: Install subsys - # install into ${{github.workspace}}/local - run: cmake --install ${{github.workspace}}/build_subsys - - # ---------------------------------------------------------------- - - - name: Clone refcnt - uses: actions/checkout@v3 - with: - repository: Rconybea/refcnt - path: repo/refcnt - - - name: Configure refcnt - # configure cmake for refcnt in dedicated build directory. - run: cmake -B ${{github.workspace}}/build_refcnt -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_PREFIX_PATH=${{github.workspace}}/local -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local repo/refcnt - - - name: Build refcnt - run: cmake --build ${{github.workspace}}/build_refcnt --config ${{env.BUILD_TYPE}} - - - name: Install refcnt - # install into ${{github.workspace}}/local - run: cmake --install ${{github.workspace}}/build_refcnt - - # ---------------------------------------------------------------- - - - name: Configure self (reflect) - # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. - # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type - run: cmake -B ${{github.workspace}}/build_reflect -DCMAKE_MODULE_PATH=${{github.workspace}}/local/share/cmake -DCMAKE_PREFIX_PATH=${{github.workspace}}/local -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/local -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} - - - name: Build self (reflect) - # Build your program with the given configuration - run: cmake --build ${{github.workspace}}/build_reflect --config ${{env.BUILD_TYPE}} - - - name: Test self (reflect) - working-directory: ${{github.workspace}}/build_reflect - # Execute tests defined by the CMake configuration. - # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail - run: ctest -C ${{env.BUILD_TYPE}} diff --git a/.xo-reflect/.gitignore b/.xo-reflect/.gitignore deleted file mode 100644 index 3d3a7826..00000000 --- a/.xo-reflect/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# emacs workspace config -.projectile -# clangd working space (see emacs+lsp) -.cache -# typical cmake build directory (source-tree-nephew) -.build* -# symlink to builddir/compile_commands.json; should be set manually in dev sandbox -compile_commands.json diff --git a/.xo-reflect/CMakeLists.txt b/.xo-reflect/CMakeLists.txt deleted file mode 100644 index be7c1d7f..00000000 --- a/.xo-reflect/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ -# xo-reflect/CMakeLists.txt - -cmake_minimum_required(VERSION 3.10) - -project(reflect 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") -add_definitions(${PROJECT_CXX_FLAGS}) - -# ---------------------------------------------------------------- - -add_subdirectory(src/reflect) -add_subdirectory(utest) - -# ---------------------------------------------------------------- -# provide find_package() support - -xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) - -# end CMakeLists.txt diff --git a/.xo-reflect/FILESYSTEM b/.xo-reflect/FILESYSTEM deleted file mode 100644 index 9af86a7a..00000000 --- a/.xo-reflect/FILESYSTEM +++ /dev/null @@ -1 +0,0 @@ -repo -- git submoduules here diff --git a/.xo-reflect/README.md b/.xo-reflect/README.md deleted file mode 100644 index d39421b6..00000000 --- a/.xo-reflect/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# reflection library - -## Getting Started - -### build + install `xo-cmake` dependency - -- [github/Rconybea/xo-cmake](https://github.com/Rconybea/xo-cmake) - -Installs a few cmake ingredients, along with a build assistant `xo-build` for XO projects such as this one. - -### build + install other XO dependencies -``` -$ xo-build --clone --configure --build --install xo-indentlog -$ xo-build --clone --configure --build --install xo-refnct -$ xo-build --clone --configure --build --install xo-subsys -$ xo-build --clone --configure --build --install xo-reflectutil -``` - -Note: can use `-n` to dry-run here - -### copy `xo-reflect` repository locally -``` -$ xo-build --clone xo-reflect -``` - -or equivalently -``` -$ git clone git@github.com:Rconybea/xo-reflect.git -``` - -### build + install `xo-reflect` -``` -$ xo-build --configure --build --install xo-reflect -``` - -or equivalently: - -``` -$ PREFIX=/usr/local # or wherever you prefer -$ cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -S xo-reflect -B xo-reflect/.build -$ cmake --build xo-reflect/.build -$ cmake --install xo-reflect/.build -``` - -### build for unit test coverage -``` -$ cmake -DCMAKE_BUILD_TYPE=coverage -DCMAKE_INSTALL_PREFIX=$PREFIX xo-reflect/.build-ccov -$ cmake --build xo-reflect/.build-ccov -``` - -### LSP support -``` -$ cd xo-reflect -$ ln -s .build/compile_commands.json # lsp will look for compile_commands.json in the root of the source tree -``` diff --git a/.xo-reflect/cmake/reflectConfig.cmake.in b/.xo-reflect/cmake/reflectConfig.cmake.in deleted file mode 100644 index b7c79684..00000000 --- a/.xo-reflect/cmake/reflectConfig.cmake.in +++ /dev/null @@ -1,9 +0,0 @@ -@PACKAGE_INIT@ - -include(CMakeFindDependencyMacro) -find_dependency(refcnt) -find_dependency(indentlog) -find_dependency(subsys) -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-reflect/cmake/run-external-ctest b/.xo-reflect/cmake/run-external-ctest deleted file mode 100755 index 386c45a4..00000000 --- a/.xo-reflect/cmake/run-external-ctest +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -# $1 = build directory - -cd $1 -shift - -ctest "${@}" diff --git a/.xo-reflect/cmake/xo-bootstrap-macros.cmake b/.xo-reflect/cmake/xo-bootstrap-macros.cmake deleted file mode 100644 index 592272c0..00000000 --- a/.xo-reflect/cmake/xo-bootstrap-macros.cmake +++ /dev/null @@ -1,41 +0,0 @@ -# ---------------------------------------------------------------- -# 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-reflect/include/xo/reflect/CMakeLists.txt b/.xo-reflect/include/xo/reflect/CMakeLists.txt deleted file mode 100644 index a7e07dd6..00000000 --- a/.xo-reflect/include/xo/reflect/CMakeLists.txt +++ /dev/null @@ -1,32 +0,0 @@ -# reflect/CMakeLists.txt - -set(SELF_LIBRARY_NAME reflect) - -# build shared library 'reflect' -add_library(${SELF_LIBRARY_NAME} SHARED TypeDescr.cpp TypeDescrExtra.cpp TaggedRcptr.cpp atomic/AtomicTdx.cpp pointer/PointerTdx.cpp vector/VectorTdx.cpp struct/StructTdx.cpp struct/StructMember.cpp init_reflect.cpp) - -set_target_properties(${SELF_LIBRARY_NAME} PROPERTIES - VERSION ${PROJECT_VERSION} - SOVERSION 1 - PUBLIC_HEADER TypeDescr.hpp) - -# ---------------------------------------------------------------- -# all the errors+warnings! -# -#target_compile_options(${SELF_LIBRARY_NAME} PRIVATE -Werror -Wall -Wextra) -xo_compile_options(${SELF_LIBRARY_NAME}) -xo_include_options(${SELF_LIBRARY_NAME}) - -# ---------------------------------------------------------------- -# internal dependencies: logutil, ... - -target_link_libraries(${SELF_LIBRARY_NAME} PUBLIC refcnt) - -# ---------------------------------------------------------------- -# 3rd party dependency: boost: - -#xo_boost_dependency(${SELF_LIBRARY_NAME}) - -xo_install_library(${SELF_LIBRARY_NAME}) - -# end CMakeLists.txt diff --git a/.xo-reflect/include/xo/reflect/EstablishTypeDescr.hpp b/.xo-reflect/include/xo/reflect/EstablishTypeDescr.hpp deleted file mode 100644 index e461a91a..00000000 --- a/.xo-reflect/include/xo/reflect/EstablishTypeDescr.hpp +++ /dev/null @@ -1,76 +0,0 @@ -/* file EstablishTypeDescr.hpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#pragma once - -#include "TypeDescr.hpp" -#include "TaggedPtr.hpp" - -namespace xo { - namespace reflect { - /** @class EstablishTypeDescr - * @brief class to establish globally-unique TypeDescr object for a type T - * - * We don't require the full definition of T to use EstablishTypeDescr::establish(). - * In particular, a forward declaration is sufficient. - * - * Additional information (that depends on full definition) may be attached later, - * by assigning (once-only) to @ref TypeDescr::tdextra_ - * - * @note Application code will use @ref Reflect::require; that in turn relies on the - * template @ref EstablishTdx to leverage template pattern-matching for - * recurring patterns. - **/ - class EstablishTypeDescr { - public: - /* implementation method; expect this to be used only within reflect/ library. - * avoids some otherwise-cyclic #include paths - * between specialized headers such as vector/VectorTdx.hpp and this - * EstablishTypeDescr.hpp - */ -#ifdef OBSOLETE - template - static TaggedPtr establish_tp(T * x) { return TaggedPtr(establish(), x); } -#endif - template - static TaggedPtr establish_most_derived_tp(T * x) { return establish()->most_derived_self_tp(x); } - - template - static TypeDescrW establish() { - static TypeDescrW td = TypeDescrBase::require(&typeid(T), - std::string(type_name()), - nullptr /*tdextra*/, - nullptr /*invoker*/); - -#ifdef NOT_USING - std::function to_self_tp; - - if (std::is_base_of_v) { - /* T is a descendant of SelfTagging (or T = SelfTagging); - * use SelfTagging.self_tp() - */ - to_self_tp = [](void * x) { return reinterpret_cast(x)->self_tp(); }; - } else { - /* T is not a descendant of SelfTagging. - * want to return - */ - to_self_tp = [td](void * x) { return TaggedPtr(td, x); }; - } - - td->assign_to_self_tp(to_self_tp); -#endif - return td; - } - }; /*EstablishTypeDescr*/ - - template - inline TaggedPtr establish_most_derived_tp(T * x) { - return EstablishTypeDescr::establish_most_derived_tp(x); - } - } /*namespace reflect*/ -} /*namespace xo*/ - - -/* end EstablishTypeDescr.hpp */ diff --git a/.xo-reflect/include/xo/reflect/Metatype.hpp b/.xo-reflect/include/xo/reflect/Metatype.hpp deleted file mode 100644 index 549d098e..00000000 --- a/.xo-reflect/include/xo/reflect/Metatype.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/* @file Metatype.hpp */ - -#pragma once - -#include - -namespace xo { - namespace reflect { - enum class Metatype { mt_invalid, mt_atomic, mt_pointer, mt_vector, mt_struct, mt_function }; - - inline std::ostream & operator<<(std::ostream & os, - Metatype x) { - switch(x) { - case Metatype::mt_invalid: - os << "invalid!"; - break; - case Metatype::mt_atomic: - os << "atomic"; - break; - case Metatype::mt_pointer: - os << "pointer"; - break; - case Metatype::mt_vector: - os << "vector"; - break; - case Metatype::mt_struct: - os << "struct"; - break; - case Metatype::mt_function: - os << "function"; - break; - default: - os << "???"; - } - return os; - } /*operator<<*/ - - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end Metatype.hpp */ diff --git a/.xo-reflect/include/xo/reflect/Object.hpp b/.xo-reflect/include/xo/reflect/Object.hpp deleted file mode 100644 index 768b6058..00000000 --- a/.xo-reflect/include/xo/reflect/Object.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/** @file Object.hpp - * - * Author: Roland Conybeare - **/ - -#pragma once - -#include "xo/reflect/SelfTagging.hpp" -//#include - -namespace xo { - namespace reflect { - /** @class Object - * - * @brief A swiss-army-knife base class for runtime polymorphism. - * - * Promote using this: - * - for interpreter integration (see xo-expression / xo-jit) - * - to allow reasonably efficient type dispatching - - * don't need to pay for a function call to find out dispatching type. - **/ - class Object : public reflect::SelfTagging { - public: - Object(TypeId type_id) : type_id_{type_id} {} - - private: - /** unique id number for this object's type - * - * Caches the value of this->self_tp().td()->id() - * - * Notes: - * 1. may want to record metatype also - * 2. a few builtin types have well-known type_ids. - * see TypeDescrTable ctor in xo-reflect. - **/ - TypeId type_id_; - }; - - } /*namespace obj*/ -} /*namespace xo*/ - - -/** end Object.hpp **/ diff --git a/.xo-reflect/include/xo/reflect/Reflect.hpp b/.xo-reflect/include/xo/reflect/Reflect.hpp deleted file mode 100644 index 52213dd8..00000000 --- a/.xo-reflect/include/xo/reflect/Reflect.hpp +++ /dev/null @@ -1,421 +0,0 @@ -/* file Reflect.hpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#pragma once - -#include "SelfTagging.hpp" -#include "EstablishTypeDescr.hpp" -#include "atomic/AtomicTdx.hpp" -#include "pointer/PointerTdx.hpp" -#include "vector/VectorTdx.hpp" -#include "struct/StructTdx.hpp" -#include "function/FunctionTdx.hpp" -#include "xo/refcnt/Refcounted.hpp" -#include -#include -#include // for std::pair<> - -namespace xo { - namespace reflect { - template - class EstablishTdx { - public: - /** Create auxiliary reflection info for type @tparam T, - * once full definition is available. - * - * This includes: - * - metatype - * - component structure (types for navigable component objects) - * - **/ - static std::unique_ptr make() { return AtomicTdx::make(); } - }; - - // ----- xo::ref::rp ----- - - template - class EstablishTdx> { - public: - /* definition provide after decl for Reflect {} below */ - static std::unique_ptr make(); - }; - - // ----- std::array ----- - - template - class EstablishTdx> { - public: - /* definition provide after decl for Reflect {} below */ - static std::unique_ptr make(); - }; - - // ----- std::vector ----- - - template - class EstablishTdx> { - public: - /* definition provide after decl for Reflect {} below */ - static std::unique_ptr make(); - }; - - // ----- std::pair ----- - - template - class EstablishTdx> { - public: - /* definition provide after decl for Reflect {} below */ - static std::unique_ptr make(); - }; - - // ----- Retval (*)(A1 .. An) ----- - - template - class EstablishTdx { - public: - /* definition provided after decl for Reflect {} below */ - static std::unique_ptr make(); - }; - - // ----- Retval (*)(A1 .. An) noexcept ----- - - template - class EstablishTdx { - public: - /* definition provided after decl for Reflect {} below */ - static std::unique_ptr make(); - }; - - // ----- EstasblishFunctionTdx ------------------------------------- - - template - class EstablishFunctionTdx; - - // ----- Retval (*)(A1 .. An) ----- - - template - class EstablishFunctionTdx { - public: - /* definition provided after decl for Reflect {} below */ - static std::unique_ptr make(); - }; - - template - class EstablishFunctionTdx { - public: - /* definition provided after decl for Reflect {} below */ - static std::unique_ptr make(); - }; - - // ----- MakeTagged ----- - - template - class TaggedPtrMaker { - public: - static TaggedPtr make_tp(T * x); - static TaggedRcptr make_rctp(T * x); - }; - - template<> - class TaggedPtrMaker { - public: - static TaggedPtr make_tp(SelfTagging * x) { - return x->self_tp(); - } /*make_tp*/ - - static TaggedRcptr make_rctp(SelfTagging * x) { - return x->self_tp(); - } /*make_rctp*/ - }; /*TaggedPtrMaker*/ - - // ----- Reflect ----- - - class Reflect { - public: - /* Use: - * using mytype = ...; - * if (Reflect::is_reflected()) { ... } - */ - template - static bool is_reflected() { return TypeDescrBase::is_reflected(&typeid(T)); } - - /* Use: - * using mytype = ...; - * TypeDescrW td = Reflect::require(); - * - * Note: - * To avoid cyclic header dependencies - * (between EstablishTypeDescr.hpp <-> {vector/VectorTdx.hpp etc.}, - * we use a 2-stage setup process: - * - * 1. EstablishTypeDescr::establish() creates a TypeDescr* object - * with lowest-common-denominator .tdextra AtomicTdx. - * (see [reflect/EstablishTypeDescr.hpp]) - * - * 2. Reflect::require() upgrades .tdextra to suitable implementation - * depending on T; this means also need to visit reflection info - * (TypeDescr objects) for nested types to upgrade them too. - * - * This allows template-fu for a compound type (like std::vector), - * implemented in specialized header (like [reflect/struct/VectorTdx.hpp]) to - * refer to reflection info for T without having to pull in all the - * headers needed to properly reflect T (like this [reflect/Reflect.hpp]) - * - */ - template - static TypeDescrW require() { - TypeDescrW retval_td = EstablishTypeDescr::establish(); - - /* mark TypeDescr for T as complete (even though it isn't quite yet), - * so that when we encounter recursive types, reflection terminates. - * For example consider type resulting from code like - * - * typename T; - * using T = std::vector; - * - */ - if (retval_td->mark_complete()) { - /* control here on 2nd+later calls to require(). - * in principle can immediately short-circuit. - */ - } else { - /* control comes here the first time require() runs */ - - auto final_tdx = EstablishTdx::make(); - - retval_td->assign_tdextra(Reflect::get_final_invoker(), - std::move(final_tdx)); - - /* also need to require for each child */ - } - - return retval_td; - } /*require*/ - - /* can optionally use this when reflecting a function pointer. - * Should get the same result as reflect(), - * but will not fallback to AtomicTdx if T is not recognized as a function pointer - */ - template - static TypeDescrW require_function() { - //static_assert(std::is_function_v); - - TypeDescrW retval_td = EstablishTypeDescr::establish(); - - /* mark TypeDescr for T as complete (even though it isn't quite yet), - * so that when we encounter recursive types, reflection terminates. - * For example consider type resulting from code like - * - * typename T; - * using T = std::vector; - * - */ - if (retval_td->mark_complete()) { - /* control here on 2nd+later calls to require(). - * in principle can immediately short-circuit. - */ - } else { - /* control comes here the first time require() runs */ - - auto final_tdx = EstablishFunctionTdx::make(); - - retval_td->assign_tdextra(Reflect::get_final_invoker(), - std::move(final_tdx)); - - /* also need to require for each child */ - } - - return retval_td; - } - - /** true iff @p src_td is a type-description for @tparam T **/ - template - static bool is_native(TypeDescr src_td) { - return (require() == src_td); - } - - /** given address @p src_address of a value with type described by @p src, - * return typed pointer of type @tparam T, provided that @p src_td - * actually describes @tparam T. Otherwise returns nullptr - **/ - template - static T * recover_native(TypeDescr src_td, void * src_address) { - return TaggedPtr(src_td, src_address).recover_native(); - } - - /* Use: - * T * xyz = ...; - * TaggedPtr xyz_tp = Reflect::make_tp(xyz); - */ - template - static TaggedPtr make_tp(T * x) { return TaggedPtrMaker::make_tp(x); } - - template - static TaggedRcptr make_rctp(T * x) { return TaggedPtrMaker::make_rctp(x); } - - template - static detail::InvokerAux * get_final_invoker() { - static detail::InvokerAux s_final_invoker; - - return &s_final_invoker; - } - }; /*Reflect*/ - - // ----- MakeTagged ----- - - template - TaggedPtr - TaggedPtrMaker::make_tp(T * x) { - return TaggedPtr(Reflect::require(), x); - } /*make_tp*/ - - template - TaggedRcptr - TaggedPtrMaker::make_rctp(T * x) { - return TaggedRcptr(Reflect::require(), x); - } /*make_rctp*/ - - // ----- xo::ref::rp ----- - - /* declared above before - * class Reflect { .. } - */ - template - std::unique_ptr - EstablishTdx>::make() { - /* need to ensure Object is property reflected. - * - * In practice must be a class type, since has to store refcount - * + supply assoc'd incr/decr methods - */ - Reflect::require(); - - return RefPointerTdx>::make(); - } /*make*/ - - // ----- std::array ----- - - /* declared above before - * class Reflect { .. } - */ - template - std::unique_ptr - EstablishTdx>::make() { - /* need to ensure Element is properly reflected */ - Reflect::require(); - - return StdArrayTdx::make(); - } /*make*/ - - // ----- std::vector ----- - - /* declared above before - * class Reflect { .. } - */ - template - std::unique_ptr - EstablishTdx>::make() { - /* need to ensure Element is properly reflected */ - Reflect::require(); - - return StdVectorTdx::make(); - } /*make*/ - - // ----- std::pair ----- - - /* declared above before - * class Reflect { .. } - */ - template - std::unique_ptr - EstablishTdx>::make() { - /* need to ensure Lhs, Rhs are properly reflected */ - Reflect::require(); - Reflect::require(); - - return StructTdx::pair(); - } /*make*/ - - // ----- Retval(A1 .. An) ----- - - namespace detail { - /** @class AssembleArgv - * @brief create vector of complete TypeDescr objects comprising all template arguments - * - * Use: - * std::vector v; - * AssembleArgv::append_argv(&v); - * // do something with v - **/ - template - struct AssembleArgv; - - template <> - struct AssembleArgv<> { - static void append_argv(std::vector * /*p_v*/) {} - }; - - template - struct AssembleArgv { - static void append_argv(std::vector * p_v) { - p_v->push_back(Reflect::require()); - AssembleArgv::append_argv(p_v); - } - }; - } /*detail*/ - - template - std::unique_ptr - EstablishFunctionTdx::make() { - std::vector argv; - detail::AssembleArgv::append_argv(&argv); - - return FunctionTdx::make_function(Reflect::require(), - std::move(argv), - false /*!is_noexcept*/); - } - - template - std::unique_ptr - EstablishFunctionTdx::make() { - std::vector argv; - detail::AssembleArgv::append_argv(&argv); - - return FunctionTdx::make_function(Reflect::require(), - std::move(argv), - true /*is_noexcept*/); - } - - /* declared above before - * class Reflect { ... } - */ - template - std::unique_ptr - EstablishTdx::make() { - std::vector argv; - detail::AssembleArgv::append_argv(&argv); - - return FunctionTdx::make_function(Reflect::require(), - std::move(argv), - false /*!is_noexcept*/); - } - - /* declared above before - * class Reflect { ... } - */ - template - std::unique_ptr - EstablishTdx::make() { - std::vector argv; - detail::AssembleArgv::append_argv(&argv); - - return FunctionTdx::make_function(Reflect::require(), - std::move(argv), - true /*is_noexcept*/); - } - - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end Reflect.hpp */ diff --git a/.xo-reflect/include/xo/reflect/SelfTagging.hpp b/.xo-reflect/include/xo/reflect/SelfTagging.hpp deleted file mode 100644 index 12eb279f..00000000 --- a/.xo-reflect/include/xo/reflect/SelfTagging.hpp +++ /dev/null @@ -1,31 +0,0 @@ -/* file SelfTagging.hpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#pragma once - -#include "xo/refcnt/Refcounted.hpp" -#include "TypeDescr.hpp" -#include "TaggedRcptr.hpp" - -namespace xo { - namespace reflect { - /* a self-tagging object uses reflection to preserve type information - * until runtime. Can use the reflected information to traverse - * object representation (e.g. for printing / serialization) - * without repetitive/bulky boilerplate. - * - * For pybind11 need to have concrete (non-template) apis, - * helpful to have various classes inherit SelfTagging - * - * For example see [printjson/PrintJson.hpp] - */ - class SelfTagging : public ref::Refcount { - public: - virtual TaggedRcptr self_tp() = 0; - }; /*SelfTagging*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end SelfTagging.hpp */ diff --git a/.xo-reflect/include/xo/reflect/StructReflector.hpp b/.xo-reflect/include/xo/reflect/StructReflector.hpp deleted file mode 100644 index b443950f..00000000 --- a/.xo-reflect/include/xo/reflect/StructReflector.hpp +++ /dev/null @@ -1,165 +0,0 @@ -/* @file StructReflector.hpp */ - -#pragma once - -#include "Reflect.hpp" -#include "TypeDescr.hpp" -#include "struct/StructMember.hpp" -#include "struct/StructTdx.hpp" -#include - -namespace xo { - namespace reflect { - template - class SelfTagger {}; - - template - struct SelfTagger { - static TaggedPtr self_tp(void * object) { - return (reinterpret_cast(object))->self_tp(); - } - }; - - template - struct SelfTagger { - static TaggedPtr self_tp(void * /*object*/) { assert(false); return TaggedPtr::universal_null(); } - }; - - /* RAII pattern for reflecting a struct. - * - * Use: - * struct Foo { int x_; double y_; }; - * - * StructReflector sr; - * REFLECT_LITERAL_MEMBER(sr, x_); - * REFLECT_LITERAL_MEMBER(sr, y_); - * - * // optional: regardless, reflection will be completed when sr goes out of scope - * sr.require_complete(); - */ - template - class StructReflector { - public: - using struct_t = StructT; - - public: - StructReflector() : td_{EstablishTypeDescr::establish()} {} - ~StructReflector() { - this->require_complete(); - } - - bool is_complete() const { return s_reflected_flag; } - bool is_incomplete() const { return !s_reflected_flag; } - TypeDescr td() const { return td_; } - - template - void reflect_member(std::string const & member_name, - MemberT OwnerT::* member_addr) { - - auto accessor - (GeneralStructMemberAccessor::make(member_addr)); - - /* used to do this in GeneralStructMemberAccessor<> ctor, - * but that introduces #include cycle - */ - Reflect::require(); - - this->member_v_.emplace_back(member_name, std::move(accessor)); - } /*reflect_member*/ - - void require_complete() { - if(!s_reflected_flag) { - s_reflected_flag = true; - - constexpr bool have_to_self_tp = std::is_base_of_v; - - /* if self-tagging, can use .self_tp() to get most-derived tagged pointer */ - auto to_self_tp_fn - = ([](void * object) - { - return SelfTagger::self_tp(object); - }); - - static detail::InvokerAux s_final_invoker; - - auto tdx = StructTdx::make(std::move(this->member_v_), - have_to_self_tp, - to_self_tp_fn); - - this->td_->assign_tdextra(&s_final_invoker, - std::move(tdx)); - } - } /*complete*/ - - template - void adopt_ancestors() { - assert(Reflect::is_reflected()); - - TypeDescr ancestor_td = Reflect::require(); - - /* requires that reflection of AncestorT has completed */ - { - assert(ancestor_td->is_struct()); - assert(ancestor_td->complete_flag()); - } - - /* for structs, - * we know that object argument to TypeDescr::n_child() is unused - */ - for (uint32_t i = 0, n = ancestor_td->n_child(nullptr); i < n; ++i) { - StructMember const & member = ancestor_td->struct_member(i); - - this->member_v_.push_back(member.for_descendant()); - } - } /*adopt_ancestors*/ - - private: - /* set irrevocably to true when .complete() runs. - * - * want to reflect a particular type once; - * short-circuit 2nd or later attempts on the same type - */ - static bool s_reflected_flag; - - /* type description object for StructT */ - TypeDescrW td_; - - /* members of StructT (at least those we're choosing to reflect) */ - std::vector member_v_; - }; /*StructReflector*/ - - template - bool StructReflector::s_reflected_flag = false; - } /*namespace reflect*/ - - /* e.g. - * struct Foo { int bar_; }; - * struct Bar : public Foo { .. }; - * - * StructReflector sr; - * REFLECT_EXPLICIT_MEMBER(sr, "bar", &Foo::bar_); - */ -#define REFLECT_EXPLICIT_MEMBER(sr, member_name, member) sr.reflect_member(member_name, member) - - /* e.g. - * struct Foo { int bar_; }; - * - * StructReflector sr; - * REFLECT_LITERAL_MEMBER(sr, bar_); - * - * then REFLECT_LITERAL_MEMBER() expands to something like: - * sr.reflect_member("bar_", &StructReflector::struct_t::bar_) - */ -#define REFLECT_LITERAL_MEMBER(sr, member_name) sr.reflect_member(#member_name, &decltype(sr)::struct_t::member_name) - - /* like REFLECT_LITERAL_MEMBER(), but append trailing underscore - * - * minor convenience, so we can write - * struct Foo { int bar_; }; - * - * StructReflector sr; - * REFLECT_MEMBER(sr, bar); // reflects Foo::bar_ as "bar" - */ -#define REFLECT_MEMBER(sr, member_name) sr.reflect_member(#member_name, &decltype(sr)::struct_t::member_name##_) - -} /*namespace xo*/ diff --git a/.xo-reflect/include/xo/reflect/TaggedPtr.hpp b/.xo-reflect/include/xo/reflect/TaggedPtr.hpp deleted file mode 100644 index fbffaa04..00000000 --- a/.xo-reflect/include/xo/reflect/TaggedPtr.hpp +++ /dev/null @@ -1,128 +0,0 @@ -/* @file TaggedPtr.hpp */ - -#pragma once - -#include "TypeDescr.hpp" -#include - -namespace xo { - namespace reflect { - class TaggedRcptr; /* see [reflect/TaggedRcptr.hpp] */ - - class TaggedPtr { - public: - TaggedPtr(TypeDescr td, void * x) : td_{td}, address_{x} {} - - static TaggedPtr universal_null() { return TaggedPtr(nullptr, nullptr); } - - /* would be clean to put make() here; - * however it leads to cyclic #include paths, - * so put it elsewhere - */ -#ifdef NOT_USING - template - static TaggedPtr make(T * x) { return TaggedPtr(Reflect::require(), x); } -#endif - - /* visit an object tree. calls preorder_visit_fn() on tp, - * and all objects reachable directly-or-indirectly from tp. - * will call preorder_visit_fn() multiple times if there are multiple paths - * to a node. - * - * require: no cycles in object graph -- undefined behavior if a cycle is present - */ - template - static void visit_tree_preorder(TaggedPtr tp, Fn && preorder_visit_fn) { - using std::uint32_t; - - preorder_visit_fn(tp); - - for(uint32_t i = 0, n = tp.n_child(); i < n; ++i) { - visit_tree_preorder(tp.get_child(i), preorder_visit_fn); - } - } /*visit_tree_preorder*/ - - /* visit object graph. calls preorder_visit_fn() on tp in depth-first - * order. detects and silently prunes duplicate/cyclic references. - */ - template - static void visit_graph(TaggedPtr tp, Fn && visit_fn) { - std::unordered_set visited_set; - - visit_graph_aux(tp, visit_fn, &visited_set); - } /*visit_graph*/ - - TypeDescr td() const { return td_; } - void * address() const { return address_; } - - void assign_td(TypeDescr x) { td_ = x; } - void assign_address(void * x) { address_ = x; } - - bool is_universal_null() const { return (td_ == nullptr) && (address_ == nullptr); } - bool is_pointer() const { return td_ && td_->is_pointer(); } - bool is_vector() const { return td_ && td_->is_vector(); } - bool is_struct() const { return td_ && td_->is_struct(); } - bool is_function() const { return td_ && td_->is_function(); } - - /* returns pointer-to-T, if in fact this tagged pointer is understood - * to refer to a T-instance; otherwise nullptr - */ - template - T * recover_native() const { return this->td_->recover_native2(this->td_, this->address_); } - - uint32_t n_child() const { - return this->td_->n_child(this->address_); - } - - TaggedPtr get_child(uint32_t i) const { - return this->td_->child_tp(i, this->address_); - } - - /* if reflected function (.is_function() = true): - * number of arguments to that function - */ - uint32_t n_fn_arg() const { return this->td_->n_fn_arg(); } - - /* require: - * - .is_struct() is true - */ - std::string const & struct_member_name(uint32_t i) const { - return this->td_->struct_member_name(i); - } - - private: - template - static void visit_graph_aux(TaggedPtr tp, - Fn && visit_fn, - std::unordered_set * p_visited_set) - { - if (tp.address() == nullptr) - return; - - if (p_visited_set->find(tp.address()) == p_visited_set->end()) { - p_visited_set->insert(tp.address()); - - visit_fn(tp); - - for (uint32_t i = 0, n = tp.n_child(); i < n; ++i) { - visit_graph_aux(tp.get_child(i), visit_fn, p_visited_set); - } - } - } /*visit_graph_aux*/ - - private: - friend class TaggedRcptr; - - private: - /* describes the actual type stored at *address. - * can be null if .address is null - */ - TypeDescr td_; - /* address with type information preserved at runtime */ - void * address_; - }; /*TaggedPtr*/ - - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end TaggedPtr.hpp */ diff --git a/.xo-reflect/include/xo/reflect/TaggedRcptr.hpp b/.xo-reflect/include/xo/reflect/TaggedRcptr.hpp deleted file mode 100644 index 5d051070..00000000 --- a/.xo-reflect/include/xo/reflect/TaggedRcptr.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* file TaggedRcptr.hpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#pragma once - -#include "TaggedPtr.hpp" -// causes #include cycle, reflect/Reflect.hpp includes this header -//#include "reflect/Reflect.hpp" -#include "xo/refcnt/Refcounted.hpp" - -namespace xo { - namespace reflect { - /* Tagged reference-counted pointer. - * Like TaggedPtr, but also maintains reference count. - * - * note that refcounting behavior is lost if assigned to a TaggedPtr variable! - */ - class TaggedRcptr : public TaggedPtr { - public: - using Refcount = ref::Refcount; - - public: - TaggedRcptr(TypeDescr td, Refcount * x) : TaggedPtr(td, x) { - ref::intrusive_ptr_add_ref(x); - } - TaggedRcptr(TaggedRcptr const & x) : TaggedPtr(x) { - ref::intrusive_ptr_add_ref(x.rc_address()); - } - TaggedRcptr(TaggedRcptr && x) : TaggedPtr(std::move(x)) { - /* since we're moving from x, need to make sure x.dtor - * doesn't decrement refcount - */ - x.assign_address(nullptr); - } - ~TaggedRcptr() { - ref::intrusive_ptr_release(this->rc_address()); - } - - /* causes #include cycle, see [reflect/Reflect.hpp] */ -#ifdef NOT_IN_USE - /* require: T --isa--> ref::Refcount */ - template - static TaggedRcptr make(T * x) { return TaggedRcptr(Reflect::require(), x); } -#endif - - Refcount * rc_address() const { - return reinterpret_cast(this->address()); - } /*rc_address*/ - - TaggedRcptr & operator=(TaggedRcptr const & rhs) { - Refcount * x = rhs.rc_address(); - Refcount * old = this->rc_address(); - - TaggedPtr::operator=(rhs); - - if (x != old) { - intrusive_ptr_release(old); - intrusive_ptr_add_ref(x); - } - - return *this; - } /*operator=*/ - - TaggedRcptr & operator=(TaggedRcptr && rhs) { - /* swap pointers + type descriptions; - * then don't need to touch refcounts - */ - std::swap(this->td_, rhs.td_); - std::swap(this->address_, rhs.address_); - - return *this; - } /*operator=*/ - - void display(std::ostream & os) const; - std::string display_string() const; - }; /*TaggedRcptr*/ - - inline std::ostream & operator<<(std::ostream & os, TaggedRcptr const & x) { - x.display(os); - return os; - } /*operator<<*/ - - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end TaggedRcptr.hpp */ diff --git a/.xo-reflect/include/xo/reflect/TypeDescr.hpp b/.xo-reflect/include/xo/reflect/TypeDescr.hpp deleted file mode 100644 index f22f96bd..00000000 --- a/.xo-reflect/include/xo/reflect/TypeDescr.hpp +++ /dev/null @@ -1,616 +0,0 @@ -/* @file TypeDescr.hpp */ - -#pragma once - -#include "TypeDescrExtra.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace xo { - namespace reflect { - class TaggedPtr; /* see [reflect/TaggedPtr.hpp] */ - - /* A reflected type is a type for which we keep information around at runtime - * Assign reflected types unique (within an executable) ids, - * allocating consecutively, starting from 1. - * Reserve 0 as a sentinel - */ - class TypeId { - public: - /* allocate a new TypeId value. - * promise: - * - retval.id() > 0 - */ - static TypeId allocate() { return TypeId(s_next_id++); } - - std::uint32_t id() const { return id_; } - - private: - explicit TypeId(std::uint32_t id) : id_{id} {} - - private: - static std::uint32_t s_next_id; - - /* unique index# for this type. - * 0 reserved for sentinel - */ - std::uint32_t id_ = 0; - }; /*TypeId*/ - - inline std::ostream & - operator<<(std::ostream & os, TypeId x) { - os << x.id(); - return os; - } /*operator<<*/ - - /* runtime description of a struct/class instance variable */ - class StructMember; - - class TypeDescrBase; - - using TypeDescr = TypeDescrBase const *; - using TypeDescrW = TypeDescrBase *; - - /* convenience wrapper for a std::type_info pointer. - * works properly with pybind11, since python doens't encounter - * native type_info pointer, it won't try to delete it. - */ - class TypeInfoRef { - public: - explicit TypeInfoRef(std::type_info const * tinfo) : tinfo_{tinfo} {} - TypeInfoRef(TypeInfoRef const & x) = default; - - /* use: - * TypeInfoRef tinfo = TypeInfoRef::make(); - */ - template - TypeInfoRef make() { return TypeInfoRef(&typeid(T)); } - - std::size_t hash_code() const { return this->tinfo_->hash_code(); } - char const * impl_name() const { return this->tinfo_->name(); } - - static bool is_equal(TypeInfoRef x, TypeInfoRef y) noexcept { - if (x.hash_code() != y.hash_code()) - return false; - - return ::strcmp(x.impl_name(), y.impl_name()) == 0; - } /*is_equal*/ - - private: - /* native type_info object for encapsulated type */ - std::type_info const * tinfo_ = nullptr; - }; /*TypeInfoRef*/ - - namespace detail { - struct Invoker { - virtual void dtor(void * addr) const = 0; - }; - - /** Auxiliary template for capturing destructor for type T, - * if it has one. - * - * Example - * T * p = new T(...); - * InvokerAux::dtor(p); - **/ - template - struct InvokerAux : public Invoker { - virtual void dtor(void * addr) const override { - T * obj = reinterpret_cast(addr); - - obj->~T(); - } - }; - - /** no dtor for void **/ - template<> - struct InvokerAux : public Invoker { - virtual void dtor(void *) const override {} - }; - - /** no dtor for function types **/ - template - struct InvokerAux : public Invoker { - virtual void dtor(void *) const override {} - }; - } /*namespace detail*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -namespace std { - template <> struct hash { - std::size_t operator()(xo::reflect::TypeInfoRef x) const noexcept { return x.hash_code(); } - }; -} /*namespace std*/ - -namespace xo { - namespace reflect { - inline bool operator==(TypeInfoRef x, TypeInfoRef y) { return TypeInfoRef::is_equal(x, y); } - inline bool operator!=(TypeInfoRef x, TypeInfoRef y) { return !TypeInfoRef::is_equal(x, y); } - -#ifdef NOT_IN_USE - namespace detail { - class HashTypeInfoRef { - public: - std::size_t operator()(TypeInfoRef x) const noexcept { return x.hash_code(); } - }; /*HashTypeInfoRef*/ - - class EqualTypeInfoRef { - public: - bool operator()(TypeInfoRef x, TypeInfoRef y) const noexcept { return TypeInfoRef::is_equal(x, y); } - }; /*EqualTypeInfoRef*/ - } /*namespace detail*/ -#endif - - /* hashable contents of a FunctionTdx instance (without requiring decl of TypeDescrExtra), - * for unique-ification of manually-constructed function types - */ - class FunctionTdxInfo { - public: - FunctionTdxInfo() = default; - FunctionTdxInfo(TypeDescr retval_td, - const std::vector & arg_td_v, - bool is_noexcept) - : retval_td_{retval_td}, - arg_td_v_{arg_td_v}, - is_noexcept_{is_noexcept} - {} - - /** compare two FunctionTdxInfo objects for equality - **/ - inline bool operator==(const FunctionTdxInfo & other) const noexcept { - if (retval_td_ != other.retval_td_) - return true; - if (arg_td_v_.size() != other.arg_td_v_.size()) - return false; - - for (std::size_t i = 0, n = arg_td_v_.size(); i < n; ++i) { - if (arg_td_v_[i] != other.arg_td_v_[i]) - return false; - } - - if (is_noexcept_ != other.is_noexcept_) - return false; - - return true; - } - - /** construct canonical description for this type - * will be like - * Retval(*)(Arg1,..,Argn) - **/ - std::string make_canonical_name() const; - - public: - /** function return value **/ - TypeDescr retval_td_ = nullptr; - /** function arguments, in positional order **/ - std::vector arg_td_v_; - /** true iff function promises never to throw **/ - bool is_noexcept_ = false; - }; /*FunctionTdxInfo*/ - - class TypeDescrExtra; - - /* run-time description for a native c++ type */ - class TypeDescrBase { - public: - using ppindentinfo = xo::print::ppindentinfo; - - public: - /* type-description objects for a type T is unique, - * --> can always use its address - */ - TypeDescrBase(TypeDescrBase const & x) = delete; - - /* test whether a type has been reflected. - * introducing this for unit testing - */ - static bool is_reflected(std::type_info const * tinfo) { - return (s_native_type_table_map.find(TypeInfoRef(tinfo)) - != s_native_type_table_map.end()); - } /*is_reflected*/ - - /* NOTE: - * implementation here will be defeated if std::type_info - * objects violate ODR. This occurs with clang + 2-level namespaces, - * so important to linke with --flat_namespace defined. - * See FAQ - * [Build Issues|Q2 - dynamic_cast> fails] - */ - static TypeDescrW require(const std::type_info * tinfo, - const std::string & canonical_name, - detail::Invoker * invoker, - std::unique_ptr tdextra); - - /** Create type-description for function from input ingredients. **/ - static TypeDescrW require_by_fn_info(const FunctionTdxInfo & fn_info); - - /** lookup type by canonical name **/ - static TypeDescr lookup_by_name(const std::string & canonical_name); - - /** print table of reflected types to os **/ - static void print_reflected_types(std::ostream & os); - /** print table of function types to os **/ - static void print_function_types(std::ostream & os); - - TypeId id() const { return id_; } - const std::type_info * native_typeinfo() const { return native_typeinfo_; } - const std::string & canonical_name() const { return canonical_name_; } - const std::string_view & short_name() const { return short_name_; } - bool complete_flag() const { return complete_flag_; } - TypeDescrExtra * tdextra() const { return tdextra_.get(); } - Metatype metatype() const { return tdextra_->metatype(); } - - /** true iff the type represented by _c *this is the same as the type - * represented by @tparam T - * - * Warning: comparing typeinfo address can give false negatives. - * suspect this is caused by problems coalescing linker symbols - * in the clang toolchain. - **/ - template - [[deprecated]] - bool is_native() const { - if (this->native_typeinfo()) { - /* reminder: typeid(T).name() is 'interesting' but not intended - * to be human-readable. It's not how compiler labels - * a type for a human reader - */ - return ((this->native_typeinfo() == &typeid(T)) - || (this->native_typeinfo()->hash_code() == typeid(T).hash_code()) - || (this->native_typeinfo()->name() == typeid(T).name())); - } else { - /** if this type was established via Reflect::require(), - * then .canonical_name is computed by type_name() - * - * (see demangle.hh in xo-refcnt, which post-processes __PRETTY_FUNCTION__ - * or __FUNCSIG__) - * - * To manually construct an equivalent type, - * it's necessary to: - * 1. construct a unique and unambiguous canonical name for the type - * 2. be aware that type will only be recognized as equivalent to - * a natively-reflected type if canonical name matches exactly. - **/ - - /** FOR NOW: give up. **/ - throw std::runtime_error("TypeDescrBase::is_native: not implemented for manually-constructed TypeDescr objects. Prefer is_native2()"); - } - } /*is_native*/ - - /** safe downcast -- like dynamic_cast<>, but does not require a source type. - * - * TODO: need variation on this to correctly-handle function types, - * since for exampple cast from void* -> void (*)() is not allowed - * - * WARNING: relies on deprecated is_native(). Application code should prefer any of: - * 1. recover_native2(src_td, src_address) - * 2. Reflect::recover_native(src_td, src_address) - * 3. TaggedPtr(src_td,src_address).recover_native() - * instead of src_td->recover_native() - * - * (note: awkwardness here is that we don't have access to {Reflect.hpp, TaggedPtr.hpp} - * from this .hpp file, since TypeDescr.hpp is included by those headers) - **/ - template - [[deprecated]] - T * recover_native(void * address) const { - if (this->is_native()) { - return reinterpret_cast(address); - } else { - return nullptr; - } - } /*recover_native*/ - - /** safe downcast -- like dynamic_cast<>, but does not require a source type. - * - * Application code should prefer TaggedPtr::recover_native() - * - * TODO: need variation on this to correctly-handle function types, - * since for exampple cast from void* -> void (*)() is not allowed - **/ - template - T * recover_native2(TypeDescr address_td, void * address) const { - if (this == address_td) { - return reinterpret_cast(address); - } else { - return nullptr; - } - } /*recover_native2*/ - - bool is_i128() const; - bool is_i64() const; - bool is_f64() const; - - bool is_pointer() const { return this->tdextra_->is_pointer(); } - bool is_vector() const { return this->tdextra_->is_vector(); } - bool is_struct() const { return this->tdextra_->is_struct(); } - bool is_function() const { return this->tdextra_->is_function(); } - - /* given a T-instance object, return tagged pointer with T replaced - * by the most-derived-subtype of T to which *object belongs. - * This works only for descendants of reflect::SelfTagging - */ - TaggedPtr most_derived_self_tp(void * object) const; - - /* if generalized vector (std::vector, std::array, ..): - * .n_child() reports #of elements - * if struct/class: - * .n_child() reports #of instance variables (that have been reflected) - */ - uint32_t n_child(void * object) const { return this->tdextra_->n_child(object); } - /** number of children, if that number is fixed at compile time. otherwise 0 - **/ - uint32_t n_child_fixed() const { return this->tdextra_->n_child_fixed(); } - /** TypeDescr for i'th child, using only information available at compile time. - * e.g. for vectors/pointers, always returns ElementType. - **/ - TypeDescr fixed_child_td(uint32_t i) const { return this->tdextra_->fixed_child_td(i); } - /** TaggedPtr to child @p i. - * Will report most-derived-type for type tag, - * so may refer to a proper subtype (e.g. derived class) of the type - * reported by @c fixed_child_td(i) - **/ - TaggedPtr child_tp(uint32_t i, void * object) const; - - /* require: - * - .is_struct() = true - * - i in [0 .. .n_child() - 1] - */ - std::string const & struct_member_name(uint32_t i) const { - return this->tdextra_->struct_member_name(i); - } - - /* fetch runtime description for i'th reflected instance variable. - * - * require: - * - .is_struct() = true - * - i in [0 .. .n_child() - 1] - */ - StructMember const & struct_member(uint32_t i) const { - StructMember const * sm = this->tdextra_->struct_member(i); - - assert(sm); - return *sm; - } /*struct_member*/ - - /** nullptr for non-function types **/ - const FunctionTdxInfo * fn_info() const { return this->tdextra_->fn_info(); } - uint32_t n_fn_arg() const { return this->tdextra_->n_fn_arg(); } - - /* require: - * - .is_function() = true - */ - TypeDescr fn_retval() const { return this->tdextra_->fn_retval(); } - TypeDescr fn_arg(uint32_t i) const { return this->tdextra_->fn_arg(i); } - bool fn_is_noexcept() const { return this->tdextra_->fn_is_noexcept(); } - - /** pretty-printer support, using @p ppii **/ - bool pretty(const ppindentinfo & ppii) const; - - void display(std::ostream & os) const; - std::string display_string() const; - - /* mark this TypeDescr complete; - * returns the value of .complete_flag from _before_ - * this call - */ - bool mark_complete(); - - /* call this once to attach extended type information to a type-description - * (e.g. description of struct members for a record type) - */ - void assign_tdextra(detail::Invoker * invoker, - std::unique_ptr tdx) { - this->complete_flag_ = true; - this->invoker_ = invoker; - this->tdextra_ = std::move(tdx); - } - - // ----- actions ----- - - private: - TypeDescrBase(TypeId id, - const std::type_info * tinfo, - const std::string & canonical_name, - std::unique_ptr tdextra, - detail::Invoker * invoker); - - void assign_native_tinfo(const std::type_info * tinfo) { - assert(!native_typeinfo_); - native_typeinfo_ = tinfo; - } - - private: - /* invariant: - * - for all TypeDescrImpl instances x: - * - s_type_table_v[x->id()] = x - * - s_native_type_table_map[TypeInfoRef(x->typeinfo())] = x - */ - - /** vector of all TypeDescr instances, indexed by TypeId. singleton. **/ - static std::vector> s_type_table_v; - - /** hashmap of all TypeDescr instances, - * indexed by canonical_name. - * - * For manually-constructed TypeDescr instances - * (see xo-expression for use-case) we require: - * - * - TypeDescr::canonical_name uniquely identifies type - * - to interact with an actually-equivalent type T - * constructed by c++ compiler, we need - * to use the same canonical name that the compiler uses. - * - * See type xo::reflect::type_name<>() [in demangle.hpp under xo-refcnt] - * for implementation - **/ - static std::unordered_map s_canonical_type_table_map; - - /** hashmap of all native TypeDescr instances, - * indexed by typeinfo. singleton. - **/ - static std::unordered_map s_native_type_table_map; - - /** hashmap of (presumed) duplicate TypeInfoRef values. - * This happens with clang sometimes when the same type is referenced - * from multiple modules (i.e. shared libs). - **/ - static std::unordered_map s_coalesced_type_table_map; - - /** map from a vector of TypeDescr objects: - * [Retval, Arg1, ...Argn] - * to TypeDescr for function type - * Retval(*)(Arg1..Argn) - * - * Use these to unique-ify function types across: - * - types sourced natively from c++ compiler - * - types manually constructed (e.g. see Lambda.cpp in xo-expression) - **/ - static std::unordered_map s_function_type_map; - - private: - /** unique id# for this type **/ - TypeId id_; - - /** typeinfo for type T, if available. nullptr otherwise. - * - * 1. Always available for type-descriptions constructed via Reflect::require. - * 2. Always missing for manually-constructed TypeDescr instances, for example - * see Lambda.cpp in xo-expression. - **/ - std::type_info const * native_typeinfo_ = nullptr; - - /** canonical name for this type (see demangle.hpp for type_name()) - * e.g. - * xo::option::Px2 - * - * NOTE: if we only had to deal with types created via Reflect::reflect(), - * then canonical_name could be string_view. For manually-constructed - * types, there is no compiler-generated C-string constant to reference, - * so need to use std::string here - **/ - std::string canonical_name_; - - /** substring .canonical_name, just after last ':' - * e.g. - * Px2 - **/ - std::string_view short_name_; - - /** set to true once final value for .tdextra is established - * intially all TypeDescr objects will use AtomicTdx for .tdextra - * Reflect::require() upgrades .tdextra for particular types. - * When that procedure makes a decision for a type T, - * .complete_flag will be set to true for the corresponding TypeDescrBase instance - **/ - bool complete_flag_ = false; - - /** capture basic instance-management operations for this type. - * Given an instance T x: - * - invoker_->dtor(&x) invokes T::~T() - **/ - detail::Invoker * invoker_; - - /** additional type information that either: - * (a) isn't universal across all types, - * e.g. dereferencing instance of a pointer type - * (b) can't be captured with template-fu, - * e.g. struct member names - * - * generally .tdextra will be populated some time after TypeDescrBase's ctor exits. - * This is necessary because of (b) above, also because of possibility of recursive - * types. - **/ - std::unique_ptr tdextra_; - }; /*TypeDescrBase*/ - - inline std::ostream & - operator<<(std::ostream & os, const TypeDescrBase & x) { - x.display(os); - return os; - } /*operator<<*/ - - inline std::ostream & - operator<<(std::ostream & os, const TypeDescrBase * p) { - if (p) - p->display(os); - else - os << ""; - return os; - } - - /* tag to drive overload resolution */ - struct reflected_types_printer {}; - - inline std::ostream & - operator<<(std::ostream & os, reflected_types_printer) { - TypeDescrBase::print_reflected_types(os); - return os; - } - - class TypeDescrTable { - public: - TypeDescrTable * instance() { return &s_instance; } - - private: - /** initialize with builtin atomic types: - * float, double, char, short, int, long, bool - **/ - TypeDescrTable(); - - private: - static TypeDescrTable s_instance; - }; - } /*namespace reflect*/ - - namespace print { - template <> - struct ppdetail { - static bool print_pretty(const ppindentinfo & ppii, - const xo::reflect::TypeDescrBase & td) { - return td.pretty(ppii); - } - }; - - template <> - struct ppdetail { - static bool print_pretty(const ppindentinfo & ppii, - xo::reflect::TypeDescr td) { - return td ? td->pretty(ppii) : true; - } - }; - } /*namespace print*/ -} /*namespace xo*/ - -namespace std { - /** @brief overload for hashing xo::reflect::FunctionTdxInfo objects - **/ - template <> - struct hash { - inline size_t operator()(const xo::reflect::FunctionTdxInfo & x) const noexcept { - /* we can hash on addresses, since TypeDescr objects are immutable */ - std::size_t h = hash{}(x.retval_td_); - - for (std::size_t i = 0, n = x.arg_td_v_.size(); i < n; ++i) { - h = (h << 1) ^ hash{}(x.arg_td_v_[i]); - } - - h = (h << 1) ^ (x.is_noexcept_ ? 1 : 0); - - return h; - } - }; -} - -/* end TypeDescr.hpp */ diff --git a/.xo-reflect/include/xo/reflect/TypeDescrExtra.hpp b/.xo-reflect/include/xo/reflect/TypeDescrExtra.hpp deleted file mode 100644 index f53508ae..00000000 --- a/.xo-reflect/include/xo/reflect/TypeDescrExtra.hpp +++ /dev/null @@ -1,91 +0,0 @@ -/* @file TypeDescrExtra.hpp */ - -#pragma once - -#include "Metatype.hpp" -#include -/* note: this file #include'd into TypeDescr.hpp */ -#include - -namespace xo { - namespace reflect { - /* forward-declaring here. see [reflect/struct/StructMember.hpp] */ - class StructMember; - class FunctionTdxInfo; - class TypeDescrBase; - class TaggedPtr; - - /* information associated with a c++ type. - * distinct from TypeDescrImpl: - * 1. want to use reflection to support for runtime polymorphism over similar but - * not directly-related types: for example - * std::vector - * and - * std::list - * are both ordered collections - * 2. some information can't be universally established via template-fu, - * for example struct member names - * 3. descriptions for recursive types require 2-stage construction - * - * A TypeDescrImpl instance will contain a pointer to a suitable - * TypeDescrExtra instance. - * - * The single TypeDescrImpl instance for some type T can be established - * automatically, see Reflect::require(). - * - * A specific TypeDescrExtra instance may be attached in a non-automated way - * later - */ - class TypeDescrExtra { - public: - using uint32_t = std::uint32_t; - - public: - virtual ~TypeDescrExtra() = default; - - bool is_pointer() const { return this->metatype() == Metatype::mt_pointer; } - bool is_vector() const { return this->metatype() == Metatype::mt_vector; } - bool is_struct() const { return this->metatype() == Metatype::mt_struct; } - bool is_function() const { return this->metatype() == Metatype::mt_function; } - - virtual Metatype metatype() const = 0; - /* given a T-instance, report most-derived subtype of T to which *object belongs. - * this works only for types that are derived from reflect::SelfTagging. - */ - virtual TaggedPtr most_derived_self_tp(TypeDescrBase const * object_td, void * object) const; - virtual uint32_t n_child(void * object) const = 0; - /** number of children, fixed at compile time. - * Will return 0 for types like std::vector<..> (because number is unknown); - * Will also return 0 for types like {bool, int, long} (because number is zero) - **/ - virtual uint32_t n_child_fixed() const = 0; - /** type description for i'th child, based on information available at compile time. - * For vectors/pointers, this always refers to element type. - * - * nullptr for atomics - **/ - virtual const TypeDescrBase * fixed_child_td(uint32_t i) const = 0; - virtual TaggedPtr child_tp(uint32_t i, void * object) const = 0; - /* require: - * .is_struct() - */ - virtual std::string const & struct_member_name(uint32_t i) const = 0; - /* nullptr unless *this represents a struct/class type */ - virtual StructMember const * struct_member(uint32_t i) const; - - // methods for working with reflected functions/methods - - /** number of arguments to function-like value - * - * @pre @ref TypeDescrExtra::is_function() is true - **/ - virtual const FunctionTdxInfo * fn_info() const { return nullptr; } - virtual const TypeDescrBase * fn_retval() const { return nullptr; } - virtual uint32_t n_fn_arg() const { return 0; } - virtual const TypeDescrBase * fn_arg(uint32_t /*i_arg*/) const { return nullptr; } - virtual bool fn_is_noexcept() const { return false; } - }; /*TypeDescrExtra*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end TypeDescrExtra.hpp */ diff --git a/.xo-reflect/include/xo/reflect/TypeDrivenMap.hpp b/.xo-reflect/include/xo/reflect/TypeDrivenMap.hpp deleted file mode 100644 index 2568887d..00000000 --- a/.xo-reflect/include/xo/reflect/TypeDrivenMap.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* @file TypeDrivenMap.hpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#pragma once - -#include "TypeDescr.hpp" -#include - -namespace xo { - namespace reflect { - /* represents a map :: TypeId -> Value */ - template - class TypeDrivenMap { - public: - TypeDrivenMap() = default; - - const Value * lookup(TypeId id) const { return this->lookup_slot(id); } - const Value * lookup(TypeDescr td) const { return this->lookup_slot(td->id()); } - - Value * require(TypeId id) { return this->require_slot(id); } - Value * require(TypeDescr td) { return this->require_slot(td->id()); } - - private: - const Value * lookup_slot(TypeId id) const { - if (contents_v_.size() <= id.id()) - return nullptr; - - return &(this->contents_v_[id.id()]); - } /*lookup_slot*/ - - Value * require_slot(TypeId id) { - if (contents_v_.size() <= id.id()) - this->contents_v_.resize(id.id() + 1); - - return &(this->contents_v_[id.id()]); - } /*require_slot*/ - - private: - /* since TypeId/s are unique, compact sequence numbers, - * can efficiently store mapping to Values using a vector indexed by TypeId - */ - std::vector contents_v_; - }; /*TypeDrivenMap*/ - } /*namespace reflect*/ -} /*namespace xo*/ - - -/* end TypeDrivenMap.hpp */ diff --git a/.xo-reflect/include/xo/reflect/atomic/AtomicTdx.hpp b/.xo-reflect/include/xo/reflect/atomic/AtomicTdx.hpp deleted file mode 100644 index d5068199..00000000 --- a/.xo-reflect/include/xo/reflect/atomic/AtomicTdx.hpp +++ /dev/null @@ -1,39 +0,0 @@ -/* @file AtomicTdx.hpp */ - -#pragma once - -#include "xo/reflect/TypeDescrExtra.hpp" -//#include "reflect/TaggedPtr.hpp" -#include - -namespace xo { - namespace reflect { - class TaggedPtr; - - /* Extra type-associated information for an atomic type. - * We use this as degenerate catch-all case for types that aren't known - * to have additional structure (std::vector, std::map, int*, etc.) - */ - class AtomicTdx : public TypeDescrExtra { - public: - virtual ~AtomicTdx() = default; - - static std::unique_ptr make(); - - // ----- Inherited from TypeDescrExtra ----- - - virtual Metatype metatype() const override { return Metatype::mt_atomic; } - virtual uint32_t n_child(void * /*object*/) const override { return 0; } - virtual uint32_t n_child_fixed() const override { return 0; } - virtual TaggedPtr child_tp(uint32_t /*i*/, void * /*object*/) const override; - virtual const TypeDescrBase * fixed_child_td(uint32_t /*i*/) const override; - virtual std::string const & struct_member_name(uint32_t i) const override; - //virtual StructMember const * struct_member(uint32_t /*i*/) const override { return nullptr; } - - private: - AtomicTdx() = default; - }; /*TypeDescrExtra*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end AtomicTdx.hpp */ diff --git a/.xo-reflect/include/xo/reflect/function/FunctionTdx.hpp b/.xo-reflect/include/xo/reflect/function/FunctionTdx.hpp deleted file mode 100644 index 02f60558..00000000 --- a/.xo-reflect/include/xo/reflect/function/FunctionTdx.hpp +++ /dev/null @@ -1,58 +0,0 @@ -/** @file FunctionTdx.hpp - * - * Author: Roland Conybeare - **/ - -#pragma once - -#include "xo/reflect/TypeDescrExtra.hpp" -#include "xo/reflect/EstablishTypeDescr.hpp" - -namespace xo { - namespace reflect { - /** Additional type-associated information for a function/procedure **/ - class FunctionTdx : public TypeDescrExtra { - public: - virtual ~FunctionTdx() = default; - - /** create instance. Will be invoked exactly once for each reflected function type - * - * @param retval_td. type description for return value - * @param arg_td_v. type descriptions for arguments, in positional order - * @param is_noexcept. true iff function marked noexcept - **/ - static std::unique_ptr make_function(TypeDescr retval_td, - std::vector arg_td_v, - bool is_noexcept); - /** create instance from FunctionTdxInfo - * @param fn_info. function ingredients -- return type, arg types, noexcept - **/ - static std::unique_ptr make_function(const FunctionTdxInfo & fn_info); - - // ----- Inherited from TypeDescrExtra ----- - - virtual Metatype metatype() const override { return Metatype::mt_function; } - virtual uint32_t n_child(void * /*object*/) const override { return 0; } - virtual uint32_t n_child_fixed() const override { return 0; } - virtual TaggedPtr child_tp(uint32_t i, void * object) const override; - virtual TypeDescr fixed_child_td(uint32_t i) const override; - const std::string & struct_member_name(uint32_t i) const override; - - virtual const FunctionTdxInfo * fn_info() const override { return &info_; } - virtual TypeDescr fn_retval() const override { return info_.retval_td_; } - virtual uint32_t n_fn_arg() const override { return info_.arg_td_v_.size(); } - virtual TypeDescr fn_arg(uint32_t i) const override { return info_.arg_td_v_[i]; } - virtual bool fn_is_noexcept() const override { return info_.is_noexcept_; } - - private: - FunctionTdx(const FunctionTdxInfo & fn_info); - - private: - /** ingredients in complete function type description **/ - FunctionTdxInfo info_; - }; /*FunctionTdx*/ - } /*namespace reflect*/ -} /*namespace xo*/ - - -/** end FunctionTdx.hpp **/ diff --git a/.xo-reflect/include/xo/reflect/init_reflect.hpp b/.xo-reflect/include/xo/reflect/init_reflect.hpp deleted file mode 100644 index 5f69eadd..00000000 --- a/.xo-reflect/include/xo/reflect/init_reflect.hpp +++ /dev/null @@ -1,22 +0,0 @@ -/* file init_reflect.hpp - * - * author: Roland Conybeare, Sep 2022 - */ - -#pragma once - -#include "xo/subsys/Subsystem.hpp" - -namespace xo { - /* tag to represent the reflect/ subsystem within ordered initialization */ - enum S_reflect_tag {}; - - template<> - struct InitSubsys { - static void init(); - static InitEvidence require(); - }; -} /*namespace xo*/ - - -/* end init_reflect.hpp */ diff --git a/.xo-reflect/include/xo/reflect/pointer/PointerTdx.hpp b/.xo-reflect/include/xo/reflect/pointer/PointerTdx.hpp deleted file mode 100644 index 4484c6ed..00000000 --- a/.xo-reflect/include/xo/reflect/pointer/PointerTdx.hpp +++ /dev/null @@ -1,85 +0,0 @@ -/* file PointerTdx.hpp - * - * author: Roland Conybeare, Sep 2022 - */ - -#pragma once - -#include "xo/reflect/TypeDescrExtra.hpp" -#include "xo/reflect/EstablishTypeDescr.hpp" -#include "xo/indentlog/scope.hpp" - -namespace xo { - namespace reflect { - /* Extra type-associated information for a pointer-like type - * - * Treat a pointer as a container that has 0 or 1 children; - * - 0 children if null - * - 1 child otherwise - */ - class PointerTdx : public TypeDescrExtra { - public: - // ----- Inherited from TypeDescrExtra ----- - - virtual Metatype metatype() const override { return Metatype::mt_pointer; } - virtual uint32_t n_child(void * object) const override = 0; - - /* number of children unknown at compile time. - * null-pointer -> 0, non-null pointer -> 1 - */ - virtual uint32_t n_child_fixed() const override { return 0; /*unknown*/ } - virtual TaggedPtr child_tp(uint32_t i, void * object) const override = 0; - /* (forbidden) */ - virtual std::string const & struct_member_name(uint32_t i) const override; - }; /*PointerTdx*/ - - // ----- RefPointerTdx ----- - - /* Pointer = xo::ref::intrusive_ptr for some T */ - template - class RefPointerTdx : public PointerTdx { - public: - using target_t = Pointer; - - static std::unique_ptr make() { - return std::unique_ptr(new RefPointerTdx()); - } /*make*/ - - virtual uint32_t n_child(void * object) const override { - /* e.g: - * target_t = ref::rp - */ - target_t * ptr = reinterpret_cast(object); - - if (*ptr) - return 1; - else - return 0; - } /*n_child*/ - - virtual TypeDescrBase * fixed_child_td(uint32_t /*i*/) const override { - return EstablishTypeDescr::establish(); - } - - virtual TaggedPtr child_tp(uint32_t i, void * object) const override { - using xo::tostr; - using xo::xtag; - - target_t * ptr = reinterpret_cast(object); - - if (i > 0) { - throw std::runtime_error(tostr("RefPointerTdx::child_tp" - ": attempt to fetch child #i from a ref::rp", - xtag("T", type_name()), - xtag("i", i), - xtag("n", this->n_child(object)))); - } - - return establish_most_derived_tp(ptr->get()); - } /*child_tp*/ - }; /*RefPointerTdx*/ - - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end PointerTdx.hpp */ diff --git a/.xo-reflect/include/xo/reflect/reflect_struct.hpp b/.xo-reflect/include/xo/reflect/reflect_struct.hpp deleted file mode 100644 index 8c0c843a..00000000 --- a/.xo-reflect/include/xo/reflect/reflect_struct.hpp +++ /dev/null @@ -1,71 +0,0 @@ -/** @file reflect_struct.hpp - * - * Author: Roland Conybeare - **/ - -#pragma once - -#include "StructReflector.hpp" -#include "xo/reflectutil/reflect_struct_info.hpp" - -namespace xo { - namespace reflect { - namespace detail { - /** - * @pre reflect_struct_member will separately - * have been specialized for T. - * See discussion in [reflect_struct_info.hpp] - * - * - **/ - template - struct sr_member_helper { - /** reflect members starting from member with index number @tparam MemberIx - * - * @pre Members [0,..,MemberIx-1] must be already represented in @p *p_sr - **/ - static void add_members_from(StructReflector * p_sr) { - const auto & member_info - = reflect_struct_member().get(); - - p_sr->reflect_member(member_info.member_name_.c_str(), - member_info.member_addr_); - - /** reflect remaining members **/ - sr_member_helper::add_members_from(p_sr); - } - }; - - template - struct sr_member_helper { - /** base case -- all members have been refleccted **/ - static void add_members_from(StructReflector *) {} - }; - } /*namespace detail*/ - - - /** It's awkward to have Reflect::reflect<>() do the right thing, - * because there's no way to specialize on whether a type T is a struct. - * - * Use - * xo::reflect::Reflect::reflect_struct() instead - **/ - template - TypeDescr reflect_struct() { - StructReflector sr; - - if (sr.is_incomplete()) - detail::sr_member_helper::n_members>::add_members_from(&sr); - - /* TODO: handle composition: where T inherits another reflected type */ - /* TODO: handle multiple inheritance **/ - - return sr.td(); - } - } /*namespace reflect*/ -} /*namespace xo*/ - - -/** end reflect_struct.hpp **/ diff --git a/.xo-reflect/include/xo/reflect/struct/StructMember.hpp b/.xo-reflect/include/xo/reflect/struct/StructMember.hpp deleted file mode 100644 index 2e138a4f..00000000 --- a/.xo-reflect/include/xo/reflect/struct/StructMember.hpp +++ /dev/null @@ -1,236 +0,0 @@ -/* @file StructMember.hpp */ - -#pragma once - -#include "xo/reflect/TypeDescr.hpp" -#include "xo/reflect/EstablishTypeDescr.hpp" -#include "xo/reflect/TaggedPtr.hpp" -#include -#include - -namespace xo { - namespace reflect { - class AbstractStructMemberAccessor { - public: - virtual ~AbstractStructMemberAccessor() = default; - - /* get tagged pointer referring to this member of the object at *struct_addr */ - TaggedPtr member_tp(void * struct_addr) const; - - /* get type-description object for struct - * containing this member. useful for consistency checking. - */ - virtual TypeDescr struct_td() const = 0; - - /* get type-description object for this member - * e.g. if this member represents Foo::bar_ in - * struct Foo { int bar_; }; - * then - * .member_td() => Reflect::require(); - */ - virtual TypeDescr member_td() const = 0; - - /* get address of a particular member, given parent address */ - virtual void * address(void * struct_addr) const = 0; - - virtual std::unique_ptr clone() const = 0; - }; /*AbstractStructMemberAccessor*/ - - /* GeneralStructMemberAccessor - * - * Use this to handle access to possibly-inherited struct members: - * - * struct Foo { int x_; } - * struct Bar { char * y_; } - * struct Quux : public Foo, public Bar { bool z_; } - * - * want to be able to access Bar::y from a Quux instance. - * in example, would use GenericStructMemberAccessor<> - * with: - * StructT = Quux, - * OwnerT = Bar, - * MemberT = char* - * - * Require: - * StructT* is assignable to OwnerT* (because StructT --isa--> OwnerT) - */ - template - class GeneralStructMemberAccessor : public AbstractStructMemberAccessor { - public: - /* pointer to a OwnerT member of type MemberT */ - using Memptr = MemberT OwnerT::*; - - public: - GeneralStructMemberAccessor(Memptr memptr) - : member_td_{EstablishTypeDescr::establish()}, - memptr_{memptr} {} - GeneralStructMemberAccessor(GeneralStructMemberAccessor const & x) = default; - virtual ~GeneralStructMemberAccessor() = default; - - static std::unique_ptr make(Memptr memptr) { - return std::unique_ptr(new GeneralStructMemberAccessor(memptr)); } - - /* get member address given address of parent struct - * (i.e. from Struct*, not from OwnerT*) - */ - MemberT * address_impl(StructT * self_addr) const { - OwnerT * owner_addr = self_addr; - - return &(owner_addr->*memptr_); - } /*address_impl*/ - - // ----- Inherited from AbstractStructMemberAccessor ----- - -#ifdef OBSOLETE - virtual TaggedPtr member_tp(void * struct_addr) const override { - /* FIXME: this reports declared type of member, instead of - * (possibly narrower) actual type of member - */ - - return this->member_td_->most_derived_self_tp(this->address(struct_addr)); - //return TaggedPtr(this->member_td_, this->address(struct_addr)); - } /*member_tp*/ -#endif - - virtual TypeDescr struct_td() const override { return EstablishTypeDescr::establish(); } - - virtual TypeDescr member_td() const override { return this->member_td_; } - - virtual void * address(void * struct_addr) const override { - return this->address_impl(reinterpret_cast(struct_addr)); - } /*address*/ - - virtual std::unique_ptr clone() const override { - return std::unique_ptr - (new GeneralStructMemberAccessor(*this)); - } /*clone*/ - - private: - /* type description for MemberT; .memptr is pointer-to-member-of-OwnerT, - * where that member has type MemberT - */ - TypeDescr member_td_ = nullptr; - /* pointer to member of OwnerT */ - Memptr memptr_ = nullptr; - }; /*GeneralStructMemberAccessor*/ - - /* struct-member accessor via delegation, - * to accessor of a parent (or some other ancestor) class. - * - * struct Foo { int x_; } - * struct Bar { char * y_; } - * - * auto bar_x_access = GeneralStructMemberAccessor::make(&Foo::x_); - * - * or equivalently: - * auto foo_x_access = GeneralStructMemberAccessor::make(&Foo::x_); - * auto bar_x_access = AncestorStructMemberAccessor::adopt(foo_x_access); - * - * can use the 2nd form to adopt accessors from an already-reflected ancestor class - * - * Require: - * - StructT -isa-> AncestorT - */ - template - class AncestorStructMemberAccessor : public AbstractStructMemberAccessor { - public: - AncestorStructMemberAccessor(std::unique_ptr ancestor_accessor) - : ancestor_accessor_{std::move(ancestor_accessor)} {} - AncestorStructMemberAccessor(AncestorStructMemberAccessor const & x) = default; - virtual ~AncestorStructMemberAccessor() = default; - - static std::unique_ptr - adopt(std::unique_ptr ancestor_accessor) { - return std::unique_ptr - (new AncestorStructMemberAccessor(std::move(ancestor_accessor))); - } /*adopt*/ - - void * address_impl(StructT * self_addr) const { - /* to use access-via-ancestor, need to convert to ancestor pointer */ - AncestorT * ancestor_addr = self_addr; - - return this->ancestor_accessor_->address(ancestor_addr); - } /*address_impl*/ - - // ----- inherited from AbstractStructMemberAccessor ----- - -#ifdef OBSOLETE - virtual TaggedPtr member_tp(void * struct_addr) const override { - AncestorT * ancestor_addr = reinterpret_cast(struct_addr); - - return this->ancestor_accessor_->member_tp(ancestor_addr); - } /*member_tp*/ -#endif - - virtual TypeDescr struct_td() const override { return EstablishTypeDescr::establish(); } - virtual TypeDescr member_td() const override { return this->ancestor_accessor_->member_td(); } - - virtual void * address(void * struct_addr) const override { - return this->address_impl(reinterpret_cast(struct_addr)); - } - - virtual std::unique_ptr clone() const override { - return std::unique_ptr - (new AncestorStructMemberAccessor(std::move(this->ancestor_accessor_->clone()))); - } /*clone*/ - - private: - /* .ancestor_accessor fetches some particular member of AncestorT */ - std::unique_ptr ancestor_accessor_; - }; /*AncestorStructMemberAccessor*/ - - /* describes a member of a struct/class - * see [reflect/StructReflector.hpp] - */ - class StructMember { - public: - StructMember() = default; - StructMember(std::string const & name, - std::unique_ptr accessor) - : member_name_{name}, accessor_{std::move(accessor)} {} - StructMember(StructMember && x) - : member_name_{std::move(x.member_name_)}, - accessor_{std::move(x.accessor_)} {} - - static StructMember null(); - - std::string const & member_name() const { return member_name_; } - - TaggedPtr get_member_tp(void * struct_addr) const { return this->accessor_->member_tp(struct_addr); } - TypeDescr get_struct_td() const { return this->accessor_->struct_td(); } - TypeDescr get_member_td() const { return this->accessor_->member_td(); } - //void * get_member_addr(void * struct_addr) const { return this->accessor_->address(struct_addr); } - - /* make copy that accesses this member, but starting - * from pointer to some derived class DescendantT, - * instead of from container type StructT known to (but not exposed by) *this - */ - template - StructMember for_descendant() const { - assert(EstablishTypeDescr::establish() == this->get_struct_td()); - - return StructMember(this->member_name(), - std::move(AncestorStructMemberAccessor::adopt - (std::move(this->accessor_->clone())))); - } /*for_descendant*/ - - StructMember & operator=(StructMember && x) { - this->member_name_ = std::move(x.member_name_); - this->accessor_ = std::move(x.accessor_); - return *this; - } - - private: - /* member name, e.g. foo if - * struct StructT { MemberT foo; } - */ - std::string member_name_; - /* T recd; - * this->accessor_->address_impl(&recd) ==> &(recd.member) - */ - std::unique_ptr accessor_; - }; /*StructMember*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end StructMember.hpp */ diff --git a/.xo-reflect/include/xo/reflect/struct/StructTdx.hpp b/.xo-reflect/include/xo/reflect/struct/StructTdx.hpp deleted file mode 100644 index 57afe277..00000000 --- a/.xo-reflect/include/xo/reflect/struct/StructTdx.hpp +++ /dev/null @@ -1,98 +0,0 @@ -/* @file StructTdx.hpp */ - -#pragma once - -#include "xo/reflect/TypeDescrExtra.hpp" -#include "xo/reflect/TaggedPtr.hpp" -#include "StructMember.hpp" -//#include "xo/reflect/struct/StructMember.hpp" -#include -#include -#include - -namespace xo { - namespace reflect { - /* Extra type-associated information for a struct/class. - * We use this to preserve information about memory layout - * at runtime - */ - class StructTdx : public TypeDescrExtra { - public: - /* named ctor idiom. create new instance for struct with given member list - * - * to_self_tp. use this function to support .most_derived_self_tp() - */ - static std::unique_ptr make(std::vector member_v, - bool have_to_self_tp, - std::function to_self_tp); - - /* specialization for std::pair - * coordinates with [reflect/Reflect.hpp] - */ - template - static std::unique_ptr pair() { - using struct_t = std::pair; - - std::vector mv; - { - auto lhs_access - (GeneralStructMemberAccessor::make - (&struct_t::first)); - - mv.push_back(StructMember("first", std::move(lhs_access))); - } - { - auto rhs_access - (GeneralStructMemberAccessor::make - (&struct_t::second)); - - mv.push_back(StructMember("second", std::move(rhs_access))); - } - - std::function null_to_self_tp; - - return make(std::move(mv), - false /*!have_to_self_tp*/, - null_to_self_tp); - } /*pair*/ - - // ----- Inherited from TypeDescrExtra ----- - - virtual Metatype metatype() const override { return Metatype::mt_struct; } - virtual TaggedPtr most_derived_self_tp(TypeDescrBase const * object_td, - void * object) const override { - if (this->have_to_self_tp_) { - return this->to_self_tp_(object); - } else { - return TypeDescrExtra::most_derived_self_tp(object_td, object); - } - } - /* object argument ignored for structs, since size is fixed */ - virtual uint32_t n_child(void * /*object*/) const override { return this->member_v_.size(); } - virtual uint32_t n_child_fixed() const override { return this->member_v_.size(); } - virtual TaggedPtr child_tp(uint32_t i, void * object) const override; - virtual TypeDescr fixed_child_td(uint32_t i) const override; - virtual std::string const & struct_member_name(uint32_t i) const override; - virtual StructMember const * struct_member(uint32_t i) const override; - - private: - StructTdx(std::vector member_v, - bool have_to_self_tp, - std::function to_self_tp) - : member_v_{std::move(member_v)}, - have_to_self_tp_{have_to_self_tp}, - to_self_tp_{std::move(to_self_tp)} {} - - private: - /* per-instance-variable reflection details */ - std::vector member_v_; - /* true if .to_self_tp() is defined */ - bool have_to_self_tp_ = false; - /* get TaggedPtr for most-derived subtype of supplied T-instance */ - std::function to_self_tp_; - }; /*StructTdx*/ - - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end StructTdx.hpp */ diff --git a/.xo-reflect/include/xo/reflect/vector/VectorTdx.hpp b/.xo-reflect/include/xo/reflect/vector/VectorTdx.hpp deleted file mode 100644 index 0919e8fd..00000000 --- a/.xo-reflect/include/xo/reflect/vector/VectorTdx.hpp +++ /dev/null @@ -1,123 +0,0 @@ -/* file VectorTdx.hpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#pragma once - -#include "xo/reflect/TypeDescrExtra.hpp" -#include "xo/reflect/EstablishTypeDescr.hpp" - -namespace xo { - namespace reflect { - /* Extra type-associated information for a vector/array. - */ - class VectorTdx : public TypeDescrExtra { - public: - /* named ctor idiom. create new instance for a vector type */ - //static std::unique_ptr make(); - - /** @brief true if array elements are stored at regularly-spaced offsets **/ - virtual bool has_contiguous_storage() const = 0; - - // ----- Inherited from TypeDescrExtra ----- - - virtual Metatype metatype() const override { return Metatype::mt_vector; } - virtual uint32_t n_child(void * object) const override = 0; - virtual uint32_t n_child_fixed() const override = 0; - virtual TaggedPtr child_tp(uint32_t i, void * object) const override = 0; - virtual TypeDescr fixed_child_td(uint32_t i) const override = 0; - /* (forbidden) */ - virtual std::string const & struct_member_name(uint32_t i) const override; - }; /*VectorTdx*/ - - // ----- StlVectorTdx ----- - - /* require: - * - VectorT::value_type - * - VectorT.size() - * - VectorT[int] :: lvalue - */ - template - class StlVectorTdx : public VectorTdx { - public: - using target_t = VectorT; - - static std::unique_ptr make() { - return std::unique_ptr(new StlVectorTdx()); - } /*make*/ - - virtual bool has_contiguous_storage() const override { return true; } - - virtual uint32_t n_child(void * object) const override { - target_t * vec = reinterpret_cast(object); - - return vec->size(); - } /*n_child*/ - - virtual uint32_t n_child_fixed() const override { return 0; /*unknown*/ } - - virtual TaggedPtr child_tp(uint32_t i, void * object) const override { - target_t * vec = reinterpret_cast(object); - - return establish_most_derived_tp(&((*vec)[i])); - } /*child_tp*/ - - virtual TypeDescr fixed_child_td(uint32_t /*i*/) const override { - return EstablishTypeDescr::establish(); - } - }; /*StlVectorTdx*/ - - // ----- std::array ----- - - /* coordinates with EstablishTdx>::make(), - * see [reflect/Reflect.hpp] - */ - - template - class StdArrayTdx : public StlVectorTdx> { - virtual uint32_t n_child(void * /*object*/) const override { return N; } - virtual uint32_t n_child_fixed() const override { return N; } - }; /*StdArrayTdx*/ - - // ----- std::vector ----- - - /* coordinates with EstablishTdx>::make() - * see [reflect/Reflect.hpp] - */ - template - class StdVectorTdx : public VectorTdx { - public: - using target_t = std::vector; - - static std::unique_ptr make() { - return std::unique_ptr(new StdVectorTdx()); - } /*make*/ - - virtual bool has_contiguous_storage() const override { return true; } - - virtual uint32_t n_child(void * object) const override { - target_t * vec = reinterpret_cast(object); - - return vec->size(); - } /*n_child*/ - - virtual uint32_t n_child_fixed() const override { - return 0; /* not known without object */ - } - - virtual TaggedPtr child_tp(uint32_t i, void * object) const override { - target_t * vec = reinterpret_cast(object); - - return establish_most_derived_tp(&((*vec)[i])); - } - - virtual TypeDescr fixed_child_td(uint32_t /*i*/) const override { - return EstablishTypeDescr::establish(); - } - }; /*StdVectorTdx*/ - } /*namespace reflect*/ - -} /*namespace xo*/ - -/* end VectorTdx.hpp */ diff --git a/.xo-reflect/src/reflect/CMakeLists.txt b/.xo-reflect/src/reflect/CMakeLists.txt deleted file mode 100644 index c9a95d66..00000000 --- a/.xo-reflect/src/reflect/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# reflect/CMakeLists.txt - -set(SELF_LIB reflect) -set(SELF_SRCS - TypeDescr.cpp TypeDescrExtra.cpp TaggedRcptr.cpp - atomic/AtomicTdx.cpp - pointer/PointerTdx.cpp - vector/VectorTdx.cpp - struct/StructTdx.cpp struct/StructMember.cpp - function/FunctionTdx.cpp - init_reflect.cpp) - -xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) -xo_dependency(${SELF_LIB} refcnt) -xo_dependency(${SELF_LIB} indentlog) -xo_headeronly_dependency(${SELF_LIB} subsys) -#xo_boost_dependency(${SELF_LIB}) - -# end CMakeLists.txt diff --git a/.xo-reflect/src/reflect/TaggedRcptr.cpp b/.xo-reflect/src/reflect/TaggedRcptr.cpp deleted file mode 100644 index 8d68a60b..00000000 --- a/.xo-reflect/src/reflect/TaggedRcptr.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* file TaggedRcptr.cpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#include "TaggedRcptr.hpp" -#include "xo/indentlog/print/tag.hpp" - -namespace xo { - using xo::xtag; - using xo::tostr; - - namespace reflect { - void - TaggedRcptr::display(std::ostream & os) const - { - os << "td()->canonical_name()) - << xtag("addr", this->rc_address()) - << ">"; - } /*display*/ - - std::string - TaggedRcptr::display_string() const { - return tostr(*this); - } /*display_string*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end TaggedRcptr.cpp */ diff --git a/.xo-reflect/src/reflect/TypeDescr.cpp b/.xo-reflect/src/reflect/TypeDescr.cpp deleted file mode 100644 index c6cb1664..00000000 --- a/.xo-reflect/src/reflect/TypeDescr.cpp +++ /dev/null @@ -1,383 +0,0 @@ -/* @file TypeDescr.cpp */ - -#include "TypeDescr.hpp" -#include "TaggedPtr.hpp" -#include "TypeDescrExtra.hpp" -#include "Reflect.hpp" -#include "atomic/AtomicTdx.hpp" -#include "function/FunctionTdx.hpp" -#include "xo/indentlog/scope.hpp" - -namespace xo { - using xo::scope; - using xo::xtag; - using xo::tostr; - - namespace reflect { - uint32_t - TypeId::s_next_id = 1; - - std::string - FunctionTdxInfo::make_canonical_name() const - { - std::ostringstream ss; - - ss << retval_td_->canonical_name(); - ss << " (*)("; - for (std::size_t i = 0, n = arg_td_v_.size(); i < n; ++i) { - if (i > 0) - ss << ","; - ss << arg_td_v_[i]->canonical_name(); - } - ss << ")"; - - return ss.str(); - } /*make_canonical_name*/ - - // ----- TypeDescrBase ----- - - std::unordered_map - TypeDescrBase::s_function_type_map; - - std::unordered_map - TypeDescrBase::s_canonical_type_table_map; - - std::unordered_map - TypeDescrBase::s_native_type_table_map; - - std::unordered_map - TypeDescrBase::s_coalesced_type_table_map; - - std::vector> - TypeDescrBase::s_type_table_v; - - TypeDescrW - TypeDescrBase::require(const std::type_info * native_tinfo, - const std::string & canonical_name, - detail::Invoker * invoker, - std::unique_ptr tdextra) - { - scope log(XO_DEBUG(false)); - - log && log(xtag("canonical_name", canonical_name)); - - if (native_tinfo) { - /* 1. lookup by tinfo hash_code in s_type_table_map - * Not available for manually-constructed type descriptions. - */ - { - auto ix = s_native_type_table_map.find(TypeInfoRef(native_tinfo)); - - if ((ix != s_native_type_table_map.end()) && ix->second) { - log && log("TypeDescrBase::require" - ": using s_native_type_table_map[TypeInfoRef(native_tinfo)]"); - - return ix->second; - } - } - - /* 2. lookup by tinfo hash_code in s_coalesced_type_table_map */ - { - auto ix = s_coalesced_type_table_map.find(TypeInfoRef(native_tinfo)); - - if ((ix != s_coalesced_type_table_map.end()) && ix->second) { - log && log("TypeDescrBase::require" - ": using s_coalesced_type_table_map[TypeInfoRef(native_tinfo)]"); - - return ix->second; - } - } - } - - log && log("TypeDescrBase::require: try lookup by canonical name"); - - /* 3. lookup by canonical_name, before we create a new slot. - * - * Have to accept that on clang type_info objects aren't always unique (!$@#!!) - */ - { - auto ix = s_canonical_type_table_map.find(canonical_name); - - if (ix != s_canonical_type_table_map.end()) { - - /** assume existing slot, with same canonical name, - * represents the same type as native_tinfo - **/ - if (native_tinfo) { - auto existing_tinfo = ix->second->native_typeinfo(); - - /* given we have a match: - * - on existing TypeDescr - * - with same canonical name as type assoc'd with native_tinfo - * then: - * it's possible existing TypeDescr was manually constructed - * (i.e. without capturing std::type_info). - * - * With that in mind, attach that typeinfo now - */ - if (!existing_tinfo) { - ix->second->assign_native_tinfo(native_tinfo); - - s_native_type_table_map[TypeInfoRef(native_tinfo)] - = ix->second; - } - - if (existing_tinfo - && (existing_tinfo != native_tinfo)) - { - /* we have encountered distinct std::type_info objects - * that appear to represent the same type. - * (at least types with the same canonical name) - * - * We observe this happening sometimes with clang-prepared - * shared libraries; perhaps something going wrong with - * symbol coalescing. - * - * Store the dups in s_coalesced_type_table_map for future reference. - */ - auto jx = s_coalesced_type_table_map.find(TypeInfoRef(native_tinfo)); - - if (jx == s_coalesced_type_table_map.end()) - s_coalesced_type_table_map[TypeInfoRef(native_tinfo)] - = ix->second; - } - } - - return ix->second; - } - } - - /* when control here: - * need type added to: - * - s_type_table_v - * - s_canonical_type_table_map - * - s_native_type_table_map - * - s_coalesced_type_table_map (omit, only used for dups) - * - s_function_type_map (if type represents a function) - */ - - /* allocate slot for a new TypeDescr instance: */ - - TypeId new_td_id = TypeId::allocate(); - - log && log("TypeDescrBase::require", xtag("new_td_id", new_td_id)); - - if (s_type_table_v.size() <= new_td_id.id()) - s_type_table_v.resize(new_td_id.id() + 1); - - auto & new_slot = s_type_table_v[new_td_id.id()]; - - auto new_td = new TypeDescrBase(new_td_id, - native_tinfo, - canonical_name, - std::move(tdextra), - invoker); - - new_slot.reset(new_td); - - s_canonical_type_table_map[std::string(new_slot->canonical_name())] = new_td; - if (native_tinfo) - s_native_type_table_map[TypeInfoRef(native_tinfo)] = new_td; - - if (new_td->tdextra() && new_td->is_function()) { - s_function_type_map[*(new_td->fn_info())] = new_td; - } - - return new_slot.get(); - } /*require*/ - - TypeDescrW - TypeDescrBase::require_by_fn_info(const FunctionTdxInfo & fn_info) { - auto ix = s_function_type_map.find(fn_info); - - if (ix != s_function_type_map.end()) - return ix->second; - - auto fn_tdextra = FunctionTdx::make_function(fn_info); - - return require(nullptr /*native_tinfo - n/avail on this path*/, - fn_info.make_canonical_name(), - nullptr /*invoker*/, - std::move(fn_tdextra)); - } /*require_by_fn_info*/ - - TypeDescr - TypeDescrBase::lookup_by_name(const std::string & name) { - auto ix = s_canonical_type_table_map.find(name); - - if (ix == s_canonical_type_table_map.end()) { - throw std::runtime_error(tostr("TypeDescrBase::lookup_by_name" - ": no registered type with canonical name T", - xtag("T", name))); - } - - return ix->second; - } /*lookup_by_name*/ - - void - TypeDescrBase::print_reflected_types(std::ostream & os) - { - os << "display(os); - } - } - - os << ">\n"; - } /*print_reflected_types*/ - - namespace { - /* readability hack: - * foo::bar::Quux ==> Quux - * but lookout for template names: - * std::pair ==> pair - */ - std::string_view - unqualified_name(std::string_view const & canonical_name) - { - size_t m = canonical_name.find_first_of('<'); - - /* skip ':', but only in range [0..m) */ - size_t p = canonical_name.find_last_of(':', m); - - if (p == std::string_view::npos) { - return canonical_name; - } else { - if ((canonical_name.substr(0, 9) == "std::pair") - || (canonical_name.substr(0, 13) == "std::_1::pair")) - { - return std::string_view("pair"); - } else { - return std::string_view(canonical_name.substr(p+1)); - } - } - } /*unqualified_name*/ - } /*namespace*/ - - TypeDescrBase::TypeDescrBase(TypeId id, - const std::type_info * native_tinfo, - const std::string & canonical_name, - std::unique_ptr tdextra, - detail::Invoker * invoker) - : id_{std::move(id)}, - native_typeinfo_{native_tinfo}, - canonical_name_{std::move(canonical_name)}, - short_name_{unqualified_name(canonical_name_)}, - invoker_{invoker}, - tdextra_{std::move(tdextra)} - { - } - - bool - TypeDescrBase::is_i64() const - { - // FIXME: on apple/clang may need to use long long - - static_assert(sizeof(std::int64_t) == 8); - - return Reflect::is_native(this); - } - - bool - TypeDescrBase::is_f64() const - { - static_assert(sizeof(double) == 8); - - return Reflect::is_native(this); - } - - TaggedPtr - TypeDescrBase::most_derived_self_tp(void * object) const - { - return this->tdextra_->most_derived_self_tp(this, object); - } /*most_derived_self_tp*/ - - TaggedPtr - TypeDescrBase::child_tp(uint32_t i, void * object) const - { - return this->tdextra_->child_tp(i, object); - } /*child_tp*/ - - bool - TypeDescrBase::pretty(const ppindentinfo & ppii) const - { - return ppii.pps()->pretty_struct - (ppii, - "TypeDescr", - refrtag("id", id_), - refrtag("canonical_name", canonical_name_), - refrtag("complete", complete_flag_), - refrtag("metatype", this->metatype())); - - } - - void - TypeDescrBase::display(std::ostream & os) const - { - os << "metatype()) - << ">"; - } /*display*/ - - std::string - TypeDescrBase::display_string() const - { - return tostr(*this); - } /*display_string*/ - - bool - TypeDescrBase::mark_complete() - { - bool retval = this->complete_flag_; - - this->complete_flag_ = true; - - return retval; - } /*mark_complete*/ - -#ifdef NOT_USING - void - TypeDescrBase::assign_tdextra(std::unique_ptr tdx) - { - scope log(XO_ENTER0(verbose), - xtag("canonical_name", this->canonical_name()), - xtag("tdextra.old", this->tdextra_.get()), - xtag("metatype.old", (this->tdextra_ - ? this->tdextra_->metatype() - : Metatype::mt_invalid)), - xtag("metatype.new", tdx->metatype())); - - this->complete_flag_ = true; - this->tdextra_ = std::move(tdx); - } /*assign_tdextra*/ -#endif - - TypeDescrTable::TypeDescrTable() { - /* want long == i64 */ - static_assert(sizeof(long) == 8); - /* want double == f64 */ - static_assert(sizeof(double) == 8); - - Reflect::require(); - Reflect::require(); - Reflect::require(); - Reflect::require(); - Reflect::require(); - Reflect::require(); - Reflect::require(); - Reflect::require(); - Reflect::require(); - } /*ctor*/ - - TypeDescrTable - TypeDescrTable::s_instance; - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end TypeDescr.cpp */ diff --git a/.xo-reflect/src/reflect/TypeDescrExtra.cpp b/.xo-reflect/src/reflect/TypeDescrExtra.cpp deleted file mode 100644 index 9e82fc8e..00000000 --- a/.xo-reflect/src/reflect/TypeDescrExtra.cpp +++ /dev/null @@ -1,37 +0,0 @@ -/* file TypeDescrExtra.cpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#include "TypeDescrExtra.hpp" -#include "TypeDescr.hpp" -#include "TaggedPtr.hpp" -#include - -namespace xo { - namespace reflect { - TaggedPtr - TypeDescrExtra::most_derived_self_tp(TypeDescrBase const * object_td, - void * object) const - { - return TaggedPtr(object_td, object); - } /*most_derived_self_tp*/ - - std::string const & - TypeDescrExtra::struct_member_name(uint32_t /*i*/) const { - assert(false); - - static std::string s_null; - return s_null; - } /*struct_member_name*/ - - StructMember const * - TypeDescrExtra::struct_member(uint32_t /*i*/) const { - assert(false); - - return nullptr; - } /*struct_member*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end TypeDescrExtra.cpp */ diff --git a/.xo-reflect/src/reflect/atomic/AtomicTdx.cpp b/.xo-reflect/src/reflect/atomic/AtomicTdx.cpp deleted file mode 100644 index bb7e1b8d..00000000 --- a/.xo-reflect/src/reflect/atomic/AtomicTdx.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* @file AtomicTdx.cpp */ - -#include "atomic/AtomicTdx.hpp" -#include "TaggedPtr.hpp" -#include "TypeDescr.hpp" -#include - -namespace xo { - namespace reflect { - std::unique_ptr - AtomicTdx::make() { - return std::unique_ptr(new AtomicTdx()); - } /*make*/ - - TaggedPtr - AtomicTdx::child_tp(uint32_t /*i*/, void * /*object*/) const { - return TaggedPtr::universal_null(); - } /*child_tp*/ - - TypeDescr - AtomicTdx::fixed_child_td(uint32_t /*i*/) const { - return nullptr; - } - - std::string const & - AtomicTdx::struct_member_name(uint32_t i) const { - return TypeDescrExtra::struct_member_name(i); - } /*struct_member_name*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end AtomicTdx.cpp */ diff --git a/.xo-reflect/src/reflect/function/FunctionTdx.cpp b/.xo-reflect/src/reflect/function/FunctionTdx.cpp deleted file mode 100644 index 551cfef0..00000000 --- a/.xo-reflect/src/reflect/function/FunctionTdx.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* @file FunctionTdx.cpp */ - -#include "function/FunctionTdx.hpp" -#include "TaggedPtr.hpp" -#include "TypeDescr.hpp" - -namespace xo { - namespace reflect { - /** create instance. Will be invoked exactly once for each reflected function type **/ - std::unique_ptr - FunctionTdx::make_function(TypeDescr retval_td, - std::vector arg_td_v, - bool is_noexcept) - { - return make_function(FunctionTdxInfo(retval_td, - std::move(arg_td_v), - is_noexcept)); - } - - std::unique_ptr - FunctionTdx::make_function(const FunctionTdxInfo & fn_info) - { - return std::unique_ptr(new FunctionTdx(fn_info)); - } - - FunctionTdx::FunctionTdx(const FunctionTdxInfo & fn_info) - : info_{fn_info} - { - if (!info_.retval_td_) { - throw std::runtime_error("FunctionTdx::ctor: null return type?"); - } - } - - TaggedPtr - FunctionTdx::child_tp(uint32_t /*i*/, void * /*object*/) const - { - return TaggedPtr::universal_null(); - } - - TypeDescr - FunctionTdx::fixed_child_td(uint32_t /*i*/) const { - return nullptr; - } - - const std::string & - FunctionTdx::struct_member_name(uint32_t i) const - { - return TypeDescrExtra::struct_member_name(i); - } - } /*namespace reflect*/ -} /*namespace xo*/ - - -/* end FunctionTdx.cpp */ diff --git a/.xo-reflect/src/reflect/init_reflect.cpp b/.xo-reflect/src/reflect/init_reflect.cpp deleted file mode 100644 index bcfa34be..00000000 --- a/.xo-reflect/src/reflect/init_reflect.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* file init_reflect.cpp - * - * author: Roland Conybeare, Sep 2022 - */ - -#include "init_reflect.hpp" -#include "xo/subsys/Subsystem.hpp" - -namespace xo { - void - InitSubsys::init() - { - /* placeholder -- expecting there to be non-trivial content soon */ - } /*init*/ - - InitEvidence - InitSubsys::require() - { - return Subsystem::provide("reflect", &init); - } /*require*/ -} /*namespace xo*/ - -/* end init_reflect.cpp */ diff --git a/.xo-reflect/src/reflect/pointer/PointerTdx.cpp b/.xo-reflect/src/reflect/pointer/PointerTdx.cpp deleted file mode 100644 index cc81e391..00000000 --- a/.xo-reflect/src/reflect/pointer/PointerTdx.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* file PointerTdx.cpp - * - * author: Roland Conybeare, Sep 2022 - */ - -#include "pointer/PointerTdx.hpp" - -namespace xo { - namespace reflect { - std::string const & - PointerTdx::struct_member_name(uint32_t i) const { - return TypeDescrExtra::struct_member_name(i); - } /*struct_member_name*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end PointerTdx.cpp */ diff --git a/.xo-reflect/src/reflect/struct/StructMember.cpp b/.xo-reflect/src/reflect/struct/StructMember.cpp deleted file mode 100644 index 7f27af8c..00000000 --- a/.xo-reflect/src/reflect/struct/StructMember.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* file StructMember.cpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#include "struct/StructMember.hpp" -#include "xo/indentlog/scope.hpp" -#include - -namespace xo { - using xo::scope; - using xo::xtag; - - namespace reflect { - static_assert(std::is_move_constructible_v); - - TaggedPtr - AbstractStructMemberAccessor::member_tp(void * struct_addr) const - { - //XO_SCOPE(lscope); - - TaggedPtr retval = (this - ->member_td() - ->most_derived_self_tp(this->address(struct_addr))); - - //lscope.log(xtag("self_td", this->struct_td()->short_name()), - // xtag("member_td.declared", this->member_td()->short_name()), - // xtag("member_td.actual", retval.td()->short_name())); - - return retval; - } /*member_tp*/ - - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end StructMember.cpp */ diff --git a/.xo-reflect/src/reflect/struct/StructTdx.cpp b/.xo-reflect/src/reflect/struct/StructTdx.cpp deleted file mode 100644 index c9edc11b..00000000 --- a/.xo-reflect/src/reflect/struct/StructTdx.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* @file StructTdx.cpp */ - -#include "struct/StructTdx.hpp" -#include "TypeDescr.hpp" - -namespace xo { - using std::uint32_t; - - namespace reflect { - std::unique_ptr - StructTdx::make(std::vector member_v, - bool have_to_self_tp, - std::function to_self_tp) - { - return std::unique_ptr(new StructTdx(std::move(member_v), - have_to_self_tp, - std::move(to_self_tp))); - } /*make*/ - - TaggedPtr - StructTdx::child_tp(uint32_t i, void * object) const - { - if (i >= this->member_v_.size()) { - /* TODO: raise exception here? */ - return TaggedPtr::universal_null(); - } - - const StructMember & member_info = this->member_v_[i]; - - return member_info.get_member_tp(object); - - } /*get_child*/ - - TypeDescr - StructTdx::fixed_child_td(uint32_t i ) const - { - if (i >= this->member_v_.size()) - return nullptr; - - const StructMember & member_info = this->member_v_[i]; - - return member_info.get_member_td(); - } /*fixed_child_td*/ - - std::string const & - StructTdx::struct_member_name(uint32_t i) const - { - StructMember const * sm = this->struct_member(i); - - return sm->member_name(); - } /*struct_member_name*/ - - StructMember const * - StructTdx::struct_member(uint32_t i) const - { - if (i >= this->member_v_.size()) { - /* TODO: raise exception here */ - assert(false); - return nullptr; - } - - return &(this->member_v_[i]); - } /*struct_member*/ - } /*namespace reflect*/ -} /*namespace xo*/ - -/* end StructTdx.cpp */ diff --git a/.xo-reflect/src/reflect/vector/VectorTdx.cpp b/.xo-reflect/src/reflect/vector/VectorTdx.cpp deleted file mode 100644 index fd2e40e4..00000000 --- a/.xo-reflect/src/reflect/vector/VectorTdx.cpp +++ /dev/null @@ -1,20 +0,0 @@ -/* file VectorTdx.cpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#include "vector/VectorTdx.hpp" - -namespace xo { - namespace reflect { - std::string const & - VectorTdx::struct_member_name(uint32_t i) const { - return TypeDescrExtra::struct_member_name(i); - } /*struct_member_name*/ - - } /*namespace reflect*/ - -} /*namespace xo*/ - - -/* end VectorTdx.cpp */ diff --git a/.xo-reflect/utest/CMakeLists.txt b/.xo-reflect/utest/CMakeLists.txt deleted file mode 100644 index 535907a5..00000000 --- a/.xo-reflect/utest/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -# build unittest reflect/utest - -set(SELF_EXECUTABLE_NAME utest.reflect) -set(SELF_SOURCE_FILES - reflect_utest_main.cpp - StructReflector.test.cpp - VectorTdx.test.cpp - StructTdx.test.cpp - FunctionTdx.test.cpp) - -xo_add_utest_executable(${SELF_EXECUTABLE_NAME} ${SELF_SOURCE_FILES}) -xo_self_dependency(${SELF_EXECUTABLE_NAME} reflect) -xo_external_target_dependency(${SELF_EXECUTABLE_NAME} Catch2 Catch2::Catch2) - -# end CMakeLists.txt diff --git a/.xo-reflect/utest/FunctionTdx.test.cpp b/.xo-reflect/utest/FunctionTdx.test.cpp deleted file mode 100644 index 278a2532..00000000 --- a/.xo-reflect/utest/FunctionTdx.test.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* @file FunctionTdx.test.cpp */ - -#include "xo/reflect/Reflect.hpp" -#include - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::TaggedPtr; - using xo::reflect::TypeDescr; - using xo::reflect::Metatype; - - namespace ut { - TEST_CASE("function-reflect1", "[reflect]") { - using FunctionType = double (*)(double); - - FunctionType fn = ::sqrt; - - TaggedPtr tp = Reflect::make_tp(&fn); - //TypeDescr td = Reflect::require>(); - - REQUIRE(Reflect::is_reflected() == true); - - REQUIRE(tp.td()->complete_flag()); - REQUIRE(tp.address() == &fn); - REQUIRE(tp.is_function()); - REQUIRE(tp.is_pointer() == false); - REQUIRE(tp.is_vector() == false); - REQUIRE(tp.is_struct() == false); - REQUIRE(tp.td()->metatype() == Metatype::mt_function); - REQUIRE(tp.recover_native() == &fn); - REQUIRE(tp.n_child() == 0); /*not a composite*/ - // REQUIRE(tp.child_td(0) == ... - REQUIRE(tp.td()->fn_retval() == Reflect::require()); - REQUIRE(tp.n_fn_arg() == 1); - REQUIRE(tp.td()->fn_arg(0) == Reflect::require()); - } /*TEST_CASE(function-reflect1)*/ - } /*namespace ut*/ -} /*namespace xo*/ - -/* end FunctionTdx.test.cpp */ diff --git a/.xo-reflect/utest/StructReflector.test.cpp b/.xo-reflect/utest/StructReflector.test.cpp deleted file mode 100644 index 4ab0772d..00000000 --- a/.xo-reflect/utest/StructReflector.test.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* file StructReflector.test.cpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#include "xo/reflect/Reflect.hpp" -#include "xo/reflect/StructReflector.hpp" -#include - -#define STRINGIFY(x) #x - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::TaggedPtr; - using xo::reflect::StructReflector; - using xo::reflect::Reflect; - - namespace ut { - namespace { - struct TestStruct0 {}; - struct TestStruct1 {}; - } - - TEST_CASE("struct-reflect-empty", "[reflect]") { - StructReflector sr; - - REQUIRE(Reflect::is_reflected() == false); - REQUIRE(Reflect::is_reflected() == true); - - TestStruct0 recd0; - TaggedPtr tp = Reflect::make_tp(&recd0); - - REQUIRE(tp.address() == &recd0); - REQUIRE(tp.td() == Reflect::require()); - - REQUIRE(tp.n_child() == 0); - - REQUIRE(tp.get_child(0).is_universal_null()); - REQUIRE(tp.get_child(0).td() == nullptr); - REQUIRE(tp.get_child(0).address() == nullptr); - } /*TEST_CASE(struct-reflect-empty)*/ - - namespace { - struct TestStructS1 { int x_; }; - } - - TEST_CASE("struct-reflect-s1", "[reflect]") { - StructReflector sr; - - REQUIRE(Reflect::is_reflected() == true); - - //sr.reflect_member(STRINGIFY(x_), &decltype(sr)::struct_t::x_); - REFLECT_LITERAL_MEMBER(sr, x_); - - REQUIRE(!Reflect::require()->is_struct()); - - sr.require_complete(); - - REQUIRE(Reflect::require()->is_struct()); - } /*TEST_CASE(struct-reflect-s1)*/ - - namespace { - struct TestStructS2 { int x_; }; - } - - TEST_CASE("struct-reflect-s2", "[reflect]") { - StructReflector sr; - - REQUIRE(Reflect::is_reflected() == true); - - //sr.reflect_member(STRINGIFY(x_), &decltype(sr)::struct_t::x_); - REFLECT_MEMBER(sr, x); - - REQUIRE(!Reflect::require()->is_struct()); - - sr.require_complete(); - - REQUIRE(Reflect::require()->is_struct()); - - TestStructS2 recd1{666}; - - TaggedPtr tp = Reflect::make_tp(&recd1); - - REQUIRE(tp.address() == &recd1); - REQUIRE(tp.td() == Reflect::require()); - - REQUIRE(tp.n_child() == 1); - - REQUIRE(tp.get_child(0).td() == Reflect::require()); - REQUIRE(tp.get_child(0).address() == &(recd1.x_)); - - REQUIRE(tp.get_child(1).is_universal_null()); - } /*TEST_CASE(struct-reflect-s2)*/ - - namespace { - struct TestStructS3 { int x_; char y_; double z_; }; - } - - TEST_CASE("struct-reflect-s3", "[reflect]") { - StructReflector sr; - - REQUIRE(Reflect::is_reflected() == true); - - REFLECT_MEMBER(sr, x); - REFLECT_MEMBER(sr, y); - REFLECT_MEMBER(sr, z); - - REQUIRE(!Reflect::require()->is_struct()); - - sr.require_complete(); - - REQUIRE(Reflect::require()->is_struct()); - - /* verify we can traverse reflected instances */ - TestStructS3 recd1{666, 'Y', -1.234}; - - TaggedPtr tp = Reflect::make_tp(&recd1); - - REQUIRE(tp.address() == &recd1); - REQUIRE(tp.td() == Reflect::require()); - - REQUIRE(tp.n_child() == 3); - - REQUIRE(tp.get_child(0).td() == Reflect::require()); - REQUIRE(tp.get_child(0).address() == &(recd1.x_)); - - REQUIRE(tp.get_child(1).td() == Reflect::require()); - REQUIRE(tp.get_child(1).address() == &(recd1.y_)); - - REQUIRE(tp.get_child(2).td() == Reflect::require()); - REQUIRE(tp.get_child(2).address() == &(recd1.z_)); - - REQUIRE(tp.get_child(3).is_universal_null()); - REQUIRE(tp.get_child(3).td() == nullptr); - REQUIRE(tp.get_child(3).address() == nullptr); - - } /*TEST_CASE(struct-reflect-s3)*/ - } /*namespace ut */ -} /*namespace xo*/ - - -/* end StructReflector.test.cpp */ diff --git a/.xo-reflect/utest/StructTdx.test.cpp b/.xo-reflect/utest/StructTdx.test.cpp deleted file mode 100644 index 6b1fb2cd..00000000 --- a/.xo-reflect/utest/StructTdx.test.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* file StructTdx.test.cpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#include "xo/reflect/Reflect.hpp" -#include - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::TaggedPtr; - using xo::reflect::TypeDescr; - using xo::reflect::Metatype; - - namespace ut { - TEST_CASE("std-pair-reflect", "[reflect]") { - std::pair p; - - TaggedPtr tp = Reflect::make_tp(&p); - - REQUIRE(Reflect::is_reflected>() == true); - - REQUIRE(tp.td()->complete_flag()); - REQUIRE(tp.address() == &p); - REQUIRE(tp.is_struct()); - REQUIRE(tp.is_vector() == false); - REQUIRE(tp.td()->metatype() == Metatype::mt_struct); - REQUIRE(tp.recover_native>() == &p); - REQUIRE(tp.n_child() == 2); /* struct with 2 members */ - REQUIRE(tp.struct_member_name(0) == "first"); - REQUIRE(tp.struct_member_name(1) == "second"); - - TaggedPtr tp0 = tp.get_child(0); - - REQUIRE(tp0.td()->complete_flag()); - REQUIRE(tp0.address() == &(p.first)); - REQUIRE(!tp0.is_vector()); - REQUIRE(!tp0.is_struct()); - REQUIRE(tp0.td()->metatype() == Metatype::mt_atomic); - REQUIRE(tp0.recover_native() == &(p.first)); - REQUIRE(tp0.n_child() == 0); - - TaggedPtr tp1 = tp.get_child(1); - - REQUIRE(tp1.td()->complete_flag()); - REQUIRE(tp1.address() == &(p.second)); - REQUIRE(!tp1.is_vector()); - REQUIRE(!tp1.is_struct()); - REQUIRE(tp1.td()->metatype() == Metatype::mt_atomic); - REQUIRE(tp1.recover_native() == &(p.second)); - REQUIRE(tp1.n_child() == 0); - - } /*TEST_CASE(std-pair-reflect)*/ - } /*namespace ut*/ -} /*namespace xo*/ - -/* end StructTdx.test.cpp */ diff --git a/.xo-reflect/utest/VectorTdx.test.cpp b/.xo-reflect/utest/VectorTdx.test.cpp deleted file mode 100644 index fe4e58a4..00000000 --- a/.xo-reflect/utest/VectorTdx.test.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* file VectorTdx.test.cpp - * - * author: Roland Conybeare, Aug 2022 - */ - -#include "xo/reflect/Reflect.hpp" -#include - -namespace xo { - using xo::reflect::Reflect; - using xo::reflect::TaggedPtr; - using xo::reflect::TypeDescr; - using xo::reflect::Metatype; - - namespace ut { - TEST_CASE("std-vector-reflect-empty", "[reflect]") { - std::vector v; - - TaggedPtr tp = Reflect::make_tp(&v); - //TypeDescr td = Reflect::require>(); - - REQUIRE(Reflect::is_reflected>() == true); - - REQUIRE(tp.td()->complete_flag()); - REQUIRE(tp.address() == &v); - REQUIRE(tp.is_vector()); - REQUIRE(tp.is_struct() == false); - REQUIRE(tp.td()->metatype() == Metatype::mt_vector); - REQUIRE(tp.recover_native>() == &v); - REQUIRE(tp.n_child() == 0); /*since empty vector*/ - // REQUIRE(tp.child_td(0) == ... - } /*TEST_CASE(std-vector-reflect-empty)*/ - - TEST_CASE("std-vector-reflect-one", "[reflect]") { - std::vector v = { 1.123 }; - - TaggedPtr tp = Reflect::make_tp(&v); - - REQUIRE(Reflect::is_reflected>() == true); - - REQUIRE(tp.td()->complete_flag()); - REQUIRE(tp.address() == &v); - REQUIRE(tp.is_vector()); - REQUIRE(tp.is_struct() == false); - REQUIRE(tp.td()->metatype() == Metatype::mt_vector); - REQUIRE(tp.recover_native>() == &v); - REQUIRE(tp.n_child() == 1); - - TaggedPtr tp0 = tp.get_child(0); - - REQUIRE(tp0.td()->complete_flag()); - REQUIRE(tp0.address() == &(v[0])); - REQUIRE(!tp0.is_vector()); - REQUIRE(!tp0.is_struct()); - REQUIRE(tp0.td()->metatype() == Metatype::mt_atomic); - REQUIRE(tp0.recover_native() == &(v[0])); - REQUIRE(tp0.n_child() == 0); - } /*TEST_CASE(std-vector-reflect-one)*/ - - TEST_CASE("std-vector-reflect-two", "[reflect]") { - std::vector v = { 1.123, 2.234 }; - - TaggedPtr tp = Reflect::make_tp(&v); - - REQUIRE(Reflect::is_reflected>() == true); - - REQUIRE(tp.td()->complete_flag()); - REQUIRE(tp.address() == &v); - REQUIRE(tp.is_vector()); - REQUIRE(tp.is_struct() == false); - REQUIRE(tp.td()->metatype() == Metatype::mt_vector); - REQUIRE(tp.recover_native>() == &v); - REQUIRE(tp.n_child() == 2); - - TaggedPtr tp0 = tp.get_child(0); - - REQUIRE(tp0.td()->complete_flag()); - REQUIRE(tp0.address() == &(v[0])); - REQUIRE(!tp0.is_vector()); - REQUIRE(!tp0.is_struct()); - REQUIRE(tp0.td()->metatype() == Metatype::mt_atomic); - REQUIRE(tp0.recover_native() == &(v[0])); - REQUIRE(tp0.n_child() == 0); - - TaggedPtr tp1 = tp.get_child(1); - - REQUIRE(tp1.td()->complete_flag()); - REQUIRE(tp1.address() == &(v[1])); - REQUIRE(!tp1.is_vector()); - REQUIRE(!tp1.is_struct()); - REQUIRE(tp1.td()->metatype() == Metatype::mt_atomic); - REQUIRE(tp1.recover_native() == &(v[1])); - REQUIRE(tp1.n_child() == 0); - } /*TEST(std-vector-reflect-two)*/ - - // ----- std::array ----- - - TEST_CASE("std-array-reflect-empty", "[reflect]") { - std::array v; - - TaggedPtr tp = Reflect::make_tp(&v); - //TypeDescr td = Reflect::require>(); - - REQUIRE(Reflect::is_reflected>() == true); - - REQUIRE(tp.td()->complete_flag()); - REQUIRE(tp.address() == &v); - REQUIRE(tp.is_vector()); - REQUIRE(tp.is_struct() == false); - REQUIRE(tp.td()->metatype() == Metatype::mt_vector); - REQUIRE(tp.recover_native>() == &v); - REQUIRE(tp.n_child() == 0); /*since empty vector*/ - // REQUIRE(tp.child_td(0) == ... - } /*TEST_CASE(std-array-reflect-empty)*/ - - TEST_CASE("std-array-reflect-one", "[reflect]") { - std::array v = { 1.123 }; - - TaggedPtr tp = Reflect::make_tp(&v); - - REQUIRE(Reflect::is_reflected>() == true); - - REQUIRE(tp.td()->complete_flag()); - REQUIRE(tp.address() == &v); - REQUIRE(tp.is_vector()); - REQUIRE(tp.is_struct() == false); - REQUIRE(tp.td()->metatype() == Metatype::mt_vector); - REQUIRE(tp.recover_native>() == &v); - REQUIRE(tp.n_child() == 1); - - TaggedPtr tp0 = tp.get_child(0); - - REQUIRE(tp0.td()->complete_flag()); - REQUIRE(tp0.address() == &(v[0])); - REQUIRE(!tp0.is_vector()); - REQUIRE(!tp0.is_struct()); - REQUIRE(tp0.td()->metatype() == Metatype::mt_atomic); - REQUIRE(tp0.recover_native() == &(v[0])); - REQUIRE(tp0.n_child() == 0); - } /*TEST_CASE(std-array-reflect-one)*/ - - TEST_CASE("std-array-reflect-two", "[reflect]") { - std::array v = { 1.123, 2.234 }; - - TaggedPtr tp = Reflect::make_tp(&v); - - REQUIRE(Reflect::is_reflected>() == true); - - REQUIRE(tp.td()->complete_flag()); - REQUIRE(tp.address() == &v); - REQUIRE(tp.is_vector()); - REQUIRE(tp.is_struct() == false); - REQUIRE(tp.td()->metatype() == Metatype::mt_vector); - REQUIRE(tp.recover_native>() == &v); - REQUIRE(tp.n_child() == 2); - - TaggedPtr tp0 = tp.get_child(0); - - REQUIRE(tp0.td()->complete_flag()); - REQUIRE(tp0.address() == &(v[0])); - REQUIRE(!tp0.is_vector()); - REQUIRE(!tp0.is_struct()); - REQUIRE(tp0.td()->metatype() == Metatype::mt_atomic); - REQUIRE(tp0.recover_native() == &(v[0])); - REQUIRE(tp0.n_child() == 0); - - TaggedPtr tp1 = tp.get_child(1); - - REQUIRE(tp1.td()->complete_flag()); - REQUIRE(tp1.address() == &(v[1])); - REQUIRE(!tp1.is_vector()); - REQUIRE(!tp1.is_struct()); - REQUIRE(tp1.td()->metatype() == Metatype::mt_atomic); - REQUIRE(tp1.recover_native() == &(v[1])); - REQUIRE(tp1.n_child() == 0); - } /*TEST(std-array-reflect-two)*/ - - } /*namespace ut*/ -} /*namespace xo*/ - -/* end VectorTdx.test.cpp */ diff --git a/.xo-reflect/utest/reflect_utest_main.cpp b/.xo-reflect/utest/reflect_utest_main.cpp deleted file mode 100644 index 91c62d09..00000000 --- a/.xo-reflect/utest/reflect_utest_main.cpp +++ /dev/null @@ -1,6 +0,0 @@ -/* file reflect_utest_main.cpp */ - -#define CATCH_CONFIG_MAIN -#include "catch2/catch.hpp" - -/* end reflect_utest_main.cpp */