Correctly handle temporaries in container views
Move temporaries into the view itself and keep a reference on non temporaries
This commit is contained in:
parent
ccb53eca42
commit
50a64a0544
|
@ -22,19 +22,26 @@ template<typename Container>
|
||||||
struct ReverseView
|
struct ReverseView
|
||||||
{
|
{
|
||||||
using iterator = decltype(std::declval<Container>().rbegin());
|
using iterator = decltype(std::declval<Container>().rbegin());
|
||||||
ReverseView(Container& container) : m_container(container) {}
|
|
||||||
|
|
||||||
iterator begin() { return m_container.rbegin(); }
|
iterator begin() { return m_container.rbegin(); }
|
||||||
iterator end() { return m_container.rend(); }
|
iterator end() { return m_container.rend(); }
|
||||||
|
|
||||||
private:
|
Container m_container;
|
||||||
Container& m_container;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename C>
|
||||||
|
using RemoveReference = typename std::remove_reference<C>::type;
|
||||||
|
|
||||||
struct ReverseFactory
|
struct ReverseFactory
|
||||||
{
|
{
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
ReverseView<Container> operator()(Container&& container) const
|
ReverseView<RemoveReference<Container>> operator()(Container&& container) const
|
||||||
|
{
|
||||||
|
return {std::move(container)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Container>
|
||||||
|
ReverseView<Container&> operator()(Container& container) const
|
||||||
{
|
{
|
||||||
return {container};
|
return {container};
|
||||||
}
|
}
|
||||||
|
@ -84,14 +91,10 @@ struct FilterView
|
||||||
const FilterView& m_view;
|
const FilterView& m_view;
|
||||||
};
|
};
|
||||||
|
|
||||||
FilterView(Container& container, Filter filter)
|
|
||||||
: m_container(container), m_filter(std::move(filter)) {}
|
|
||||||
|
|
||||||
Iterator begin() const { return {*this, m_container.begin(), m_container.end()}; }
|
Iterator begin() const { return {*this, m_container.begin(), m_container.end()}; }
|
||||||
Iterator end() const { return {*this, m_container.end(), m_container.end()}; }
|
Iterator end() const { return {*this, m_container.end(), m_container.end()}; }
|
||||||
|
|
||||||
private:
|
Container m_container;
|
||||||
Container& m_container;
|
|
||||||
Filter m_filter;
|
Filter m_filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -99,7 +102,10 @@ template<typename Filter>
|
||||||
struct FilterFactory
|
struct FilterFactory
|
||||||
{
|
{
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
FilterView<Container, Filter> operator()(Container&& container) const { return {container, std::move(m_filter)}; }
|
FilterView<Container&, Filter> operator()(Container& container) const { return {container, std::move(m_filter)}; }
|
||||||
|
|
||||||
|
template<typename Container>
|
||||||
|
FilterView<RemoveReference<Container>, Filter> operator()(Container&& container) const { return {std::move(container), std::move(m_filter)}; }
|
||||||
|
|
||||||
Filter m_filter;
|
Filter m_filter;
|
||||||
};
|
};
|
||||||
|
@ -142,14 +148,10 @@ struct TransformView
|
||||||
const TransformView& m_view;
|
const TransformView& m_view;
|
||||||
};
|
};
|
||||||
|
|
||||||
TransformView(Container& container, Transform transform)
|
|
||||||
: m_container(container), m_transform(std::move(transform)) {}
|
|
||||||
|
|
||||||
Iterator begin() const { return {*this, m_container.begin()}; }
|
Iterator begin() const { return {*this, m_container.begin()}; }
|
||||||
Iterator end() const { return {*this, m_container.end()}; }
|
Iterator end() const { return {*this, m_container.end()}; }
|
||||||
|
|
||||||
private:
|
Container m_container;
|
||||||
Container& m_container;
|
|
||||||
Transform m_transform;
|
Transform m_transform;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -157,7 +159,10 @@ template<typename Transform>
|
||||||
struct TransformFactory
|
struct TransformFactory
|
||||||
{
|
{
|
||||||
template<typename Container>
|
template<typename Container>
|
||||||
TransformView<Container, Transform> operator()(Container&& container) const { return {container, std::move(m_transform)}; }
|
TransformView<Container&, Transform> operator()(Container& container) const { return {container, std::move(m_transform)}; }
|
||||||
|
|
||||||
|
template<typename Container>
|
||||||
|
TransformView<RemoveReference<Container>, Transform> operator()(Container&& container) const { return {std::move(container), std::move(m_transform)}; }
|
||||||
|
|
||||||
Transform m_transform;
|
Transform m_transform;
|
||||||
};
|
};
|
||||||
|
@ -166,7 +171,6 @@ template<typename Transform>
|
||||||
inline ContainerView<TransformFactory<Transform>> transform(Transform t) { return {{std::move(t)}}; }
|
inline ContainerView<TransformFactory<Transform>> transform(Transform t) { return {{std::move(t)}}; }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<typename Container1, typename Container2>
|
template<typename Container1, typename Container2>
|
||||||
struct ConcatView
|
struct ConcatView
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user