* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef BOOST_SS_ITERATOR_H
#define BOOST_SS_ITERATOR_H
#include <memory>
#include <stdexcept>
#include <vector>
#include "bss_log.h"
#include "include/ref.h"
namespace ock {
namespace bss {
enum Iterator_Result { Iterator_Result_Continue = 0, Iterator_Result_End = 1, Iterator_Result_Failed = 2 };
template <typename E> class Iterator : public Referable {
public:
~Iterator() override = default;
virtual bool HasNext()
{
return false;
}
virtual E Next()
{
return {};
}
virtual void Close()
{
}
virtual void PrintUsefulInfo()
{
LOG_INFO("virtual PrintUsefulInfo");
}
};
template <typename E> using IteratorRef = Ref<Iterator<E>>;
template <typename E> using IteratorPtr = std::shared_ptr<Iterator<E>>;
template <typename E> class VectorIterator : public Iterator<E> {
public:
explicit VectorIterator(std::vector<E> &vec) : mData(&vec, [](std::vector<E> *) {})
{
}
explicit VectorIterator(std::vector<E> &&vec)
: mData(new std::vector<E>(std::move(vec)), [](std::vector<E> *ptr) { delete ptr; })
{
}
inline bool HasNext() override
{
return mIndex < mData->size();
}
inline E Next() override
{
if (!HasNext()) {
LOG_ERROR("No more elements in the vector.");
return {};
}
return (*mData)[mIndex++];
}
private:
std::unique_ptr<std::vector<E>, void (*)(std::vector<E> *)> mData;
size_t mIndex = 0;
};
template <typename E> using VectorIteratorRef = Ref<VectorIterator<E>>;
template <typename E> class ChainedIterator : public Iterator<E> {
public:
ChainedIterator(std::vector<std::shared_ptr<Iterator<E>>> &&iterators)
: mIterators(std::move(iterators)), mCurrentElement()
{
Advance();
}
bool HasNext() override
{
return mCurrentElement != nullptr;
}
E Next() override
{
if (!HasNext()) {
throw std::out_of_range("No more elements in the chained iterator.");
}
E result = mCurrentElement;
Advance();
return result;
}
void Close() override
{
for (const auto &it : mIterators) {
it->Close();
}
}
private:
void Advance()
{
mCurrentElement = nullptr;
while (mCurrentIterator < mIterators.size()) {
if (mIterators[mCurrentIterator]->HasNext()) {
mCurrentElement = mIterators[mCurrentIterator]->Next();
break;
}
++mCurrentIterator;
}
}
private:
std::vector<std::shared_ptr<Iterator<E>>> mIterators;
size_t mCurrentIterator = 0;
E mCurrentElement;
};
}
}
#endif