mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
add range/adaptor/transformed
This commit is contained in:
parent
3e5facb754
commit
3ff16b4054
8 changed files with 743 additions and 41 deletions
|
@ -58,36 +58,38 @@ namespace sprout {
|
||||||
struct placeholder {};
|
struct placeholder {};
|
||||||
|
|
||||||
namespace placeholders {
|
namespace placeholders {
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<1> _1;
|
namespace {
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<2> _2;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<1> _1{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<3> _3;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<2> _2{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<4> _4;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<3> _3{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<5> _5;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<4> _4{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<6> _6;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<5> _5{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<7> _7;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<6> _6{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<8> _8;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<7> _7{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<9> _9;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<8> _8{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<10> _10;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<9> _9{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<11> _11;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<10> _10{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<12> _12;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<11> _11{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<13> _13;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<12> _12{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<14> _14;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<13> _13{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<15> _15;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<14> _14{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<16> _16;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<15> _15{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<17> _17;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<16> _16{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<18> _18;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<17> _17{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<19> _19;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<18> _18{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<20> _20;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<19> _19{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<21> _21;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<20> _20{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<22> _22;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<21> _21{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<23> _23;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<22> _22{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<24> _24;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<23> _23{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<25> _25;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<24> _24{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<26> _26;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<25> _25{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<27> _27;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<26> _26{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<28> _28;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<27> _27{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<29> _29;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<28> _28{};
|
||||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<30> _30;
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<29> _29{};
|
||||||
|
SPROUT_STATIC_CONSTEXPR sprout::placeholder<30> _30{};
|
||||||
|
} // anonymous-namespace
|
||||||
} // namespace placeholders
|
} // namespace placeholders
|
||||||
using sprout::placeholders::_1;
|
using sprout::placeholders::_1;
|
||||||
using sprout::placeholders::_2;
|
using sprout::placeholders::_2;
|
||||||
|
|
|
@ -162,10 +162,10 @@ namespace sprout {
|
||||||
return !(lhs < rhs);
|
return !(lhs < rhs);
|
||||||
}
|
}
|
||||||
template<typename Iterator1, typename Iterator2>
|
template<typename Iterator1, typename Iterator2>
|
||||||
SPROUT_CONSTEXPR auto operator-(
|
SPROUT_CONSTEXPR decltype(std::declval<Iterator1>() - std::declval<Iterator2>()) operator-(
|
||||||
sprout::reverse_iterator<Iterator1> const& lhs,
|
sprout::reverse_iterator<Iterator1> const& lhs,
|
||||||
sprout::reverse_iterator<Iterator2> const& rhs
|
sprout::reverse_iterator<Iterator2> const& rhs
|
||||||
) -> decltype(lhs.base() - rhs.base())
|
)
|
||||||
{
|
{
|
||||||
return lhs.base() - rhs.base();
|
return lhs.base() - rhs.base();
|
||||||
}
|
}
|
||||||
|
|
441
sprout/iterator/transform_iterator.hpp
Normal file
441
sprout/iterator/transform_iterator.hpp
Normal file
|
@ -0,0 +1,441 @@
|
||||||
|
#ifndef SPROUT_ITERATOR_TRANSFORM_ITERATOR_HPP
|
||||||
|
#define SPROUT_ITERATOR_TRANSFORM_ITERATOR_HPP
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <utility>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/iterator/next.hpp>
|
||||||
|
#include <sprout/iterator/prev.hpp>
|
||||||
|
#include <sprout/iterator/distance.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
//
|
||||||
|
// transform_iterator
|
||||||
|
//
|
||||||
|
template<typename BinaryFunction, typename LIterator, typename RIterator = void>
|
||||||
|
class transform_iterator
|
||||||
|
: public std::iterator<
|
||||||
|
typename std::iterator_traits<LIterator>::iterator_category,
|
||||||
|
typename std::remove_reference<
|
||||||
|
typename std::result_of<
|
||||||
|
BinaryFunction (
|
||||||
|
typename std::iterator_traits<LIterator>::reference,
|
||||||
|
typename std::iterator_traits<RIterator>::reference
|
||||||
|
)
|
||||||
|
>::type
|
||||||
|
>::type,
|
||||||
|
typename std::iterator_traits<LIterator>::difference_type,
|
||||||
|
typename std::remove_reference<
|
||||||
|
typename std::result_of<
|
||||||
|
BinaryFunction (
|
||||||
|
typename std::iterator_traits<LIterator>::reference,
|
||||||
|
typename std::iterator_traits<RIterator>::reference
|
||||||
|
)
|
||||||
|
>::type
|
||||||
|
>::type*,
|
||||||
|
typename std::result_of<
|
||||||
|
BinaryFunction (
|
||||||
|
typename std::iterator_traits<LIterator>::reference,
|
||||||
|
typename std::iterator_traits<RIterator>::reference
|
||||||
|
)
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef BinaryFunction functor_type;
|
||||||
|
typedef LIterator iterator_type;
|
||||||
|
typedef RIterator iterator2_type;
|
||||||
|
typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
|
||||||
|
typedef typename std::result_of<
|
||||||
|
BinaryFunction (
|
||||||
|
typename std::iterator_traits<LIterator>::reference,
|
||||||
|
typename std::iterator_traits<RIterator>::reference
|
||||||
|
)
|
||||||
|
>::type reference;
|
||||||
|
typedef typename std::remove_reference<reference>::type value_type;
|
||||||
|
typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
protected:
|
||||||
|
iterator_type current;
|
||||||
|
iterator2_type current2;
|
||||||
|
functor_type func;
|
||||||
|
public:
|
||||||
|
transform_iterator() = default;
|
||||||
|
transform_iterator(transform_iterator const&) = default;
|
||||||
|
SPROUT_CONSTEXPR transform_iterator(iterator_type it, iterator2_type it2)
|
||||||
|
: current(it)
|
||||||
|
, current2(it2)
|
||||||
|
{}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator(iterator_type it, iterator2_type it2, functor_type func)
|
||||||
|
: current(it)
|
||||||
|
, current2(it2)
|
||||||
|
, func(func)
|
||||||
|
{}
|
||||||
|
template<typename U, typename V, typename W>
|
||||||
|
SPROUT_CONSTEXPR transform_iterator(transform_iterator<U, V, W> const& it)
|
||||||
|
: current(it.current)
|
||||||
|
, current2(it.current2)
|
||||||
|
, func(it.func)
|
||||||
|
{}
|
||||||
|
template<typename U, typename V, typename W>
|
||||||
|
transform_iterator& operator=(transform_iterator<U, V, W> const& it) {
|
||||||
|
transform_iterator temp(it);
|
||||||
|
temp.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR iterator_type base() const {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR iterator_type base2() const {
|
||||||
|
return current2;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR functor_type functor() const {
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR reference operator*() const {
|
||||||
|
return func(*current, *current2);
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR pointer operator->() const {
|
||||||
|
return &func(*current, *current2);
|
||||||
|
}
|
||||||
|
transform_iterator& operator++() {
|
||||||
|
++current;
|
||||||
|
++current2;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
transform_iterator operator++(int) {
|
||||||
|
transform_iterator result(*this);
|
||||||
|
++current;
|
||||||
|
++current2;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
transform_iterator& operator--() {
|
||||||
|
--current;
|
||||||
|
--current2;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
transform_iterator operator--(int) {
|
||||||
|
transform_iterator temp(*this);
|
||||||
|
--current;
|
||||||
|
--current2;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator operator+(difference_type n) const {
|
||||||
|
return transform_iterator(current + n, current2 + n, func);
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator operator-(difference_type n) const {
|
||||||
|
return transform_iterator(current - n, current2 - n, func);
|
||||||
|
}
|
||||||
|
transform_iterator& operator+=(difference_type n) {
|
||||||
|
transform_iterator temp(current + n, current2 + n, func);
|
||||||
|
temp.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
transform_iterator& operator-=(difference_type n) {
|
||||||
|
transform_iterator temp(current - n, current2 - n, func);
|
||||||
|
temp.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
|
||||||
|
return func(current[n], current2[n]);
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator next() const {
|
||||||
|
return transform_iterator(sprout::next(current), sprout::next(current2), func);
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator prev() const {
|
||||||
|
return transform_iterator(sprout::prev(current), sprout::prev(current2), func);
|
||||||
|
}
|
||||||
|
void swap(transform_iterator& other) {
|
||||||
|
using std::swap;
|
||||||
|
swap(current, other.current);
|
||||||
|
swap(current2, other.current2);
|
||||||
|
swap(func, other.func);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// transform_iterator
|
||||||
|
//
|
||||||
|
template<typename UnaryFunction, typename Iterator>
|
||||||
|
class transform_iterator<UnaryFunction, Iterator, void>
|
||||||
|
: public std::iterator<
|
||||||
|
typename std::iterator_traits<Iterator>::iterator_category,
|
||||||
|
typename std::remove_reference<
|
||||||
|
typename std::result_of<
|
||||||
|
UnaryFunction (typename std::iterator_traits<Iterator>::reference)
|
||||||
|
>::type
|
||||||
|
>::type,
|
||||||
|
typename std::iterator_traits<Iterator>::difference_type,
|
||||||
|
typename std::remove_reference<
|
||||||
|
typename std::result_of<
|
||||||
|
UnaryFunction (typename std::iterator_traits<Iterator>::reference)
|
||||||
|
>::type
|
||||||
|
>::type*,
|
||||||
|
typename std::result_of<
|
||||||
|
UnaryFunction (typename std::iterator_traits<Iterator>::reference)
|
||||||
|
>::type
|
||||||
|
>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef UnaryFunction functor_type;
|
||||||
|
typedef Iterator iterator_type;
|
||||||
|
typedef typename std::iterator_traits<iterator_type>::iterator_category iterator_category;
|
||||||
|
typedef typename std::result_of<
|
||||||
|
UnaryFunction (typename std::iterator_traits<Iterator>::reference)
|
||||||
|
>::type reference;
|
||||||
|
typedef typename std::remove_reference<reference>::type value_type;
|
||||||
|
typedef typename std::iterator_traits<iterator_type>::difference_type difference_type;
|
||||||
|
typedef value_type* pointer;
|
||||||
|
protected:
|
||||||
|
iterator_type current;
|
||||||
|
functor_type func;
|
||||||
|
public:
|
||||||
|
transform_iterator() = default;
|
||||||
|
transform_iterator(transform_iterator const&) = default;
|
||||||
|
explicit SPROUT_CONSTEXPR transform_iterator(iterator_type it)
|
||||||
|
: current(it)
|
||||||
|
{}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator(iterator_type it, functor_type func)
|
||||||
|
: current(it)
|
||||||
|
, func(func)
|
||||||
|
{}
|
||||||
|
template<typename U, typename V>
|
||||||
|
SPROUT_CONSTEXPR transform_iterator(transform_iterator<U, V> const& it)
|
||||||
|
: current(it.current)
|
||||||
|
, func(it.func)
|
||||||
|
{}
|
||||||
|
template<typename U, typename V>
|
||||||
|
transform_iterator& operator=(transform_iterator<U, V> const& it) {
|
||||||
|
transform_iterator temp(it);
|
||||||
|
temp.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR iterator_type base() const {
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR functor_type functor() const {
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR reference operator*() const {
|
||||||
|
return func(*current);
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR pointer operator->() const {
|
||||||
|
return &func(*current);
|
||||||
|
}
|
||||||
|
transform_iterator& operator++() {
|
||||||
|
++current;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
transform_iterator operator++(int) {
|
||||||
|
transform_iterator result(*this);
|
||||||
|
++current;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
transform_iterator& operator--() {
|
||||||
|
--current;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
transform_iterator operator--(int) {
|
||||||
|
transform_iterator temp(*this);
|
||||||
|
--current;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator operator+(difference_type n) const {
|
||||||
|
return transform_iterator(current + n, func);
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator operator-(difference_type n) const {
|
||||||
|
return transform_iterator(current - n, func);
|
||||||
|
}
|
||||||
|
transform_iterator& operator+=(difference_type n) {
|
||||||
|
transform_iterator temp(current + n, func);
|
||||||
|
temp.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
transform_iterator& operator-=(difference_type n) {
|
||||||
|
transform_iterator temp(current - n, func);
|
||||||
|
temp.swap(*this);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
|
||||||
|
return func(current[n]);
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator next() const {
|
||||||
|
return transform_iterator(sprout::next(current), func);
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR transform_iterator prev() const {
|
||||||
|
return transform_iterator(sprout::prev(current), func);
|
||||||
|
}
|
||||||
|
void swap(transform_iterator& other) {
|
||||||
|
using std::swap;
|
||||||
|
swap(current, other.current);
|
||||||
|
swap(func, other.func);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<
|
||||||
|
typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1,
|
||||||
|
typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2
|
||||||
|
>
|
||||||
|
SPROUT_CONSTEXPR bool operator==(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction1, LIterator1, RIterator1> const& lhs,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction2, LIterator2, RIterator2> const& rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return lhs.base() == rhs.base();
|
||||||
|
}
|
||||||
|
template<
|
||||||
|
typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1,
|
||||||
|
typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2
|
||||||
|
>
|
||||||
|
SPROUT_CONSTEXPR bool operator!=(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction1, LIterator1, RIterator1> const& lhs,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction2, LIterator2, RIterator2> const& rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
template<
|
||||||
|
typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1,
|
||||||
|
typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2
|
||||||
|
>
|
||||||
|
SPROUT_CONSTEXPR bool operator<(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction1, LIterator1, RIterator1> const& lhs,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction2, LIterator2, RIterator2> const& rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return lhs.base() < rhs.base();
|
||||||
|
}
|
||||||
|
template<
|
||||||
|
typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1,
|
||||||
|
typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2
|
||||||
|
>
|
||||||
|
SPROUT_CONSTEXPR bool operator>(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction1, LIterator1, RIterator1> const& lhs,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction2, LIterator2, RIterator2> const& rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return rhs < lhs;
|
||||||
|
}
|
||||||
|
template<
|
||||||
|
typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1,
|
||||||
|
typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2
|
||||||
|
>
|
||||||
|
SPROUT_CONSTEXPR bool operator<=(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction1, LIterator1, RIterator1> const& lhs,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction2, LIterator2, RIterator2> const& rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return !(rhs < lhs);
|
||||||
|
}
|
||||||
|
template<
|
||||||
|
typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1,
|
||||||
|
typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2
|
||||||
|
>
|
||||||
|
SPROUT_CONSTEXPR bool operator>=(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction1, LIterator1, RIterator1> const& lhs,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction2, LIterator2, RIterator2> const& rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return !(lhs < rhs);
|
||||||
|
}
|
||||||
|
template<
|
||||||
|
typename UnaryOrBinaryFunction1, typename LIterator1, typename RIterator1,
|
||||||
|
typename UnaryOrBinaryFunction2, typename LIterator2, typename RIterator2
|
||||||
|
>
|
||||||
|
SPROUT_CONSTEXPR decltype(std::declval<LIterator1>() - std::declval<LIterator2>()) operator-(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction1, LIterator1, RIterator1> const& lhs,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction2, LIterator2, RIterator2> const& rhs
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return lhs.base() - rhs.base();
|
||||||
|
}
|
||||||
|
template<typename UnaryOrBinaryFunction, typename LIterator, typename RIterator>
|
||||||
|
SPROUT_CONSTEXPR sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> operator+(
|
||||||
|
typename sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator>::difference_type n,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> const& it
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return it + n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// make_transform_iterator
|
||||||
|
//
|
||||||
|
template<typename BinaryFunction, typename LIterator, typename RIterator>
|
||||||
|
SPROUT_CONSTEXPR sprout::transform_iterator<BinaryFunction, LIterator, RIterator>
|
||||||
|
make_transform_iterator(LIterator it1, RIterator it2, BinaryFunction func) {
|
||||||
|
return sprout::transform_iterator<BinaryFunction, LIterator, RIterator>(it1, it2, func);
|
||||||
|
}
|
||||||
|
template<typename UnaryFunction, typename Iterator>
|
||||||
|
SPROUT_CONSTEXPR sprout::transform_iterator<UnaryFunction, Iterator>
|
||||||
|
make_transform_iterator(Iterator it, UnaryFunction func) {
|
||||||
|
return sprout::transform_iterator<UnaryFunction, Iterator>(it, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// swap
|
||||||
|
//
|
||||||
|
template<typename UnaryOrBinaryFunction, typename LIterator, typename RIterator>
|
||||||
|
void swap(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator>& lhs,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator>& rhs
|
||||||
|
)
|
||||||
|
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs)))
|
||||||
|
{
|
||||||
|
lhs.swap(rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// next
|
||||||
|
//
|
||||||
|
template<typename UnaryOrBinaryFunction, typename LIterator, typename RIterator>
|
||||||
|
SPROUT_CONSTEXPR sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> next(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> const& it
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return it.next();
|
||||||
|
}
|
||||||
|
template<typename UnaryOrBinaryFunction, typename LIterator, typename RIterator>
|
||||||
|
SPROUT_CONSTEXPR sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> next(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> const& it,
|
||||||
|
typename sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator>::difference_type n
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return it + n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// prev
|
||||||
|
//
|
||||||
|
template<typename UnaryOrBinaryFunction, typename LIterator, typename RIterator>
|
||||||
|
SPROUT_CONSTEXPR sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> prev(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> const& it
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return it.prev();
|
||||||
|
}
|
||||||
|
template<typename UnaryOrBinaryFunction, typename LIterator, typename RIterator>
|
||||||
|
SPROUT_CONSTEXPR sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> prev(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> const& it,
|
||||||
|
typename sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator>::difference_type n
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return it - n;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// distance
|
||||||
|
//
|
||||||
|
template<typename UnaryOrBinaryFunction, typename LIterator, typename RIterator>
|
||||||
|
SPROUT_CONSTEXPR typename std::iterator_traits<sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> >::difference_type
|
||||||
|
distance(
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> first,
|
||||||
|
sprout::transform_iterator<UnaryOrBinaryFunction, LIterator, RIterator> last
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return last - first;
|
||||||
|
}
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_ITERATOR_TRANSFORM_ITERATOR_HPP
|
|
@ -192,7 +192,7 @@ namespace sprout {
|
||||||
Args&&... args
|
Args&&... args
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return sprout::remake<Container>(sprout::forward<Cont>(cont), size, sprout::forward<Args>(args)...);
|
return sprout::remake<copied_type>(sprout::forward<Cont>(cont), size, sprout::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
7
sprout/range/adaptor.hpp
Normal file
7
sprout/range/adaptor.hpp
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#ifndef SPROUT_RANGE_ADAPTOR_HPP
|
||||||
|
#define SPROUT_RANGE_ADAPTOR_HPP
|
||||||
|
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/range/adaptor/transformed.hpp>
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_RANGE_ADAPTOR_HPP
|
226
sprout/range/adaptor/transformed.hpp
Normal file
226
sprout/range/adaptor/transformed.hpp
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
#ifndef SPROUT_RANGE_ADAPTOR_TRANSFORMD_HPP
|
||||||
|
#define SPROUT_RANGE_ADAPTOR_TRANSFORMD_HPP
|
||||||
|
|
||||||
|
#include <type_traits>
|
||||||
|
#include <sprout/config.hpp>
|
||||||
|
#include <sprout/pit.hpp>
|
||||||
|
#include <sprout/container/traits.hpp>
|
||||||
|
#include <sprout/container/functions.hpp>
|
||||||
|
#include <sprout/iterator/transform_iterator.hpp>
|
||||||
|
#include <sprout/range/range_container.hpp>
|
||||||
|
#include <sprout/range/algorithm/copy.hpp>
|
||||||
|
#include <sprout/type_traits/lvalue_reference.hpp>
|
||||||
|
#include <sprout/utility/forward.hpp>
|
||||||
|
#include <sprout/utility/lvalue_forward.hpp>
|
||||||
|
#include <sprout/utility/value_holder.hpp>
|
||||||
|
|
||||||
|
namespace sprout {
|
||||||
|
namespace range {
|
||||||
|
//
|
||||||
|
// transformed_range
|
||||||
|
//
|
||||||
|
template<typename BinaryFunction, typename LRange, typename RRange = void>
|
||||||
|
class transformed_range
|
||||||
|
: public sprout::range::range_container<
|
||||||
|
sprout::transform_iterator<
|
||||||
|
BinaryFunction,
|
||||||
|
typename sprout::container_traits<LRange>::iterator,
|
||||||
|
typename sprout::container_traits<RRange>::iterator
|
||||||
|
>
|
||||||
|
>
|
||||||
|
, public sprout::detail::inherit_if_fixed_size<LRange>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef BinaryFunction functor_type;
|
||||||
|
typedef LRange range_type;
|
||||||
|
typedef RRange range2_type;
|
||||||
|
typedef sprout::range::range_container<
|
||||||
|
sprout::transform_iterator<
|
||||||
|
BinaryFunction,
|
||||||
|
typename sprout::container_traits<LRange>::iterator,
|
||||||
|
typename sprout::container_traits<RRange>::iterator
|
||||||
|
>
|
||||||
|
> base_type;
|
||||||
|
typedef typename base_type::iterator iterator;
|
||||||
|
typedef typename base_type::size_type size_type;
|
||||||
|
public:
|
||||||
|
transformed_range() = default;
|
||||||
|
transformed_range(transformed_range const&) = default;
|
||||||
|
SPROUT_CONSTEXPR transformed_range(functor_type func, range_type& range1, range2_type& range2)
|
||||||
|
: base_type(
|
||||||
|
iterator(sprout::begin(range1), sprout::begin(range2), func),
|
||||||
|
iterator(sprout::end(range1), sprout::end(range2), func)
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename UnaryFunction, typename Range>
|
||||||
|
class transformed_range<UnaryFunction, Range, void>
|
||||||
|
: public sprout::range::range_container<
|
||||||
|
sprout::transform_iterator<
|
||||||
|
UnaryFunction,
|
||||||
|
typename sprout::container_traits<Range>::iterator
|
||||||
|
>
|
||||||
|
>
|
||||||
|
, public sprout::detail::inherit_if_fixed_size<Range>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef UnaryFunction functor_type;
|
||||||
|
typedef Range range_type;
|
||||||
|
typedef sprout::range::range_container<
|
||||||
|
sprout::transform_iterator<
|
||||||
|
UnaryFunction,
|
||||||
|
typename sprout::container_traits<Range>::iterator
|
||||||
|
>
|
||||||
|
> base_type;
|
||||||
|
typedef typename base_type::iterator iterator;
|
||||||
|
public:
|
||||||
|
transformed_range() = default;
|
||||||
|
transformed_range(transformed_range const&) = default;
|
||||||
|
SPROUT_CONSTEXPR transformed_range(functor_type func, range_type& range)
|
||||||
|
: base_type(
|
||||||
|
iterator(sprout::begin(range), func),
|
||||||
|
iterator(sprout::end(range), func)
|
||||||
|
)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// transform_holder
|
||||||
|
//
|
||||||
|
template<typename BinaryFunction, typename RRange = void>
|
||||||
|
class transform_holder {
|
||||||
|
public:
|
||||||
|
typedef BinaryFunction functor_type;
|
||||||
|
typedef RRange range2_type;
|
||||||
|
private:
|
||||||
|
functor_type func_;
|
||||||
|
sprout::value_holder<range2_type&> range_;
|
||||||
|
public:
|
||||||
|
transform_holder() = default;
|
||||||
|
transform_holder(transform_holder const&) = default;
|
||||||
|
SPROUT_CONSTEXPR transform_holder(functor_type func, range2_type& range)
|
||||||
|
: func_(func)
|
||||||
|
, range_(range)
|
||||||
|
{}
|
||||||
|
SPROUT_CONSTEXPR functor_type functor() const {
|
||||||
|
return func_;
|
||||||
|
}
|
||||||
|
SPROUT_CONSTEXPR range2_type& range() const {
|
||||||
|
return range_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
template<typename UnaryFunction>
|
||||||
|
class transform_holder<UnaryFunction, void> {
|
||||||
|
public:
|
||||||
|
typedef UnaryFunction functor_type;
|
||||||
|
private:
|
||||||
|
functor_type func_;
|
||||||
|
public:
|
||||||
|
transform_holder() = default;
|
||||||
|
transform_holder(transform_holder const&) = default;
|
||||||
|
explicit SPROUT_CONSTEXPR transform_holder(functor_type func)
|
||||||
|
: func_(func)
|
||||||
|
{}
|
||||||
|
SPROUT_CONSTEXPR functor_type functor() const {
|
||||||
|
return func_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// transformed_forwarder
|
||||||
|
//
|
||||||
|
class transformed_forwarder {
|
||||||
|
public:
|
||||||
|
template<typename RRange, typename BinaryFunction>
|
||||||
|
SPROUT_CONSTEXPR sprout::range::transform_holder<
|
||||||
|
BinaryFunction,
|
||||||
|
typename std::remove_reference<typename sprout::lvalue_reference<RRange>::type>::type
|
||||||
|
>
|
||||||
|
operator()(RRange&& range, BinaryFunction func) {
|
||||||
|
return sprout::range::transform_holder<
|
||||||
|
BinaryFunction,
|
||||||
|
typename std::remove_reference<typename sprout::lvalue_reference<RRange>::type>::type
|
||||||
|
> (
|
||||||
|
func,
|
||||||
|
sprout::lvalue_forward<RRange>(range)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
template<typename UnaryFunction>
|
||||||
|
SPROUT_CONSTEXPR sprout::range::transform_holder<UnaryFunction>
|
||||||
|
operator()(UnaryFunction func) {
|
||||||
|
return sprout::range::transform_holder<UnaryFunction>(func);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// transformed
|
||||||
|
//
|
||||||
|
namespace {
|
||||||
|
SPROUT_STATIC_CONSTEXPR sprout::range::transformed_forwarder transformed{};
|
||||||
|
} // anonymous-namespace
|
||||||
|
|
||||||
|
//
|
||||||
|
// operator|
|
||||||
|
//
|
||||||
|
template<typename LRange, typename BinaryFunction, typename RRange>
|
||||||
|
inline SPROUT_CONSTEXPR sprout::range::transformed_range<
|
||||||
|
BinaryFunction,
|
||||||
|
typename std::remove_reference<typename sprout::lvalue_reference<LRange>::type>::type,
|
||||||
|
RRange
|
||||||
|
>
|
||||||
|
operator|(LRange&& lhs, sprout::range::transform_holder<BinaryFunction, RRange> const& rhs) {
|
||||||
|
return sprout::range::transformed_range<
|
||||||
|
BinaryFunction,
|
||||||
|
typename std::remove_reference<typename sprout::lvalue_reference<LRange>::type>::type,
|
||||||
|
RRange
|
||||||
|
>(
|
||||||
|
rhs.functor(),
|
||||||
|
sprout::lvalue_forward<LRange>(lhs),
|
||||||
|
rhs.range()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
template<typename Range, typename UnaryFunction>
|
||||||
|
inline SPROUT_CONSTEXPR sprout::range::transformed_range<
|
||||||
|
UnaryFunction,
|
||||||
|
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
|
||||||
|
>
|
||||||
|
operator|(Range&& lhs, sprout::range::transform_holder<UnaryFunction> const& rhs) {
|
||||||
|
return sprout::range::transformed_range<
|
||||||
|
UnaryFunction,
|
||||||
|
typename std::remove_reference<typename sprout::lvalue_reference<Range>::type>::type
|
||||||
|
>(
|
||||||
|
rhs.functor(),
|
||||||
|
sprout::lvalue_forward<Range>(lhs)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} // namespace range
|
||||||
|
//
|
||||||
|
// container_construct_traits
|
||||||
|
//
|
||||||
|
template<typename UnaryOrBinaryFunction, typename LRange, typename RRange>
|
||||||
|
struct container_construct_traits<sprout::range::transformed_range<UnaryOrBinaryFunction, LRange, RRange> > {
|
||||||
|
public:
|
||||||
|
typedef typename sprout::container_construct_traits<LRange>::copied_type copied_type;
|
||||||
|
public:
|
||||||
|
template<typename Cont>
|
||||||
|
static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) {
|
||||||
|
return sprout::range::fixed::copy(sprout::forward<Cont>(cont), sprout::pit<copied_type>());
|
||||||
|
}
|
||||||
|
template<typename... Args>
|
||||||
|
static SPROUT_CONSTEXPR copied_type make(Args&&... args) {
|
||||||
|
return sprout::make<copied_type>(sprout::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
template<typename Cont, typename... Args>
|
||||||
|
static SPROUT_CONSTEXPR copied_type remake(
|
||||||
|
Cont&& cont,
|
||||||
|
typename sprout::container_traits<sprout::range::transformed_range<UnaryOrBinaryFunction, LRange, RRange> >::difference_type size,
|
||||||
|
Args&&... args
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return sprout::remake<copied_type>(sprout::forward<Cont>(cont), size, sprout::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace sprout
|
||||||
|
|
||||||
|
#endif // #ifndef SPROUT_RANGE_ADAPTOR_TRANSFORMD_HPP
|
|
@ -6,6 +6,7 @@
|
||||||
#include <sprout/config.hpp>
|
#include <sprout/config.hpp>
|
||||||
#include <sprout/container/traits.hpp>
|
#include <sprout/container/traits.hpp>
|
||||||
#include <sprout/container/functions.hpp>
|
#include <sprout/container/functions.hpp>
|
||||||
|
#include <sprout/range/lvalue_iterator.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
namespace range {
|
namespace range {
|
||||||
|
|
|
@ -13,27 +13,52 @@ namespace sprout {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<std::size_t Index, typename Head, bool IsEmpty>
|
template<std::size_t Index, typename Head, bool IsEmpty>
|
||||||
class head_base;
|
class head_base;
|
||||||
|
//!!!
|
||||||
|
// EBO disabled
|
||||||
|
// template<std::size_t Index, typename Head>
|
||||||
|
// class head_base<Index, Head, true>
|
||||||
|
// : public Head
|
||||||
|
// {
|
||||||
|
// public:
|
||||||
|
// static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT {
|
||||||
|
// return t;
|
||||||
|
// }
|
||||||
|
// static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT {
|
||||||
|
// return t;
|
||||||
|
// }
|
||||||
|
// public:
|
||||||
|
// SPROUT_CONSTEXPR head_base()
|
||||||
|
// : Head()
|
||||||
|
// {}
|
||||||
|
// SPROUT_CONSTEXPR head_base(Head const& v)
|
||||||
|
// : Head(v)
|
||||||
|
// {}
|
||||||
|
// template<typename UHead>
|
||||||
|
// SPROUT_CONSTEXPR head_base(UHead&& v)
|
||||||
|
// : Head(sprout::forward<UHead>(v))
|
||||||
|
// {}
|
||||||
|
// };
|
||||||
template<std::size_t Index, typename Head>
|
template<std::size_t Index, typename Head>
|
||||||
class head_base<Index, Head, true>
|
class head_base<Index, Head, true> {
|
||||||
: public Head
|
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT {
|
static SPROUT_CONSTEXPR Head& head(head_base& t) SPROUT_NOEXCEPT {
|
||||||
return t;
|
return t.head_;
|
||||||
}
|
}
|
||||||
static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT {
|
static SPROUT_CONSTEXPR Head const& head(head_base const& t) SPROUT_NOEXCEPT {
|
||||||
return t;
|
return t.head_;
|
||||||
}
|
}
|
||||||
|
private:
|
||||||
|
Head head_;
|
||||||
public:
|
public:
|
||||||
SPROUT_CONSTEXPR head_base()
|
SPROUT_CONSTEXPR head_base()
|
||||||
: Head()
|
: head_()
|
||||||
{}
|
{}
|
||||||
SPROUT_CONSTEXPR head_base(Head const& v)
|
SPROUT_CONSTEXPR head_base(Head const& v)
|
||||||
: Head(v)
|
: head_(v)
|
||||||
{}
|
{}
|
||||||
template<typename UHead>
|
template<typename UHead>
|
||||||
SPROUT_CONSTEXPR head_base(UHead&& v)
|
SPROUT_CONSTEXPR head_base(UHead&& v)
|
||||||
: Head(sprout::forward<UHead>(v))
|
: head_(sprout::forward<UHead>(v))
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
template<std::size_t Index, typename Head>
|
template<std::size_t Index, typename Head>
|
||||||
|
|
Loading…
Reference in a new issue