mirror of
https://github.com/bolero-MURAKAMI/Sprout
synced 2024-11-12 21:09:01 +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 {};
|
||||
|
||||
namespace placeholders {
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<1> _1;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<2> _2;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<3> _3;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<4> _4;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<5> _5;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<6> _6;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<7> _7;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<8> _8;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<9> _9;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<10> _10;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<11> _11;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<12> _12;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<13> _13;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<14> _14;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<15> _15;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<16> _16;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<17> _17;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<18> _18;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<19> _19;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<20> _20;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<21> _21;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<22> _22;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<23> _23;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<24> _24;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<25> _25;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<26> _26;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<27> _27;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<28> _28;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<29> _29;
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<30> _30;
|
||||
namespace {
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<1> _1{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<2> _2{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<3> _3{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<4> _4{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<5> _5{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<6> _6{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<7> _7{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<8> _8{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<9> _9{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<10> _10{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<11> _11{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<12> _12{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<13> _13{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<14> _14{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<15> _15{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<16> _16{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<17> _17{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<18> _18{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<19> _19{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<20> _20{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<21> _21{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<22> _22{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<23> _23{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<24> _24{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<25> _25{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<26> _26{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<27> _27{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<28> _28{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<29> _29{};
|
||||
SPROUT_STATIC_CONSTEXPR sprout::placeholder<30> _30{};
|
||||
} // anonymous-namespace
|
||||
} // namespace placeholders
|
||||
using sprout::placeholders::_1;
|
||||
using sprout::placeholders::_2;
|
||||
|
|
|
@ -162,10 +162,10 @@ namespace sprout {
|
|||
return !(lhs < rhs);
|
||||
}
|
||||
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<Iterator2> const& rhs
|
||||
) -> decltype(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
|
||||
)
|
||||
{
|
||||
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/container/traits.hpp>
|
||||
#include <sprout/container/functions.hpp>
|
||||
#include <sprout/range/lvalue_iterator.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace range {
|
||||
|
|
|
@ -13,27 +13,52 @@ namespace sprout {
|
|||
namespace detail {
|
||||
template<std::size_t Index, typename Head, bool IsEmpty>
|
||||
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>
|
||||
class head_base<Index, Head, true>
|
||||
: public Head
|
||||
{
|
||||
class head_base<Index, Head, true> {
|
||||
public:
|
||||
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 {
|
||||
return t;
|
||||
return t.head_;
|
||||
}
|
||||
private:
|
||||
Head head_;
|
||||
public:
|
||||
SPROUT_CONSTEXPR head_base()
|
||||
: Head()
|
||||
: head_()
|
||||
{}
|
||||
SPROUT_CONSTEXPR head_base(Head const& v)
|
||||
: Head(v)
|
||||
: head_(v)
|
||||
{}
|
||||
template<typename UHead>
|
||||
SPROUT_CONSTEXPR head_base(UHead&& v)
|
||||
: Head(sprout::forward<UHead>(v))
|
||||
: head_(sprout::forward<UHead>(v))
|
||||
{}
|
||||
};
|
||||
template<std::size_t Index, typename Head>
|
||||
|
|
Loading…
Reference in a new issue