Skip to content

Commit

Permalink
Specialize std::back_insert_iterator
Browse files Browse the repository at this point in the history
  • Loading branch information
morzhovets committed Dec 25, 2024
1 parent 51a4496 commit 62d1cae
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 8 deletions.
15 changes: 15 additions & 0 deletions include/momo/Array.h
Original file line number Diff line number Diff line change
Expand Up @@ -1112,3 +1112,18 @@ namespace internal
}

} // namespace momo

namespace std
{
template<typename... Params>
class back_insert_iterator<momo::Array<Params...>>
: public momo::internal::BackAddIterator<momo::Array<Params...>>
{
public:
typedef momo::Array<Params...> container_type;

public:
using momo::internal::BackAddIterator<container_type>::BackAddIterator;
using momo::internal::BackAddIterator<container_type>::operator=;
};
} // namespace std
59 changes: 59 additions & 0 deletions include/momo/ArrayUtility.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,55 @@ namespace internal
return remCount;
}
};

template<typename TContainer>
class BackAddIterator
{
public:
typedef TContainer Container;
typedef typename Container::Item Item;

public:
explicit BackAddIterator(Container& cont) noexcept
: container(&cont)
{
}

template<typename Iterator>
Iterator& operator=(this Iterator& iter, Item&& item)
{
iter.container->AddBack(std::move(item));
return iter;
}

template<typename Iterator>
Iterator& operator=(this Iterator& iter, const Item& item)
{
iter.container->AddBack(item);
return iter;
}

template<typename Iterator>
Iterator& operator*(this Iterator& iter) noexcept
{
return iter;
}

template<typename Iterator>
Iterator& operator++(this Iterator& iter) noexcept
{
return iter;
}

template<typename Iterator>
Iterator operator++(this Iterator& iter, int) noexcept
{
return iter;
}

protected:
Container* container;
};
}

} // namespace momo
Expand All @@ -295,4 +344,14 @@ namespace std
random_access_iterator_tag, contiguous_iterator_tag>
{
};

template<typename C>
struct iterator_traits<momo::internal::BackAddIterator<C>>
{
typedef std::output_iterator_tag iterator_category;
typedef ptrdiff_t difference_type;
typedef void pointer;
typedef void reference;
typedef void value_type;
};
} // namespace std
15 changes: 15 additions & 0 deletions include/momo/MergeArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -833,3 +833,18 @@ class MergeArray
};

} // namespace momo

namespace std
{
template<typename... Params>
class back_insert_iterator<momo::MergeArray<Params...>>
: public momo::internal::BackAddIterator<momo::MergeArray<Params...>>
{
public:
typedef momo::MergeArray<Params...> container_type;

public:
using momo::internal::BackAddIterator<container_type>::BackAddIterator;
using momo::internal::BackAddIterator<container_type>::operator=;
};
} // namespace std
15 changes: 15 additions & 0 deletions include/momo/SegmentedArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -788,3 +788,18 @@ using SegmentedArraySqrt = SegmentedArray<TItem, TMemManager, TItemTraits,
SegmentedArraySettings<SegmentedArrayItemCountFunc::sqrt>>;

} // namespace momo

namespace std
{
template<typename... Params>
class back_insert_iterator<momo::SegmentedArray<Params...>>
: public momo::internal::BackAddIterator<momo::SegmentedArray<Params...>>
{
public:
typedef momo::SegmentedArray<Params...> container_type;

public:
using momo::internal::BackAddIterator<container_type>::BackAddIterator;
using momo::internal::BackAddIterator<container_type>::operator=;
};
} // namespace std
14 changes: 6 additions & 8 deletions test/sources/SimpleArrayTester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,11 @@ class SimpleArrayTester

~TemplItem() noexcept = default;

TemplItem& operator=(TemplItem&& item) noexcept = default;
TemplItem& operator=(TemplItem&&) noexcept = default;

TemplItem& operator=(const TemplItem& item) noexcept = default;
TemplItem& operator=(const TemplItem&) noexcept = default;

bool operator==(const TemplItem& item) const noexcept
{
return mValue == item.mValue;
}
bool operator==(const TemplItem&) const noexcept = default;

private:
size_t mValue;
Expand Down Expand Up @@ -218,8 +215,9 @@ class SimpleArrayTester
Array ar;
static const size_t count = 20000;

for (size_t i = 0; i < count; ++i)
ar.AddBack(Item(i));
std::fill_n(std::back_inserter(ar), 1, Item(0));
std::generate_n(std::back_inserter(ar), count - 1,
[&ar] () { return Item(ar.GetCount()); });

ar.Reserve(count * 3);
ar.Shrink();
Expand Down

0 comments on commit 62d1cae

Please sign in to comment.