diff --git a/xo-type/CMakeLists.txt b/xo-type/CMakeLists.txt index b1ea2905..7a318537 100644 --- a/xo-type/CMakeLists.txt +++ b/xo-type/CMakeLists.txt @@ -70,6 +70,26 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-type-facetimpl-type-arraytype + FACET_PKG xo_type + FACET Type + REPR ArrayType + INPUT idl/IType_DArrayType.json5 +) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-type-facetimpl-gcobject-arraytype + FACET_PKG xo_alloc2 + FACET GCObject + REPR ArrayType + INPUT idl/IGCObject_DArrayType.json5 +) + +# ---------------------------------------------------------------- + xo_add_genfacet_all(xo-type-genfacet-all) install(DIRECTORY idl/ diff --git a/xo-type/idl/IGCObject_DArrayType.json5 b/xo-type/idl/IGCObject_DArrayType.json5 new file mode 100644 index 00000000..77e59249 --- /dev/null +++ b/xo-type/idl/IGCObject_DArrayType.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/type", + output_hpp_dir: "include/xo/type", + output_impl_subdir: "array", + includes: [ + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DArrayType", + using_doxygen: true, + repr: "DArrayType", + doc: [ "implement AGCObject for DArrayType" ], +} diff --git a/xo-type/idl/IType_DArrayType.json5 b/xo-type/idl/IType_DArrayType.json5 new file mode 100644 index 00000000..b84ab477 --- /dev/null +++ b/xo-type/idl/IType_DArrayType.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/type", + output_hpp_dir: "include/xo/type", + output_impl_subdir: "array", + includes: [], + local_types: [], + namespace1: "xo", + namespace2: "scm", + + facet_idl: "idl/Type.json5", + brief: "provide AType interface for DArrayType", + using_doxygen: true, + repr: "DArrayType", + doc: [ "implement AType for DArrayType" ], +} diff --git a/xo-type/include/xo/type/ArrayType.hpp b/xo-type/include/xo/type/ArrayType.hpp new file mode 100644 index 00000000..f0c5aa7a --- /dev/null +++ b/xo-type/include/xo/type/ArrayType.hpp @@ -0,0 +1,12 @@ +/** @file ArrayType.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DArrayType.hpp" +#include "array/IType_DArrayType.hpp" +#include "array/IGCObject_DArrayType.hpp" + +/* end ArrayType.hpp */ diff --git a/xo-type/include/xo/type/DArrayType.hpp b/xo-type/include/xo/type/DArrayType.hpp new file mode 100644 index 00000000..945f7f0a --- /dev/null +++ b/xo-type/include/xo/type/DArrayType.hpp @@ -0,0 +1,60 @@ +/** @file DArrayType.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "Type.hpp" +#include "Metatype.hpp" +#include +#include + +namespace xo { + namespace scm { + /** @brief A parameterized array type: array(T) + * + * Represents a fixed-size homogeneous collection. + **/ + class DArrayType { + public: + using ACollector = xo::mm::ACollector; + using AAllocator = xo::mm::AAllocator; + + public: + /** @defgroup xo-scm-arraytype-ctors **/ + ///@{ + + explicit DArrayType(obj elt); + + /** create instance using memory from @p mm with element type @p elt_type **/ + static DArrayType * _make(obj mm, obj elt_type); + + ///@} + /** @defgroup xo-scm-arraytype-type-facet **/ + ///@{ + Metatype metatype() const noexcept { return Metatype::array(); } + bool is_equal_to(const obj & y) const noexcept; + bool is_subtype_of(const obj & y) const noexcept; + ///@} + /** @defgroup xo-scm-arraytype-gcobject-facet **/ + ///@{ + std::size_t shallow_size() const noexcept; + DArrayType * shallow_copy(obj mm) const noexcept; + std::size_t forward_children(obj gc) noexcept; + ///@} + + private: + /** @defgroup xo-scm-arraytype-member-vars **/ + ///@{ + + /** all array elements satisfy @ref elt_type_ **/ + obj elt_type_; + + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DArrayType.hpp */ diff --git a/xo-type/include/xo/type/Metatype.hpp b/xo-type/include/xo/type/Metatype.hpp index 2d7b2a5d..e1119801 100644 --- a/xo-type/include/xo/type/Metatype.hpp +++ b/xo-type/include/xo/type/Metatype.hpp @@ -46,6 +46,7 @@ namespace xo { static Metatype any() { return Metatype(code::t_any); } static Metatype list() { return Metatype(code::t_list); } + static Metatype array() { return Metatype(code::t_array); } /** description string for this type category **/ const char * _descr() const noexcept; diff --git a/xo-type/include/xo/type/TypeOps.hpp b/xo-type/include/xo/type/TypeOps.hpp index b31fa039..8877ae8d 100644 --- a/xo-type/include/xo/type/TypeOps.hpp +++ b/xo-type/include/xo/type/TypeOps.hpp @@ -5,6 +5,7 @@ #include "AtomicType.hpp" #include "ListType.hpp" +#include "ArrayType.hpp" #include namespace xo { @@ -23,6 +24,11 @@ namespace xo { static obj list_type(obj mm, obj elt_type) { return obj(DListType::_make(mm, elt_type)); } + + template + static obj array_type(obj mm, obj elt_type) { + return obj(DArrayType::_make(mm, elt_type)); + } }; } /*namespace scm*/ diff --git a/xo-type/include/xo/type/array/IGCObject_DArrayType.hpp b/xo-type/include/xo/type/array/IGCObject_DArrayType.hpp new file mode 100644 index 00000000..bb71960f --- /dev/null +++ b/xo-type/include/xo/type/array/IGCObject_DArrayType.hpp @@ -0,0 +1,65 @@ +/** @file IGCObject_DArrayType.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DArrayType.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DArrayType.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include "DArrayType.hpp" + +namespace xo { namespace scm { class IGCObject_DArrayType; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DArrayType + **/ + class IGCObject_DArrayType { + public: + /** @defgroup scm-gcobject-darraytype-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-darraytype-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DArrayType & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DArrayType & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DArrayType & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-type/include/xo/type/array/IType_DArrayType.hpp b/xo-type/include/xo/type/array/IType_DArrayType.hpp new file mode 100644 index 00000000..e323931b --- /dev/null +++ b/xo-type/include/xo/type/array/IType_DArrayType.hpp @@ -0,0 +1,63 @@ +/** @file IType_DArrayType.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IType_DArrayType.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IType_DArrayType.json5] + **/ + +#pragma once + +#include "Type.hpp" +#include "DArrayType.hpp" + +namespace xo { namespace scm { class IType_DArrayType; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::scm::IType_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IType_DArrayType + **/ + class IType_DArrayType { + public: + /** @defgroup scm-type-darraytype-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-darraytype-methods **/ + ///@{ + // const methods + /** category for this type **/ + static Metatype metatype(const DArrayType & self) noexcept; + /** true iff this type is equal to y **/ + static bool is_equal_to(const DArrayType & self, const obj_AType & y); + /** true iff this is a subtype of y **/ + static bool is_subtype_of(const DArrayType & self, const obj_AType & y); + + // non-const methods + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-type/src/type/CMakeLists.txt b/xo-type/src/type/CMakeLists.txt index 7f708fb4..d00c30bf 100644 --- a/xo-type/src/type/CMakeLists.txt +++ b/xo-type/src/type/CMakeLists.txt @@ -9,11 +9,14 @@ set(SELF_SRCS Metatype.cpp DAtomicType.cpp DListType.cpp + DArrayType.cpp IType_Any.cpp IType_DAtomicType.cpp IType_DListType.cpp + IType_DArrayType.cpp IGCObject_DAtomicType.cpp IGCObject_DListType.cpp + IGCObject_DArrayType.cpp ) xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) diff --git a/xo-type/src/type/DArrayType.cpp b/xo-type/src/type/DArrayType.cpp new file mode 100644 index 00000000..de5320e2 --- /dev/null +++ b/xo-type/src/type/DArrayType.cpp @@ -0,0 +1,92 @@ +/** @file DArrayType.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "Type.hpp" +#include "ArrayType.hpp" +#include +#include +#include + +namespace xo { + using xo::mm::AGCObject; + using xo::mm::AAllocator; + using xo::facet::FacetRegistry; + + namespace scm { + + DArrayType::DArrayType(obj elt) : elt_type_{elt} {} + + DArrayType * + DArrayType::_make(obj mm, + obj elt_type) + { + void * mem = mm.alloc_for(); + + return new (mem) DArrayType(elt_type); + } + + // ----- type facet ----- + + bool + DArrayType::is_equal_to(const obj & y_arg) const noexcept + { + Metatype y_mtype = y_arg.metatype(); + + if (y_mtype != Metatype::array()) + return false; + + auto y = obj::from(y_arg); + + obj e = elt_type_; + + return (e.is_equal_to(y->elt_type_)); + } + + bool + DArrayType::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::array()) + 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 + DArrayType::shallow_size() const noexcept + { + return sizeof(*this); + } + + DArrayType * + DArrayType::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DArrayType::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 DArrayType.cpp */ diff --git a/xo-type/src/type/IGCObject_DArrayType.cpp b/xo-type/src/type/IGCObject_DArrayType.cpp new file mode 100644 index 00000000..936f8eec --- /dev/null +++ b/xo-type/src/type/IGCObject_DArrayType.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DArrayType.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DArrayType.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DArrayType.json5] +**/ + +#include "array/IGCObject_DArrayType.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DArrayType::shallow_size(const DArrayType & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DArrayType::shallow_copy(const DArrayType & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DArrayType::forward_children(DArrayType & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DArrayType.cpp */ diff --git a/xo-type/src/type/IType_DArrayType.cpp b/xo-type/src/type/IType_DArrayType.cpp new file mode 100644 index 00000000..2ed60101 --- /dev/null +++ b/xo-type/src/type/IType_DArrayType.cpp @@ -0,0 +1,40 @@ +/** @file IType_DArrayType.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IType_DArrayType.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IType_DArrayType.json5] +**/ + +#include "array/IType_DArrayType.hpp" + +namespace xo { + namespace scm { + auto + IType_DArrayType::metatype(const DArrayType & self) noexcept -> Metatype + { + return self.metatype(); + } + + auto + IType_DArrayType::is_equal_to(const DArrayType & self, const obj_AType & y) -> bool + { + return self.is_equal_to(y); + } + + auto + IType_DArrayType::is_subtype_of(const DArrayType & self, const obj_AType & y) -> bool + { + return self.is_subtype_of(y); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IType_DArrayType.cpp */ diff --git a/xo-type/src/type/type_register_facets.cpp b/xo-type/src/type/type_register_facets.cpp index 549633cd..8cebc6f0 100644 --- a/xo-type/src/type/type_register_facets.cpp +++ b/xo-type/src/type/type_register_facets.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -28,8 +29,12 @@ namespace xo { 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())); + log && log(xtag("DArrayType.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 8e2cdda6..884de0cd 100644 --- a/xo-type/src/type/type_register_types.cpp +++ b/xo-type/src/type/type_register_types.cpp @@ -7,6 +7,7 @@ #include "AtomicType.hpp" #include "ListType.hpp" +#include "ArrayType.hpp" #include #include #include @@ -27,6 +28,7 @@ namespace xo { ok &= gc.install_type(impl_for()); 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 cc18708a..6ddf4ce4 100644 --- a/xo-type/utest/CMakeLists.txt +++ b/xo-type/utest/CMakeLists.txt @@ -5,6 +5,7 @@ set(UTEST_SRCS type_utest_main.cpp DAtomicType.test.cpp DListType.test.cpp + DArrayType.test.cpp # DString.test.cpp # StringOps.test.cpp # X1Collector.test.cpp diff --git a/xo-type/utest/DArrayType.test.cpp b/xo-type/utest/DArrayType.test.cpp new file mode 100644 index 00000000..fc4ed8cb --- /dev/null +++ b/xo-type/utest/DArrayType.test.cpp @@ -0,0 +1,70 @@ +/** @file DArrayType.test.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "init_type.hpp" +#include "TypeOps.hpp" +#include "ArrayType.hpp" +#include "ListType.hpp" +#include "AtomicType.hpp" +#include +#include +#include +#include + +namespace xo { + using xo::scm::TypeOps; + using xo::scm::AType; + 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("DArrayType-make", "[type][DArrayType]") + { + 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 array_i64_type = TypeOps::array_type(alloc, i64_type); + + REQUIRE(array_i64_type); + REQUIRE(array_i64_type.is_equal_to(array_i64_type)); + + auto bool_type = TypeOps::atomic_type(alloc, Metatype::t_bool()); + auto array_bool_type = TypeOps::array_type(alloc, bool_type); + + REQUIRE(array_bool_type); + REQUIRE(array_bool_type.is_equal_to(array_bool_type)); + + auto any_type = TypeOps::atomic_type(alloc, Metatype::any()); + auto array_any_type = TypeOps::array_type(alloc, any_type); + + REQUIRE(array_any_type); + REQUIRE(array_any_type.is_equal_to(array_any_type)); + + REQUIRE(array_bool_type.is_subtype_of(array_any_type)); + REQUIRE(array_i64_type.is_subtype_of(array_any_type)); + + REQUIRE(!array_i64_type.is_subtype_of(array_bool_type)); + REQUIRE(!array_any_type.is_subtype_of(array_bool_type)); + REQUIRE(!array_bool_type.is_subtype_of(array_i64_type)); + REQUIRE(!array_any_type.is_subtype_of(array_i64_type)); + + // array and list are unrelated + auto list_i64_type = TypeOps::list_type(alloc, i64_type); + REQUIRE(!array_i64_type.is_equal_to(list_i64_type)); + REQUIRE(!array_i64_type.is_subtype_of(list_i64_type)); + REQUIRE(!list_i64_type.is_subtype_of(array_i64_type)); + } + } +} + + +/* end DArrayType.test.cpp */