11#pragma once
22
3+ #include " ../base/projected_iterator.h"
34#include " array.h"
45#include " column.h"
56#include " tuple.h"
@@ -122,6 +123,8 @@ class ColumnMapT : public ColumnMap {
122123 typename ArrayColumnType::ArrayValueView::Iterator data_iterator_;
123124
124125 public:
126+ Iterator () = default ;
127+
125128 Iterator (typename ArrayColumnType::ArrayValueView::Iterator data_iterator)
126129 : data_iterator_(data_iterator) {}
127130
@@ -187,13 +190,16 @@ class ColumnMapT : public ColumnMap {
187190 if (size () != other.size ()) {
188191 return false ;
189192 }
190- using Vector = std::vector<std::pair<Key, Value>>;
191- Vector l (begin (), end ());
192- Vector r (other.begin (), other.end ());
193- auto comp = [](const auto & l, const auto & r) { return l.frist < r.first ; };
194- std::sort (l.begin (), l.end (), comp);
195- std::sort (r.begin (), r.end (), comp);
196- return std::equal (l.begin (), l.end (), r.begin (), r.end ());
193+ const auto make_index = [](const auto & data) {
194+ std::vector<size_t > result{data.Size ()};
195+ std::generate (result.begin (), result.end (), [i = 0 ] () mutable { return i++; });
196+ std::sort (result.begin (), result.end (), [&data](size_t l, size_t r) {return data[l] < data[r];});
197+ return result;
198+ };
199+ const auto l_index = make_index (data_);
200+ const auto r_index = make_index (other.data_ );
201+ return std::equal (l_index.begin (), l_index.end (), r_index.begin (), r_index.end (),
202+ [&l_data = data_, &r_data = other.data_ ](size_t l, size_t r) { return l_data[l] == r_data[r];});
197203 return true ;
198204 }
199205
@@ -214,13 +220,17 @@ class ColumnMapT : public ColumnMap {
214220
215221 template <typename T>
216222 inline void Append (const T& value) {
217- // TODO Refuse to copy.
218- std::vector<std::tuple<typename T::key_type, typename T::mapped_type>> container;
219- container.reserve (value.size ());
220- for (const auto & i : value) {
221- container.emplace_back (i.first , i.second );
222- }
223- typed_data_->Append (container.begin (), container.end ());
223+ using BaseIter = typename T::const_iterator;
224+ using KeyOfT = decltype (std::declval<BaseIter>()->first );
225+ using ValOfT = decltype (std::declval<BaseIter>()->second );
226+ using Functor = std::function<std::tuple<KeyOfT, ValOfT>(const BaseIter&)>;
227+ using Iterator = ProjectedIterator<Functor, BaseIter>;
228+
229+ Functor functor = [](const BaseIter& i) {
230+ return std::make_tuple (i->first , i->second );
231+ };
232+
233+ typed_data_->Append (Iterator{value.begin (), functor}, Iterator{value.end (), functor});
224234 }
225235
226236 static auto Wrap (ColumnMap&& col) {
0 commit comments