add compost stereo, left_channel, right_channel, effected_xxx

This commit is contained in:
bolero-MURAKAMI 2012-11-25 01:05:11 +09:00
parent 7da0aa0343
commit c33ae70d13
14 changed files with 763 additions and 4 deletions

View file

@ -5,6 +5,8 @@
#include <sprout/functional/plus.hpp>
#include <sprout/utility/forward.hpp>
#include <sprout/utility/value_holder.hpp>
#include <sprout/utility/lvalue_forward.hpp>
#include <sprout/type_traits/lvalue_reference.hpp>
#include <sprout/range/adaptor/transformed.hpp>
namespace sprout {

View file

@ -5,5 +5,9 @@
#include <sprout/compost/formats/as_pcm_wave.hpp>
#include <sprout/compost/formats/left_channel.hpp>
#include <sprout/compost/formats/right_channel.hpp>
#include <sprout/compost/formats/stereo.hpp>
#include <sprout/compost/formats/effected_each_cannel.hpp>
#include <sprout/compost/formats/effected_left_cannel.hpp>
#include <sprout/compost/formats/effected_right_cannel.hpp>
#endif // #ifndef SPROUT_COMPOST_FORMATS_HPP

View file

@ -0,0 +1,107 @@
#ifndef SPROUT_COMPOST_FORMATS_EFFECTED_EACH_CHANNEL_HPP
#define SPROUT_COMPOST_FORMATS_EFFECTED_EACH_CHANNEL_HPP
#include <sprout/config.hpp>
#include <sprout/utility/lvalue_forward.hpp>
#include <sprout/compost/formats/left_channel.hpp>
#include <sprout/compost/formats/right_channel.hpp>
#include <sprout/compost/formats/stereo.hpp>
namespace sprout {
namespace compost {
namespace formats {
//
// effect_each_channel_holder
//
template<typename LAdaptor, typename RAdaptor = void>
class effect_each_channel_holder {
public:
typedef LAdaptor left_adaptor_type;
typedef RAdaptor right_adaptor_type;
private:
left_adaptor_type left_adaptor_;
right_adaptor_type right_adaptor_;
public:
SPROUT_CONSTEXPR effect_each_channel_holder(left_adaptor_type const& left_adaptor, right_adaptor_type const& right_adaptor)
: left_adaptor_(left_adaptor), right_adaptor_(right_adaptor)
{}
SPROUT_CONSTEXPR left_adaptor_type const& left_adaptor() const {
return left_adaptor_;
}
SPROUT_CONSTEXPR right_adaptor_type const& right_adaptor() const {
return right_adaptor_;
}
};
template<typename Adaptor>
class effect_each_channel_holder<Adaptor, void> {
public:
typedef Adaptor adaptor_type;
private:
adaptor_type adaptor_;
public:
explicit SPROUT_CONSTEXPR effect_each_channel_holder(adaptor_type const& adaptor)
: adaptor_(adaptor)
{}
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
return adaptor_;
}
};
//
// effected_each_cannel_forwarder
//
class effected_each_cannel_forwarder {
public:
template<typename LAdaptor, typename RAdaptor>
SPROUT_CONSTEXPR sprout::compost::formats::effect_each_channel_holder<LAdaptor, RAdaptor>
operator()(LAdaptor const& left_adaptor, RAdaptor const& right_adaptor) {
return sprout::compost::formats::effect_each_channel_holder<LAdaptor, RAdaptor>(left_adaptor, right_adaptor);
}
template<typename Adaptor>
SPROUT_CONSTEXPR sprout::compost::formats::effect_each_channel_holder<Adaptor>
operator()(Adaptor const& adaptor) {
return sprout::compost::formats::effect_each_channel_holder<Adaptor>(adaptor);
}
};
//
// effected_each_cannel
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::compost::formats::effected_each_cannel_forwarder effected_each_cannel{};
} // anonymous-namespace
//
// operator|
//
template<typename Range, typename LAdaptor, typename RAdaptor>
inline SPROUT_CONSTEXPR auto
operator|(Range&& lhs, sprout::compost::formats::effect_each_channel_holder<LAdaptor, RAdaptor> const& rhs)
-> decltype(
sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::left_channel | rhs.left_adaptor()
| sprout::compost::formats::stereo(sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::right_channel | rhs.right_adaptor())
)
{
return sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::left_channel | rhs.left_adaptor()
| sprout::compost::formats::stereo(sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::right_channel | rhs.right_adaptor())
;
}
template<typename Range, typename Adaptor>
inline SPROUT_CONSTEXPR auto
operator|(Range&& lhs, sprout::compost::formats::effect_each_channel_holder<Adaptor> const& rhs)
-> decltype(
sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::left_channel | rhs.adaptor()
| sprout::compost::formats::stereo(sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::right_channel | rhs.adaptor())
)
{
return sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::left_channel | rhs.adaptor()
| sprout::compost::formats::stereo(sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::right_channel | rhs.adaptor())
;
}
} // namespace formats
using sprout::compost::formats::effected_each_cannel;
} // namespace compost
} // namespace sprout
#endif // #ifndef SPROUT_COMPOST_FORMATS_EFFECTED_EACH_CHANNEL_HPP

View file

@ -0,0 +1,71 @@
#ifndef SPROUT_COMPOST_FORMATS_EFFECTED_LEFT_CHANNEL_HPP
#define SPROUT_COMPOST_FORMATS_EFFECTED_LEFT_CHANNEL_HPP
#include <sprout/config.hpp>
#include <sprout/utility/lvalue_forward.hpp>
#include <sprout/compost/formats/left_channel.hpp>
#include <sprout/compost/formats/right_channel.hpp>
#include <sprout/compost/formats/stereo.hpp>
namespace sprout {
namespace compost {
namespace formats {
//
// effect_left_channel_holder
//
template<typename Adaptor>
class effect_left_channel_holder {
public:
typedef Adaptor adaptor_type;
private:
adaptor_type adaptor_;
public:
explicit SPROUT_CONSTEXPR effect_left_channel_holder(adaptor_type const& adaptor)
: adaptor_(adaptor)
{}
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
return adaptor_;
}
};
//
// effected_left_cannel_forwarder
//
class effected_left_cannel_forwarder {
public:
template<typename Adaptor>
SPROUT_CONSTEXPR sprout::compost::formats::effect_left_channel_holder<Adaptor>
operator()(Adaptor const& adaptor) {
return sprout::compost::formats::effect_left_channel_holder<Adaptor>(adaptor);
}
};
//
// effected_left_cannel
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::compost::formats::effected_left_cannel_forwarder effected_left_cannel{};
} // anonymous-namespace
//
// operator|
//
template<typename Range, typename Adaptor>
inline SPROUT_CONSTEXPR auto
operator|(Range&& lhs, sprout::compost::formats::effect_left_channel_holder<Adaptor> const& rhs)
-> decltype(
sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::left_channel | rhs.adaptor()
| sprout::compost::formats::stereo(sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::right_channel)
)
{
return sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::left_channel | rhs.adaptor()
| sprout::compost::formats::stereo(sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::right_channel)
;
}
} // namespace formats
using sprout::compost::formats::effected_left_cannel;
} // namespace compost
} // namespace sprout
#endif // #ifndef SPROUT_COMPOST_FORMATS_EFFECTED_LEFT_CHANNEL_HPP

View file

@ -0,0 +1,71 @@
#ifndef SPROUT_COMPOST_FORMATS_EFFECTED_RIGHT_CHANNEL_HPP
#define SPROUT_COMPOST_FORMATS_EFFECTED_RIGHT_CHANNEL_HPP
#include <sprout/config.hpp>
#include <sprout/utility/lvalue_forward.hpp>
#include <sprout/compost/formats/left_channel.hpp>
#include <sprout/compost/formats/right_channel.hpp>
#include <sprout/compost/formats/stereo.hpp>
namespace sprout {
namespace compost {
namespace formats {
//
// effect_right_channel_holder
//
template<typename Adaptor>
class effect_right_channel_holder {
public:
typedef Adaptor adaptor_type;
private:
adaptor_type adaptor_;
public:
explicit SPROUT_CONSTEXPR effect_right_channel_holder(adaptor_type const& adaptor)
: adaptor_(adaptor)
{}
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
return adaptor_;
}
};
//
// effected_right_cannel_forwarder
//
class effected_right_cannel_forwarder {
public:
template<typename Adaptor>
SPROUT_CONSTEXPR sprout::compost::formats::effect_right_channel_holder<Adaptor>
operator()(Adaptor const& adaptor) {
return sprout::compost::formats::effect_right_channel_holder<Adaptor>(adaptor);
}
};
//
// effected_right_cannel
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::compost::formats::effected_right_cannel_forwarder effected_right_cannel{};
} // anonymous-namespace
//
// operator|
//
template<typename Range, typename Adaptor>
inline SPROUT_CONSTEXPR auto
operator|(Range&& lhs, sprout::compost::formats::effect_right_channel_holder<Adaptor> const& rhs)
-> decltype(
sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::left_channel
| sprout::compost::formats::stereo(sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::right_channel | rhs.adaptor())
)
{
return sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::left_channel
| sprout::compost::formats::stereo(sprout::lvalue_forward<Range>(lhs) | sprout::compost::formats::right_channel | rhs.adaptor())
;
}
} // namespace formats
using sprout::compost::formats::effected_right_cannel;
} // namespace compost
} // namespace sprout
#endif // #ifndef SPROUT_COMPOST_FORMATS_EFFECTED_RIGHT_CHANNEL_HPP

View file

@ -0,0 +1,22 @@
#ifndef SPROUT_COMPOST_FORMATS_STEREO_HPP
#define SPROUT_COMPOST_FORMATS_STEREO_HPP
#include <sprout/config.hpp>
#include <sprout/range/adaptor/alternated.hpp>
namespace sprout {
namespace compost {
namespace formats {
//
// stereo
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::adaptors::alternated_forwarder stereo{};
} // anonymous-namespace
} // namespace formats
using sprout::compost::formats::stereo;
} // namespace compost
} // namespace sprout
#endif // #ifndef SPROUT_COMPOST_FORMATS_STEREO_HPP

View file

@ -9,6 +9,7 @@
#include <sprout/iterator/indexed_iterator.hpp>
#include <sprout/iterator/valued_iterator.hpp>
#include <sprout/iterator/joint_iterator.hpp>
#include <sprout/iterator/alternate_iterator.hpp>
#include <sprout/iterator/size_enum_iterator.hpp>
#include <sprout/iterator/bytes_iterator.hpp>

View file

@ -0,0 +1,329 @@
#ifndef SPROUT_ITERATOR_ALTERNATE_ITERATOR_HPP
#define SPROUT_ITERATOR_ALTERNATE_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>
#include <sprout/iterator/type_traits/common.hpp>
#include <sprout/utility/swap.hpp>
#include <sprout/type_traits/arithmetic_promote.hpp>
#include HDR_ITERATOR_SSCRISK_CEL_OR_SPROUT
namespace sprout {
//
// alternate_iterator
//
template<typename LIterator, typename RIterator>
class alternate_iterator
: public std::iterator<
typename sprout::common_iterator_category<LIterator, RIterator>::type,
typename sprout::common_iterator_value_type<LIterator, RIterator>::type,
typename sprout::common_iterator_difference_type<LIterator, RIterator>::type,
typename sprout::common_iterator_pointer<LIterator, RIterator>::type,
typename sprout::common_iterator_reference<LIterator, RIterator>::type
>
{
public:
typedef LIterator iterator_type;
typedef RIterator iterator2_type;
typedef typename sprout::common_iterator_category<LIterator, RIterator>::type iterator_category;
typedef typename sprout::common_iterator_value_type<LIterator, RIterator>::type value_type;
typedef typename sprout::common_iterator_difference_type<LIterator, RIterator>::type difference_type;
typedef typename sprout::common_iterator_pointer<LIterator, RIterator>::type pointer;
typedef typename sprout::common_iterator_reference<LIterator, RIterator>::type reference;
protected:
iterator_type current1;
iterator2_type current2;
bool in_left;
private:
SPROUT_CONSTEXPR alternate_iterator advance_impl_1(difference_type n) const {
return alternate_iterator(sprout::next(current1, n / 2), sprout::next(current2, n / 2), n % 2);
}
SPROUT_CONSTEXPR alternate_iterator advance_impl(difference_type n) const {
return advance_impl_1(n + (!is_in_left() ? 1 : 0));
}
SPROUT_CONSTEXPR alternate_iterator(iterator_type it1, iterator2_type it2, bool in_left)
: current1(it1), current2(it2), in_left(in_left)
{}
public:
alternate_iterator()
: current1(), current2(), in_left(true)
{}
alternate_iterator(alternate_iterator const&) = default;
SPROUT_CONSTEXPR alternate_iterator(iterator_type it1, iterator2_type it2)
: current1(it1), current2(it2), in_left(true)
{}
template<typename U, typename V>
SPROUT_CONSTEXPR alternate_iterator(alternate_iterator<U, V> const& it)
: current1(it.base()), current2(it.base2()), in_left(it.is_in_left())
{}
template<typename U, typename V>
alternate_iterator& operator=(alternate_iterator<U, V> const& it) {
alternate_iterator temp(it);
temp.swap(*this);
return *this;
}
SPROUT_CONSTEXPR iterator_type base() const {
return current1;
}
SPROUT_CONSTEXPR iterator2_type base2() const {
return current2;
}
SPROUT_CONSTEXPR bool is_in_left() const {
return in_left;
}
SPROUT_CONSTEXPR reference operator*() const {
return is_in_left() ? *current1 : *current2;
}
SPROUT_CONSTEXPR pointer operator->() const {
return &*(*this);
}
alternate_iterator& operator++() {
if (is_in_left()) {
in_left = false;
} else {
in_left = true;
++current1;
++current2;
}
return *this;
}
alternate_iterator operator++(int) {
alternate_iterator result(*this);
if (is_in_left()) {
in_left = false;
} else {
in_left = true;
++current1;
++current2;
}
return result;
}
alternate_iterator& operator--() {
if (is_in_left()) {
in_left = false;
--current1;
--current2;
} else {
in_left = true;
}
return *this;
}
alternate_iterator operator--(int) {
alternate_iterator temp(*this);
if (is_in_left()) {
in_left = false;
--current1;
--current2;
} else {
in_left = true;
}
return temp;
}
SPROUT_CONSTEXPR alternate_iterator operator+(difference_type n) const {
return advance_impl(n);
}
SPROUT_CONSTEXPR alternate_iterator operator-(difference_type n) const {
return advance_impl(-n);
}
alternate_iterator& operator+=(difference_type n) {
alternate_iterator temp(*this + n);
temp.swap(*this);
return *this;
}
alternate_iterator& operator-=(difference_type n) {
alternate_iterator temp(*this - n);
temp.swap(*this);
return *this;
}
SPROUT_CONSTEXPR reference operator[](difference_type n) const {
return *(*this + n);
}
SPROUT_CONSTEXPR alternate_iterator next() const {
return is_in_left() ? alternate_iterator(current1, current2, false)
: alternate_iterator(sprout::next(current1), sprout::next(current2), true)
;
}
SPROUT_CONSTEXPR alternate_iterator prev() const {
return is_in_left() ? alternate_iterator(sprout::prev(current1), sprout::prev(current2), false)
: alternate_iterator(current1, current2, true)
;
}
void swap(alternate_iterator& other)
SPROUT_NOEXCEPT_EXPR(
SPROUT_NOEXCEPT_EXPR(sprout::swap(current1, other.current1))
&& SPROUT_NOEXCEPT_EXPR(sprout::swap(current2, other.current2))
&& SPROUT_NOEXCEPT_EXPR(sprout::swap(in_left, other.in_left))
)
{
sprout::swap(current1, other.current1);
sprout::swap(current2, other.current2);
sprout::swap(in_left, other.in_left);
}
};
template<
typename LIterator1, typename RIterator1,
typename LIterator2, typename RIterator2
>
inline SPROUT_CONSTEXPR bool operator==(
sprout::alternate_iterator<LIterator1, RIterator1> const& lhs,
sprout::alternate_iterator<LIterator2, RIterator2> const& rhs
)
{
return lhs.base() == rhs.base() && (lhs.is_in_left() == rhs.is_in_left());
}
template<
typename LIterator1, typename RIterator1,
typename LIterator2, typename RIterator2
>
inline SPROUT_CONSTEXPR bool operator!=(
sprout::alternate_iterator<LIterator1, RIterator1> const& lhs,
sprout::alternate_iterator<LIterator2, RIterator2> const& rhs
)
{
return !(lhs == rhs);
}
template<
typename LIterator1, typename RIterator1,
typename LIterator2, typename RIterator2
>
inline SPROUT_CONSTEXPR bool operator<(
sprout::alternate_iterator<LIterator1, RIterator1> const& lhs,
sprout::alternate_iterator<LIterator2, RIterator2> const& rhs
)
{
return lhs.base() < rhs.base() || (lhs.base() == rhs.base() && lhs.is_in_left() && !rhs.is_in_left());
}
template<
typename LIterator1, typename RIterator1,
typename LIterator2, typename RIterator2
>
inline SPROUT_CONSTEXPR bool operator>(
sprout::alternate_iterator<LIterator1, RIterator1> const& lhs,
sprout::alternate_iterator<LIterator2, RIterator2> const& rhs
)
{
return rhs < lhs;
}
template<
typename LIterator1, typename RIterator1,
typename LIterator2, typename RIterator2
>
inline SPROUT_CONSTEXPR bool operator<=(
sprout::alternate_iterator<LIterator1, RIterator1> const& lhs,
sprout::alternate_iterator<LIterator2, RIterator2> const& rhs
)
{
return !(rhs < lhs);
}
template<
typename LIterator1, typename RIterator1,
typename LIterator2, typename RIterator2
>
inline SPROUT_CONSTEXPR bool operator>=(
sprout::alternate_iterator<LIterator1, RIterator1> const& lhs,
sprout::alternate_iterator<LIterator2, RIterator2> const& rhs
)
{
return !(lhs < rhs);
}
template<
typename LIterator1, typename RIterator1,
typename LIterator2, typename RIterator2
>
inline SPROUT_CONSTEXPR decltype(std::declval<LIterator1>() - std::declval<LIterator2>())
operator-(
sprout::alternate_iterator<LIterator1, RIterator1> const& lhs,
sprout::alternate_iterator<LIterator2, RIterator2> const& rhs
)
{
return lhs.base() - rhs.base() + (lhs.is_in_left() ? (rhs.is_in_left() ? 0 : 1) : (rhs.is_in_left() ? 1 : 0));
}
template<typename LIterator, typename RIterator>
inline SPROUT_CONSTEXPR sprout::alternate_iterator<LIterator, RIterator> operator+(
typename sprout::alternate_iterator<LIterator, RIterator>::difference_type n,
sprout::alternate_iterator<LIterator, RIterator> const& it
)
{
return it + n;
}
//
// make_alternate_iterator
//
template<typename LIterator, typename RIterator>
inline SPROUT_CONSTEXPR sprout::alternate_iterator<LIterator, RIterator>
make_alternate_iterator(LIterator it1, RIterator it2) {
return sprout::alternate_iterator<LIterator, RIterator>(it1, it2);
}
//
// swap
//
template<typename LIterator, typename RIterator>
inline void
swap(
sprout::alternate_iterator<LIterator, RIterator>& lhs,
sprout::alternate_iterator<LIterator, RIterator>& rhs
)
SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs)))
{
lhs.swap(rhs);
}
//
// iterator_distance
//
template<typename LIterator, typename RIterator>
inline SPROUT_CONSTEXPR typename std::iterator_traits<sprout::alternate_iterator<LIterator, RIterator> >::difference_type
iterator_distance(
sprout::alternate_iterator<LIterator, RIterator> first,
sprout::alternate_iterator<LIterator, RIterator> last
)
{
return last - first;
}
//
// iterator_next
//
template<typename LIterator, typename RIterator>
inline SPROUT_CONSTEXPR sprout::alternate_iterator<LIterator, RIterator>
iterator_next(sprout::alternate_iterator<LIterator, RIterator> const& it) {
return it.next();
}
template<typename LIterator, typename RIterator>
inline SPROUT_CONSTEXPR sprout::alternate_iterator<LIterator, RIterator>
iterator_next(
sprout::alternate_iterator<LIterator, RIterator> const& it,
typename sprout::alternate_iterator<LIterator, RIterator>::difference_type n
)
{
return it + n;
}
//
// iterator_prev
//
template<typename LIterator, typename RIterator>
inline SPROUT_CONSTEXPR sprout::alternate_iterator<LIterator, RIterator>
iterator_prev(sprout::alternate_iterator<LIterator, RIterator> const& it) {
return it.prev();
}
template<typename LIterator, typename RIterator>
inline SPROUT_CONSTEXPR sprout::alternate_iterator<LIterator, RIterator>
iterator_prev(
sprout::alternate_iterator<LIterator, RIterator> const& it,
typename sprout::alternate_iterator<LIterator, RIterator>::difference_type n
)
{
return it - n;
}
} // namespace sprout
#endif // #ifndef SPROUT_ITERATOR_ALTERNATE_ITERATOR_HPP

View file

@ -25,6 +25,7 @@
#include <sprout/range/adaptor/adapted_offset.hpp>
#include <sprout/range/adaptor/steps.hpp>
#include <sprout/range/adaptor/jointed.hpp>
#include <sprout/range/adaptor/alternated.hpp>
#include <sprout/range/adaptor/deep_copied.hpp>
#include <sprout/range/adaptor/indexed.hpp>
#include <sprout/range/adaptor/valued.hpp>

View file

@ -21,7 +21,7 @@ namespace sprout {
adaptor_type adaptor_;
difference_type distance_;
public:
explicit SPROUT_CONSTEXPR adapt_drop_holder(adaptor_type const& adaptor, difference_type distance)
SPROUT_CONSTEXPR adapt_drop_holder(adaptor_type const& adaptor, difference_type distance)
: adaptor_(adaptor), distance_(distance)
{}
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {

View file

@ -21,7 +21,7 @@ namespace sprout {
adaptor_type adaptor_;
difference_type distance_;
public:
explicit SPROUT_CONSTEXPR adapt_drop_end_holder(adaptor_type const& adaptor, difference_type distance)
SPROUT_CONSTEXPR adapt_drop_end_holder(adaptor_type const& adaptor, difference_type distance)
: adaptor_(adaptor), distance_(distance)
{}
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {

View file

@ -21,7 +21,7 @@ namespace sprout {
adaptor_type adaptor_;
difference_type distance_;
public:
explicit SPROUT_CONSTEXPR adapt_take_holder(adaptor_type const& adaptor, difference_type distance)
SPROUT_CONSTEXPR adapt_take_holder(adaptor_type const& adaptor, difference_type distance)
: adaptor_(adaptor), distance_(distance)
{}
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {

View file

@ -21,7 +21,7 @@ namespace sprout {
adaptor_type adaptor_;
difference_type distance_;
public:
explicit SPROUT_CONSTEXPR adapt_take_end_holder(adaptor_type const& adaptor, difference_type distance)
SPROUT_CONSTEXPR adapt_take_end_holder(adaptor_type const& adaptor, difference_type distance)
: adaptor_(adaptor), distance_(distance)
{}
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {

View file

@ -0,0 +1,151 @@
#ifndef SPROUT_RANGE_ADAPTOR_ALTERNATED_HPP
#define SPROUT_RANGE_ADAPTOR_ALTERNATED_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/next.hpp>
#include <sprout/iterator/alternate_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>
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
namespace sprout {
namespace adaptors {
//
// alternated_range
//
template<typename LRange, typename RRange>
class alternated_range
: public sprout::range::range_container<
sprout::alternate_iterator<
typename sprout::container_traits<LRange>::iterator,
typename sprout::container_traits<RRange>::iterator
>
>
, public sprout::detail::container_nosy_static_size<LRange>
, public sprout::detail::container_nosy_fixed_size<LRange>
{
public:
typedef LRange range_type;
typedef RRange range2_type;
typedef sprout::range::range_container<
sprout::alternate_iterator<
typename sprout::container_traits<LRange>::iterator,
typename sprout::container_traits<RRange>::iterator
>
> base_type;
typedef typename base_type::iterator iterator;
public:
alternated_range() = default;
alternated_range(alternated_range const&) = default;
SPROUT_CONSTEXPR alternated_range(range_type& range1, range2_type& range2)
: base_type(
iterator(sprout::begin(range1), sprout::begin(range2)),
iterator(
sprout::next(sprout::begin(range1), NS_SSCRISK_CEL_OR_SPROUT::min(sprout::size(range1), sprout::size(range2))),
sprout::next(sprout::begin(range2), NS_SSCRISK_CEL_OR_SPROUT::min(sprout::size(range1), sprout::size(range2)))
)
)
{}
};
//
// alternate_holder
//
template<typename RRange>
class alternate_holder {
public:
typedef RRange range2_type;
private:
sprout::value_holder<range2_type&> range_;
public:
alternate_holder() = default;
alternate_holder(alternate_holder const&) = default;
explicit SPROUT_CONSTEXPR alternate_holder(range2_type& range)
: range_(range)
{}
SPROUT_CONSTEXPR range2_type& range() const {
return range_;
}
};
//
// alternated_forwarder
//
class alternated_forwarder {
public:
template<typename RRange>
SPROUT_CONSTEXPR sprout::adaptors::alternate_holder<
typename std::remove_reference<typename sprout::lvalue_reference<RRange>::type>::type
>
operator()(RRange&& range) {
return sprout::adaptors::alternate_holder<
typename std::remove_reference<typename sprout::lvalue_reference<RRange>::type>::type
>(
sprout::lvalue_forward<RRange>(range)
);
}
};
//
// alternated
//
namespace {
SPROUT_STATIC_CONSTEXPR sprout::adaptors::alternated_forwarder alternated{};
} // anonymous-namespace
//
// operator|
//
template<typename LRange, typename RRange>
inline SPROUT_CONSTEXPR sprout::adaptors::alternated_range<
typename std::remove_reference<typename sprout::lvalue_reference<LRange>::type>::type,
RRange
>
operator|(LRange&& lhs, sprout::adaptors::alternate_holder<RRange> const& rhs) {
return sprout::adaptors::alternated_range<
typename std::remove_reference<typename sprout::lvalue_reference<LRange>::type>::type,
RRange
>(
sprout::lvalue_forward<LRange>(lhs),
rhs.range()
);
}
} // namespace adaptors
//
// container_construct_traits
//
template<typename LRange, typename RRange>
struct container_construct_traits<sprout::adaptors::alternated_range<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::adaptors::alternated_range<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_ALTERNATED_HPP