@@ -243,52 +243,130 @@ namespace hgraph {
243243 struct TimeSeriesValueReferenceInput : TimeSeriesReferenceInput {
244244 using TimeSeriesReferenceInput::TimeSeriesReferenceInput;
245245 static void register_with_nanobind (nb::module_ &m);
246+
247+ // CRTP visitor support (compile-time dispatch)
248+ template <typename Visitor>
249+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
250+ decltype (auto ) accept(Visitor& visitor) {
251+ return visitor (*this );
252+ }
253+
254+ template <typename Visitor>
255+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
256+ decltype (auto ) accept(Visitor& visitor) const {
257+ return visitor (*this );
258+ }
246259 };
247260
248261 struct TimeSeriesListReferenceInput : TimeSeriesReferenceInput {
249262 using TimeSeriesReferenceInput::TimeSeriesReferenceInput;
250-
263+
251264 // Constructor that accepts size
252265 TimeSeriesListReferenceInput (Node *owning_node, size_t size);
253266 TimeSeriesListReferenceInput (TimeSeriesType *parent_input, size_t size);
254-
267+
255268 TimeSeriesInput *get_input (size_t index) override ;
256269 size_t size () const { return _size; }
257-
270+
258271 static void register_with_nanobind (nb::module_ &m);
259-
272+
273+ // CRTP visitor support (compile-time dispatch)
274+ template <typename Visitor>
275+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
276+ decltype (auto ) accept(Visitor& visitor) {
277+ return visitor (*this );
278+ }
279+
280+ template <typename Visitor>
281+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
282+ decltype (auto ) accept(Visitor& visitor) const {
283+ return visitor (*this );
284+ }
285+
260286 private:
261287 size_t _size{0 };
262288 };
263289
264290 struct TimeSeriesBundleReferenceInput : TimeSeriesReferenceInput {
265291 using TimeSeriesReferenceInput::TimeSeriesReferenceInput;
266-
292+
267293 // Constructor that accepts size
268294 TimeSeriesBundleReferenceInput (Node *owning_node, size_t size);
269295 TimeSeriesBundleReferenceInput (TimeSeriesType *parent_input, size_t size);
270-
296+
271297 size_t size () const { return _size; }
272-
298+
273299 static void register_with_nanobind (nb::module_ &m);
274-
300+
301+ // CRTP visitor support (compile-time dispatch)
302+ template <typename Visitor>
303+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
304+ decltype (auto ) accept(Visitor& visitor) {
305+ return visitor (*this );
306+ }
307+
308+ template <typename Visitor>
309+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
310+ decltype (auto ) accept(Visitor& visitor) const {
311+ return visitor (*this );
312+ }
313+
275314 private:
276315 size_t _size{0 };
277316 };
278317
279318 struct TimeSeriesDictReferenceInput : TimeSeriesReferenceInput {
280319 using TimeSeriesReferenceInput::TimeSeriesReferenceInput;
281320 static void register_with_nanobind (nb::module_ &m);
321+
322+ // CRTP visitor support (compile-time dispatch)
323+ template <typename Visitor>
324+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
325+ decltype (auto ) accept(Visitor& visitor) {
326+ return visitor (*this );
327+ }
328+
329+ template <typename Visitor>
330+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
331+ decltype (auto ) accept(Visitor& visitor) const {
332+ return visitor (*this );
333+ }
282334 };
283335
284336 struct TimeSeriesSetReferenceInput : TimeSeriesReferenceInput {
285337 using TimeSeriesReferenceInput::TimeSeriesReferenceInput;
286338 static void register_with_nanobind (nb::module_ &m);
339+
340+ // CRTP visitor support (compile-time dispatch)
341+ template <typename Visitor>
342+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
343+ decltype (auto ) accept(Visitor& visitor) {
344+ return visitor (*this );
345+ }
346+
347+ template <typename Visitor>
348+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
349+ decltype (auto ) accept(Visitor& visitor) const {
350+ return visitor (*this );
351+ }
287352 };
288353
289354 struct TimeSeriesWindowReferenceInput : TimeSeriesReferenceInput {
290355 using TimeSeriesReferenceInput::TimeSeriesReferenceInput;
291356 static void register_with_nanobind (nb::module_ &m);
357+
358+ // CRTP visitor support (compile-time dispatch)
359+ template <typename Visitor>
360+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
361+ decltype (auto ) accept(Visitor& visitor) {
362+ return visitor (*this );
363+ }
364+
365+ template <typename Visitor>
366+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
367+ decltype (auto ) accept(Visitor& visitor) const {
368+ return visitor (*this );
369+ }
292370 };
293371
294372 // ============================================================
@@ -298,51 +376,207 @@ namespace hgraph {
298376 struct TimeSeriesValueReferenceOutput final : TimeSeriesReferenceOutput {
299377 using TimeSeriesReferenceOutput::TimeSeriesReferenceOutput;
300378 static void register_with_nanobind (nb::module_ &m);
379+
380+ // Visitor support - Acyclic pattern (runtime dispatch)
381+ void accept (TimeSeriesVisitor& visitor) override {
382+ if (auto * typed_visitor = dynamic_cast <TimeSeriesOutputVisitor<TimeSeriesValueReferenceOutput>*>(&visitor)) {
383+ typed_visitor->visit (*this );
384+ }
385+ }
386+
387+ void accept (TimeSeriesVisitor& visitor) const override {
388+ if (auto * typed_visitor = dynamic_cast <ConstTimeSeriesOutputVisitor<TimeSeriesValueReferenceOutput>*>(&visitor)) {
389+ typed_visitor->visit (*this );
390+ }
391+ }
392+
393+ // CRTP visitor support (compile-time dispatch)
394+ template <typename Visitor>
395+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
396+ decltype (auto ) accept(Visitor& visitor) {
397+ return visitor (*this );
398+ }
399+
400+ template <typename Visitor>
401+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
402+ decltype (auto ) accept(Visitor& visitor) const {
403+ return visitor (*this );
404+ }
301405 };
302406
303407 struct TimeSeriesListReferenceOutput final : TimeSeriesReferenceOutput {
304408 using TimeSeriesReferenceOutput::TimeSeriesReferenceOutput;
305-
409+
306410 // Constructor that accepts size
307411 TimeSeriesListReferenceOutput (Node *owning_node, size_t size);
308412 TimeSeriesListReferenceOutput (TimeSeriesType *parent_output, size_t size);
309-
413+
310414 size_t size () const { return _size; }
311-
415+
312416 static void register_with_nanobind (nb::module_ &m);
313-
417+
418+ // Visitor support - Acyclic pattern (runtime dispatch)
419+ void accept (TimeSeriesVisitor& visitor) override {
420+ if (auto * typed_visitor = dynamic_cast <TimeSeriesOutputVisitor<TimeSeriesListReferenceOutput>*>(&visitor)) {
421+ typed_visitor->visit (*this );
422+ }
423+ }
424+
425+ void accept (TimeSeriesVisitor& visitor) const override {
426+ if (auto * typed_visitor = dynamic_cast <ConstTimeSeriesOutputVisitor<TimeSeriesListReferenceOutput>*>(&visitor)) {
427+ typed_visitor->visit (*this );
428+ }
429+ }
430+
431+ // CRTP visitor support (compile-time dispatch)
432+ template <typename Visitor>
433+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
434+ decltype (auto ) accept(Visitor& visitor) {
435+ return visitor (*this );
436+ }
437+
438+ template <typename Visitor>
439+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
440+ decltype (auto ) accept(Visitor& visitor) const {
441+ return visitor (*this );
442+ }
443+
314444 private:
315445 size_t _size{0 };
316446 };
317447
318448 struct TimeSeriesBundleReferenceOutput final : TimeSeriesReferenceOutput {
319449 using TimeSeriesReferenceOutput::TimeSeriesReferenceOutput;
320-
450+
321451 // Constructor that accepts size
322452 TimeSeriesBundleReferenceOutput (Node *owning_node, size_t size);
323453 TimeSeriesBundleReferenceOutput (TimeSeriesType *parent_output, size_t size);
324-
454+
325455 size_t size () const { return _size; }
326-
456+
327457 static void register_with_nanobind (nb::module_ &m);
328-
458+
459+ // Visitor support - Acyclic pattern (runtime dispatch)
460+ void accept (TimeSeriesVisitor& visitor) override {
461+ if (auto * typed_visitor = dynamic_cast <TimeSeriesOutputVisitor<TimeSeriesBundleReferenceOutput>*>(&visitor)) {
462+ typed_visitor->visit (*this );
463+ }
464+ }
465+
466+ void accept (TimeSeriesVisitor& visitor) const override {
467+ if (auto * typed_visitor = dynamic_cast <ConstTimeSeriesOutputVisitor<TimeSeriesBundleReferenceOutput>*>(&visitor)) {
468+ typed_visitor->visit (*this );
469+ }
470+ }
471+
472+ // CRTP visitor support (compile-time dispatch)
473+ template <typename Visitor>
474+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
475+ decltype (auto ) accept(Visitor& visitor) {
476+ return visitor (*this );
477+ }
478+
479+ template <typename Visitor>
480+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
481+ decltype (auto ) accept(Visitor& visitor) const {
482+ return visitor (*this );
483+ }
484+
329485 private:
330486 size_t _size{0 };
331487 };
332488
333489 struct TimeSeriesDictReferenceOutput final : TimeSeriesReferenceOutput {
334490 using TimeSeriesReferenceOutput::TimeSeriesReferenceOutput;
335491 static void register_with_nanobind (nb::module_ &m);
492+
493+ // Visitor support - Acyclic pattern (runtime dispatch)
494+ void accept (TimeSeriesVisitor& visitor) override {
495+ if (auto * typed_visitor = dynamic_cast <TimeSeriesOutputVisitor<TimeSeriesDictReferenceOutput>*>(&visitor)) {
496+ typed_visitor->visit (*this );
497+ }
498+ }
499+
500+ void accept (TimeSeriesVisitor& visitor) const override {
501+ if (auto * typed_visitor = dynamic_cast <ConstTimeSeriesOutputVisitor<TimeSeriesDictReferenceOutput>*>(&visitor)) {
502+ typed_visitor->visit (*this );
503+ }
504+ }
505+
506+ // CRTP visitor support (compile-time dispatch)
507+ template <typename Visitor>
508+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
509+ decltype (auto ) accept(Visitor& visitor) {
510+ return visitor (*this );
511+ }
512+
513+ template <typename Visitor>
514+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
515+ decltype (auto ) accept(Visitor& visitor) const {
516+ return visitor (*this );
517+ }
336518 };
337519
338520 struct TimeSeriesSetReferenceOutput final : TimeSeriesReferenceOutput {
339521 using TimeSeriesReferenceOutput::TimeSeriesReferenceOutput;
340522 static void register_with_nanobind (nb::module_ &m);
523+
524+ // Visitor support - Acyclic pattern (runtime dispatch)
525+ void accept (TimeSeriesVisitor& visitor) override {
526+ if (auto * typed_visitor = dynamic_cast <TimeSeriesOutputVisitor<TimeSeriesSetReferenceOutput>*>(&visitor)) {
527+ typed_visitor->visit (*this );
528+ }
529+ }
530+
531+ void accept (TimeSeriesVisitor& visitor) const override {
532+ if (auto * typed_visitor = dynamic_cast <ConstTimeSeriesOutputVisitor<TimeSeriesSetReferenceOutput>*>(&visitor)) {
533+ typed_visitor->visit (*this );
534+ }
535+ }
536+
537+ // CRTP visitor support (compile-time dispatch)
538+ template <typename Visitor>
539+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
540+ decltype (auto ) accept(Visitor& visitor) {
541+ return visitor (*this );
542+ }
543+
544+ template <typename Visitor>
545+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
546+ decltype (auto ) accept(Visitor& visitor) const {
547+ return visitor (*this );
548+ }
341549 };
342550
343551 struct TimeSeriesWindowReferenceOutput final : TimeSeriesReferenceOutput {
344552 using TimeSeriesReferenceOutput::TimeSeriesReferenceOutput;
345553 static void register_with_nanobind (nb::module_ &m);
554+
555+ // Visitor support - Acyclic pattern (runtime dispatch)
556+ void accept (TimeSeriesVisitor& visitor) override {
557+ if (auto * typed_visitor = dynamic_cast <TimeSeriesOutputVisitor<TimeSeriesWindowReferenceOutput>*>(&visitor)) {
558+ typed_visitor->visit (*this );
559+ }
560+ }
561+
562+ void accept (TimeSeriesVisitor& visitor) const override {
563+ if (auto * typed_visitor = dynamic_cast <ConstTimeSeriesOutputVisitor<TimeSeriesWindowReferenceOutput>*>(&visitor)) {
564+ typed_visitor->visit (*this );
565+ }
566+ }
567+
568+ // CRTP visitor support (compile-time dispatch)
569+ template <typename Visitor>
570+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
571+ decltype (auto ) accept(Visitor& visitor) {
572+ return visitor (*this );
573+ }
574+
575+ template <typename Visitor>
576+ requires (!std::is_base_of_v<TimeSeriesVisitor, Visitor>)
577+ decltype (auto ) accept(Visitor& visitor) const {
578+ return visitor (*this );
579+ }
346580 };
347581
348582} // namespace hgraph
0 commit comments