@@ -663,6 +663,22 @@ suite mustache_list_template_tests = [] {
663663
664664#include " glaze/stencil/stencilcount.hpp"
665665
666+ struct stencilcount_point
667+ {
668+ int x{};
669+ int y{};
670+ int z{};
671+ };
672+
673+ struct stencilcount_front_hash
674+ {
675+ int aaaa{};
676+ int aaab{};
677+ int aaba{};
678+ int aabb{};
679+ int abaa{};
680+ };
681+
666682suite stencilcount_tests = [] {
667683 " basic docstencil" _test = [] {
668684 std::string_view layout = R"( # About
@@ -705,6 +721,49 @@ suite stencilcount_tests = [] {
7057213.1.2 English
706722)" ) << result;
707723 };
724+
725+ " truncated tags stay within the buffer" _test = [] {
726+ static_assert (glz::hash_info<stencilcount_point>.type == glz::hash_type::mod4);
727+
728+ constexpr std::array cases{
729+ std::pair<std::string_view, std::string_view>{" {{x}}" , " 42" },
730+ std::pair<std::string_view, std::string_view>{" {{ x }}" , " 42" },
731+ std::pair<std::string_view, std::string_view>{" {{\t x\t }}" , " 42" },
732+ std::pair<std::string_view, std::string_view>{" {{+++}}" , " 0.0.1" },
733+ std::pair<std::string_view, std::string_view>{" before {{x}} after" , " before 42 after" },
734+ };
735+
736+ const auto render_prefix = []<class T >(const std::string_view layout, const size_t size, T& value) {
737+ auto buffer = std::make_unique_for_overwrite<char []>(size);
738+ std::copy_n (layout.data (), size, buffer.get ());
739+ return glz::stencilcount (std::string_view{buffer.get (), size}, value);
740+ };
741+
742+ stencilcount_point point{.x = 42 };
743+ for (const auto & [layout, expected] : cases) {
744+ for (size_t size = 1 ; size <= layout.size (); ++size) {
745+ auto result = render_prefix (layout, size, point);
746+ expect (result.has_value ()) << layout << " prefix size " << size;
747+ if (size == layout.size ()) {
748+ expect (result.value_or (" " ) == expected) << layout;
749+ }
750+ }
751+ }
752+
753+ static_assert (glz::hash_info<stencilcount_front_hash>.type == glz::hash_type::front_hash);
754+ static_assert (glz::hash_info<stencilcount_front_hash>.front_hash_bytes == 4 );
755+
756+ stencilcount_front_hash front_hash_value{.aaaa = 42 };
757+ for (const std::string_view layout : {" {{a}" , " {{a}}" , " {{a }" , " {{aaaa}}" }) {
758+ for (size_t size = 1 ; size <= layout.size (); ++size) {
759+ auto result = render_prefix (layout, size, front_hash_value);
760+ expect (result.has_value ()) << layout << " prefix size " << size;
761+ if (size == layout.size () && layout == " {{aaaa}}" ) {
762+ expect (result.value_or (" " ) == " 42" );
763+ }
764+ }
765+ }
766+ };
708767};
709768
710769int main () { return 0 ; }
0 commit comments