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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*
|
*
|
||||||
* Copyright 2010-2012 Danny Robson <danny@nerdcruft.net>
|
* Copyright 2010-2018 Danny Robson <danny@nerdcruft.net>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef __UTIL_ITERATOR_HPP
|
#ifndef CRUFT_UTIL_ITERATOR_HPP
|
||||||
#define __UTIL_ITERATOR_HPP
|
#define CRUFT_UTIL_ITERATOR_HPP
|
||||||
|
|
||||||
#include "types/traits.hpp"
|
#include "types/traits.hpp"
|
||||||
#include "variadic.hpp"
|
#include "variadic.hpp"
|
||||||
@ -288,8 +288,15 @@ namespace util {
|
|||||||
//
|
//
|
||||||
// this must be expressed in terms of iterators, rather than containers,
|
// this must be expressed in terms of iterators, rather than containers,
|
||||||
// because it dramatically simplifies iterating over raw arrays.
|
// 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 <
|
template <
|
||||||
typename IteratorT,
|
typename IteratorT,
|
||||||
|
typename StoreT,
|
||||||
typename I = std::make_index_sequence<std::tuple_size<IteratorT>::value>
|
typename I = std::make_index_sequence<std::tuple_size<IteratorT>::value>
|
||||||
>
|
>
|
||||||
class collection;
|
class collection;
|
||||||
@ -298,16 +305,19 @@ namespace util {
|
|||||||
//---------------------------------------------------------------------
|
//---------------------------------------------------------------------
|
||||||
template <
|
template <
|
||||||
typename IteratorT,
|
typename IteratorT,
|
||||||
|
typename StoreT,
|
||||||
std::size_t ...I
|
std::size_t ...I
|
||||||
>
|
>
|
||||||
class collection<
|
class collection<
|
||||||
IteratorT,
|
IteratorT,
|
||||||
|
StoreT,
|
||||||
std::index_sequence<I...>
|
std::index_sequence<I...>
|
||||||
> {
|
> {
|
||||||
public:
|
public:
|
||||||
collection (const IteratorT &_begin, const IteratorT &_end):
|
collection (IteratorT _begin, IteratorT _end, StoreT &&_store):
|
||||||
m_begin { _begin },
|
m_begin { _begin },
|
||||||
m_end { _end }
|
m_end { _end },
|
||||||
|
m_store { std::forward<StoreT> (_store) }
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
struct iterator : std::iterator<
|
struct iterator : std::iterator<
|
||||||
@ -320,7 +330,7 @@ namespace util {
|
|||||||
std::size_t
|
std::size_t
|
||||||
> {
|
> {
|
||||||
public:
|
public:
|
||||||
iterator (const IteratorT &_iterators):
|
iterator (IteratorT _iterators):
|
||||||
m_iterators (_iterators)
|
m_iterators (_iterators)
|
||||||
{ ; }
|
{ ; }
|
||||||
|
|
||||||
@ -381,6 +391,7 @@ namespace util {
|
|||||||
private:
|
private:
|
||||||
IteratorT m_begin;
|
IteratorT m_begin;
|
||||||
IteratorT m_end;
|
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}}
|
/// eg, util::zip ({1,2,3}, {4,5,6}) ~= {{1,4},{2,5},{3,6}}
|
||||||
template <typename ...ContainerT>
|
template <typename ...ContainerT>
|
||||||
auto
|
auto
|
||||||
zip (const ContainerT&... data)
|
zip (ContainerT&&... data)
|
||||||
{
|
{
|
||||||
using IteratorT = std::tuple<decltype(std::begin(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<
|
return detail::zip::collection<
|
||||||
IteratorT,
|
IteratorT,
|
||||||
|
decltype(store),
|
||||||
std::make_index_sequence<sizeof...(ContainerT)>
|
std::make_index_sequence<sizeof...(ContainerT)>
|
||||||
> {
|
> {
|
||||||
std::make_tuple (std::begin (data)...),
|
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'}}
|
/// eg, util::izip ("abc") ~= {{0,'a'},{1,'b'},{2,'c'}}
|
||||||
template <typename ...ContainerT>
|
template <typename ...ContainerT>
|
||||||
auto
|
auto
|
||||||
izip (const ContainerT&... data)
|
izip (ContainerT&&... data)
|
||||||
{
|
{
|
||||||
return zip (
|
return zip (
|
||||||
::util::make_indices (::util::variadic::get<0> (data...)),
|
::util::make_indices (::util::variadic::get<0> (data...)),
|
||||||
data...
|
std::forward<ContainerT> (data)...
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user