From 7e9c02441ca43dc8f11ac579e7ca924111ae0da3 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Tue, 13 Jan 2026 17:52:27 -0500 Subject: [PATCH] xo-object2: + DString iterator methods --- xo-object2/include/xo/object2/DString.hpp | 19 +++++++ xo-object2/utest/DString.test.cpp | 66 +++++++++++++++++++++++ 2 files changed, 85 insertions(+) diff --git a/xo-object2/include/xo/object2/DString.hpp b/xo-object2/include/xo/object2/DString.hpp index 0292c818..7f8e1eeb 100644 --- a/xo-object2/include/xo/object2/DString.hpp +++ b/xo-object2/include/xo/object2/DString.hpp @@ -25,9 +25,21 @@ namespace xo { **/ 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; 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; + ///@} /** @defgroup dstring-ctors constructors **/ ///@{ @@ -66,6 +78,13 @@ namespace xo { ///@} /** @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 **/ diff --git a/xo-object2/utest/DString.test.cpp b/xo-object2/utest/DString.test.cpp index b757c1b6..c6d217f1 100644 --- a/xo-object2/utest/DString.test.cpp +++ b/xo-object2/utest/DString.test.cpp @@ -6,7 +6,9 @@ #include #include #include +#include #include +#include namespace xo { using xo::scm::DString; @@ -177,6 +179,70 @@ namespace xo { 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); + } } /*namespace ut*/ } /*namespace xo*/