diff --git a/cmake/xo_object2Config.cmake.in b/cmake/xo_object2Config.cmake.in index 2277209..78ee9e0 100644 --- a/cmake/xo_object2Config.cmake.in +++ b/cmake/xo_object2Config.cmake.in @@ -3,6 +3,7 @@ include(CMakeFindDependencyMacro) find_dependency(reflect) find_dependency(xo_gc) +find_dependency(xo_stringtable2) find_dependency(xo_printable2) find_dependency(subsys) find_dependency(indentlog) diff --git a/idl/IGCObject_DString.json5 b/idl/IGCObject_DString.json5 deleted file mode 100644 index caf33fa..0000000 --- a/idl/IGCObject_DString.json5 +++ /dev/null @@ -1,18 +0,0 @@ -{ - mode: "implementation", - output_cpp_dir: "src/object2", - output_hpp_dir: "include/xo/object2", - output_impl_subdir: "string", - 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/idl/IPrintable_DString.json5 b/idl/IPrintable_DString.json5 deleted file mode 100644 index 8510938..0000000 --- a/idl/IPrintable_DString.json5 +++ /dev/null @@ -1,16 +0,0 @@ -{ - mode: "implementation", - output_cpp_dir: "src/object2", - output_hpp_dir: "include/xo/object2", - output_impl_subdir: "string", - includes: [ "", - "" ], - local_types: [ ], - namespace1: "xo", - namespace2: "scm", - facet_idl: "idl/Printable.json5", - brief: "provide APrintable interface for DString", - using_doxygen: true, - repr: "DString", - doc: [ "implement APrintable for DString" ], -} diff --git a/include/xo/object2/DString.hpp b/include/xo/object2/DString.hpp deleted file mode 100644 index bb57e3d..0000000 --- a/include/xo/object2/DString.hpp +++ /dev/null @@ -1,348 +0,0 @@ -/** @file DString.hpp -* - * @author Roland Conybeare, Jan 2026 - **/ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -//#include - -namespace xo { - namespace mm { class ACollector; } - - namespace scm { - /** @class DString - * @brief String implementation with gc hooks - * - * String implementation for Schematika. - * Size-prefixed and null-terminated. - * Note however that string length != size for utf-8. - * - * Uses flexible array for chars, - * with string contents in memory immediately - * following the DString itself - **/ - struct DString { - public: - /** @defgroup dstring-types type traits **/ - ///@{ - /** character traits for this DString **/ - using traits_type = std::char_traits; - /** type of each character in this DString **/ - using value_type = char; - /** type for string index / size **/ - using size_type = std::uint32_t; - /** representation for a read/write iterator **/ - using iterator = char *; - /** representation for a readonly iterator **/ - 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 @p cap chars - * (including null terminator). - * Use memory from allocator @p mm - **/ - static DString * empty(obj mm, - size_type cap); - - /** create string containing a copy of null-terminated @p cstr. - * Use memory from allocator @p mm - **/ - static DString * from_cstr(obj mm, - const char * cstr); - - /** create string containing a copy of @p sv. - * Use memory from allocator @p mm. - **/ - static DString * from_view(obj mm, - std::string_view sv); - - /** create string containing a copy @p str. - * Use memory from allocator @p mm. - **/ - static DString * from_str(obj mm, - const std::string & str); - - /** create string containing a copy of @p sv. - * Use memory from allocator @p mm via sub_alloc. - * (load-bearing for StringTable) - **/ - static DString * from_view_suballoc(obj mm, - std::string_view sv); - - /** clone existing string **/ - static DString * clone(obj mm, - const DString * src); - -#ifdef NOT_YET - /** **/ - static DString * concat(obj mm, - DString * s1, - DString * s2); -#endif - - /** create string using printf-style formatting. - * Use memory from allocator @p mm with capacity @p cap. - * Truncates if result exceeds capacity. - * @return pointer to newly created DString - **/ - template - static DString * printf(obj mm, - size_type cap, - const char * fmt, - Args&&... args); - - ///@} - /** @defgroup dstring-access access methods **/ - ///@{ - - /** get writeable access to string representation. - * Caller responsible for calling fixup() if string length modified - **/ - char * data() noexcept { return chars_; } - - /** return char at position @p pos in this string, counting from zero. - * Does not check bounds. Undefined behavior if @p pos = @ref capacity_ - **/ - char & operator[](size_type pos) noexcept { return chars_[pos]; } - const char & operator[](size_type pos) const noexcept { return chars_[pos]; } - - size_type capacity() const noexcept { return capacity_; } - size_type size() const noexcept { return size_; } - const char * chars() const noexcept { return chars_; } - - ///@} - /** @defgroup dstring-iterators iterators **/ - ///@{ - iterator begin() noexcept { return &chars_[0]; } - iterator end() noexcept { return &chars_[size_]; } - - const_iterator cbegin() const noexcept { return &chars_[0]; } - const_iterator cend() const noexcept { return &chars_[size_]; } - const_iterator begin() const noexcept { return cbegin(); } - const_iterator end() const noexcept { return cend(); } - - ///@} - /** @defgroup dstring-assign assignment **/ - ///@{ - - /** put string into empty state **/ - void clear() noexcept { size_ = 0; chars_[0] = '\0'; } - - /** replace contents with @p other, or prefix of up to @p capacity - 1 chars **/ - DString & assign(const DString & other); - ///@} - /** @defgroup dstring-general general methods **/ - ///@{ - - /** format string into this DString using printf-style formatting. - * Truncates if result exceeds capacity. - * @return number of characters written (excluding null terminator) - **/ - template - size_type sprintf(const char * fmt, Args&&... args) { - int n; - if constexpr (sizeof...(Args) == 0) { - n = std::snprintf(chars_, capacity_, "%s", fmt); - } else { - n = std::snprintf(chars_, capacity_, fmt, std::forward(args)...); - } - if (n < 0) { - size_ = 0; - chars_[0] = '\0'; - } else { - size_ = (n < static_cast(capacity_)) ? n : capacity_ - 1; - } - return size_; - } - - /** lexicographically compare two strings. - * @return <0 if lhs < rhs, 0 if equal, >0 if lhs > rhs - **/ - static int compare(const DString & lhs, const DString & rhs) noexcept; - - /** compute hash of string contents **/ - std::size_t hash() const noexcept { - return std::hash{}(std::string_view(chars_, size_)); - } - - // TODO - behave like std::string, to the extent feasible - // insert - // insert_range - // erase - // push_back - // append - // append_range - // operator+= - // replace - // replace_with_range - // copy - // find - // rfind - // find_first_of - // find_first_not_of - // find_last_of - // find_last_not_of - // starts_with - // end_with - // contains - // substr - - /** recalculate string size if string contents modified without - * through side effects - **/ - size_type fixup_size() noexcept; - - ///@} - /** @defgroup dstring-conversion-operators conversion operators **/ - ///@{ - - operator std::string_view() const noexcept { return std::string_view(chars_); } - - /** @brief conversion oeprator to C-style string. - * - * Example - * @code - * DString s = ...; - * ::strcmp(s, "obey..."); - * @endcode - **/ - 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; - - size_type forward_children(obj gc) noexcept; - /** fixup child pointers (trivial for DString, no children) - * note: cref so we can use forward decl - **/ - - ///@} - - private: - /** @defgroup dstring-impl-methods implementation methods **/ - ///@{ - - /** create instance from view @p sv, using memory from @p mm. - * @p suballoc_flag chooses whether to use alloc() or suballoc(). - * Load-bearing for StringTable - **/ - static DString * _from_view_aux(obj mm, - std::string_view sv, - bool suballoc_flag); - - ///@} - - private: - /** @defgroup dstring-instance-variables instance variables **/ - ///@{ - - /** extent of @ref chars_ array **/ - size_type capacity_ = 0; - /** null terminator at @c chars_[size_] **/ - size_type size_ = 0; - /** string contents **/ - char chars_[]; - - ///@} - }; - - /** create string using printf-style formatting. - * Use memory from allocator @p mm with capacity @p cap. - * Truncates if result exceeds capacity. - * @return pointer to newly created DString - **/ - template - DString * DString::printf(obj mm, - size_type cap, - const char * fmt, - Args&&... args) - { - DString * result = DString::empty(mm, cap); - if (result) { - result->sprintf(fmt, std::forward(args)...); - } - return result; - } - - inline std::ostream & operator<<(std::ostream & os, const DString * x) { - if (x) { - os << std::string_view(*x); - } else { - os << "nullptr"; - } - return os; - } - - inline bool operator==(const DString & lhs, const DString & rhs) { - return DString::compare(lhs, rhs) == 0; - } - - inline bool operator!=(const DString & lhs, const DString & rhs) { - return DString::compare(lhs, rhs) != 0; - } - - inline bool operator<(const DString & lhs, const DString & rhs) { - return DString::compare(lhs, rhs) < 0; - } - - inline bool operator<=(const DString & lhs, const DString & rhs) { - return DString::compare(lhs, rhs) <= 0; - } - - inline bool operator>(const DString & lhs, const DString & rhs) { - return DString::compare(lhs, rhs) > 0; - } - - inline bool operator>=(const DString & lhs, const DString & rhs) { - return DString::compare(lhs, rhs) >= 0; - } - - } /*namespace scm*/ -} /*namespace xo*/ - -namespace std { - template <> - struct hash { - std::size_t operator()(const xo::scm::DString & x) const noexcept { - return x.hash(); - } - }; -} /*namespace std*/ - -/* end DString.hpp */ diff --git a/include/xo/object2/String.hpp b/include/xo/object2/String.hpp deleted file mode 100644 index f3d0527..0000000 --- a/include/xo/object2/String.hpp +++ /dev/null @@ -1,14 +0,0 @@ -/** @file String.hpp - * - * @author Roland Conybeare, Feb 2026 - **/ - -#pragma once - -#include "DString.hpp" -#include "string/IGCObject_DString.hpp" -#include "string/IPrintable_DString.hpp" - -#include - -/* end String.hpp */ diff --git a/include/xo/object2/StringOps.hpp b/include/xo/object2/StringOps.hpp deleted file mode 100644 index 70441b4..0000000 --- a/include/xo/object2/StringOps.hpp +++ /dev/null @@ -1,80 +0,0 @@ -/** @file StringOps.hpp -* - * @author Roland Conybeare, Jan 2026 - **/ - -#pragma once - -#include "string/IGCObject_DString.hpp" -#include "DString.hpp" - -namespace xo { - namespace scm { - /** @brief string functions - * - * note: separate from DString - **/ - struct StringOps { - using AGCObject = xo::mm::AGCObject; - using AAllocator = xo::mm::AAllocator; - using size_type = DString::size_type; - - /** wrapper for DString.empty() **/ - template - static obj empty(obj mm, - size_type cap); - - /** wrapper for DString.from_cstr() **/ - template - static obj from_cstr(obj mm, - const char * cstr); - - /** wrapper for DString.clone() **/ - template - static obj clone(obj mm, - obj src); - - /** wrapper for DString.printf() **/ - template - static obj printf(obj mm, - size_type cap, - const char * fmt, - Args&&... args); - }; - - template - obj - StringOps::empty(obj mm, size_type cap) - { - return obj(DString::empty(mm, cap)); - } - - template - obj - StringOps::from_cstr(obj mm, const char * cstr) - { - return obj(DString::from_cstr(mm, cstr)); - } - - template - obj - StringOps::clone(obj mm, obj src) - { - return obj(DString::clone(mm, src.data())); - } - - template - obj - StringOps::printf(obj mm, - size_type cap, - const char * fmt, - Args&&... args) - { - return obj(DString::printf(mm, cap, fmt, - std::forward(args)...)); - } - } -} - -/* end StringOps.hpp */ diff --git a/include/xo/object2/object2_register_facets.hpp b/include/xo/object2/object2_register_facets.hpp index 7f42d5a..7fb75cc 100644 --- a/include/xo/object2/object2_register_facets.hpp +++ b/include/xo/object2/object2_register_facets.hpp @@ -5,8 +5,6 @@ #pragma once -#include - namespace xo { namespace scm { /** Register object2 (facet,impl) combinations with FacetRegistry **/ diff --git a/include/xo/object2/string/IGCObject_DString.hpp b/include/xo/object2/string/IGCObject_DString.hpp deleted file mode 100644 index 2a907f3..0000000 --- a/include/xo/object2/string/IGCObject_DString.hpp +++ /dev/null @@ -1,67 +0,0 @@ -/** @file IGCObject_DString.hpp - * - * Generated automagically from ingredients: - * 1. code generator: - * [xo-facet/codegen/genfacet] - * arguments: - * --input [idl/IGCObject_DString.json5] - * 2. jinja2 template for abstract facet .hpp file: - * [iface_facet_repr.hpp.j2] - * 3. idl for facet methods - * [idl/IGCObject_DString.json5] - **/ - -#pragma once - -#include "GCObject.hpp" -#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 */ diff --git a/include/xo/object2/string/IPrintable_DString.hpp b/include/xo/object2/string/IPrintable_DString.hpp deleted file mode 100644 index f898a17..0000000 --- a/include/xo/object2/string/IPrintable_DString.hpp +++ /dev/null @@ -1,62 +0,0 @@ -/** @file IPrintable_DString.hpp - * - * Generated automagically from ingredients: - * 1. code generator: - * [xo-facet/codegen/genfacet] - * arguments: - * --input [idl/IPrintable_DString.json5] - * 2. jinja2 template for abstract facet .hpp file: - * [iface_facet_repr.hpp.j2] - * 3. idl for facet methods - * [idl/IPrintable_DString.json5] - **/ - -#pragma once - -#include "Printable.hpp" -#include -#include -#include "DString.hpp" - -namespace xo { namespace scm { class IPrintable_DString; } } - -namespace xo { - namespace facet { - template <> - struct FacetImplementation - { - using ImplType = xo::print::IPrintable_Xfer - ; - }; - } -} - -namespace xo { - namespace scm { - /** @class IPrintable_DString - **/ - class IPrintable_DString { - public: - /** @defgroup scm-printable-dstring-type-traits **/ - ///@{ - using ppindentinfo = xo::print::APrintable::ppindentinfo; - using Copaque = xo::print::APrintable::Copaque; - using Opaque = xo::print::APrintable::Opaque; - ///@} - /** @defgroup scm-printable-dstring-methods **/ - ///@{ - // const methods - /** Pretty-printing support for this object. -See [xo-indentlog/xo/indentlog/pretty.hpp] **/ - static bool pretty(const DString & self, const ppindentinfo & ppii); - - // non-const methods - ///@} - }; - - } /*namespace scm*/ -} /*namespace xo*/ - -/* end */ \ No newline at end of file diff --git a/src/object2/CMakeLists.txt b/src/object2/CMakeLists.txt index e9ae687..f0aaefb 100644 --- a/src/object2/CMakeLists.txt +++ b/src/object2/CMakeLists.txt @@ -33,10 +33,6 @@ set(SELF_SRCS IGCObject_DBoolean.cpp IPrintable_DBoolean.cpp - DString.cpp - IGCObject_DString.cpp - IPrintable_DString.cpp - DDictionary.cpp IGCObject_DDictionary.cpp IPrintable_DDictionary.cpp @@ -50,6 +46,7 @@ xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 $ # note: deps here must also appear in cmake/xo_object2Config.cmake.in xo_dependency(${SELF_LIB} reflect) xo_dependency(${SELF_LIB} xo_gc) +xo_dependency(${SELF_LIB} xo_stringtable2) xo_dependency(${SELF_LIB} xo_printable2) xo_dependency(${SELF_LIB} subsys) xo_dependency(${SELF_LIB} indentlog) diff --git a/src/object2/DString.cpp b/src/object2/DString.cpp deleted file mode 100644 index 230fa4a..0000000 --- a/src/object2/DString.cpp +++ /dev/null @@ -1,187 +0,0 @@ -/** @file DString.cpp - * - * @author Roland Conybeare, Jan 2026 - **/ - -#include "DString.hpp" -#include -#include -#include -#include - -namespace xo { - using xo::reflect::typeseq; - using xo::print::ppdetail_atomic; - - namespace scm { - DString * - DString::empty(obj mm, - size_type cap) - { - assert(cap > 0); - - DString * result = nullptr; - - if (cap > 0) { - void * mem = mm.alloc(typeseq::id(), - sizeof(DString) + cap); - - result = new (mem) DString(); - - assert(result); - - result->capacity_ = cap; - result->size_ = 0; - if (cap > 0) { - result->chars_[0] = '\0'; - } - } - - return result; - } - - DString * - DString::from_cstr(obj mm, - const char * cstr) - { - size_type len = std::strlen(cstr); - size_type cap = len + 1; - - void * mem = mm.alloc(typeseq::id(), - sizeof(DString) + cap); - - DString * result = new (mem) DString(); - result->capacity_ = cap; - result->size_ = len; - std::memcpy(result->chars_, cstr, cap); - - return result; - } - - DString * - DString::_from_view_aux(obj mm, - std::string_view sv, - bool suballoc_flag) - { - size_type len = sv.size(); - size_type cap = len + 1; - - auto tseq = typeseq::id(); - void * mem = nullptr; - size_type mem_z = sizeof(DString) + cap; - - if (suballoc_flag) - mem = mm.sub_alloc(mem_z, false /*!complete_flag*/); - else - mem = mm.alloc(tseq, mem_z); - - DString * result = new (mem) DString(); - - result->capacity_ = cap; - result->size_ = len; - std::memcpy(result->chars_, sv.data(), len); - result->chars_[len] = '\0'; - - return result; - } - - DString * - DString::from_view(obj mm, - std::string_view sv) - { - return _from_view_aux(mm, sv, false /*!suballoc_flag*/); - } - - DString * - DString::from_str(obj mm, - const std::string & str) - { - return _from_view_aux(mm, - std::string_view(str), - false /*!suballoc_flag*/); - } - - DString * - DString::from_view_suballoc(obj mm, - std::string_view sv) - { - return _from_view_aux(mm, sv, true /*suballoc_flag*/); - } - - 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) - { - size_type n = std::min(other.size_, capacity_ - 1); - std::memcpy(chars_, other.chars_, n); - chars_[n] = '\0'; - size_ = n; - - return *this; - } - - int - DString::compare(const DString & lhs, const DString & rhs) noexcept - { - return ::strcmp(lhs.chars_, rhs.chars_); - } - - auto - DString::fixup_size() noexcept -> size_type - { - this->chars_[capacity_ - 1] = '\0'; - this->size_ = ::strlen(chars_); - 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(); - } - - bool - DString::pretty(const ppindentinfo & ppii) const - { - return ppdetail_atomic::print_pretty(ppii, &(chars_[0])); - } - - } /*namespace scm*/ -} /*namespace xo*/ - -/* end DString.cpp */ diff --git a/src/object2/IGCObject_DString.cpp b/src/object2/IGCObject_DString.cpp deleted file mode 100644 index d34f0ea..0000000 --- a/src/object2/IGCObject_DString.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/** @file IGCObject_DString.cpp - * - * Generated automagically from ingredients: - * 1. code generator: - * [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 "string/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 */ diff --git a/src/object2/IPrintable_DString.cpp b/src/object2/IPrintable_DString.cpp deleted file mode 100644 index f5ec496..0000000 --- a/src/object2/IPrintable_DString.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/** @file IPrintable_DString.cpp - * - * Generated automagically from ingredients: - * 1. code generator: - * [xo-facet/codegen/genfacet] - * arguments: - * --input [idl/IPrintable_DString.json5] - * 2. jinja2 template for abstract facet .hpp file: - * [iface_facet_any.hpp.j2] - * 3. idl for facet methods - * [idl/IPrintable_DString.json5] -**/ - -#include "string/IPrintable_DString.hpp" - -namespace xo { - namespace scm { - auto - IPrintable_DString::pretty(const DString & self, const ppindentinfo & ppii) -> bool - { - return self.pretty(ppii); - } - - - } /*namespace scm*/ -} /*namespace xo*/ - -/* end IPrintable_DString.cpp */ diff --git a/src/object2/init_object2.cpp b/src/object2/init_object2.cpp index bcf7608..7e4f6e4 100644 --- a/src/object2/init_object2.cpp +++ b/src/object2/init_object2.cpp @@ -6,7 +6,8 @@ #include "init_object2.hpp" #include "object2_register_facets.hpp" #include "object2_register_types.hpp" -#include +#include +#include #include namespace xo { @@ -29,6 +30,7 @@ namespace xo { /* direct subsystem deps for xo-object2/ */ retval ^= InitSubsys::require(); + retval ^= InitSubsys::require(); /* xo-expression2/'s own initialization code */ retval ^= Subsystem::provide("object2", &init); diff --git a/src/object2/object2_register_facets.cpp b/src/object2/object2_register_facets.cpp index 0b12717..3710b1d 100644 --- a/src/object2/object2_register_facets.cpp +++ b/src/object2/object2_register_facets.cpp @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include @@ -70,7 +70,6 @@ namespace xo { log && log(xtag("DBoolean.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("DArray.tseq", typeseq::id())); log && log(xtag("DDictionary.tseq", typeseq::id())); log && log(xtag("DRuntimeError.tseq", typeseq::id())); diff --git a/src/object2/object2_register_types.cpp b/src/object2/object2_register_types.cpp index 3e0d50d..20ae3b8 100644 --- a/src/object2/object2_register_types.cpp +++ b/src/object2/object2_register_types.cpp @@ -36,8 +36,6 @@ namespace xo { ok &= gc.install_type(impl_for()); - ok &= gc.install_type(impl_for()); - ok &= gc.install_type(impl_for()); ok &= gc.install_type(impl_for()); diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt index 573fefd..7843e0e 100644 --- a/utest/CMakeLists.txt +++ b/utest/CMakeLists.txt @@ -4,8 +4,8 @@ set(UTEST_EXE utest.object2) set(UTEST_SRCS object2_utest_main.cpp DArray.test.cpp - DString.test.cpp - StringOps.test.cpp +# DString.test.cpp +# StringOps.test.cpp X1Collector.test.cpp Printable.test.cpp ) diff --git a/utest/DString.test.cpp b/utest/DString.test.cpp deleted file mode 100644 index 53db8e7..0000000 --- a/utest/DString.test.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/** @file DString.test.cpp - * - * @author Roland Conybeare, Jan 2026 - **/ - -#include "init_object2.hpp" -#include "StringOps.hpp" -#include -#include -#include -#include -#include -#include - -namespace xo { - using xo::scm::DString; - using xo::mm::AAllocator; - using xo::mm::DArena; - using xo::mm::ArenaConfig; - using xo::facet::with_facet; - using xo::facet::obj; - - namespace ut { - static InitEvidence s_init = (InitSubsys::require()); - - TEST_CASE("DString-init", "[object2][DString]") - { - // real purpose: ensure s_init survives static linking - REQUIRE(s_init.evidence()); - } - - TEST_CASE("DString-empty", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::empty(alloc, 16); - - REQUIRE(s != nullptr); - REQUIRE(s->capacity() == 16); - REQUIRE(s->size() == 0); - REQUIRE(s->chars()[0] == '\0'); - } - - TEST_CASE("DString-from_cstr", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - const char * cstr = "hello world"; - DString * s = DString::from_cstr(alloc, cstr); - - REQUIRE(s != nullptr); - REQUIRE(s->capacity() == 12); - REQUIRE(s->size() == 11); - REQUIRE(std::strcmp(s->chars(), cstr) == 0); - } - - TEST_CASE("DString-from_view", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - std::string_view sv = "hello world"; - DString * s = DString::from_view(alloc, sv); - - REQUIRE(s != nullptr); - REQUIRE(s->capacity() == 12); - REQUIRE(s->size() == 11); - REQUIRE(std::strcmp(s->chars(), "hello world") == 0); - - // test with substring (not null-terminated) - std::string_view sub = sv.substr(0, 5); - DString * s2 = DString::from_view(alloc, sub); - - REQUIRE(s2 != nullptr); - REQUIRE(s2->capacity() == 6); - REQUIRE(s2->size() == 5); - REQUIRE(std::strcmp(s2->chars(), "hello") == 0); - } - - TEST_CASE("DString-assign", "[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"); - DString * dst = DString::empty(alloc, 16); - - dst->assign(*src); - - REQUIRE(dst->size() == 5); - REQUIRE(std::strcmp(dst->chars(), "hello") == 0); - } - - TEST_CASE("DString-assign-truncate", "[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 * dst = DString::empty(alloc, 6); - - dst->assign(*src); - - REQUIRE(dst->size() == 5); - REQUIRE(std::strcmp(dst->chars(), "hello") == 0); - } - - TEST_CASE("DString-data", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::empty(alloc, 16); - char * p = s->data(); - std::strcpy(p, "test"); - s->fixup_size(); - - REQUIRE(s->size() == 4); - REQUIRE(std::strcmp(s->chars(), "test") == 0); - } - - TEST_CASE("DString-operator-bracket", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::from_cstr(alloc, "hello"); - - REQUIRE((*s)[0] == 'h'); - REQUIRE((*s)[4] == 'o'); - - (*s)[0] = 'H'; - REQUIRE(std::strcmp(s->chars(), "Hello") == 0); - } - - TEST_CASE("DString-clear", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::from_cstr(alloc, "hello"); - REQUIRE(s->size() == 5); - - s->clear(); - - REQUIRE(s->size() == 0); - REQUIRE(s->chars()[0] == '\0'); - REQUIRE(s->capacity() == 6); - } - - TEST_CASE("DString-fixup_size", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::empty(alloc, 16); - char * p = s->data(); - p[0] = 'a'; - p[1] = 'b'; - p[2] = 'c'; - p[3] = '\0'; - - REQUIRE(s->size() == 0); - - auto new_size = s->fixup_size(); - - REQUIRE(new_size == 3); - REQUIRE(s->size() == 3); - } - - TEST_CASE("DString-string_view", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::from_cstr(alloc, "hello"); - std::string_view sv = *s; - - REQUIRE(sv == "hello"); - REQUIRE(sv.size() == 5); - } - - TEST_CASE("DString-cstr-conversion", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::from_cstr(alloc, "hello"); - const char * cstr = *s; - - REQUIRE(std::strcmp(cstr, "hello") == 0); - } - - TEST_CASE("DString-begin-end", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::from_cstr(alloc, "hello"); - - REQUIRE(s->begin() == s->chars()); - REQUIRE(s->end() == s->chars() + 5); - REQUIRE(s->end() - s->begin() == 5); - - *s->begin() = 'H'; - REQUIRE(std::strcmp(s->chars(), "Hello") == 0); - } - - TEST_CASE("DString-cbegin-cend", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::from_cstr(alloc, "hello"); - - REQUIRE(s->cbegin() == s->chars()); - REQUIRE(s->cend() == s->chars() + 5); - REQUIRE(s->cend() - s->cbegin() == 5); - } - - TEST_CASE("DString-range-for", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::from_cstr(alloc, "hello"); - - std::string result; - for (char c : *s) { - result += c; - } - - REQUIRE(result == "hello"); - } - - TEST_CASE("DString-iterator-modify", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::from_cstr(alloc, "hello"); - - for (auto it = s->begin(); it != s->end(); ++it) { - *it = std::toupper(*it); - } - - 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); - } - - TEST_CASE("DString-sprintf", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::empty(alloc, 32); - - auto n = s->sprintf("hello %s %d", "world", 42); - - REQUIRE(n == 14); - REQUIRE(s->size() == 14); - REQUIRE(std::strcmp(s->chars(), "hello world 42") == 0); - } - - TEST_CASE("DString-sprintf-truncate", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s = DString::empty(alloc, 8); - - auto n = s->sprintf("hello world"); - - REQUIRE(n == 7); - REQUIRE(s->size() == 7); - REQUIRE(std::strcmp(s->chars(), "hello w") == 0); - } - - TEST_CASE("DString-compare", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s1 = DString::from_cstr(alloc, "apple"); - DString * s2 = DString::from_cstr(alloc, "apple"); - DString * s3 = DString::from_cstr(alloc, "banana"); - DString * s4 = DString::from_cstr(alloc, "aardvark"); - - REQUIRE(DString::compare(*s1, *s2) == 0); - REQUIRE(DString::compare(*s1, *s3) < 0); - REQUIRE(DString::compare(*s3, *s1) > 0); - REQUIRE(DString::compare(*s1, *s4) > 0); - REQUIRE(DString::compare(*s4, *s1) < 0); - } - - TEST_CASE("DString-comparison-operators", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * apple1 = DString::from_cstr(alloc, "apple"); - DString * apple2 = DString::from_cstr(alloc, "apple"); - DString * banana = DString::from_cstr(alloc, "banana"); - - // operator== - REQUIRE(*apple1 == *apple1); - REQUIRE(*apple2 == *apple2); - REQUIRE(*banana == *banana); - REQUIRE(*apple1 == *apple2); - - REQUIRE_FALSE(*apple1 == *banana); - - // operator!= - REQUIRE(*apple1 != *banana); - REQUIRE_FALSE(*apple1 != *apple1); - REQUIRE_FALSE(*apple2 != *apple2); - REQUIRE_FALSE(*apple1 != *apple2); - REQUIRE_FALSE(*banana != *banana); - - // operator< - REQUIRE(*apple1 < *banana); - REQUIRE_FALSE(*banana < *apple1); - REQUIRE_FALSE(*apple1 < *apple2); - - // operator<= - REQUIRE(*apple1 <= *banana); - REQUIRE(*apple1 <= *apple2); - REQUIRE_FALSE(*banana <= *apple1); - - // operator> - REQUIRE(*banana > *apple1); - REQUIRE_FALSE(*apple1 > *banana); - REQUIRE_FALSE(*apple1 > *apple2); - - // operator>= - REQUIRE(*banana >= *apple1); - REQUIRE(*apple1 >= *apple2); - REQUIRE_FALSE(*apple1 >= *banana); - } - - TEST_CASE("DString-hash", "[object2][DString]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - DString * s1 = DString::from_cstr(alloc, "hello"); - DString * s2 = DString::from_cstr(alloc, "hello"); - DString * s3 = DString::from_cstr(alloc, "world"); - DString * empty1 = DString::empty(alloc, 16); - DString * empty2 = DString::empty(alloc, 32); - - // same content produces same hash - REQUIRE(s1->hash() == s2->hash()); - - // empty strings have same hash - REQUIRE(empty1->hash() == empty2->hash()); - - // different content produces different hash (not guaranteed, but highly likely) - REQUIRE(s1->hash() != s3->hash()); - - // std::hash specialization works - std::hash hasher; - REQUIRE(hasher(*s1) == s1->hash()); - REQUIRE(hasher(*s2) == s2->hash()); - REQUIRE(hasher(*s1) == hasher(*s2)); - } - } /*namespace ut*/ -} /*namespace xo*/ - -/* end DString.test.cpp */ diff --git a/utest/Printable.test.cpp b/utest/Printable.test.cpp index 2ca792f..15de595 100644 --- a/utest/Printable.test.cpp +++ b/utest/Printable.test.cpp @@ -12,9 +12,9 @@ #include #include -#include -#include -#include +#include +//#include +//#include #include #include diff --git a/utest/StringOps.test.cpp b/utest/StringOps.test.cpp deleted file mode 100644 index 26464f9..0000000 --- a/utest/StringOps.test.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/** @file StringOps.test.cpp - * - * @author Roland Conybeare, Jan 2026 - **/ - -#include -#include -#include -#include - -namespace xo { - using xo::scm::StringOps; - using xo::scm::DString; - using xo::mm::AAllocator; - using xo::mm::AGCObject; - using xo::mm::DArena; - using xo::mm::ArenaConfig; - using xo::facet::with_facet; - using xo::facet::obj; - - namespace ut { - TEST_CASE("StringOps-empty", "[object2][StringOps]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - auto s = StringOps::empty(alloc, 16); - - REQUIRE(s.data() != nullptr); - REQUIRE(s.data()->capacity() == 16); - REQUIRE(s.data()->size() == 0); - REQUIRE(s.data()->chars()[0] == '\0'); - } - - TEST_CASE("StringOps-empty-with-content", "[object2][StringOps]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - auto s = StringOps::empty(alloc, 32); - - s.data()->sprintf("hello %s %d", "world", 42); - - REQUIRE(s.data()->size() == 14); - REQUIRE(std::strcmp(s.data()->chars(), "hello world 42") == 0); - } - - TEST_CASE("StringOps-from_cstr", "[object2][StringOps]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - const char * cstr = "hello world"; - auto s = StringOps::from_cstr(alloc, cstr); - - REQUIRE(s.data() != nullptr); - REQUIRE(s.data()->capacity() == 12); - REQUIRE(s.data()->size() == 11); - REQUIRE(std::strcmp(s.data()->chars(), cstr) == 0); - } - - TEST_CASE("StringOps-clone", "[object2][StringOps]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - auto src = StringOps::from_cstr(alloc, "hello world"); - auto copy = StringOps::clone(alloc, src); - - REQUIRE(copy.data() != nullptr); - REQUIRE(copy.data() != src.data()); - REQUIRE(copy.data()->size() == src.data()->size()); - REQUIRE(copy.data()->capacity() == src.data()->capacity()); - REQUIRE(std::strcmp(copy.data()->chars(), src.data()->chars()) == 0); - } - - TEST_CASE("StringOps-printf", "[object2][StringOps]") - { - ArenaConfig cfg { .name_ = "testarena", - .size_ = 4*1024 }; - DArena arena = DArena::map(cfg); - auto alloc = with_facet::mkobj(&arena); - - auto s = StringOps::printf(alloc, 32, "hello %s %d", "world", 42); - - REQUIRE(s.data() != nullptr); - REQUIRE(s.data()->capacity() == 32); - REQUIRE(s.data()->size() == 14); - REQUIRE(std::strcmp(s.data()->chars(), "hello world 42") == 0); - } - } /*namespace ut*/ -} /*namespace xo*/ - -/* end StringOps.test.cpp */ diff --git a/utest/X1Collector.test.cpp b/utest/X1Collector.test.cpp index a2a2dec..55e0107 100644 --- a/utest/X1Collector.test.cpp +++ b/utest/X1Collector.test.cpp @@ -15,7 +15,7 @@ #include "number/IGCObject_DInteger.hpp" #include "list/IGCObject_DList.hpp" -#include +#include #include #include