NEW 163370
We should have a map function that operates over Vector
https://bugs.webkit.org/show_bug.cgi?id=163370
Summary We should have a map function that operates over Vector
Saam Barati
Reported 2016-10-12 17:14:43 PDT
And maybe alternatively, something like mapTo, which would utilize one type having a conversion operation to another type. Maybe something like this: ``` template <typename T, size_t InlineCapacity, typename U, typename F, typename ResultInlineCapacity = InlineCapacity> Vector<U, ResultInlineCapacity>&& Vector<T, InlineCapacity>::map(F& function) { Vector<U, ResultInlineCapacity> result; result.reserveInitialCapacity(size()); for (auto& item : *this) result.uncheckedAppend(WTFMove(function(item))); return WTFMove(result); } ``` There is definitely code inside JSC and WebCore that is doing this manually. Also, as Simon suggested, we could have something that invokes the conversion operator. Maybe something like this: ``` template <typename T, size_t InlineCapacity, typename U, typename ResultInlineCapacity = InlineCapacity> Vector<U, ResultInlineCapacity>&& Vector<T, InlineCapacity>::mapTo() { auto converter = [&] (T& t) -> U&& { return t; // Would this work? } return this->map<U, SomeTypeForConverterHere, ResultInlineCapacity>(converter); }
Attachments
Saam Barati
Comment 1 2016-10-12 17:17:22 PDT
(In reply to comment #0) > And maybe alternatively, something like mapTo, which would utilize one type > having a conversion operation to another type. > > Maybe something like this: > ``` > template <typename T, size_t InlineCapacity, typename U, typename F, > typename ResultInlineCapacity = InlineCapacity> > Vector<U, ResultInlineCapacity>&& Vector<T, InlineCapacity>::map(F& function) > { > Vector<U, ResultInlineCapacity> result; > result.reserveInitialCapacity(size()); > for (auto& item : *this) > result.uncheckedAppend(WTFMove(function(item))); > return WTFMove(result); > } > ``` Maybe we could write this differently such that we can determine the return type of `F& function` to allow us to skip passing in U. > > There is definitely code inside JSC and WebCore that is doing this manually. > > Also, as Simon suggested, we could have something that invokes the > conversion operator. > Maybe something like this: > > ``` > template <typename T, size_t InlineCapacity, typename U, typename > ResultInlineCapacity = InlineCapacity> > Vector<U, ResultInlineCapacity>&& Vector<T, InlineCapacity>::mapTo() > { > auto converter = [&] (T& t) -> U&& { > return t; // Would this work? > } > return this->map<U, SomeTypeForConverterHere, > ResultInlineCapacity>(converter); > }
Saam Barati
Comment 2 2016-10-12 17:18:51 PDT
There is std::transform, but the API looks ugly to me. Maybe we could use it internally. http://www.cplusplus.com/reference/algorithm/transform/
Anders Carlsson
Comment 3 2016-10-13 11:06:28 PDT
(In reply to comment #2) > There is std::transform, but the API looks ugly to me. Maybe we could use it > internally. > http://www.cplusplus.com/reference/algorithm/transform/ I don't think we should have a member function on vector that does this. If we decide to add this, we should have a free function.
Darin Adler
Comment 4 2016-10-13 11:16:18 PDT
(In reply to comment #3) > (In reply to comment #2) > > There is std::transform, but the API looks ugly to me. Maybe we could use it > > internally. > > http://www.cplusplus.com/reference/algorithm/transform/ > > I don't think we should have a member function on vector that does this. If > we decide to add this, we should have a free function. I agree with this 100%.
Saam Barati
Comment 5 2016-10-13 11:18:26 PDT
Anders, Darin, if the API is a free function, would it be only for vectors? Or would it be more generalized over many types?
Saam Barati
Comment 6 2016-10-13 11:20:46 PDT
(In reply to comment #5) > Anders, Darin, if the API is a free function, would it be only for vectors? > Or would it be more generalized over many types? Also, if you both have the time, can you elaborate on why this is your preference?
Darin Adler
Comment 7 2016-10-13 18:03:44 PDT
Saam, this is a good article from the year 2000 about this: http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197 (By the way, while looking for information on the web about this I came here <http://stackoverflow.com/questions/967538/c-member-functions-vs-free-functions> and besides the answer above, it led me to <http://www.gotw.ca/publications/mill08.htm>, which mentioned me, calling me "Astute Reader Darin Adler"! I had completely forgotten about writing in to Herb so long ago.)
Saam Barati
Comment 8 2016-10-13 19:14:47 PDT
(In reply to comment #7) > Saam, this is a good article from the year 2000 about this: > > http://www.drdobbs.com/cpp/how-non-member-functions-improve-encapsu/184401197 I agree with the sentiment of this article. I think the reason I prefer such a function not to be free is for purely aesthetic reasons. I like to write this code: ``` Vector<T> foo; auto somethingElse = foo.map([&] { ... }); ``` more than this: ``` Vector<T> foo; auto somethingElse = map(foo, [&] { ... }); ``` > > (By the way, while looking for information on the web about this I came here > <http://stackoverflow.com/questions/967538/c-member-functions-vs-free- > functions> and besides the answer above, it led me to > <http://www.gotw.ca/publications/mill08.htm>, which mentioned me, calling me > "Astute Reader Darin Adler"! I had completely forgotten about writing in to > Herb so long ago.)
Darin Adler
Comment 9 2016-10-14 09:19:13 PDT
(In reply to comment #8) > I think the reason I prefer such > a function not to be free is for purely aesthetic reasons. Yes, many C++ programmers like have felt conflicted about this for years because they preferred the syntax of member functions. Given the encapsulation benefits of free functions, I suggest you try to consciously change your taste; that is something I definitely did, although it was many years ago. One of the great things about Swift extensions is that they let you use syntax like C++ member functions without the encapsulation costs. The Swift creators were thinking about this dilemma in C++, among other things, when they created that feature.
Note You need to log in before you can comment on or make changes to this bug.