diff --git a/xo-alloc2/idl/GCObject.json5 b/xo-alloc2/idl/GCObject.json5 deleted file mode 100644 index e826af21..00000000 --- a/xo-alloc2/idl/GCObject.json5 +++ /dev/null @@ -1,59 +0,0 @@ -{ - mode: "facet", - includes: [], - namespace1: "xo", - namespace2: "scm", - facet: "GCObject", - detail_subdir: "detail", - brief: "xxx", - using_doxygen: true, - doc: [ - "GC hooks for collector-aware data" - ], - types: [ - // using size_type = std::size_t - { - name: "size_type", - doc: ["type for an amount of memory"], - definition: "std::size_t", - }, - ], - const_methods: [ - // size_type shallow_size() const noexcept - { - name: "shallow_size", - doc: ["memory consumption for this instance"], - return_type: "size_type", - args: [], - const: true, - noexcept: true, - attributes: [], - }, - // Opaque shallow_copy(obj>) const noexcept - { - name: "shallow_copy", - doc: ["copy instance using allocator"], - return_type: "Opaque", - args:[ - {types: "obj", name: "mm"}, - ], - const: true, - noexcept: true, - attributes: [], - }, - ], - nonconst_methods: [ - // size_type forward_children(obj) const noexcept - { - name: "size_type", - doc: ["during GC: forward immdiate children"]. - return_type: "size_type", - args: [ - {types: "obj", name: "gc"}, - ], - const: true, - noexcept: true, - attributes: [], - }, - ], -} \ No newline at end of file diff --git a/xo-facet/codegen/abstract_facet.hpp.j2 b/xo-facet/codegen/abstract_facet.hpp.j2 index e1fc17cf..76985b6a 100644 --- a/xo-facet/codegen/abstract_facet.hpp.j2 +++ b/xo-facet/codegen/abstract_facet.hpp.j2 @@ -43,6 +43,8 @@ public: // types /** integer identifying a type **/ using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; {% for ty in types %} /** {{ty.doc}} **/ using {{ty.name}} = {{ty.definition}}; diff --git a/xo-facet/codegen/genfacet b/xo-facet/codegen/genfacet index eef2eec1..788faf46 100755 --- a/xo-facet/codegen/genfacet +++ b/xo-facet/codegen/genfacet @@ -265,8 +265,8 @@ def gen_facet_impl(env, # doc section for facet facet_doc = '\n'.join(idl['doc']) - types = facet_idl['types'] - for ty in types: + facet_types = facet_idl['types'] + for ty in facet_types: ty['doc'] = '\n'.join(ty['doc']) const_methods = facet_idl['const_methods'] @@ -328,6 +328,8 @@ def gen_facet_impl(env, # repr_ns2: nested namespace for repr [e.g. scm]. repr_ns2 = idl['namespace2'] + # local_types: addition type defs (e.g. repr_ns2 != facet_ns2) + local_types = idl['local_types'] # iface_facet_repr: IFoo_DRepr iface_facet_repr = f'{iface_facet}_{data_repr}' @@ -379,7 +381,8 @@ def gen_facet_impl(env, 'router_facet_hpp_j2': 'router_facet.hpp.j2', 'router_facet_hpp_fname': router_facet_hpp_fname, # - 'types': types, + 'types': facet_types, + 'local_types': local_types, # 'const_methods': const_methods, # diff --git a/xo-facet/codegen/iface_facet_repr.hpp.j2 b/xo-facet/codegen/iface_facet_repr.hpp.j2 index 55b7994b..221d6799 100644 --- a/xo-facet/codegen/iface_facet_repr.hpp.j2 +++ b/xo-facet/codegen/iface_facet_repr.hpp.j2 @@ -46,6 +46,11 @@ namespace {{repr_ns1}} { {% for ty in types %} using {{ty.name}} = {{facet_ns1}}::{{facet_ns2}}::{{abstract_facet}}::{{ty.name}}; {% endfor %} + using Copaque = {{facet_ns1}}::{{facet_ns2}}::{{abstract_facet}}::Copaque; + using Opaque = {{facet_ns1}}::{{facet_ns2}}::{{abstract_facet}}::Opaque; + {% for ty in local_types %} + using {{ty.name}} = {{ty.definition}}; + {% endfor %} {% if using_dox %} ///@} /** @defgroup {{repr_ns2}}-{{facet_name_lc}}-{{data_repr_lc}}-methods **/ diff --git a/xo-gc/idl/GCObject.json5 b/xo-gc/idl/GCObject.json5 index d35916b8..ef00b5d9 100644 --- a/xo-gc/idl/GCObject.json5 +++ b/xo-gc/idl/GCObject.json5 @@ -25,6 +25,16 @@ doc: ["type for an amount of memory"], definition: "std::size_t", }, + { + name: "AAllocator", + doc: ["fomo allocator type"], + definition: "xo::mm::AAllocator", + }, + { + name: "ACollector", + doc: ["fomo collector type"], + definition: "xo::mm::ACollector", + }, ], const_methods: [ // size_type shallow_size() const noexcept diff --git a/xo-gc/include/xo/gc/GCObject.hpp b/xo-gc/include/xo/gc/GCObject.hpp index ebb6d26f..25834817 100644 --- a/xo-gc/include/xo/gc/GCObject.hpp +++ b/xo-gc/include/xo/gc/GCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for facet .hpp file: diff --git a/xo-gc/include/xo/gc/detail/AGCObject.hpp b/xo-gc/include/xo/gc/detail/AGCObject.hpp index 5210dc97..b7a5ffa3 100644 --- a/xo-gc/include/xo/gc/detail/AGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/AGCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -40,8 +40,14 @@ public: // types /** integer identifying a type **/ using typeseq = xo::facet::typeseq; + using Copaque = const void *; + using Opaque = void *; /** type for an amount of memory **/ using size_type = std::size_t; + /** fomo allocator type **/ + using AAllocator = xo::mm::AAllocator; + /** fomo collector type **/ + using ACollector = xo::mm::ACollector; ///@} /** @defgroup mm-gcobject-methods **/ diff --git a/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp b/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp index 9f086669..c930693f 100644 --- a/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObject_Any.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -45,6 +45,8 @@ namespace mm { /** integer identifying a type **/ using typeseq = xo::facet::typeseq; using size_type = AGCObject::size_type; + using AAllocator = AGCObject::AAllocator; + using ACollector = AGCObject::ACollector; ///@} /** @defgroup mm-gcobject-any-methods **/ diff --git a/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp b/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp index 2ece6b01..655263bf 100644 --- a/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp +++ b/xo-gc/include/xo/gc/detail/IGCObject_Xfer.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -32,6 +32,8 @@ namespace mm { /** integer identifying a type **/ using typeseq = AGCObject::typeseq; using size_type = AGCObject::size_type; + using AAllocator = AGCObject::AAllocator; + using ACollector = AGCObject::ACollector; ///@} /** @defgroup mm-gcobject-xfer-methods **/ diff --git a/xo-gc/include/xo/gc/detail/RGCObject.hpp b/xo-gc/include/xo/gc/detail/RGCObject.hpp index ace699c5..e54a2539 100644 --- a/xo-gc/include/xo/gc/detail/RGCObject.hpp +++ b/xo-gc/include/xo/gc/detail/RGCObject.hpp @@ -2,7 +2,7 @@ * * Generated automagically from ingredients: * 1. code generator: - * [/Users/roland/proj/xo-umbrella2/xo-facet/codegen/genfacet] + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] * arguments: * --input [idl/GCObject.json5] * 2. jinja2 template for abstract facet .hpp file: @@ -32,6 +32,8 @@ public: using DataPtr = Object::DataPtr; using typeseq = xo::reflect::typeseq; using size_type = AGCObject::size_type; + using AAllocator = AGCObject::AAllocator; + using ACollector = AGCObject::ACollector; ///@} /** @defgroup mm-gcobject-router-ctors **/ diff --git a/xo-object2/CMakeLists.txt b/xo-object2/CMakeLists.txt index 4dfdf4d8..556e6d66 100644 --- a/xo-object2/CMakeLists.txt +++ b/xo-object2/CMakeLists.txt @@ -64,6 +64,18 @@ xo_add_genfacetimpl( OUTPUT_CPP_DIR src/object2 ) +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-gcobject-string + FACET_PKG xo_gc + FACET GCObject + REPR String + INPUT idl/IGCObject_DString.json5 + OUTPUT_HPP_DIR include/xo/object2 + OUTPUT_IMPL_SUBDIR string + OUTPUT_CPP_DIR src/object2 +) + # ---------------------------------------------------------------- # must complete definition of expression lib before configuring examples diff --git a/xo-object2/idl/IGCObject_DString.json5 b/xo-object2/idl/IGCObject_DString.json5 new file mode 100644 index 00000000..b8fcfba5 --- /dev/null +++ b/xo-object2/idl/IGCObject_DString.json5 @@ -0,0 +1,14 @@ +{ + mode: "implementation", + includes: [ "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DString", + using_doxygen: true, + repr: "DString", + doc: [ "implement AGCObject for DString" ], +} diff --git a/xo-object2/include/xo/object2/DString.hpp b/xo-object2/include/xo/object2/DString.hpp index 7f8e1eeb..accdd96d 100644 --- a/xo-object2/include/xo/object2/DString.hpp +++ b/xo-object2/include/xo/object2/DString.hpp @@ -6,7 +6,9 @@ #pragma once #include +#include #include +#include #include #include @@ -38,11 +40,22 @@ namespace xo { using const_iterator = const char *; /** xo allocator **/ using AAllocator = xo::mm::AAllocator; - + /** garbage collector **/ + using ACollector = xo::mm::ACollector; + /** ppindentinfo for APrintable **/ + using ppindentinfo = xo::print::ppindentinfo; ///@} /** @defgroup dstring-ctors constructors **/ ///@{ + /** default ctor **/ + DString() = default; + + /** not simply copyable, because of flexible array. + * Need allocator + **/ + DString(const DString &) = delete; + /** create empty string with space for @cap chars * (including null terminator). * Use memory from allocator @p mm @@ -56,6 +69,17 @@ namespace xo { static DString * from_cstr(obj mm, const char * cstr); + /** clone existing string **/ + static DString * clone(obj mm, + const DString * src); + +#ifdef NOT_YET + /** **/ + static DString * concat(obj mm, + DString * s1, + DString * s2); +#endif + ///@} /** @defgroup dstring-access access methods **/ ///@{ @@ -141,6 +165,24 @@ namespace xo { operator const char * () const noexcept { return &(chars_[0]); } ///@} + /** @defgroup dstring-printable-methods printable facet methods **/ + ///@{ + + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup dstring-gcobject-methods gcobject facet methods **/ + ///@{ + + size_type shallow_size() const noexcept; + + /** clone string, using memory from allocator @p mm **/ + DString * shallow_copy(obj mm) const noexcept; + + /** fixup child pointers (trivial for DString, no children) **/ + size_type forward_children(obj gc) noexcept; + + ///@} private: /** @defgroup dstring-instance-variables instance variables **/ diff --git a/xo-object2/include/xo/object2/IGCObject_DString.hpp b/xo-object2/include/xo/object2/IGCObject_DString.hpp new file mode 100644 index 00000000..ad12cb80 --- /dev/null +++ b/xo-object2/include/xo/object2/IGCObject_DString.hpp @@ -0,0 +1,66 @@ +/** @file IGCObject_DString.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DString.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DString.json5] + **/ + +#pragma once + +#include +#include +#include "DString.hpp" + +namespace xo { namespace scm { class IGCObject_DString; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DString + **/ + class IGCObject_DString { + public: + /** @defgroup scm-gcobject-dstring-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-dstring-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DString & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DString & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DString & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/xo-object2/src/object2/CMakeLists.txt b/xo-object2/src/object2/CMakeLists.txt index a3658925..4c74529f 100644 --- a/xo-object2/src/object2/CMakeLists.txt +++ b/xo-object2/src/object2/CMakeLists.txt @@ -5,6 +5,7 @@ set(SELF_SRCS IGCObject_DFloat.cpp IGCObject_DInteger.cpp IGCObject_DList.cpp + IGCObject_DString.cpp ISequence_Any.cpp ISequence_DList.cpp IPrintable_DList.cpp diff --git a/xo-object2/src/object2/DString.cpp b/xo-object2/src/object2/DString.cpp index c173d106..3278d258 100644 --- a/xo-object2/src/object2/DString.cpp +++ b/xo-object2/src/object2/DString.cpp @@ -52,6 +52,22 @@ namespace xo { return result; } + DString * + DString::clone(obj mm, const DString * src) + { + size_type cap = src->capacity_; + + void * mem = mm.alloc(typeseq::id(), + sizeof(DString) + cap); + + DString * result = new (mem) DString(); + result->capacity_ = cap; + result->size_ = src->size_; + std::memcpy(result->chars_, src->chars_, cap); + + return result; + } + DString & DString::assign(const DString & other) { @@ -71,6 +87,32 @@ namespace xo { return this->size_; } + auto + DString::shallow_size() const noexcept -> size_type + { + return sizeof(DString) + capacity_; + } + + DString * + DString::shallow_copy(obj mm) const noexcept + { + DString * copy = (DString *)mm.alloc_copy((std::byte *)this); + + if (copy) { + copy->capacity_ = capacity_; + copy->size_ = size_; + ::memcpy(copy->chars_, chars_, capacity_); + } + + return copy; + } + + auto + DString::forward_children(obj) noexcept -> size_type + { + return shallow_size(); + } + } /*namespace scm*/ } /*namespace xo*/ diff --git a/xo-object2/src/object2/IGCObject_DString.cpp b/xo-object2/src/object2/IGCObject_DString.cpp new file mode 100644 index 00000000..72a81244 --- /dev/null +++ b/xo-object2/src/object2/IGCObject_DString.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DString.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [/home/roland/proj/xo-umbrella2-claude1/xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DString.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DString.json5] +**/ + +#include "IGCObject_DString.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DString::shallow_size(const DString & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DString::shallow_copy(const DString & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DString::forward_children(DString & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DString.cpp */ \ No newline at end of file diff --git a/xo-object2/src/object2/object2_register_facets.cpp b/xo-object2/src/object2/object2_register_facets.cpp index 210fb7c0..c33b0637 100644 --- a/xo-object2/src/object2/object2_register_facets.cpp +++ b/xo-object2/src/object2/object2_register_facets.cpp @@ -4,9 +4,11 @@ **/ #include "object2_register_facets.hpp" + #include #include #include +#include #include #include @@ -23,6 +25,7 @@ namespace xo { using xo::mm::AGCObject; using xo::scm::DList; using xo::scm::DFloat; + using xo::scm::DString; using xo::facet::FacetRegistry; using xo::facet::typeseq; @@ -41,9 +44,12 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + log && log(xtag("DList.tseq", typeseq::id())); log && log(xtag("DFloat.tseq", typeseq::id())); log && log(xtag("DInteger.tseq", typeseq::id())); + log && log(xtag("DString.tseq", typeseq::id())); log && log(xtag("AAllocator.tseq", typeseq::id())); log && log(xtag("APrintable.tseq", typeseq::id())); diff --git a/xo-object2/utest/DString.test.cpp b/xo-object2/utest/DString.test.cpp index c6d217f1..b5f70f17 100644 --- a/xo-object2/utest/DString.test.cpp +++ b/xo-object2/utest/DString.test.cpp @@ -243,6 +243,23 @@ namespace xo { REQUIRE(std::strcmp(s->chars(), "HELLO") == 0); } + + TEST_CASE("DString-clone", "[object2][DString]") + { + ArenaConfig cfg { .name_ = "testarena", + .size_ = 4*1024 }; + DArena arena = DArena::map(cfg); + auto alloc = with_facet::mkobj(&arena); + + DString * src = DString::from_cstr(alloc, "hello world"); + DString * copy = DString::clone(alloc, src); + + REQUIRE(copy != nullptr); + REQUIRE(copy != src); + REQUIRE(copy->size() == src->size()); + REQUIRE(copy->capacity() == src->capacity()); + REQUIRE(std::strcmp(copy->chars(), src->chars()) == 0); + } } /*namespace ut*/ } /*namespace xo*/