From 7871c7dbeafe101ae0fabd66cd96b93a12d735dc Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 3 Mar 2026 16:45:54 +1100 Subject: [PATCH] xo-interpreter2 stack: + dict.make() + Dictionary impl --- CMakeLists.txt | 20 ++ idl/IGCObject_DDictionary.json5 | 18 ++ idl/IPrintable_DDictionary.json5 | 16 ++ include/xo/object2/DArray.hpp | 8 + include/xo/object2/DDictionary.hpp | 217 ++++++++++++++++++ include/xo/object2/DStruct.hpp | 183 +++++++++++++++ include/xo/object2/Dictionary.hpp | 12 + .../dictionary/IGCObject_DDictionary.hpp | 67 ++++++ .../dictionary/IPrintable_DDictionary.hpp | 62 +++++ src/object2/CMakeLists.txt | 4 + src/object2/DArray.cpp | 13 ++ src/object2/DDictionary.cpp | 208 +++++++++++++++++ src/object2/IGCObject_DDictionary.cpp | 39 ++++ src/object2/IPrintable_DDictionary.cpp | 28 +++ src/object2/object2_register_facets.cpp | 24 +- src/object2/object2_register_types.cpp | 8 +- 16 files changed, 904 insertions(+), 23 deletions(-) create mode 100644 idl/IGCObject_DDictionary.json5 create mode 100644 idl/IPrintable_DDictionary.json5 create mode 100644 include/xo/object2/DDictionary.hpp create mode 100644 include/xo/object2/DStruct.hpp create mode 100644 include/xo/object2/Dictionary.hpp create mode 100644 include/xo/object2/dictionary/IGCObject_DDictionary.hpp create mode 100644 include/xo/object2/dictionary/IPrintable_DDictionary.hpp create mode 100644 src/object2/DDictionary.cpp create mode 100644 src/object2/IGCObject_DDictionary.cpp create mode 100644 src/object2/IPrintable_DDictionary.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index af08b26..4b27b70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -165,6 +165,26 @@ xo_add_genfacetimpl( # ---------------------------------------------------------------- +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-printable-dictionary + FACET_PKG xo_printable2 + FACET Printable + REPR Dictionary + INPUT idl/IPrintable_DDictionary.json5 + ) + +# note: manual target; generated code committed to git +xo_add_genfacetimpl( + TARGET xo-object2-facetimpl-gcobject-dictionary + FACET_PKG xo_gc + FACET GCObject + REPR Dictionary + INPUT idl/IGCObject_DDictionary.json5 +) + +# ---------------------------------------------------------------- + # note: manual target; generated code committed to git xo_add_genfacetimpl( TARGET xo-object2-facetimpl-printable-runtimeerror diff --git a/idl/IGCObject_DDictionary.json5 b/idl/IGCObject_DDictionary.json5 new file mode 100644 index 0000000..636413b --- /dev/null +++ b/idl/IGCObject_DDictionary.json5 @@ -0,0 +1,18 @@ +{ + mode: "implementation", + output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "dictionary", + includes: [ + "", + "" + ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/GCObject.json5", + brief: "provide AGCObject interface for DDictionary", + using_doxygen: true, + repr: "DDictionary", + doc: [ "implement AGCObject for DDictionary" ], +} diff --git a/idl/IPrintable_DDictionary.json5 b/idl/IPrintable_DDictionary.json5 new file mode 100644 index 0000000..ad1fda5 --- /dev/null +++ b/idl/IPrintable_DDictionary.json5 @@ -0,0 +1,16 @@ +{ + mode: "implementation", + output_cpp_dir: "src/object2", + output_hpp_dir: "include/xo/object2", + output_impl_subdir: "dictionary", + includes: [ "", + "" ], + local_types: [ ], + namespace1: "xo", + namespace2: "scm", + facet_idl: "idl/Printable.json5", + brief: "provide APrintable interface for DDictionary", + using_doxygen: true, + repr: "DDictionary", + doc: [ "implement APrintable for DDictionary" ], +} diff --git a/include/xo/object2/DArray.hpp b/include/xo/object2/DArray.hpp index 282e0e5..879bb76 100644 --- a/include/xo/object2/DArray.hpp +++ b/include/xo/object2/DArray.hpp @@ -90,6 +90,7 @@ namespace xo { obj at(size_type index) const; const obj & operator[](size_type index) const noexcept { return elts_[index]; } + // TODO: nuke this or provide LValue shim. need write barrier! obj & operator[](size_type index) noexcept { return elts_[index]; } ///@} @@ -99,10 +100,17 @@ namespace xo { ///@} /** @defgroup darray-assign assignment **/ ///@{ + + /** store @p elt at position @p index. + * true on success, false otherwise + **/ + bool assign_at(size_type index, obj elt) noexcept; + /** append @p elt at the end of array. * true on success, false otherwise **/ bool push_back(obj elt) noexcept; + ///@} /** @defgroup darray-general general methods **/ ///@{ diff --git a/include/xo/object2/DDictionary.hpp b/include/xo/object2/DDictionary.hpp new file mode 100644 index 0000000..1f02843 --- /dev/null +++ b/include/xo/object2/DDictionary.hpp @@ -0,0 +1,217 @@ +/** @file DDictionary.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DArray.hpp" +#include "DString.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace xo { + namespace scm { + /** @class DStruct + * @brief Polymorphic in-memory key-value store with gc hooks + * + * Small dictionary implementation for Schematika. + * O(n) lookup, at least for now. Not typed. Keys are strings, + * so functionally equivalent to python dictionaries. + **/ + class DDictionary { + public: + /** @defgroup ddictionary-types type traits **/ + ///@{ + + /** type for array size **/ + using size_type = std::uint32_t; + /** xo allocator facet **/ + using AAllocator = xo::mm::AAllocator; + /** garbage collector facet **/ + using ACollector = xo::mm::ACollector; + /** gc-aware object facet **/ + using AGCObject = xo::mm::AGCObject; + /** pretty-printer state for APrintable **/ + using ppindentinfo = xo::print::ppindentinfo; + /** canonical type representing a key-value pair **/ + using pair_type = std::pair>; + + /** shim to represent result of expression like @c dict[key] + **/ + template + class LValue { + public: + LValue(DictPtr d, const DString * key) : dict_{d}, key_{key} {} + + bool is_sentinel() const noexcept { return dict_ == nullptr; } + bool is_valid() const noexcept { return dict_ != nullptr; } + + obj & operator=(obj & rvalue) { + return dict_->upsert(key_, rvalue); + } + + operator std::optional>() const noexcept { + return dict_->lookup(key_); + } + + private: + /** sentinel LValue represented by null ptr here **/ + DictPtr dict_ = nullptr; + /** sentinel LValue has null ptr here **/ + const DString * key_ = nullptr; + }; + + ///@} + /** @defgroup ddictionary-ctors constructors **/ + ///@{ + + /** default ctor. zero capacity sentinel **/ + DDictionary(DArray * keys, DArray * values); + + /** create empty array with space for @p cap elements + * using memory from allocator @p mm. + * Nullptr if space exhausted + **/ + static DDictionary * empty(obj mm, + size_type cap); + + /** create copy of @p src using memory from @p mm + * with capacity for @p new_cap elements + **/ + static DDictionary * copy(obj mm, + DDictionary * src, + size_type new_cap); + + /** create dictionary containing elements @p kv_pairs, using memory from @p mm. + * Nullptr if space exhausted. + * + * Use: + * auto kv1 = std::make_pair>(...); + * auto kv2 = std::make_pair>(...); + * Ddictionary * v = DDictionary::make(mm, kv1, kv2, ..); + **/ + template + requires (std::same_as>> && ...) + static DDictionary * make(obj mm, Args... args); + + ///@} + /** @defgroup ddictionary-access acecss methods **/ + ///@{ + /** true iff array is empty **/ + bool is_empty() const noexcept { return keys_->size() == 0; } + /** array capacity **/ + size_type capacity() const noexcept { return keys_->capacity(); } + /** current dictionary size (number of key-value pairs) **/ + size_type size() const noexcept { return keys_->size(); } + + /** return element @p key-value pair at position @p index (0-based) **/ + std::pair> at_index(size_type index) const; + /** return @p i'th key. O(1) **/ + const DString * key_at_index(size_type i) const; + /** return @p i'th value. O(1) **/ + obj value_at_index(size_type i) const; + + auto operator[](const DString * key) const noexcept { return LValue(this, key); } + auto operator[](const DString * key) noexcept { return LValue(this, key); } + + ///@} + /** @defgroup ddictionary-iterators iterators **/ + ///@{ + + ///@} + /** @defgroup ddictionary-assign assignment **/ + ///@{ + + /** update key-value pair @p kvpair in-place, + * provide key is already present. + * + * @return true if key-value pair updated; false if key not found + **/ + bool try_update(const pair_type & kvpair); + + /** upsert key-value pair @p kvpair into dictionary. + * If key kvpair.first not already present, add it. + * In either case replace/establish associated value with kvpair.second. + * + * False if dictionary already at capacity + **/ + bool try_upsert(const pair_type & kvpair); + + /** upsert key-value pair @p kvpair into dictionary. + * If at capacity, expand capacity, getting new memory from @p mm. + * + * False iff upsert failed because allocator memory exhausted + **/ + bool upsert(obj mm, const pair_type & kvpair); + + ///@} + /** @defgroup ddictionary-general general methods **/ + ///@{ + + /** reduce array capacity to current array size + * + * note: with X1Collector, capacity is reduced but memory not recycled + * until next collection + **/ + void shrink_to_fit() noexcept; + + ///@} + /** @defgroup ddictionary-conversion-operators conversion operators **/ + ///@{ + + ///@} + /** @defgroup ddictionary-sequence-methods **/ + ///@{ + + ///@} + /** @defgroup ddictionary-printable-methods **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup ddictionary-gcobject-methods **/ + ///@{ + /** shallow memory consumption. Excludes child objects **/ + AAllocator::size_type shallow_size() const noexcept; + /** return shallow copy of this array, using memory from @p mm **/ + DDictionary * shallow_copy(obj mm) const noexcept; + /** forward elements to @p gc to-space; replace originals with forarding pointers **/ + AAllocator::size_type forward_children(obj gc) noexcept; + ///@} + + private: + /** @defgroup ddictionary-instance-variables instance variables **/ + ///@{ + + /** dictionary keys. These will be strings **/ + DArray * keys_; + /** dictionary values. values_[i] associates with keys_[i] **/ + DArray * values_; + + ///@} + }; + + template + requires (std::same_as>> && ...) + DDictionary * + DDictionary::make(obj mm, Args... args) + { + DDictionary * result = empty(mm, sizeof...(args)); + if (result) { + (result->upsert(args), ...); + } + return result; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDictionary.hpp */ diff --git a/include/xo/object2/DStruct.hpp b/include/xo/object2/DStruct.hpp new file mode 100644 index 0000000..d7a7d84 --- /dev/null +++ b/include/xo/object2/DStruct.hpp @@ -0,0 +1,183 @@ +/** @file DStruct.hpp +* + * @author Roland Conybeare, Jan 2026 + **/ + +#pragma once + +#include "DArray.hpp" +#include +#include +#include +#include +#include +#include +#include + +namespace xo { + namespace scm { + /** @class DStruct + * @brief Polymorphic in-memory key-value store with gc hooks + * + * Small dictionary implementation for Schematika. + * O(n) lookup, at least for now. Keys are unique strings. + * Intended to have key-space fixed at comptime. + * Relevant since keys are immortal DUniqueStrings. + **/ + class DStruct { + public: + /** @defgroup dstruct-types type traits **/ + ///@{ + + /** type for array size **/ + using size_type = std::uint32_t; + /** xo allocator facet **/ + using AAllocator = xo::mm::AAllocator; + /** garbage collector facet **/ + using ACollector = xo::mm::ACollector; + /** gc-aware object facet **/ + using AGCObject = xo::mm::AGCObject; + /** pretty-printer state for APrintable **/ + using ppindentinfo = xo::print::ppindentinfo; + + ///@} + /** @defgroup dstruct-ctors constructors **/ + ///@{ + + /** default ctor. zero capacity sentinel **/ + DStruct() = default; + + /** not simply copyable because of flexible array. + * Need allocator. See @ref clone + **/ + DStruct(const DStruct &) = delete; + + /** create empty array with space for @p cap elements + * using memory from allocator @p mm. + * Nullptr if space exhausted + **/ + static DStruct * empty(obj mm, + size_type cap); + + /** create copy of @p src using memory from @p mm + * with capacity for @p new_cap elements + **/ + static DStruct * copy(obj mm, + DStruct * src, + size_type new_cap); + + /** create array containing elements @p args, using memory from @p mm. + * Nullptr if space exhausted. + * + * Use: + * Dstruct * v = DStruct::array(mm, e1, e2, e3); + **/ + template + requires (std::same_as> && ...) + static DStruct * array(obj mm, Args... args); + + ///@} + /** @defgroup dstruct-access acecss methods **/ + ///@{ + /** true iff array is empty **/ + bool is_empty() const noexcept { return size_ == 0; } + /** only support finite arrays :-) **/ + bool is_finite() const noexcept { return true; } + /** array capacity **/ + size_type capacity() const noexcept { return capacity_; } + /** current array size (number of elements) **/ + size_type size() const noexcept { return size_; } + /** return element @p index of this array (0-based) **/ + obj at(size_type index) const; + + const obj & operator[](size_type index) const noexcept { return elts_[index]; } + obj & operator[](size_type index) noexcept { return elts_[index]; } + + ///@} + /** @defgroup dstruct-iterators iterators **/ + ///@{ + + ///@} + /** @defgroup dstruct-assign assignment **/ + ///@{ + /** append @p elt at the end of array. + * true on success, false otherwise + **/ + bool push_back(obj elt) noexcept; + + ///@} + /** @defgroup dstruct-general general methods **/ + ///@{ + + /** resize to @p new_size. @p new_size may not be larger than capacity + * Return true if resize was accomplished; false otherwise. + **/ + bool resize(size_type new_size) noexcept; + + /** reduce array capacity to current array size + * + * note: with X1Collector, capacity is reduced but memory not recycled + * until next collection + **/ + void shrink_to_fit() noexcept; + + ///@} + /** @defgroup dstruct-conversion-operators conversion operators **/ + ///@{ + + ///@} + /** @defgroup dstruct-sequence-methods **/ + ///@{ + + ///@} + /** @defgroup dstruct-printable-methods **/ + ///@{ + + /** pretty-printing support **/ + bool pretty(const ppindentinfo & ppii) const; + + ///@} + /** @defgroup dstruct-gcobject-methods **/ + ///@{ + /** shallow memory consumption. Excludes child objects **/ + AAllocator::size_type shallow_size() const noexcept; + /** return shallow copy of this array, using memory from @p mm **/ + DStruct * shallow_copy(obj mm) const noexcept; + /** forward elements to @p gc to-space; replace originals with forarding pointers **/ + AAllocator::size_type forward_children(obj gc) noexcept; + ///@} + + private: + /** @defgroup dstruct-instance-variables instance variables **/ + ///@{ + + /** extent of @ref elts_ array **/ + size_type capacity_ = 0; + /** array size + * Invariant: size_ <= capacity_ + **/ + size_type size_ = 0; + /** struct keys. These will be unique strings **/ + DArray * keys_ = nullptr; + /** struct member values **/ + DArray * values_ = nullptr; + + ///@} + }; + + template + requires (std::same_as> && ...) + DStruct * + DStruct::array(obj mm, Args... args) + { + DStruct * result = empty(mm, sizeof...(args)); + if (result) { + (result->push_back(args), ...); + } + return result; + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DStruct.hpp */ diff --git a/include/xo/object2/Dictionary.hpp b/include/xo/object2/Dictionary.hpp new file mode 100644 index 0000000..6eaf7c2 --- /dev/null +++ b/include/xo/object2/Dictionary.hpp @@ -0,0 +1,12 @@ +/** @file Dictionary.hpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#pragma once + +#include "DDictionary.hpp" +#include "dictionary/IGCObject_DDictionary.hpp" +#include "dictionary/IPrintable_DDictionary.hpp" + +/* end Dictionary.hpp */ diff --git a/include/xo/object2/dictionary/IGCObject_DDictionary.hpp b/include/xo/object2/dictionary/IGCObject_DDictionary.hpp new file mode 100644 index 0000000..7f2e0ad --- /dev/null +++ b/include/xo/object2/dictionary/IGCObject_DDictionary.hpp @@ -0,0 +1,67 @@ +/** @file IGCObject_DDictionary.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DDictionary.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DDictionary.json5] + **/ + +#pragma once + +#include "GCObject.hpp" +#include +#include +#include "DDictionary.hpp" + +namespace xo { namespace scm { class IGCObject_DDictionary; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::mm::IGCObject_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IGCObject_DDictionary + **/ + class IGCObject_DDictionary { + public: + /** @defgroup scm-gcobject-ddictionary-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-ddictionary-methods **/ + ///@{ + // const methods + /** memory consumption for this instance **/ + static size_type shallow_size(const DDictionary & self) noexcept; + /** copy instance using allocator **/ + static Opaque shallow_copy(const DDictionary & self, obj mm) noexcept; + + // non-const methods + /** during GC: forward immdiate children **/ + static size_type forward_children(DDictionary & self, obj gc) noexcept; + ///@} + }; + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end */ \ No newline at end of file diff --git a/include/xo/object2/dictionary/IPrintable_DDictionary.hpp b/include/xo/object2/dictionary/IPrintable_DDictionary.hpp new file mode 100644 index 0000000..abd79d7 --- /dev/null +++ b/include/xo/object2/dictionary/IPrintable_DDictionary.hpp @@ -0,0 +1,62 @@ +/** @file IPrintable_DDictionary.hpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDictionary.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_repr.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDictionary.json5] + **/ + +#pragma once + +#include "Printable.hpp" +#include +#include +#include "DDictionary.hpp" + +namespace xo { namespace scm { class IPrintable_DDictionary; } } + +namespace xo { + namespace facet { + template <> + struct FacetImplementation + { + using ImplType = xo::print::IPrintable_Xfer + ; + }; + } +} + +namespace xo { + namespace scm { + /** @class IPrintable_DDictionary + **/ + class IPrintable_DDictionary { + public: + /** @defgroup scm-printable-ddictionary-type-traits **/ + ///@{ + using ppindentinfo = xo::print::APrintable::ppindentinfo; + using Copaque = xo::print::APrintable::Copaque; + using Opaque = xo::print::APrintable::Opaque; + ///@} + /** @defgroup scm-printable-ddictionary-methods **/ + ///@{ + // const methods + /** Pretty-printing support for this object. +See [xo-indentlog/xo/indentlog/pretty.hpp] **/ + static bool pretty(const DDictionary & 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 a559524..e9ae687 100644 --- a/src/object2/CMakeLists.txt +++ b/src/object2/CMakeLists.txt @@ -37,6 +37,10 @@ set(SELF_SRCS IGCObject_DString.cpp IPrintable_DString.cpp + DDictionary.cpp + IGCObject_DDictionary.cpp + IPrintable_DDictionary.cpp + DRuntimeError.cpp IGCObject_DRuntimeError.cpp IPrintable_DRuntimeError.cpp diff --git a/src/object2/DArray.cpp b/src/object2/DArray.cpp index 459b459..f26c523 100644 --- a/src/object2/DArray.cpp +++ b/src/object2/DArray.cpp @@ -67,6 +67,19 @@ namespace xo { } } + bool + DArray::assign_at(size_type ix, obj x) noexcept + { + if (ix >= size_) + return false; + + scope log(XO_DEBUG(true), "need write barrier"); + + this->elts_[ix] = x; + + return true; + } + bool DArray::push_back(obj elt) noexcept { diff --git a/src/object2/DDictionary.cpp b/src/object2/DDictionary.cpp new file mode 100644 index 0000000..b939eaa --- /dev/null +++ b/src/object2/DDictionary.cpp @@ -0,0 +1,208 @@ +/** @file DDictionary.cpp + * + * @author Roland Conybeare, Mar 2026 + **/ + +#include "DDictionary.hpp" +#include "Array.hpp" +#include "String.hpp" +#include +#include + +namespace xo { + using xo::print::APrintable; + using xo::facet::FacetRegistry; + using xo::mm::AGCObject; + + namespace scm { + + DDictionary::DDictionary(DArray * keys, + DArray * values) + : keys_{keys}, values_{values} + {} + + DDictionary * + DDictionary::empty(obj mm, size_type cap) + { + void * mem = mm.alloc_for(); + + if (cap <= 0) + cap = 1; + + DArray * keys = DArray::empty(mm, cap); + DArray * values = DArray::empty(mm, cap); + + return new (mem) DDictionary(keys, values); + } + + std::pair> + DDictionary::at_index(size_type ix) const + { + if (ix < keys_->size()) { + auto key_str = obj::from((*keys_)[ix]); + + assert(key_str); + + return pair_type(this->key_at_index(ix), (*values_)[ix]); + } + + return pair_type(); + } + + const DString * + DDictionary::key_at_index(size_type ix) const + { + auto key_str = obj::from((*keys_)[ix]); + + assert(key_str); + + return key_str.data(); + } + + obj + DDictionary::value_at_index(size_type ix) const + { + if (ix < keys_->size()) { + assert(ix < values_->size()); + + return (*values_)[ix]; + } + + return obj(); + } + + bool + DDictionary::try_update(const pair_type & kv_pair) + { + for (size_type i = 0, n = keys_->size(); i < n; ++i) { + auto key_i = obj::from((*keys_)[i]); + + assert(key_i); + + if (*(key_i.data()) == *(kv_pair.first)) { + values_->assign_at(i, kv_pair.second); + return true; + } + } + + return false; + } + + bool + DDictionary::try_upsert(const pair_type & kv_pair) + { + if (this->try_update(kv_pair)) + return true; + + if (keys_->size() == keys_->capacity()) + return false; + + keys_->push_back(obj(const_cast(kv_pair.first))); + values_->push_back(kv_pair.second); + + return true; + } + + bool + DDictionary::upsert(obj mm, const pair_type & kv_pair) + { + if (this->try_update(kv_pair)) + return true; + + if (keys_->size() == keys_->capacity()) { + assert(keys_->capacity() > 0); + + size_type cap_2x = 2 * keys_->capacity(); + + DArray * keys_2x = DArray::copy(mm, keys_, cap_2x); + DArray * values_2x = DArray::copy(mm, values_, cap_2x); + + if (keys_2x && values_2x) { + this->keys_ = keys_2x; + this->values_ = values_2x; + } else { + return false; + } + } + + keys_->push_back(obj(const_cast(kv_pair.first))); + values_->push_back(kv_pair.second); + + return true; + } + + void + DDictionary::shrink_to_fit() noexcept + { + keys_->shrink_to_fit(); + values_->shrink_to_fit(); + } + + // ----- printable facet ---- + + bool + DDictionary::pretty(const ppindentinfo & ppii) const + { + using xo::print::ppstate; + + ppstate * pps = ppii.pps(); + + if (ppii.upto()) { + pps->write("{"); + + for (size_type i = 0, n = this->size(); i < n; ++i) { + if (i > 0) + pps->write(" "); + + obj key + = FacetRegistry::instance().variant((*keys_)[i]); + obj value + = FacetRegistry::instance().variant((*values_)[i]); + + assert(key.data()); + assert(value.data()); + + if (!pps->print_upto(key)) + return false; + pps->write(": "); + + if (!pps->print_upto(value)) + return false; + } + + pps->write("}"); + return true; + } else { + pps->write("{...}"); + return false; + } + } + + // ----- gcobject facet ----- + + std::size_t + DDictionary::shallow_size() const noexcept + { + return sizeof(DDictionary); + } + + DDictionary * + DDictionary::shallow_copy(obj mm) const noexcept + { + return mm.std_copy_for(this); + } + + std::size_t + DDictionary::forward_children(obj gc) noexcept + { + + gc.forward_inplace(&keys_); + gc.forward_inplace(&values_); + + return this->shallow_size(); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end DDictionary.cpp */ diff --git a/src/object2/IGCObject_DDictionary.cpp b/src/object2/IGCObject_DDictionary.cpp new file mode 100644 index 0000000..a6705d9 --- /dev/null +++ b/src/object2/IGCObject_DDictionary.cpp @@ -0,0 +1,39 @@ +/** @file IGCObject_DDictionary.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IGCObject_DDictionary.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IGCObject_DDictionary.json5] +**/ + +#include "dictionary/IGCObject_DDictionary.hpp" + +namespace xo { + namespace scm { + auto + IGCObject_DDictionary::shallow_size(const DDictionary & self) noexcept -> size_type + { + return self.shallow_size(); + } + + auto + IGCObject_DDictionary::shallow_copy(const DDictionary & self, obj mm) noexcept -> Opaque + { + return self.shallow_copy(mm); + } + + auto + IGCObject_DDictionary::forward_children(DDictionary & self, obj gc) noexcept -> size_type + { + return self.forward_children(gc); + } + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IGCObject_DDictionary.cpp */ diff --git a/src/object2/IPrintable_DDictionary.cpp b/src/object2/IPrintable_DDictionary.cpp new file mode 100644 index 0000000..059196e --- /dev/null +++ b/src/object2/IPrintable_DDictionary.cpp @@ -0,0 +1,28 @@ +/** @file IPrintable_DDictionary.cpp + * + * Generated automagically from ingredients: + * 1. code generator: + * [xo-facet/codegen/genfacet] + * arguments: + * --input [idl/IPrintable_DDictionary.json5] + * 2. jinja2 template for abstract facet .hpp file: + * [iface_facet_any.hpp.j2] + * 3. idl for facet methods + * [idl/IPrintable_DDictionary.json5] +**/ + +#include "dictionary/IPrintable_DDictionary.hpp" + +namespace xo { + namespace scm { + auto + IPrintable_DDictionary::pretty(const DDictionary & self, const ppindentinfo & ppii) -> bool + { + return self.pretty(ppii); + } + + + } /*namespace scm*/ +} /*namespace xo*/ + +/* end IPrintable_DDictionary.cpp */ diff --git a/src/object2/object2_register_facets.cpp b/src/object2/object2_register_facets.cpp index 01d6ef0..4faf911 100644 --- a/src/object2/object2_register_facets.cpp +++ b/src/object2/object2_register_facets.cpp @@ -6,30 +6,14 @@ #include "object2_register_facets.hpp" #include "RuntimeError.hpp" +#include #include -//#include +#include #include #include #include #include -//#include -#include -//#include -//#include -//#include -//#include - -//#include -#include -//#include -//#include -//#include -//#include - -#include -//#include - #include #include #include @@ -74,6 +58,9 @@ namespace xo { FacetRegistry::register_impl(); FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); + FacetRegistry::register_impl(); FacetRegistry::register_impl(); @@ -85,6 +72,7 @@ namespace xo { 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())); log && log(xtag("AAllocator.tseq", typeseq::id())); diff --git a/src/object2/object2_register_types.cpp b/src/object2/object2_register_types.cpp index 275995f..3e0d50d 100644 --- a/src/object2/object2_register_types.cpp +++ b/src/object2/object2_register_types.cpp @@ -11,10 +11,7 @@ #include "string/IGCObject_DString.hpp" #include "list/IGCObject_DList.hpp" #include "array/IGCObject_DArray.hpp" - -//#include "list/IPrintable_DList.hpp" -//#include "IPrintable_DFloat.hpp" -//#include "number/IPrintable_DInteger.hpp" +#include "dictionary/IGCObject_DDictionary.hpp" #include #include @@ -23,7 +20,6 @@ namespace xo { using xo::mm::ACollector; using xo::mm::AGCObject; using xo::facet::impl_for; - using xo::facet::typeseq; using xo::scope; namespace scm { @@ -46,6 +42,8 @@ namespace xo { ok &= gc.install_type(impl_for()); + ok &= gc.install_type(impl_for()); + return ok; } }