From 270efabff5f6795536990308ff3c6fc2e4f0d181 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 7 Mar 2026 00:01:57 +1100 Subject: [PATCH] xo-type: + gcobject facet + DListType --- xo-type/CMakeLists.txt | 20 ++++ xo-type/idl/IGCObject_DListType.json5 | 16 ++++ xo-type/idl/IType_DListType.json5 | 16 ++++ xo-type/idl/Type.json5 | 19 +++- xo-type/include/xo/type/DAtomicType.hpp | 7 +- xo-type/include/xo/type/DListType.hpp | 63 +++++++++++++ xo-type/include/xo/type/ListType.hpp | 12 +++ xo-type/include/xo/type/Metatype.hpp | 22 +++++ xo-type/include/xo/type/TypeOps.hpp | 31 +++++++ .../xo/type/atomic/IType_DAtomicType.hpp | 4 + .../xo/type/list/IGCObject_DListType.hpp | 65 +++++++++++++ .../include/xo/type/list/IType_DListType.hpp | 63 +++++++++++++ xo-type/include/xo/type/type/AType.hpp | 4 + xo-type/include/xo/type/type/IType_Any.hpp | 2 + xo-type/include/xo/type/type/IType_Xfer.hpp | 6 ++ xo-type/include/xo/type/type/RType.hpp | 6 ++ xo-type/src/type/CMakeLists.txt | 5 + xo-type/src/type/DAtomicType.cpp | 20 ++++ xo-type/src/type/DListType.cpp | 92 +++++++++++++++++++ xo-type/src/type/IGCObject_DListType.cpp | 39 ++++++++ xo-type/src/type/IType_DAtomicType.cpp | 12 +++ xo-type/src/type/IType_DListType.cpp | 40 ++++++++ xo-type/src/type/Metatype.cpp | 29 ++++++ xo-type/src/type/TypeOps.cpp | 15 +++ xo-type/src/type/type_register_facets.cpp | 7 +- xo-type/src/type/type_register_types.cpp | 2 + xo-type/utest/CMakeLists.txt | 1 + xo-type/utest/DAtomicType.test.cpp | 72 ++++++++++++++- xo-type/utest/DListType.test.cpp | 65 +++++++++++++ 29 files changed, 749 insertions(+), 6 deletions(-) create mode 100644 xo-type/idl/IGCObject_DListType.json5 create mode 100644 xo-type/idl/IType_DListType.json5 create mode 100644 xo-type/include/xo/type/DListType.hpp create mode 100644 xo-type/include/xo/type/ListType.hpp create mode 100644 xo-type/include/xo/type/TypeOps.hpp create mode 100644 xo-type/include/xo/type/list/IGCObject_DListType.hpp create mode 100644 xo-type/include/xo/type/list/IType_DListType.hpp create mode 100644 xo-type/src/type/DListType.cpp create mode 100644 xo-type/src/type/IGCObject_DListType.cpp create mode 100644 xo-type/src/type/IType_DListType.cpp create mode 100644 xo-type/src/type/TypeOps.cpp create mode 100644 xo-type/utest/DListType.test.cpp diff --git a/xo-type/CMakeLists.txt b/xo-type/CMakeLists.txt index e11f53b1..b1ea2905 100644 --- a/xo-type/CMakeLists.txt +++ b/xo-type/CMakeLists.txt @@ -50,6 +50,26 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-type-facetimpl-type-listtype + FACET_PKG xo_type + FACET Type + REPR ListType + INPUT idl/IType_DListType.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-type-facetimpl-gcobject-listtype + FACET_PKG xo_alloc2 + FACET GCObject + REPR ListType + INPUT idl/IGCObject_DListType.json5 +) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-type-genfacet-all) install(DIRECTORY idl/ diff --git a/xo-type/idl/IGCObject_DListType.json5 b/xo-type/idl/IGCObject_DListType.json5 new file mode 100644 index 00000000..1f4c00ea --- /dev/null +++ b/xo-type/idl/IGCObject_DListType.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/type", + output_hpp_dir: "include/xo/type", + output_impl_subdir: "list", + includes: [ + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DListType", + using_doxygen: true, + repr: "DListType", + doc: [ "implement AGCObject for DListType" ], +} diff --git a/xo-type/idl/IType_DListType.json5 b/xo-type/idl/IType_DListType.json5 new file mode 100644 index 00000000..0cd59785 --- /dev/null +++ b/xo-type/idl/IType_DListType.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/type", + output_hpp_dir: "include/xo/type", + output_impl_subdir: "list", + includes: [], + local_types: [], + namespace1: "xo", + namespace2: "scm", + + facet_idl: "idl/Type.json5", + brief: "provide AType interface for DListType", + using_doxygen: true, + repr: "DListType", + doc: [ "implement AType for DListType" ], +} diff --git a/xo-type/idl/Type.json5 b/xo-type/idl/Type.json5 index eeb22334..1ddac826 100644 --- a/xo-type/idl/Type.json5 +++ b/xo-type/idl/Type.json5 @@ -37,6 +37,22 @@ const: true, noexcept: true, }, + { + name: "is_equal_to", + doc: ["true iff this type is equal to y"], + return_type: "bool", + args: [ + {type: "const obj_AType &", name: "y"}, + ] + }, + { + name: "is_subtype_of", + doc: ["true iff this is a subtype of y"], + return_type: "bool", + args: [ + {type: "const obj_AType &", name: "y"}, + ] + }, // TODO: define methods, e.g.: // { @@ -49,5 +65,6 @@ // }, ], nonconst_methods: [], - router_facet_explicit_content: [], + router_facet_explicit_content: [ + ], } diff --git a/xo-type/include/xo/type/DAtomicType.hpp b/xo-type/include/xo/type/DAtomicType.hpp index 253b678b..074e0c64 100644 --- a/xo-type/include/xo/type/DAtomicType.hpp +++ b/xo-type/include/xo/type/DAtomicType.hpp @@ -5,6 +5,7 @@ #pragma once +#include "Type.hpp" #include "Metatype.hpp" #include #include @@ -29,8 +30,12 @@ namespace xo { /** create instance using memory from @p mm with metatype @p mtype **/ static DAtomicType * _make(obj mm, Metatype mtype); + /** @defgroup xo-scm-atomictype-type-facet **/ + ///@{ Metatype metatype() const noexcept { return metatype_; } - + bool is_equal_to(const obj & y) const noexcept; + bool is_subtype_of(const obj & y) const noexcept; + ///@} /** @defgroup xo-scm-atomictype-gcobject-facet **/ ///@{ std::size_t shallow_size() const noexcept; diff --git a/xo-type/include/xo/type/DListType.hpp b/xo-type/include/xo/type/DListType.hpp new file mode 100644 index 00000000..41808ce6 --- /dev/null +++ b/xo-type/include/xo/type/DListType.hpp @@ -0,0 +1,63 @@ +/** @file DListType.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "Type.hpp" +#include "Metatype.hpp" +#include +#include + +namespace xo { + namespace scm { + /** @brief An atomic schematika type + * + * Types that are not parameterized by types or values. + * For example + * unit, bool, i64, f64 + * are atomic in this sense. + **/ + class DListType { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + + public: + /** @defgroup xo-scm-listtype-ctors **/ + ///@{ + + explicit DListType(obj elt); + + /** create instance using memory from @p mm with metatype @p mtype **/ + static DListType * _make(obj mm, obj elt_type); + + ///@} + /** @defgroup xo-scm-listtype-type-facet **/ + ///@{ + Metatype metatype() const noexcept { return Metatype::list(); } + bool is_equal_to(const obj & y) const noexcept; + bool is_subtype_of(const obj & y) const noexcept; + ///@} + /** @defgroup xo-scm-listtype-gcobject-facet **/ + ///@{ + std::size_t shallow_size() const noexcept; + DListType * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} + + private: + /** @defgroup xo-scm-listtype-member-vars **/ + ///@{ + + /** all list elements satisfy @ref elt_type_ **/ + obj elt_type_; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DListType.hpp */ diff --git a/xo-type/include/xo/type/ListType.hpp b/xo-type/include/xo/type/ListType.hpp new file mode 100644 index 00000000..3b573792 --- /dev/null +++ b/xo-type/include/xo/type/ListType.hpp @@ -0,0 +1,12 @@ +/** @file ListType.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DListType.hpp" +#include "list/IType_DListType.hpp" +#include "list/IGCObject_DListType.hpp" + +/* end ListType.hpp */ diff --git a/xo-type/include/xo/type/Metatype.hpp b/xo-type/include/xo/type/Metatype.hpp index 813b1446..2d7b2a5d 100644 --- a/xo-type/include/xo/type/Metatype.hpp +++ b/xo-type/include/xo/type/Metatype.hpp @@ -39,16 +39,38 @@ namespace xo { explicit Metatype(code x) : code_{x} {} static Metatype unit() { return Metatype(code::t_unit); } + static Metatype t_bool() { return Metatype(code::t_bool); } + static Metatype i64() { return Metatype(code::t_i64); } + static Metatype f64() { return Metatype(code::t_f64); } + static Metatype str() { return Metatype(code::t_str); } + static Metatype any() { return Metatype(code::t_any); } + + static Metatype list() { return Metatype(code::t_list); } /** description string for this type category **/ const char * _descr() const noexcept; code code() const noexcept { return code_; } + /** true iff this metatype is non-parametric: + * i.e. stands for a single type + **/ + bool is_atomic() const noexcept; + private: enum code code_; }; + inline bool + operator==(Metatype x, Metatype y) { + return (x.code() == y.code()); + } + + inline bool + operator!=(Metatype x, Metatype y) { + return (x.code() != y.code()); + } + inline std::ostream & operator<<(std::ostream & os, Metatype x) { os << x._descr(); diff --git a/xo-type/include/xo/type/TypeOps.hpp b/xo-type/include/xo/type/TypeOps.hpp new file mode 100644 index 00000000..b31fa039 --- /dev/null +++ b/xo-type/include/xo/type/TypeOps.hpp @@ -0,0 +1,31 @@ +/** @file TypeOps.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "AtomicType.hpp" +#include "ListType.hpp" +#include + +namespace xo { + namespace scm { + class TypeOps { + public: + using AAllocator = xo::mm::AAllocator; + + template + static obj atomic_type(obj mm, Metatype metatype) { + assert(metatype.is_atomic()); + return obj(DAtomicType::_make(mm, metatype)); + } + + template + static obj list_type(obj mm, obj elt_type) { + return obj(DListType::_make(mm, elt_type)); + } + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end TypeOps.hpp */ diff --git a/xo-type/include/xo/type/atomic/IType_DAtomicType.hpp b/xo-type/include/xo/type/atomic/IType_DAtomicType.hpp index 8a351cf9..fc73539f 100644 --- a/xo-type/include/xo/type/atomic/IType_DAtomicType.hpp +++ b/xo-type/include/xo/type/atomic/IType_DAtomicType.hpp @@ -48,6 +48,10 @@ namespace xo { // const methods /** category for this type **/ static Metatype metatype(const DAtomicType & self) noexcept; + /** true iff this type is equal to y **/ + static bool is_equal_to(const DAtomicType & self, const obj_AType & y); + /** true iff this is a subtype of y **/ + static bool is_subtype_of(const DAtomicType & self, const obj_AType & y); // non-const methods ///@} diff --git a/xo-type/include/xo/type/list/IGCObject_DListType.hpp b/xo-type/include/xo/type/list/IGCObject_DListType.hpp new file mode 100644 index 00000000..6393d35b --- /dev/null +++ b/xo-type/include/xo/type/list/IGCObject_DListType.hpp @@ -0,0 +1,65 @@ +/** @file IGCObject_DListType.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DListType.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DListType.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include "DListType.hpp" + +namespace xo { namespace scm { class IGCObject_DListType; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DListType + **/ + class IGCObject_DListType { + public: + /** @defgroup scm-gcobject-dlisttype-type-traits **/ + ///@{ + using size_type = xo::mm::AGCObject::size_type; + using AAllocator = xo::mm::AGCObject::AAllocator; + using ACollector = xo::mm::AGCObject::ACollector; + using Copaque = xo::mm::AGCObject::Copaque; + using Opaque = xo::mm::AGCObject::Opaque; + ///@} + /** @defgroup scm-gcobject-dlisttype-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DListType & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DListType & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DListType & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-type/include/xo/type/list/IType_DListType.hpp b/xo-type/include/xo/type/list/IType_DListType.hpp new file mode 100644 index 00000000..546b9cbe --- /dev/null +++ b/xo-type/include/xo/type/list/IType_DListType.hpp @@ -0,0 +1,63 @@ +/** @file IType_DListType.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IType_DListType.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IType_DListType.json5] + **/ + +#pragma once + +#include "Type.hpp" +#include "DListType.hpp" + +namespace xo { namespace scm { class IType_DListType; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IType_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IType_DListType + **/ + class IType_DListType { + public: + /** @defgroup scm-type-dlisttype-type-traits **/ + ///@{ + using obj_AType = xo::scm::AType::obj_AType; + using Copaque = xo::scm::AType::Copaque; + using Opaque = xo::scm::AType::Opaque; + ///@} + /** @defgroup scm-type-dlisttype-methods **/ + ///@{ + // const methods + /** category for this type **/ + static Metatype metatype(const DListType & self) noexcept; + /** true iff this type is equal to y **/ + static bool is_equal_to(const DListType & self, const obj_AType & y); + /** true iff this is a subtype of y **/ + static bool is_subtype_of(const DListType & self, const obj_AType & y); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-type/include/xo/type/type/AType.hpp b/xo-type/include/xo/type/type/AType.hpp index 50389fe7..dde14805 100644 --- a/xo-type/include/xo/type/type/AType.hpp +++ b/xo-type/include/xo/type/type/AType.hpp @@ -53,6 +53,10 @@ public: virtual void _drop(Opaque d) const noexcept = 0; /** category for this type **/ virtual Metatype metatype(Copaque data) const noexcept = 0; + /** true iff this type is equal to y **/ + virtual bool is_equal_to(Copaque data, const obj_AType & y) = 0; + /** true iff this is a subtype of y **/ + virtual bool is_subtype_of(Copaque data, const obj_AType & y) = 0; // nonconst methods ///@} diff --git a/xo-type/include/xo/type/type/IType_Any.hpp b/xo-type/include/xo/type/type/IType_Any.hpp index 6db13097..b8bdb58c 100644 --- a/xo-type/include/xo/type/type/IType_Any.hpp +++ b/xo-type/include/xo/type/type/IType_Any.hpp @@ -60,6 +60,8 @@ namespace scm { // const methods [[noreturn]] Metatype metatype(Copaque) const noexcept override { _fatal(); } + [[noreturn]] bool is_equal_to(Copaque, const obj_AType &) override { _fatal(); } + [[noreturn]] bool is_subtype_of(Copaque, const obj_AType &) override { _fatal(); } // nonconst methods diff --git a/xo-type/include/xo/type/type/IType_Xfer.hpp b/xo-type/include/xo/type/type/IType_Xfer.hpp index ead6c45e..98b138c7 100644 --- a/xo-type/include/xo/type/type/IType_Xfer.hpp +++ b/xo-type/include/xo/type/type/IType_Xfer.hpp @@ -47,6 +47,12 @@ namespace scm { Metatype metatype(Copaque data) const noexcept override { return I::metatype(_dcast(data)); } + bool is_equal_to(Copaque data, const obj_AType & y) override { + return I::is_equal_to(_dcast(data), y); + } + bool is_subtype_of(Copaque data, const obj_AType & y) override { + return I::is_subtype_of(_dcast(data), y); + } // non-const methods diff --git a/xo-type/include/xo/type/type/RType.hpp b/xo-type/include/xo/type/type/RType.hpp index a6376fe0..853745ed 100644 --- a/xo-type/include/xo/type/type/RType.hpp +++ b/xo-type/include/xo/type/type/RType.hpp @@ -56,6 +56,12 @@ public: Metatype metatype() const noexcept { return O::iface()->metatype(O::data()); } + bool is_equal_to(const obj_AType & y) { + return O::iface()->is_equal_to(O::data(), y); + } + bool is_subtype_of(const obj_AType & y) { + return O::iface()->is_subtype_of(O::data(), y); + } // non-const methods (still const in router!) diff --git a/xo-type/src/type/CMakeLists.txt b/xo-type/src/type/CMakeLists.txt index 806e67a9..7f708fb4 100644 --- a/xo-type/src/type/CMakeLists.txt +++ b/xo-type/src/type/CMakeLists.txt @@ -5,10 +5,15 @@ set(SELF_SRCS init_type.cpp type_register_facets.cpp type_register_types.cpp + TypeOps.cpp Metatype.cpp DAtomicType.cpp + DListType.cpp + IType_Any.cpp IType_DAtomicType.cpp + IType_DListType.cpp IGCObject_DAtomicType.cpp + IGCObject_DListType.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/xo-type/src/type/DAtomicType.cpp b/xo-type/src/type/DAtomicType.cpp index 561e8777..18c64c81 100644 --- a/xo-type/src/type/DAtomicType.cpp +++ b/xo-type/src/type/DAtomicType.cpp @@ -16,6 +16,26 @@ namespace xo { return new (mem) DAtomicType(mtype); } + // ----- Type facet ----- + + bool + DAtomicType::is_equal_to(const obj & y) const noexcept + { + return (metatype_.code() == y.metatype().code()); + } + + bool + DAtomicType::is_subtype_of(const obj & y) const noexcept + { + Metatype x_mtype = metatype_; + Metatype y_mtype = y.metatype(); + + if (y_mtype.code() == Metatype::code::t_any) + return true; + + return (x_mtype.code() == y_mtype.code()); + } + // ----- GCObject facet ----- std::size_t diff --git a/xo-type/src/type/DListType.cpp b/xo-type/src/type/DListType.cpp new file mode 100644 index 00000000..4be59a36 --- /dev/null +++ b/xo-type/src/type/DListType.cpp @@ -0,0 +1,92 @@ +/** @file DListType.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "Type.hpp" +#include "ListType.hpp" +#include +#include +#include + +namespace xo { + using xo::mm::AGCObject; + using xo::mm::AAllocator; + using xo::facet::FacetRegistry; + + namespace scm { + + DListType::DListType(obj elt) : elt_type_{elt} {} + + DListType * + DListType::_make(obj mm, + obj elt_type) + { + void * mem = mm.alloc_for(); + + return new (mem) DListType(elt_type); + } + + // ----- type facet ----- + + bool + DListType::is_equal_to(const obj & y_arg) const noexcept + { + Metatype y_mtype = y_arg.metatype(); + + if (y_mtype != Metatype::list()) + return false; + + auto y = obj::from(y_arg); + + obj e = elt_type_; + + return (e.is_equal_to(y->elt_type_)); + } + + bool + DListType::is_subtype_of(const obj & y_arg) const noexcept + { + Metatype y_mtype = y_arg.metatype(); + + if (y_mtype == Metatype::any()) + return true; + + if (y_mtype != Metatype::list()) + return false; + + auto y = obj::from(y_arg); + + obj e = elt_type_; + + return (e.is_subtype_of(y->elt_type_)); + } + + // ----- gcobject facet ----- + + std::size_t + DListType::shallow_size() const noexcept + { + return sizeof(*this); + } + + DListType * + DListType::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DListType::forward_children(obj gc) noexcept + { + { + auto e = FacetRegistry::instance().variant(elt_type_); + gc.forward_inplace(e.iface(), (void **)&(e.data_)); + } + + return this->shallow_size(); + } + } +} + +/* end DListType.cpp */ diff --git a/xo-type/src/type/IGCObject_DListType.cpp b/xo-type/src/type/IGCObject_DListType.cpp new file mode 100644 index 00000000..761ae617 --- /dev/null +++ b/xo-type/src/type/IGCObject_DListType.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DListType.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DListType.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DListType.json5] +**/ + +#include "list/IGCObject_DListType.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DListType::shallow_size(const DListType & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DListType::shallow_copy(const DListType & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DListType::forward_children(DListType & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DListType.cpp */ diff --git a/xo-type/src/type/IType_DAtomicType.cpp b/xo-type/src/type/IType_DAtomicType.cpp index 663653ad..65fcb023 100644 --- a/xo-type/src/type/IType_DAtomicType.cpp +++ b/xo-type/src/type/IType_DAtomicType.cpp @@ -21,6 +21,18 @@ namespace xo { return self.metatype(); } + auto + IType_DAtomicType::is_equal_to(const DAtomicType & self, const obj_AType & y) -> bool + { + return self.is_equal_to(y); + } + + auto + IType_DAtomicType::is_subtype_of(const DAtomicType & self, const obj_AType & y) -> bool + { + return self.is_subtype_of(y); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-type/src/type/IType_DListType.cpp b/xo-type/src/type/IType_DListType.cpp new file mode 100644 index 00000000..a29e3d74 --- /dev/null +++ b/xo-type/src/type/IType_DListType.cpp @@ -0,0 +1,40 @@ +/** @file IType_DListType.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IType_DListType.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IType_DListType.json5] +**/ + +#include "list/IType_DListType.hpp" + +namespace xo { + namespace scm { + auto + IType_DListType::metatype(const DListType & self) noexcept -> Metatype + { + return self.metatype(); + } + + auto + IType_DListType::is_equal_to(const DListType & self, const obj_AType & y) -> bool + { + return self.is_equal_to(y); + } + + auto + IType_DListType::is_subtype_of(const DListType & self, const obj_AType & y) -> bool + { + return self.is_subtype_of(y); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IType_DListType.cpp */ diff --git a/xo-type/src/type/Metatype.cpp b/xo-type/src/type/Metatype.cpp index acc82b67..aa97fdcc 100644 --- a/xo-type/src/type/Metatype.cpp +++ b/xo-type/src/type/Metatype.cpp @@ -26,6 +26,35 @@ namespace xo { } } + bool + Metatype::is_atomic() const noexcept + { + switch (code_) { + case code::t_any: + return true; + case code::t_bool: + return true; + case code::t_i64: + return true; + case code::t_f64: + return true; + case code::t_str: + return true; + case code::t_sum: + return false; + case code::t_list: + return false; + case code::t_array: + return false; + case code::t_function: + return false; + case code::t_struct: + return false; + case code::t_unit: + return false; + } + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-type/src/type/TypeOps.cpp b/xo-type/src/type/TypeOps.cpp new file mode 100644 index 00000000..f344fb5b --- /dev/null +++ b/xo-type/src/type/TypeOps.cpp @@ -0,0 +1,15 @@ +/** @file TypeOps.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "TypeOps.hpp" + +namespace xo { + namespace scm { + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end TypeOps.cpp */ diff --git a/xo-type/src/type/type_register_facets.cpp b/xo-type/src/type/type_register_facets.cpp index 6c7bd512..549633cd 100644 --- a/xo-type/src/type/type_register_facets.cpp +++ b/xo-type/src/type/type_register_facets.cpp @@ -6,13 +6,13 @@ #include "type_register_facets.hpp" #include +#include #include #include namespace xo { using xo::mm::AGCObject; using xo::facet::FacetRegistry; - //using xo::facet::TypeRegistry; using xo::reflect::typeseq; namespace scm { @@ -22,9 +22,14 @@ namespace xo { { scope log(XO_DEBUG(true)); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DAtomicType.tseq", typeseq::id())); + log && log(xtag("DListType.tseq", typeseq::id())); return true; } diff --git a/xo-type/src/type/type_register_types.cpp b/xo-type/src/type/type_register_types.cpp index e5da5d1d..8e2cdda6 100644 --- a/xo-type/src/type/type_register_types.cpp +++ b/xo-type/src/type/type_register_types.cpp @@ -6,6 +6,7 @@ #include "type_register_types.hpp" #include "AtomicType.hpp" +#include "ListType.hpp" #include #include #include @@ -25,6 +26,7 @@ namespace xo { bool ok = true; ok &= gc.install_type(impl_for()); + ok &= gc.install_type(impl_for()); return ok; } diff --git a/xo-type/utest/CMakeLists.txt b/xo-type/utest/CMakeLists.txt index ff79bda4..cc18708a 100644 --- a/xo-type/utest/CMakeLists.txt +++ b/xo-type/utest/CMakeLists.txt @@ -4,6 +4,7 @@ set(UTEST_EXE utest.type) set(UTEST_SRCS type_utest_main.cpp DAtomicType.test.cpp + DListType.test.cpp # DString.test.cpp # StringOps.test.cpp # X1Collector.test.cpp diff --git a/xo-type/utest/DAtomicType.test.cpp b/xo-type/utest/DAtomicType.test.cpp index 6ee26cee..9bab45d0 100644 --- a/xo-type/utest/DAtomicType.test.cpp +++ b/xo-type/utest/DAtomicType.test.cpp @@ -28,10 +28,76 @@ namespace xo { DArena arena = DArena::map(cfg); auto alloc = obj(&arena); - auto f64_type = obj(DAtomicType::_make(alloc, Metatype::unit())); + auto unit_type = obj(DAtomicType::_make(alloc, Metatype::unit())); + auto i64_type = obj(DAtomicType::_make(alloc, Metatype::i64())); + auto f64_type = obj(DAtomicType::_make(alloc, Metatype::f64())); + auto str_type = obj(DAtomicType::_make(alloc, Metatype::str())); + auto any_type = obj(DAtomicType::_make(alloc, Metatype::any())); + { + REQUIRE(unit_type); + REQUIRE(unit_type.metatype().code() == Metatype::unit().code()); - REQUIRE(f64_type); - REQUIRE(f64_type.metatype().code() == Metatype::unit().code()); + REQUIRE(unit_type.is_equal_to(unit_type)); + REQUIRE(unit_type.is_subtype_of(unit_type)); + } + + { + REQUIRE(i64_type); + REQUIRE(i64_type.metatype().code() == Metatype::i64().code()); + + REQUIRE(i64_type.is_equal_to(i64_type)); + REQUIRE(i64_type.is_subtype_of(i64_type)); + + REQUIRE(!i64_type.is_subtype_of(unit_type)); + REQUIRE(!unit_type.is_subtype_of(i64_type)); + } + + { + REQUIRE(f64_type); + REQUIRE(f64_type.metatype().code() == Metatype::f64().code()); + + REQUIRE(f64_type.is_equal_to(f64_type)); + REQUIRE(f64_type.is_subtype_of(f64_type)); + + REQUIRE(!f64_type.is_subtype_of(unit_type)); + REQUIRE(!f64_type.is_subtype_of(i64_type)); + REQUIRE(!unit_type.is_subtype_of(f64_type)); + REQUIRE(!i64_type.is_subtype_of(f64_type)); + } + + { + REQUIRE(str_type); + REQUIRE(str_type.metatype().code() == Metatype::str().code()); + + REQUIRE(str_type.is_equal_to(str_type)); + REQUIRE(str_type.is_subtype_of(str_type)); + + REQUIRE(!str_type.is_subtype_of(unit_type)); + REQUIRE(!str_type.is_subtype_of(i64_type)); + REQUIRE(!str_type.is_subtype_of(f64_type)); + + REQUIRE(!unit_type.is_subtype_of(str_type)); + REQUIRE(!i64_type.is_subtype_of(str_type)); + REQUIRE(!f64_type.is_subtype_of(str_type)); + } + + { + REQUIRE(any_type); + REQUIRE(any_type.metatype().code() == Metatype::any().code()); + + REQUIRE(any_type.is_equal_to(any_type)); + REQUIRE(any_type.is_subtype_of(any_type)); + + REQUIRE(!any_type.is_subtype_of(unit_type)); + REQUIRE(!any_type.is_subtype_of(i64_type)); + REQUIRE(!any_type.is_subtype_of(f64_type)); + REQUIRE(!any_type.is_subtype_of(str_type)); + + REQUIRE(unit_type.is_subtype_of(any_type)); + REQUIRE(i64_type.is_subtype_of(any_type)); + REQUIRE(f64_type.is_subtype_of(any_type)); + REQUIRE(str_type.is_subtype_of(any_type)); + } } } /*namespace ut*/ diff --git a/xo-type/utest/DListType.test.cpp b/xo-type/utest/DListType.test.cpp new file mode 100644 index 00000000..fed5d916 --- /dev/null +++ b/xo-type/utest/DListType.test.cpp @@ -0,0 +1,65 @@ +/** @file DListType.test.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "init_type.hpp" +#include "TypeOps.hpp" +#include "ListType.hpp" +#include "AtomicType.hpp" +#include +#include +#include +#include + +namespace xo { + using xo::scm::TypeOps; + using xo::scm::AType; + //using xo::scm::DListType; + //using xo::scm::DAtomicType; + using xo::scm::Metatype; + using xo::mm::AAllocator; + using xo::mm::DArena; + using xo::mm::ArenaConfig; + + namespace ut { + static InitEvidence s_init = (InitSubsys::require()); + + TEST_CASE("DListType-make", "[type][DListType]") + { + ArenaConfig cfg { .name_ = "testarena", + .size_ = 4*1024 }; + DArena arena = DArena::map(cfg); + auto alloc = obj(&arena); + + auto i64_type = TypeOps::atomic_type(alloc, Metatype::i64()); + auto list_i64_type = TypeOps::list_type(alloc, i64_type); + + REQUIRE(list_i64_type); + REQUIRE(list_i64_type.is_equal_to(list_i64_type)); + + auto bool_type = TypeOps::atomic_type(alloc, Metatype::t_bool()); + auto list_bool_type = TypeOps::list_type(alloc, bool_type); + + REQUIRE(list_bool_type); + REQUIRE(list_bool_type.is_equal_to(list_bool_type)); + + auto any_type = TypeOps::atomic_type(alloc, Metatype::any()); + auto list_any_type = TypeOps::list_type(alloc, any_type); + + REQUIRE(list_any_type); + REQUIRE(list_any_type.is_equal_to(list_any_type)); + + REQUIRE(list_bool_type.is_subtype_of(list_any_type)); + REQUIRE(list_i64_type.is_subtype_of(list_any_type)); + + REQUIRE(!list_i64_type.is_subtype_of(list_bool_type)); + REQUIRE(!list_any_type.is_subtype_of(list_bool_type)); + REQUIRE(!list_bool_type.is_subtype_of(list_i64_type)); + REQUIRE(!list_any_type.is_subtype_of(list_i64_type)); + } + } +} + + +/* end DListType.cpp */