mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
add compost stereo, left_channel, right_channel, effected_xxx
This commit is contained in:
parent
7da0aa0343
commit
c33ae70d13
14 changed files with 763 additions and 4 deletions
|
@ -5,6 +5,8 @@
|
||||||
#include <sprout/functional/plus.hpp>
|
#include <sprout/functional/plus.hpp>
|
||||||
#include <sprout/utility/forward.hpp>
|
#include <sprout/utility/forward.hpp>
|
||||||
#include <sprout/utility/value_holder.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>
|
#include <sprout/range/adaptor/transformed.hpp>
|
||||||
|
|
||||||
namespace sprout {
|
namespace sprout {
|
||||||
|
|
|
@ -5,5 +5,9 @@
|
||||||
#include <sprout/compost/formats/as_pcm_wave.hpp>
|
#include <sprout/compost/formats/as_pcm_wave.hpp>
|
||||||
#include <sprout/compost/formats/left_channel.hpp>
|
#include <sprout/compost/formats/left_channel.hpp>
|
||||||
#include <sprout/compost/formats/right_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
|
#endif // #ifndef SPROUT_COMPOST_FORMATS_HPP
|
||||||
|
|
107
sprout/compost/formats/effected_each_cannel.hpp
Normal file
107
sprout/compost/formats/effected_each_cannel.hpp
Normal 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
|
71
sprout/compost/formats/effected_left_cannel.hpp
Normal file
71
sprout/compost/formats/effected_left_cannel.hpp
Normal 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
|
71
sprout/compost/formats/effected_right_cannel.hpp
Normal file
71
sprout/compost/formats/effected_right_cannel.hpp
Normal 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
|
22
sprout/compost/formats/stereo.hpp
Normal file
22
sprout/compost/formats/stereo.hpp
Normal 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
|
|
@ -9,6 +9,7 @@
|
||||||
#include <sprout/iterator/indexed_iterator.hpp>
|
#include <sprout/iterator/indexed_iterator.hpp>
|
||||||
#include <sprout/iterator/valued_iterator.hpp>
|
#include <sprout/iterator/valued_iterator.hpp>
|
||||||
#include <sprout/iterator/joint_iterator.hpp>
|
#include <sprout/iterator/joint_iterator.hpp>
|
||||||
|
#include <sprout/iterator/alternate_iterator.hpp>
|
||||||
#include <sprout/iterator/size_enum_iterator.hpp>
|
#include <sprout/iterator/size_enum_iterator.hpp>
|
||||||
#include <sprout/iterator/bytes_iterator.hpp>
|
#include <sprout/iterator/bytes_iterator.hpp>
|
||||||
|
|
||||||
|
|
329
sprout/iterator/alternate_iterator.hpp
Normal file
329
sprout/iterator/alternate_iterator.hpp
Normal 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
|
|
@ -25,6 +25,7 @@
|
||||||
#include <sprout/range/adaptor/adapted_offset.hpp>
|
#include <sprout/range/adaptor/adapted_offset.hpp>
|
||||||
#include <sprout/range/adaptor/steps.hpp>
|
#include <sprout/range/adaptor/steps.hpp>
|
||||||
#include <sprout/range/adaptor/jointed.hpp>
|
#include <sprout/range/adaptor/jointed.hpp>
|
||||||
|
#include <sprout/range/adaptor/alternated.hpp>
|
||||||
#include <sprout/range/adaptor/deep_copied.hpp>
|
#include <sprout/range/adaptor/deep_copied.hpp>
|
||||||
#include <sprout/range/adaptor/indexed.hpp>
|
#include <sprout/range/adaptor/indexed.hpp>
|
||||||
#include <sprout/range/adaptor/valued.hpp>
|
#include <sprout/range/adaptor/valued.hpp>
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace sprout {
|
||||||
adaptor_type adaptor_;
|
adaptor_type adaptor_;
|
||||||
difference_type distance_;
|
difference_type distance_;
|
||||||
public:
|
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)
|
: adaptor_(adaptor), distance_(distance)
|
||||||
{}
|
{}
|
||||||
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
|
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace sprout {
|
||||||
adaptor_type adaptor_;
|
adaptor_type adaptor_;
|
||||||
difference_type distance_;
|
difference_type distance_;
|
||||||
public:
|
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)
|
: adaptor_(adaptor), distance_(distance)
|
||||||
{}
|
{}
|
||||||
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
|
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace sprout {
|
||||||
adaptor_type adaptor_;
|
adaptor_type adaptor_;
|
||||||
difference_type distance_;
|
difference_type distance_;
|
||||||
public:
|
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)
|
: adaptor_(adaptor), distance_(distance)
|
||||||
{}
|
{}
|
||||||
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
|
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace sprout {
|
||||||
adaptor_type adaptor_;
|
adaptor_type adaptor_;
|
||||||
difference_type distance_;
|
difference_type distance_;
|
||||||
public:
|
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)
|
: adaptor_(adaptor), distance_(distance)
|
||||||
{}
|
{}
|
||||||
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
|
SPROUT_CONSTEXPR adaptor_type const& adaptor() const {
|
||||||
|
|
151
sprout/range/adaptor/alternated.hpp
Normal file
151
sprout/range/adaptor/alternated.hpp
Normal 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
|
Loading…
Reference in a new issue