/** @file IAllocIterator_Xfer.hpp
 *
 *  @author Roland Conybeare, Dec 2025
 **/

#pragma once

#include "AAllocIterator.hpp"

namespace xo {
    namespace mm {
        /** @class IAllocIterator_Xfer
         *  @brief Adapts typed alloc iterator implementation
         *  @tparam IAllocIterator_DRepr to type-erased
         *  @ref AAllocIterator instance
         **/
        template <typename DRepr,
                  typename IAllocIterator_DRepr>
        struct IAllocIterator_Xfer : public AAllocIterator {
            using Impl = IAllocIterator_DRepr;
            using typeseq = xo::reflect::typeseq;

            static const DRepr & _dcast(Copaque d) { return *(const DRepr *)d; }
            static DRepr & _dcast(Opaque d) { return *(DRepr *)d; }

            // from AAllocIterator

            // const methods

            typeseq _typeseq() const noexcept override { return s_typeseq; }
            AllocInfo deref(Copaque d)
                const noexcept override { return I::deref(_dcast(d)); }
            cmpresult compare(Copaque d,
                              const obj_AAllocIterator & other)
                const noexcept override
                { return I::compare(_dcast(d), other); }

            // non-const methods

            void next(Opaque d) const noexcept override { I::next(_dcast(d)); }

        private:
            using I = Impl;

        public:
            static typeseq s_typeseq;
            static bool _valid;
        };

        template <typename DRepr, typename IAllocIterator_DRepr>
        xo::reflect::typeseq
        IAllocIterator_Xfer<DRepr, IAllocIterator_DRepr>::s_typeseq
        = reflect::typeseq::id<DRepr>();

        template <typename DRepr, typename IAllocIterator_DRepr>
        bool
        IAllocIterator_Xfer<DRepr, IAllocIterator_DRepr>::_valid
        = facet::valid_facet_implementation<AAllocIterator, IAllocIterator_Xfer>();
    } /*namespace mm*/
} /*namespace xo*/

/* end IAllocIterator_Xfer.hpp */
