iterator: retain rvalue sources when constructing zip/izip
This commit is contained in:
parent
86b1fa38c7
commit
490aab08bc
35
iterator.hpp
35
iterator.hpp
@ -11,12 +11,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Copyright 2010-2012 Danny Robson <danny@nerdcruft.net>
|
||||
* Copyright 2010-2018 Danny Robson <danny@nerdcruft.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UTIL_ITERATOR_HPP
|
||||
#define __UTIL_ITERATOR_HPP
|
||||
#ifndef CRUFT_UTIL_ITERATOR_HPP
|
||||
#define CRUFT_UTIL_ITERATOR_HPP
|
||||
|
||||
#include "types/traits.hpp"
|
||||
#include "variadic.hpp"
|
||||
@ -288,8 +288,15 @@ namespace util {
|
||||
//
|
||||
// this must be expressed in terms of iterators, rather than containers,
|
||||
// because it dramatically simplifies iterating over raw arrays.
|
||||
//
|
||||
// IteratorT: a tuple of iterators across all containers
|
||||
//
|
||||
// StoreT: a tuple of containers we own. used when we were provided
|
||||
// with an rval at zip time. allows us to destroy the data
|
||||
// when we're actually done iterating.
|
||||
template <
|
||||
typename IteratorT,
|
||||
typename StoreT,
|
||||
typename I = std::make_index_sequence<std::tuple_size<IteratorT>::value>
|
||||
>
|
||||
class collection;
|
||||
@ -298,16 +305,19 @@ namespace util {
|
||||
//---------------------------------------------------------------------
|
||||
template <
|
||||
typename IteratorT,
|
||||
typename StoreT,
|
||||
std::size_t ...I
|
||||
>
|
||||
class collection<
|
||||
IteratorT,
|
||||
StoreT,
|
||||
std::index_sequence<I...>
|
||||
> {
|
||||
public:
|
||||
collection (const IteratorT &_begin, const IteratorT &_end):
|
||||
collection (IteratorT _begin, IteratorT _end, StoreT &&_store):
|
||||
m_begin { _begin },
|
||||
m_end { _end }
|
||||
m_end { _end },
|
||||
m_store { std::forward<StoreT> (_store) }
|
||||
{ ; }
|
||||
|
||||
struct iterator : std::iterator<
|
||||
@ -320,7 +330,7 @@ namespace util {
|
||||
std::size_t
|
||||
> {
|
||||
public:
|
||||
iterator (const IteratorT &_iterators):
|
||||
iterator (IteratorT _iterators):
|
||||
m_iterators (_iterators)
|
||||
{ ; }
|
||||
|
||||
@ -381,6 +391,7 @@ namespace util {
|
||||
private:
|
||||
IteratorT m_begin;
|
||||
IteratorT m_end;
|
||||
const StoreT m_store;
|
||||
};
|
||||
}
|
||||
|
||||
@ -395,16 +406,20 @@ namespace util {
|
||||
/// eg, util::zip ({1,2,3}, {4,5,6}) ~= {{1,4},{2,5},{3,6}}
|
||||
template <typename ...ContainerT>
|
||||
auto
|
||||
zip (const ContainerT&... data)
|
||||
zip (ContainerT&&... data)
|
||||
{
|
||||
using IteratorT = std::tuple<decltype(std::begin(data))...>;
|
||||
|
||||
auto store = util::variadic::filter<std::is_rvalue_reference> (std::forward<ContainerT> (data)...);
|
||||
|
||||
return detail::zip::collection<
|
||||
IteratorT,
|
||||
decltype(store),
|
||||
std::make_index_sequence<sizeof...(ContainerT)>
|
||||
> {
|
||||
std::make_tuple (std::begin (data)...),
|
||||
std::make_tuple (std::end (data)...)
|
||||
std::make_tuple (std::end (data)...),
|
||||
std::move (store)
|
||||
};
|
||||
};
|
||||
|
||||
@ -417,11 +432,11 @@ namespace util {
|
||||
/// eg, util::izip ("abc") ~= {{0,'a'},{1,'b'},{2,'c'}}
|
||||
template <typename ...ContainerT>
|
||||
auto
|
||||
izip (const ContainerT&... data)
|
||||
izip (ContainerT&&... data)
|
||||
{
|
||||
return zip (
|
||||
::util::make_indices (::util::variadic::get<0> (data...)),
|
||||
data...
|
||||
std::forward<ContainerT> (data)...
|
||||
);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user