diff --git a/sprout/compost/effects.hpp b/sprout/compost/effects.hpp index ddb451f8..a180ae5a 100644 --- a/sprout/compost/effects.hpp +++ b/sprout/compost/effects.hpp @@ -3,8 +3,16 @@ #include #include +#include #include +#include #include +#include +#include +#include +#include +#include +#include #include #endif // #ifndef SPROUT_COMPOST_EFFECTS_HPP diff --git a/sprout/compost/effects/compress.hpp b/sprout/compost/effects/compress.hpp new file mode 100644 index 00000000..86c8a724 --- /dev/null +++ b/sprout/compost/effects/compress.hpp @@ -0,0 +1,126 @@ +#ifndef SPROUT_COMPOST_EFFECTS_COMPRESS_HPP +#define SPROUT_COMPOST_EFFECTS_COMPRESS_HPP + +#include +#include +#include + +namespace sprout { + namespace compost { + namespace detail { + template + SPROUT_CONSTEXPR T + compress_value(T const& x, Value const& threshold, Value const& ratio, Value const& gain) { + return (x > threshold ? threshold + (x - threshold) * ratio + : x < -threshold ? -threshold + (x + threshold) * ratio + : x + ) * gain + ; + } + } // namespace detail + // + // compress_value + // + template + struct compress_value { + public: + typedef Value value_type; + typedef T argument_type; + typedef T result_type; + private: + value_type threshold_; + value_type ratio_; + value_type gain_; + public: + SPROUT_CONSTEXPR compress_value(Value const& threshold, Value const& ratio) + : threshold_(threshold), ratio_(ratio), gain_(1 / (threshold + (1 - threshold) * ratio)) + {} + SPROUT_CONSTEXPR result_type + operator()(T const& x) const { + return sprout::compost::detail::compress_value(x, threshold_, ratio_, gain_); + } + }; + template + struct compress_value { + public: + typedef Value value_type; + private: + value_type threshold_; + value_type ratio_; + value_type gain_; + public: + SPROUT_CONSTEXPR compress_value(Value const& threshold, Value const& ratio) + : threshold_(threshold), ratio_(ratio), gain_(1 / (threshold + (1 - threshold) * ratio)) + {} + template + SPROUT_CONSTEXPR T + operator()(T const& x) const { + return sprout::compost::detail::compress_value(x, threshold_, ratio_, gain_); + } + }; + + namespace effects { + // + // compress_holder + // + template + class compress_holder { + public: + typedef T value_type; + private: + value_type threshold_; + value_type ratio_; + public: + compress_holder() = default; + compress_holder(compress_holder const&) = default; + SPROUT_CONSTEXPR compress_holder(value_type const& threshold, value_type const& ratio) + : threshold_(threshold), ratio_(ratio) + {} + SPROUT_CONSTEXPR value_type const& threshold() const { + return threshold_; + } + SPROUT_CONSTEXPR value_type const& ratio() const { + return ratio_; + } + }; + + + // + // compressed_forwarder + // + class compressed_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::effects::compress_holder + operator()(T const& threshold, T const& ratio) { + return sprout::compost::effects::compress_holder(threshold, ratio); + } + }; + + // + // compressed + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::effects::compressed_forwarder compressed{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::effects::compress_holder const& rhs) + -> decltype( + sprout::forward(lhs) + | sprout::adaptors::transformed(sprout::compost::compress_value(rhs.threshold(), rhs.ratio())) + ) + { + return sprout::forward(lhs) + | sprout::adaptors::transformed(sprout::compost::compress_value(rhs.threshold(), rhs.ratio())) + ; + } + } // namespace effects + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_EFFECTS_COMPRESS_HPP diff --git a/sprout/compost/effects/fuzz.hpp b/sprout/compost/effects/fuzz.hpp new file mode 100644 index 00000000..b8b1c513 --- /dev/null +++ b/sprout/compost/effects/fuzz.hpp @@ -0,0 +1,77 @@ +#ifndef SPROUT_COMPOST_EFFECTS_FUZZ_HPP +#define SPROUT_COMPOST_EFFECTS_FUZZ_HPP + +#include +#include +#include +#include +#include + +namespace sprout { + namespace compost { + namespace effects { + // + // fuzz_holder + // + template + class fuzz_holder { + public: + typedef T value_type; + private: + value_type gain_; + value_type level_; + public: + fuzz_holder() = default; + fuzz_holder(fuzz_holder const&) = default; + SPROUT_CONSTEXPR fuzz_holder(value_type const& gain, value_type const& level) + : gain_(gain) , level_(level) + {} + SPROUT_CONSTEXPR value_type const& gain() const { + return gain_; + } + SPROUT_CONSTEXPR value_type const& level() const { + return level_; + } + }; + + // + // fuzzed_forwarder + // + class fuzzed_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::effects::fuzz_holder + operator()(T const& gain, T const& level) { + return sprout::compost::effects::fuzz_holder(gain, level); + } + }; + + // + // fuzzed + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::effects::fuzzed_forwarder fuzzed{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::effects::fuzz_holder const& rhs) + -> decltype( + sprout::forward(lhs) + | sprout::compost::effects::rectified + | sprout::compost::effects::distorted(rhs.gain(), rhs.level()) + ) + { + return sprout::forward(lhs) + | sprout::compost::effects::rectified + | sprout::compost::effects::distorted(rhs.gain(), rhs.level()) + ; + } + } // namespace effects + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_EFFECTS_FUZZ_HPP diff --git a/sprout/compost/effects/noise_gate.hpp b/sprout/compost/effects/noise_gate.hpp new file mode 100644 index 00000000..e6eff75e --- /dev/null +++ b/sprout/compost/effects/noise_gate.hpp @@ -0,0 +1,116 @@ +#ifndef SPROUT_COMPOST_EFFECTS_NOISE_GATE_HPP +#define SPROUT_COMPOST_EFFECTS_NOISE_GATE_HPP + +#include +#include +#include + +namespace sprout { + namespace compost { + namespace detail { + template + SPROUT_CONSTEXPR T + noise_gate_value(T const& x, Value const& threshold) { + return x <= threshold && x >= -threshold ? 0 + : x + ; + } + } // namespace detail + // + // noise_gate_value + // + template + struct noise_gate_value { + public: + typedef Value value_type; + typedef T argument_type; + typedef T result_type; + private: + value_type threshold_; + public: + explicit SPROUT_CONSTEXPR noise_gate_value(Value const& threshold) + : threshold_(threshold) + {} + SPROUT_CONSTEXPR result_type + operator()(T const& x) const { + return sprout::compost::detail::noise_gate_value(x, threshold_); + } + }; + template + struct noise_gate_value { + public: + typedef Value value_type; + private: + value_type threshold_; + public: + explicit SPROUT_CONSTEXPR noise_gate_value(Value const& threshold) + : threshold_(threshold) + {} + template + SPROUT_CONSTEXPR T + operator()(T const& x) const { + return sprout::compost::detail::noise_gate_value(x, threshold_); + } + }; + + namespace effects { + // + // noise_gate_holder + // + template + class noise_gate_holder { + public: + typedef T value_type; + private: + value_type threshold_; + public: + noise_gate_holder() = default; + noise_gate_holder(noise_gate_holder const&) = default; + explicit SPROUT_CONSTEXPR noise_gate_holder(value_type const& threshold) + : threshold_(threshold) + {} + SPROUT_CONSTEXPR value_type const& threshold() const { + return threshold_; + } + }; + + + // + // noise_gated_forwarder + // + class noise_gated_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::effects::noise_gate_holder + operator()(T const& threshold) { + return sprout::compost::effects::noise_gate_holder(threshold); + } + }; + + // + // noise_gated + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::effects::noise_gated_forwarder noise_gated{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::effects::noise_gate_holder const& rhs) + -> decltype( + sprout::forward(lhs) + | sprout::adaptors::transformed(sprout::compost::noise_gate_value(rhs.threshold())) + ) + { + return sprout::forward(lhs) + | sprout::adaptors::transformed(sprout::compost::noise_gate_value(rhs.threshold())) + ; + } + } // namespace effects + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_EFFECTS_NOISE_GATE_HPP diff --git a/sprout/compost/effects/overdrive.hpp b/sprout/compost/effects/overdrive.hpp new file mode 100644 index 00000000..c7363e6e --- /dev/null +++ b/sprout/compost/effects/overdrive.hpp @@ -0,0 +1,106 @@ +#ifndef SPROUT_COMPOST_EFFECTS_OVERDRIVE_HPP +#define SPROUT_COMPOST_EFFECTS_OVERDRIVE_HPP + +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace compost { + // + // overdrive_clip_value + // + template + struct overdrive_clip_value { + public: + typedef T argument_type; + typedef T result_type; + public: + SPROUT_CONSTEXPR T + operator()(T const& x) const { + return x >= 0 ? sprout::math::atan(x) / sprout::math::half_pi() + : sprout::math::atan(x) / sprout::math::half_pi() / 10 + ; + } + }; + template<> + struct overdrive_clip_value { + public: + template + SPROUT_CONSTEXPR T + operator()(T const& x) const { + return sprout::compost::overdrive_clip_value()(x); + } + }; + + namespace effects { + // + // overdrive_holder + // + template + class overdrive_holder { + public: + typedef T value_type; + private: + value_type gain_; + value_type level_; + public: + overdrive_holder() = default; + overdrive_holder(overdrive_holder const&) = default; + SPROUT_CONSTEXPR overdrive_holder(value_type const& gain, value_type const& level) + : gain_(gain) , level_(level) + {} + SPROUT_CONSTEXPR value_type const& gain() const { + return gain_; + } + SPROUT_CONSTEXPR value_type const& level() const { + return level_; + } + }; + + // + // overdriven_forwarder + // + class overdriven_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::effects::overdrive_holder + operator()(T const& gain, T const& level) { + return sprout::compost::effects::overdrive_holder(gain, level); + } + }; + + // + // overdriven + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::effects::overdriven_forwarder overdriven{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::effects::overdrive_holder const& rhs) + -> decltype( + sprout::forward(lhs) + | sprout::compost::effects::changed_volume(rhs.gain()) + | sprout::adaptors::transformed(sprout::compost::overdrive_clip_value<>()) + | sprout::compost::effects::changed_volume(rhs.level()) + ) + { + return sprout::forward(lhs) + | sprout::compost::effects::changed_volume(rhs.gain()) + | sprout::adaptors::transformed(sprout::compost::overdrive_clip_value<>()) + | sprout::compost::effects::changed_volume(rhs.level()) + ; + } + } // namespace effects + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_EFFECTS_OVERDRIVE_HPP diff --git a/sprout/compost/effects/rectify.hpp b/sprout/compost/effects/rectify.hpp new file mode 100644 index 00000000..10b2cabb --- /dev/null +++ b/sprout/compost/effects/rectify.hpp @@ -0,0 +1,66 @@ +#ifndef SPROUT_COMPOST_EFFECTS_RECTIFY_HPP +#define SPROUT_COMPOST_EFFECTS_RECTIFY_HPP + +#include +#include +#include + +namespace sprout { + namespace compost { + // + // rectify_value + // + template + struct rectify_value { + public: + typedef T argument_type; + typedef T result_type; + public: + SPROUT_CONSTEXPR T + operator()(T const& x) const { + return x < 0 ? -x : x; + } + }; + template<> + struct rectify_value { + public: + template + SPROUT_CONSTEXPR T + operator()(T const& x) const { + return sprout::compost::rectify_value()(x); + } + }; + + namespace effects { + // + // rectified_forwarder + // + class rectified_forwarder {}; + + // + // rectified + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::effects::rectified_forwarder rectified{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::effects::rectified_forwarder const& rhs) + -> decltype( + sprout::forward(lhs) + | sprout::adaptors::transformed(sprout::compost::rectify_value<>()) + ) + { + return sprout::forward(lhs) + | sprout::adaptors::transformed(sprout::compost::rectify_value<>()) + ; + } + } // namespace effects + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_EFFECTS_RECTIFY_HPP diff --git a/sprout/compost/effects/reverb.hpp b/sprout/compost/effects/reverb.hpp new file mode 100644 index 00000000..73c0bb9f --- /dev/null +++ b/sprout/compost/effects/reverb.hpp @@ -0,0 +1,149 @@ +#ifndef SPROUT_COMPOST_EFFECTS_REVERB_HPP +#define SPROUT_COMPOST_EFFECTS_REVERB_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace compost { + // + // reverb_outdirected_value + // + template + struct reverb_outdirected_value { + public: + typedef Value value_type; + typedef IntType int_type; + private: + value_type attenuation_; + value_type delay_; + std::size_t repeat_; + int_type samples_per_sec_; + private: + template + SPROUT_CONSTEXPR typename std::iterator_traits::value_type + calc_1(Outdirected const& x, std::size_t i, typename Outdirected::index_type m) const { + return m >= 0 ? sprout::math::pow(attenuation_, i) * x[m - x.index()] + : 0 + ; + } + template + SPROUT_CONSTEXPR typename std::iterator_traits::value_type + calc(Outdirected const& x, std::size_t i = 1) const { + return i <= repeat_ + ? calc_1(x, i, static_cast(x.index() - i * delay_ * samples_per_sec_)) + calc(x, i + 1) + : 0 + ; + } + public: + SPROUT_CONSTEXPR reverb_outdirected_value( + value_type const& attenuation, value_type const& delay, + std::size_t repeat = 2, int_type samples_per_sec = 44100 + ) + : attenuation_(attenuation), delay_(delay), repeat_(repeat), samples_per_sec_(samples_per_sec) + {} + template + SPROUT_CONSTEXPR typename std::iterator_traits::value_type + operator()(Outdirected const& x) const { + return *x + calc(x); + } + }; + + namespace effects { + // + // reverb_holder + // + template + class reverb_holder { + public: + typedef T value_type; + typedef IntType int_type; + private: + value_type attenuation_; + value_type delay_; + std::size_t repeat_; + int_type samples_per_sec_; + public: + reverb_holder() = default; + reverb_holder(reverb_holder const&) = default; + SPROUT_CONSTEXPR reverb_holder( + value_type const& attenuation, value_type const& delay, + std::size_t repeat = 2, int_type samples_per_sec = 44100 + ) + : attenuation_(attenuation), delay_(delay), repeat_(repeat), samples_per_sec_(samples_per_sec) + {} + SPROUT_CONSTEXPR value_type const& attenuation() const { + return attenuation_; + } + SPROUT_CONSTEXPR value_type const& delay() const { + return delay_; + } + SPROUT_CONSTEXPR std::size_t const& repeat() const { + return repeat_; + } + SPROUT_CONSTEXPR int_type const& samples_per_sec() const { + return samples_per_sec_; + } + }; + + // + // reverbed_forwarder + // + class reverbed_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::effects::reverb_holder + operator()(T const& attenuation, T const& delay, std::size_t repeat, IntType samples_per_sec) { + return sprout::compost::effects::reverb_holder(attenuation, delay, repeat, samples_per_sec); + } + template + SPROUT_CONSTEXPR sprout::compost::effects::reverb_holder + operator()(T const& attenuation, T const& delay, std::size_t repeat = 2) { + return sprout::compost::effects::reverb_holder(attenuation, delay, repeat); + } + }; + + // + // reverbed + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::effects::reverbed_forwarder reverbed{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::effects::reverb_holder const& rhs) + -> decltype( + sprout::forward(lhs) + | sprout::adaptors::indexed | sprout::adaptors::outdirected + | sprout::adaptors::transformed( + sprout::compost::reverb_outdirected_value( + rhs.attenuation(), rhs.delay(), rhs.repeat(), rhs.samples_per_sec() + ) + ) + ) + { + return sprout::forward(lhs) + | sprout::adaptors::indexed | sprout::adaptors::outdirected + | sprout::adaptors::transformed( + sprout::compost::reverb_outdirected_value( + rhs.attenuation(), rhs.delay(), rhs.repeat(), rhs.samples_per_sec() + ) + ) + ; + } + } // namespace effects + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_EFFECTS_REVERB_HPP diff --git a/sprout/compost/effects/tremolo.hpp b/sprout/compost/effects/tremolo.hpp new file mode 100644 index 00000000..6449741d --- /dev/null +++ b/sprout/compost/effects/tremolo.hpp @@ -0,0 +1,117 @@ +#ifndef SPROUT_COMPOST_EFFECTS_TREMOLO_HPP +#define SPROUT_COMPOST_EFFECTS_TREMOLO_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace compost { + // + // tremolo_outdirected_value + // + template + struct tremolo_outdirected_value { + public: + typedef Value value_type; + typedef IntType int_type; + private: + value_type depth_; + value_type rate_; + int_type samples_per_sec_; + public: + SPROUT_CONSTEXPR tremolo_outdirected_value(value_type const& depth, value_type const& rate, int_type samples_per_sec = 44100) + : depth_(depth), rate_(rate), samples_per_sec_(samples_per_sec) + {} + template + SPROUT_CONSTEXPR typename std::iterator_traits::value_type + operator()(Outdirected const& x) const { + return (1 + depth_ * sprout::math::sin(2 * sprout::math::pi() * rate_ * x.index() / samples_per_sec_)) * *x; + } + }; + + namespace effects { + // + // tremolo_holder + // + template + class tremolo_holder { + public: + typedef T value_type; + typedef IntType int_type; + private: + value_type depth_; + value_type rate_; + int_type samples_per_sec_; + public: + tremolo_holder() = default; + tremolo_holder(tremolo_holder const&) = default; + SPROUT_CONSTEXPR tremolo_holder(value_type const& depth, value_type const& rate, int_type samples_per_sec = 44100) + : depth_(depth), rate_(rate), samples_per_sec_(samples_per_sec) + {} + SPROUT_CONSTEXPR value_type const& depth() const { + return depth_; + } + SPROUT_CONSTEXPR value_type const& rate() const { + return rate_; + } + SPROUT_CONSTEXPR int_type const& samples_per_sec() const { + return samples_per_sec_; + } + }; + + // + // tremolo_forwarder + // + class tremolo_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::effects::tremolo_holder + operator()(T const& depth, T const& rate, IntType samples_per_sec) { + return sprout::compost::effects::tremolo_holder(depth, rate, samples_per_sec); + } + template + SPROUT_CONSTEXPR sprout::compost::effects::tremolo_holder + operator()(T const& depth, T const& rate) { + return sprout::compost::effects::tremolo_holder(depth, rate); + } + }; + + // + // tremolo + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::effects::tremolo_forwarder tremolo{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::effects::tremolo_holder const& rhs) + -> decltype( + sprout::forward(lhs) + | sprout::adaptors::indexed | sprout::adaptors::outdirected + | sprout::adaptors::transformed( + sprout::compost::tremolo_outdirected_value(rhs.depth(), rhs.rate(), rhs.samples_per_sec()) + ) + ) + { + return sprout::forward(lhs) + | sprout::adaptors::indexed | sprout::adaptors::outdirected + | sprout::adaptors::transformed( + sprout::compost::tremolo_outdirected_value(rhs.depth(), rhs.rate(), rhs.samples_per_sec()) + ) + ; + } + } // namespace effects + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_EFFECTS_TREMOLO_HPP diff --git a/sprout/compost/effects/vibrato.hpp b/sprout/compost/effects/vibrato.hpp new file mode 100644 index 00000000..7a90a112 --- /dev/null +++ b/sprout/compost/effects/vibrato.hpp @@ -0,0 +1,155 @@ +#ifndef SPROUT_COMPOST_EFFECTS_VIBRATO_HPP +#define SPROUT_COMPOST_EFFECTS_VIBRATO_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace compost { + // + // vibrato_outdirected_value + // + template + struct vibrato_outdirected_value { + public: + typedef Value value_type; + typedef IntType int_type; + private: + value_type d_; + value_type depth_; + value_type rate_; + int_type samples_per_sec_; + private: + template + SPROUT_CONSTEXPR typename std::iterator_traits::value_type + calc_2(Outdirected const& x, typename Outdirected::index_type m, value_type const& delta) const { + return m >= 0 && (m + 1 < x.base().get() || x.base().get() < 0) + ? delta * x[m + 1 - x.index()] + (1 - delta) * x[m - x.index()] + : *x + ; + } + template + SPROUT_CONSTEXPR typename std::iterator_traits::value_type + calc_1(Outdirected const& x, value_type const& tau, value_type const& t) const { + return calc_2(x, static_cast(t), t - static_cast(t)); + } + template + SPROUT_CONSTEXPR typename std::iterator_traits::value_type + calc(Outdirected const& x, value_type const& tau) const { + return calc_1(x, tau, x.index() - tau); + } + public: + SPROUT_CONSTEXPR vibrato_outdirected_value( + value_type const& d, value_type const& depth, value_type const& rate, + int_type samples_per_sec = 44100 + ) + : d_(d), depth_(depth), rate_(rate), samples_per_sec_(samples_per_sec) + {} + template + SPROUT_CONSTEXPR typename std::iterator_traits::value_type + operator()(Outdirected const& x) const { + return calc(x, d_ + depth_ * sprout::math::sin(2 * sprout::math::pi() * rate_ * x.index() / samples_per_sec_)); + } + }; + + namespace effects { + // + // vibrato_holder + // + template + class vibrato_holder { + public: + typedef T value_type; + typedef IntType int_type; + private: + value_type d_; + value_type depth_; + value_type rate_; + int_type samples_per_sec_; + public: + vibrato_holder() = default; + vibrato_holder(vibrato_holder const&) = default; + SPROUT_CONSTEXPR vibrato_holder( + value_type const& d, value_type const& depth, value_type const& rate, + int_type samples_per_sec = 44100 + ) + : d_(d), depth_(depth), rate_(rate), samples_per_sec_(samples_per_sec) + {} + SPROUT_CONSTEXPR value_type const& d() const { + return d_; + } + SPROUT_CONSTEXPR value_type const& depth() const { + return depth_; + } + SPROUT_CONSTEXPR value_type const& rate() const { + return rate_; + } + SPROUT_CONSTEXPR int_type const& samples_per_sec() const { + return samples_per_sec_; + } + }; + + // + // vibrato_forwarder + // + class vibrato_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::compost::effects::vibrato_holder + operator()(T const& d, T const& depth, T const& rate, IntType samples_per_sec) { + return sprout::compost::effects::vibrato_holder(d, depth, rate, samples_per_sec); + } + template + SPROUT_CONSTEXPR sprout::compost::effects::vibrato_holder + operator()(T const& d, T const& depth, T const& rate) { + return sprout::compost::effects::vibrato_holder(d, depth, rate); + } + }; + + // + // vibrato + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::compost::effects::vibrato_forwarder vibrato{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR auto + operator|(Range&& lhs, sprout::compost::effects::vibrato_holder const& rhs) + -> decltype( + sprout::forward(lhs) + | sprout::adaptors::valued(sprout::size(sprout::forward(lhs))) + | sprout::adaptors::indexed | sprout::adaptors::outdirected + | sprout::adaptors::transformed( + sprout::compost::vibrato_outdirected_value( + rhs.d(), rhs.depth(), rhs.rate(), rhs.samples_per_sec() + ) + ) + ) + { + return sprout::forward(lhs) + | sprout::adaptors::valued(sprout::size(sprout::forward(lhs))) + | sprout::adaptors::indexed | sprout::adaptors::outdirected + | sprout::adaptors::transformed( + sprout::compost::vibrato_outdirected_value( + rhs.d(), rhs.depth(), rhs.rate(), rhs.samples_per_sec() + ) + ) + ; + } + } // namespace effects + } // namespace compost +} // namespace sprout + +#endif // #ifndef SPROUT_COMPOST_EFFECTS_VIBRATO_HPP diff --git a/sprout/iterator/adaptor.hpp b/sprout/iterator/adaptor.hpp index c870d5b2..3b2d6b70 100644 --- a/sprout/iterator/adaptor.hpp +++ b/sprout/iterator/adaptor.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include diff --git a/sprout/iterator/counting_iterator.hpp b/sprout/iterator/counting_iterator.hpp index 1998e764..362b10d9 100644 --- a/sprout/iterator/counting_iterator.hpp +++ b/sprout/iterator/counting_iterator.hpp @@ -10,6 +10,7 @@ #include #include #include +#include namespace sprout { // @@ -32,11 +33,21 @@ namespace sprout { typedef value_type* pointer; typedef value_type reference; private: - value_type current_; + template::value>::type = sprout::enabler> + static SPROUT_CONSTEXPR T + default_value() { + return std::numeric_limits::max(); + } + template::value>::type = sprout::enabler> + static SPROUT_CONSTEXPR T + default_value() { + return T(); + } private: + value_type current_; public: SPROUT_CONSTEXPR counting_iterator() - : current_(std::numeric_limits::max()) + : current_(default_value()) {} counting_iterator(counting_iterator const&) = default; explicit SPROUT_CONSTEXPR counting_iterator(value_type const& v) diff --git a/sprout/iterator/indexed_iterator.hpp b/sprout/iterator/indexed_iterator.hpp new file mode 100644 index 00000000..9dea19ca --- /dev/null +++ b/sprout/iterator/indexed_iterator.hpp @@ -0,0 +1,239 @@ +#ifndef SPROUT_ITERATOR_INDEXED_ITERATOR_HPP +#define SPROUT_ITERATOR_INDEXED_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // indexed_iterator + // + template + class indexed_iterator + : public std::iterator< + typename std::iterator_traits::iterator_category, + typename std::iterator_traits::value_type, + typename std::iterator_traits::difference_type, + typename std::iterator_traits::pointer, + typename std::iterator_traits::reference + > + { + public: + typedef Iterator iterator_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::reference reference; + typedef difference_type index_type; + protected: + iterator_type current; + index_type idx; + public: + indexed_iterator() = default; + SPROUT_CONSTEXPR indexed_iterator(indexed_iterator const& other) + : current(other.current) + , idx(other.idx) + {} + explicit SPROUT_CONSTEXPR indexed_iterator(iterator_type it, index_type idx = 0) + : current(it) + , idx(idx) + {} + template + SPROUT_CONSTEXPR indexed_iterator(indexed_iterator const& it) + : current(it.base()) + , idx(it.index()) + {} + template + indexed_iterator& operator=(indexed_iterator const& it) { + indexed_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current; + } + SPROUT_CONSTEXPR index_type index() const { + return idx; + } + SPROUT_CONSTEXPR reference operator*() const { + return *current; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*current; + } + indexed_iterator& operator++() { + ++current; + ++idx; + return *this; + } + indexed_iterator operator++(int) { + indexed_iterator result(*this); + ++current; + ++idx; + return result; + } + indexed_iterator& operator--() { + --current; + --idx; + return *this; + } + indexed_iterator operator--(int) { + indexed_iterator temp(*this); + --current; + --idx; + return temp; + } + SPROUT_CONSTEXPR indexed_iterator operator+(difference_type n) const { + return indexed_iterator(current + n, idx + n); + } + SPROUT_CONSTEXPR indexed_iterator operator-(difference_type n) const { + return indexed_iterator(current - n, idx - n); + } + indexed_iterator& operator+=(difference_type n) { + indexed_iterator temp(current + n, idx + n); + temp.swap(*this); + return *this; + } + indexed_iterator& operator-=(difference_type n) { + indexed_iterator temp(current - n, idx - n); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR reference operator[](difference_type n) const { + return *(current + n); + } + SPROUT_CONSTEXPR indexed_iterator next() const { + return indexed_iterator(sprout::next(current), idx + 1); + } + SPROUT_CONSTEXPR indexed_iterator prev() const { + return indexed_iterator(sprout::prev(current), idx - 1); + } + void swap(indexed_iterator& other) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(swap(current, other.current)) + && SPROUT_NOEXCEPT_EXPR(swap(idx, other.idx)) + ) + { + swap(current, other.current); + swap(idx, other.idx); + } + }; + + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::indexed_iterator const& lhs, sprout::indexed_iterator const& rhs) { + return lhs.base() == rhs.base(); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::indexed_iterator const& lhs, sprout::indexed_iterator const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::indexed_iterator const& lhs, sprout::indexed_iterator const& rhs) { + return lhs.base() < rhs.base(); + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::indexed_iterator const& lhs, sprout::indexed_iterator const& rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::indexed_iterator const& lhs, sprout::indexed_iterator const& rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::indexed_iterator const& lhs, sprout::indexed_iterator const& rhs) { + return !(lhs < rhs); + } + template + inline SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) + operator-(sprout::indexed_iterator const& lhs, sprout::indexed_iterator const& rhs) { + return lhs.base() - rhs.base(); + } + template + inline SPROUT_CONSTEXPR sprout::indexed_iterator + operator+( + typename sprout::indexed_iterator::difference_type n, + sprout::indexed_iterator const& it + ) + { + return it + n; + } + + // + // make_indexed_iterator + // + template + inline SPROUT_CONSTEXPR sprout::indexed_iterator + make_indexed_iterator(Iterator it, typename sprout::indexed_iterator::index_type idx = 0) { + return sprout::indexed_iterator(it, idx); + } + + // + // swap + // + template + inline void + swap(sprout::indexed_iterator& lhs, sprout::indexed_iterator& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // iterator_distance + // + template + inline SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type + iterator_distance(sprout::indexed_iterator first, sprout::indexed_iterator last) { + return last - first; + } + + // + // iterator_next + // + template + inline SPROUT_CONSTEXPR sprout::indexed_iterator + iterator_next(sprout::indexed_iterator const& it) { + return it.next(); + } + template + inline SPROUT_CONSTEXPR sprout::indexed_iterator + iterator_next( + sprout::indexed_iterator const& it, + typename sprout::indexed_iterator::difference_type n + ) + { + return it + n; + } + + // + // iterator_prev + // + template + inline SPROUT_CONSTEXPR sprout::indexed_iterator + iterator_prev(sprout::indexed_iterator const& it) { + return it.prev(); + } + template + inline SPROUT_CONSTEXPR sprout::indexed_iterator + iterator_prev( + sprout::indexed_iterator const& it, + typename sprout::indexed_iterator::difference_type n + ) + { + return it - n; + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_INDEXED_ITERATOR_HPP diff --git a/sprout/iterator/reverse_iterator.hpp b/sprout/iterator/reverse_iterator.hpp index 2ba32bf5..0ec2908e 100644 --- a/sprout/iterator/reverse_iterator.hpp +++ b/sprout/iterator/reverse_iterator.hpp @@ -46,8 +46,8 @@ namespace sprout { {} template SPROUT_CONSTEXPR reverse_iterator(reverse_iterator const& it) - : current(it) - , deref_tmp(sprout::prev(it)) + : current(it.base()) + , deref_tmp(sprout::prev(it.base())) {} template reverse_iterator& operator=(reverse_iterator const& it) { diff --git a/sprout/iterator/valued_iterator.hpp b/sprout/iterator/valued_iterator.hpp new file mode 100644 index 00000000..7b59ff54 --- /dev/null +++ b/sprout/iterator/valued_iterator.hpp @@ -0,0 +1,247 @@ +#ifndef SPROUT_ITERATOR_VALUED_ITERATOR_HPP +#define SPROUT_ITERATOR_VALUED_ITERATOR_HPP + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + // + // valued_iterator + // + template + class valued_iterator + : public std::iterator< + typename std::iterator_traits::iterator_category, + typename std::iterator_traits::value_type, + typename std::iterator_traits::difference_type, + typename std::iterator_traits::pointer, + typename std::iterator_traits::reference + > + { + public: + typedef Iterator iterator_type; + typedef typename std::iterator_traits::iterator_category iterator_category; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::difference_type difference_type; + typedef typename std::iterator_traits::pointer pointer; + typedef typename std::iterator_traits::reference reference; + typedef T content_type; + typedef sprout::value_holder holder_type; + typedef typename holder_type::param_type param_type; + typedef typename holder_type::mutable_or_const_reference get_type; + protected: + iterator_type current; + holder_type holder; + public: + valued_iterator() = default; + SPROUT_CONSTEXPR valued_iterator(valued_iterator const& other) + : current(other.current) + , holder(other.holder) + {} + explicit SPROUT_CONSTEXPR valued_iterator(iterator_type it) + : current(it) + , holder() + {} + SPROUT_CONSTEXPR valued_iterator(iterator_type it, holder_type const& r) + : current(it) + , holder(r) + {} + SPROUT_CONSTEXPR valued_iterator(iterator_type it, param_type p) + : current(it) + , holder(p) + {} + template + SPROUT_CONSTEXPR valued_iterator(valued_iterator const& it) + : current(it.base()) + , holder(it.get()) + {} + template + valued_iterator& operator=(valued_iterator const& it) { + valued_iterator temp(it); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR iterator_type base() const { + return current; + } + SPROUT_CONSTEXPR get_type get() const { + return holder.get(); + } + SPROUT_CONSTEXPR reference operator*() const { + return *current; + } + SPROUT_CONSTEXPR pointer operator->() const { + return &*current; + } + valued_iterator& operator++() { + ++current; + return *this; + } + valued_iterator operator++(int) { + valued_iterator result(*this); + ++current; + return result; + } + valued_iterator& operator--() { + --current; + return *this; + } + valued_iterator operator--(int) { + valued_iterator temp(*this); + --current; + return temp; + } + SPROUT_CONSTEXPR valued_iterator operator+(difference_type n) const { + return valued_iterator(current + n, holder); + } + SPROUT_CONSTEXPR valued_iterator operator-(difference_type n) const { + return valued_iterator(current - n, holder); + } + valued_iterator& operator+=(difference_type n) { + valued_iterator temp(current + n, holder); + temp.swap(*this); + return *this; + } + valued_iterator& operator-=(difference_type n) { + valued_iterator temp(current - n, holder); + temp.swap(*this); + return *this; + } + SPROUT_CONSTEXPR reference operator[](difference_type n) const { + return *(current + n); + } + SPROUT_CONSTEXPR valued_iterator next() const { + return valued_iterator(sprout::next(current), holder); + } + SPROUT_CONSTEXPR valued_iterator prev() const { + return valued_iterator(sprout::prev(current), holder); + } + void swap(valued_iterator& other) + SPROUT_NOEXCEPT_EXPR( + SPROUT_NOEXCEPT_EXPR(swap(current, other.current)) + && SPROUT_NOEXCEPT_EXPR(swap(holder, other.holder)) + ) + { + swap(current, other.current); + swap(holder, other.holder); + } + }; + + template + inline SPROUT_CONSTEXPR bool + operator==(sprout::valued_iterator const& lhs, sprout::valued_iterator const& rhs) { + return lhs.base() == rhs.base(); + } + template + inline SPROUT_CONSTEXPR bool + operator!=(sprout::valued_iterator const& lhs, sprout::valued_iterator const& rhs) { + return !(lhs == rhs); + } + template + inline SPROUT_CONSTEXPR bool + operator<(sprout::valued_iterator const& lhs, sprout::valued_iterator const& rhs) { + return lhs.base() < rhs.base(); + } + template + inline SPROUT_CONSTEXPR bool + operator>(sprout::valued_iterator const& lhs, sprout::valued_iterator const& rhs) { + return rhs < lhs; + } + template + inline SPROUT_CONSTEXPR bool + operator<=(sprout::valued_iterator const& lhs, sprout::valued_iterator const& rhs) { + return !(rhs < lhs); + } + template + inline SPROUT_CONSTEXPR bool + operator>=(sprout::valued_iterator const& lhs, sprout::valued_iterator const& rhs) { + return !(lhs < rhs); + } + template + inline SPROUT_CONSTEXPR decltype(std::declval() - std::declval()) + operator-(sprout::valued_iterator const& lhs, sprout::valued_iterator const& rhs) { + return lhs.base() - rhs.base(); + } + template + inline SPROUT_CONSTEXPR sprout::valued_iterator + operator+( + typename sprout::valued_iterator::difference_type n, + sprout::valued_iterator const& it + ) + { + return it + n; + } + + // + // make_valued_iterator + // + template + inline SPROUT_CONSTEXPR sprout::valued_iterator + make_valued_iterator(Iterator it, T const& param) { + return sprout::valued_iterator(it, param); + } + + // + // swap + // + template + inline void + swap(sprout::valued_iterator& lhs, sprout::valued_iterator& rhs) + SPROUT_NOEXCEPT_EXPR(SPROUT_NOEXCEPT_EXPR(lhs.swap(rhs))) + { + lhs.swap(rhs); + } + + // + // iterator_distance + // + template + inline SPROUT_CONSTEXPR typename std::iterator_traits >::difference_type + iterator_distance(sprout::valued_iterator first, sprout::valued_iterator last) { + return last - first; + } + + // + // iterator_next + // + template + inline SPROUT_CONSTEXPR sprout::valued_iterator + iterator_next(sprout::valued_iterator const& it) { + return it.next(); + } + template + inline SPROUT_CONSTEXPR sprout::valued_iterator + iterator_next( + sprout::valued_iterator const& it, + typename sprout::valued_iterator::difference_type n + ) + { + return it + n; + } + + // + // iterator_prev + // + template + inline SPROUT_CONSTEXPR sprout::valued_iterator + iterator_prev(sprout::valued_iterator const& it) { + return it.prev(); + } + template + inline SPROUT_CONSTEXPR sprout::valued_iterator + iterator_prev( + sprout::valued_iterator const& it, + typename sprout::valued_iterator::difference_type n + ) + { + return it - n; + } +} // namespace sprout + +#endif // #ifndef SPROUT_ITERATOR_VALUED_ITERATOR_HPP diff --git a/sprout/range/adaptor.hpp b/sprout/range/adaptor.hpp index 743019f7..38da08e1 100644 --- a/sprout/range/adaptor.hpp +++ b/sprout/range/adaptor.hpp @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include #include #include #include diff --git a/sprout/range/adaptor/indexed.hpp b/sprout/range/adaptor/indexed.hpp new file mode 100644 index 00000000..e8f375cf --- /dev/null +++ b/sprout/range/adaptor/indexed.hpp @@ -0,0 +1,149 @@ +#ifndef SPROUT_RANGE_ADAPTOR_INDEXED_HPP +#define SPROUT_RANGE_ADAPTOR_INDEXED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // indexed_range + // + template + class indexed_range + : public sprout::range::range_container< + sprout::indexed_iterator::iterator> + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef Range range_type; + typedef sprout::range::range_container< + sprout::indexed_iterator::iterator> + > base_type; + typedef typename base_type::iterator iterator; + typedef typename base_type::value_type value_type; + typedef typename iterator::index_type index_type; + public: + indexed_range() = default; + indexed_range(indexed_range const&) = default; + explicit SPROUT_CONSTEXPR indexed_range(range_type& range) + : base_type( + iterator(sprout::begin(range)), + iterator(sprout::end(range)) + ) + {} + SPROUT_CONSTEXPR indexed_range(index_type index, range_type& range) + : base_type( + iterator(sprout::begin(range), index), + iterator(sprout::end(range), index) + ) + {} + }; + + // + // indexed_holder + // + template + class indexed_holder { + public: + typedef Index index_type; + private: + index_type index_; + public: + indexed_holder() = default; + indexed_holder(indexed_holder const&) = default; + SPROUT_CONSTEXPR indexed_holder(index_type index) + : index_(index) + {} + SPROUT_CONSTEXPR index_type index() const { + return index_; + } + }; + + // + // indexed_forwarder + // + class indexed_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::indexed_holder + operator()(Index index) { + return sprout::adaptors::indexed_holder(index); + } + }; + + // + // indexed + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::indexed_forwarder indexed{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::indexed_range< + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::indexed_forwarder const& rhs) { + return sprout::adaptors::indexed_range< + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs) + ); + } + template + inline SPROUT_CONSTEXPR sprout::adaptors::indexed_range< + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::indexed_holder const& rhs) { + return sprout::adaptors::indexed_range< + typename std::remove_reference::type>::type + >( + rhs.index(), + sprout::lvalue_forward(lhs) + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_INDEXED_HPP diff --git a/sprout/range/adaptor/outdirected.hpp b/sprout/range/adaptor/outdirected.hpp new file mode 100644 index 00000000..a431feb2 --- /dev/null +++ b/sprout/range/adaptor/outdirected.hpp @@ -0,0 +1,103 @@ +#ifndef SPROUT_RANGE_ADAPTOR_OUTDIRECTED_HPP +#define SPROUT_RANGE_ADAPTOR_OUTDIRECTED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // outdirected_range + // + template + class outdirected_range + : public sprout::range::range_container< + sprout::counting_iterator::iterator> + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef Range range_type; + typedef sprout::range::range_container< + sprout::counting_iterator::iterator> + > base_type; + typedef typename base_type::iterator iterator; + typedef typename base_type::value_type value_type; + public: + outdirected_range() = default; + outdirected_range(outdirected_range const&) = default; + explicit SPROUT_CONSTEXPR outdirected_range(range_type& range) + : base_type( + iterator(sprout::begin(range)), + iterator(sprout::end(range)) + ) + {} + }; + + // + // outdirected_forwarder + // + class outdirected_forwarder {}; + + // + // outdirected + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::outdirected_forwarder outdirected{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::outdirected_range< + typename std::remove_reference::type>::type + > + operator|(Range&& lhs, sprout::adaptors::outdirected_forwarder const& rhs) { + return sprout::adaptors::outdirected_range< + typename std::remove_reference::type>::type + >( + sprout::lvalue_forward(lhs) + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_OUTDIRECTED_HPP diff --git a/sprout/range/adaptor/valued.hpp b/sprout/range/adaptor/valued.hpp new file mode 100644 index 00000000..016c772a --- /dev/null +++ b/sprout/range/adaptor/valued.hpp @@ -0,0 +1,137 @@ +#ifndef SPROUT_RANGE_ADAPTOR_VALUED_HPP +#define SPROUT_RANGE_ADAPTOR_VALUED_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace sprout { + namespace adaptors { + // + // valued_range + // + template + class valued_range + : public sprout::range::range_container< + sprout::valued_iterator::iterator, T> + > + , public sprout::detail::container_nosy_static_size + , public sprout::detail::container_nosy_fixed_size + { + public: + typedef Range range_type; + typedef sprout::range::range_container< + sprout::valued_iterator::iterator, T> + > base_type; + typedef typename base_type::iterator iterator; + typedef typename base_type::value_type value_type; + typedef typename iterator::param_type param_type; + public: + valued_range() = default; + valued_range(valued_range const&) = default; + SPROUT_CONSTEXPR valued_range(param_type param, range_type& range) + : base_type( + iterator(sprout::begin(range), param), + iterator(sprout::end(range), param) + ) + {} + }; + + // + // valued_holder + // + template + class valued_holder { + public: + typedef T content_type; + typedef sprout::value_holder holder_type; + typedef typename holder_type::param_type param_type; + typedef typename holder_type::mutable_or_const_reference get_type; + private: + holder_type holder_; + public: + valued_holder() = default; + valued_holder(valued_holder const&) = default; + SPROUT_CONSTEXPR valued_holder(param_type param) + : holder_(param) + {} + SPROUT_CONSTEXPR get_type get() const { + return holder_.get(); + } + }; + + // + // valued_forwarder + // + class valued_forwarder { + public: + template + SPROUT_CONSTEXPR sprout::adaptors::valued_holder + operator()(T const& param) { + return sprout::adaptors::valued_holder(param); + } + }; + + // + // valued + // + namespace { + SPROUT_STATIC_CONSTEXPR sprout::adaptors::valued_forwarder valued{}; + } // anonymous-namespace + + // + // operator| + // + template + inline SPROUT_CONSTEXPR sprout::adaptors::valued_range< + typename std::remove_reference::type>::type, + T + > + operator|(Range&& lhs, sprout::adaptors::valued_holder const& rhs) { + return sprout::adaptors::valued_range< + typename std::remove_reference::type>::type, + T + >( + rhs.get(), + sprout::lvalue_forward(lhs) + ); + } + } // namespace adaptors + + // + // container_construct_traits + // + template + struct container_construct_traits > { + public: + typedef typename sprout::container_construct_traits::copied_type copied_type; + public: + template + static SPROUT_CONSTEXPR copied_type deep_copy(Cont&& cont) { + return sprout::range::fixed::copy(sprout::forward(cont), sprout::pit()); + } + template + static SPROUT_CONSTEXPR copied_type make(Args&&... args) { + return sprout::make(sprout::forward(args)...); + } + template + static SPROUT_CONSTEXPR copied_type remake( + Cont&& cont, + typename sprout::container_traits >::difference_type size, + Args&&... args + ) + { + return sprout::remake(sprout::forward(cont), size, sprout::forward(args)...); + } + }; +} // namespace sprout + +#endif // #ifndef SPROUT_RANGE_ADAPTOR_VALUED_HPP diff --git a/sprout/weed/parser/numeric/int_p.hpp b/sprout/weed/parser/numeric/int_p.hpp index f82e17a9..d460b08d 100644 --- a/sprout/weed/parser/numeric/int_p.hpp +++ b/sprout/weed/parser/numeric/int_p.hpp @@ -49,7 +49,6 @@ namespace sprout { ) const { typedef typename result::type result_type; - typedef typename attribute::type attribute_type; return res.success() && sign < 0 ? result_type(true, res.current(), -res.attr()) : res diff --git a/sprout/weed/parser/numeric/uint_p.hpp b/sprout/weed/parser/numeric/uint_p.hpp index 820f544c..e3296521 100644 --- a/sprout/weed/parser/numeric/uint_p.hpp +++ b/sprout/weed/parser/numeric/uint_p.hpp @@ -49,7 +49,6 @@ namespace sprout { ) const { typedef typename result::type result_type; - typedef typename attribute::type attribute_type; return res.success() && sign < 0 ? result_type(true, res.current(), -res.attr()) : res