|
libpsynth 0.2.1
|
00001 00011 /* 00012 * Copyright (C) 2010 Juan Pedro Bolivar Puente 00013 * 00014 * This file is part of Psychosynth. 00015 * 00016 * Psychosynth is free software: you can redistribute it and/or modify 00017 * it under the terms of the GNU General Public License as published by 00018 * the Free Software Foundation, either version 3 of the License, or 00019 * (at your option) any later version. 00020 * 00021 * Psychosynth is distributed in the hope that it will be useful, 00022 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00024 * GNU General Public License for more details. 00025 * 00026 * You should have received a copy of the GNU General Public License 00027 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00028 * 00029 */ 00030 00031 /* 00032 * Copyright 2005-2007 Adobe Systems Incorporated 00033 * 00034 * Use, modification and distribution are subject to the Boost 00035 * Software License, Version 1.0. (See accompanying file 00036 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). 00037 */ 00038 00039 00040 #ifndef PSYNTH_SOUND_CHANNEL_BASE_ALGORITHM_HPP 00041 #define PSYNTH_SOUND_CHANNEL_BASE_ALGORITHM_HPP 00042 00043 #include <algorithm> 00044 #include <boost/type_traits.hpp> 00045 #include <boost/utility/enable_if.hpp> 00046 #include <boost/mpl/contains.hpp> 00047 #include <boost/mpl/at.hpp> 00048 00049 #include <psynth/base/compat.hpp> 00050 #include <psynth/sound/concept.hpp> 00051 #include <psynth/sound/util.hpp> 00052 00053 namespace psynth 00054 { 00055 namespace sound 00056 { 00057 00058 /* 00059 * 00060 * size: Semantic sample size 00061 * 00062 */ 00063 00083 template <typename ChannelBase> 00084 struct size : public boost::mpl::size< 00085 typename ChannelBase::layout::channel_space> {}; 00086 00087 00088 /* 00089 * 00090 * semantic_at_c: Semantic sample accessors 00091 * 00092 */ 00093 00140 template <typename ChannelBase, int K> 00141 struct kth_semantic_element_type 00142 { 00143 BOOST_STATIC_CONSTANT( 00144 int, semantic_index = ( 00145 boost::mpl::at_c<typename ChannelBase::layout::sample_mapping, 00146 K>::type::value)); 00147 typedef typename kth_element_type <ChannelBase, semantic_index>::type type; 00148 }; 00149 00155 template <typename ChannelBase, int K> 00156 struct kth_semantic_element_reference_type 00157 { 00158 BOOST_STATIC_CONSTANT( 00159 int, semantic_index = ( 00160 boost::mpl::at_c<typename ChannelBase::layout::sample_mapping, 00161 K>::type::value)); 00162 typedef typename kth_element_reference_type< 00163 ChannelBase, semantic_index>::type type; 00164 00165 static type get (ChannelBase& cb) 00166 { 00167 return sound::at_c<semantic_index>(cb); 00168 } 00169 }; 00170 00171 00178 template <typename ChannelBase, int K> 00179 struct kth_semantic_element_const_reference_type 00180 { 00181 BOOST_STATIC_CONSTANT( 00182 int, semantic_index = ( 00183 boost::mpl::at_c<typename ChannelBase::layout::sample_mapping, 00184 K>::type::value)); 00185 typedef typename kth_element_const_reference_type< 00186 ChannelBase, semantic_index>::type type; 00187 00188 static type get (const ChannelBase& cb) 00189 { 00190 return sound::at_c<semantic_index> (cb); 00191 } 00192 }; 00193 00199 template <int K, typename ChannelBase> inline 00200 typename boost::disable_if< 00201 boost::is_const<ChannelBase>, 00202 typename kth_semantic_element_reference_type<ChannelBase,K>::type>::type 00203 semantic_at_c (ChannelBase& p) 00204 { 00205 return kth_semantic_element_reference_type<ChannelBase, K>::get (p); 00206 } 00207 00213 template <int K, typename ChannelBase> inline 00214 typename kth_semantic_element_const_reference_type<ChannelBase,K>::type 00215 semantic_at_c (const ChannelBase& p) 00216 { 00217 return kth_semantic_element_const_reference_type<ChannelBase,K>::get (p); 00218 } 00219 00220 00221 /* 00222 * 00223 * get_channel: Named sample accessors 00224 * 00225 */ 00226 00257 template <typename ChannelBase, typename Channel> 00258 struct contains_channel : 00259 public boost::mpl::contains<typename ChannelBase::layout::channel_space, 00260 Channel> {}; 00261 00262 template <typename ChannelBase, typename Channel> 00263 struct channel_index_type : 00264 public detail::type_to_index<typename ChannelBase::layout::channel_space, 00265 Channel> {}; 00266 00272 template <typename ChannelBase, typename Channel> 00273 struct channel_element_type : public kth_semantic_element_type< 00274 ChannelBase, channel_index_type<ChannelBase,Channel>::value> {}; 00275 00282 template <typename ChannelBase, typename Channel> 00283 struct channel_element_reference_type : 00284 public kth_semantic_element_reference_type< 00285 ChannelBase, channel_index_type<ChannelBase, Channel>::value> {}; 00286 00293 template <typename ChannelBase, typename Channel> 00294 struct channel_element_const_reference_type : 00295 public kth_semantic_element_const_reference_type< 00296 ChannelBase, channel_index_type<ChannelBase, Channel>::value> {}; 00297 00303 template <typename ChannelBase, typename Channel> 00304 typename channel_element_reference_type<ChannelBase,Channel>::type 00305 get_channel (ChannelBase& cb, Channel = Channel()) 00306 { 00307 return channel_element_reference_type<ChannelBase, Channel>::get (cb); 00308 } 00309 00314 template <typename ChannelBase, typename Channel> 00315 typename channel_element_const_reference_type<ChannelBase,Channel>::type 00316 get_channel (const ChannelBase& cb, Channel=Channel()) 00317 { 00318 return channel_element_const_reference_type<ChannelBase,Channel>::get (cb); 00319 } 00320 00321 00322 /* 00323 * 00324 * element_type, element_reference_type, 00325 * element_const_reference_type: Support for homogeneous channel 00326 * bases 00327 * 00328 */ 00329 00348 template <typename ChannelBase> 00349 struct element_type : public kth_element_type<ChannelBase, 0> {}; 00350 00357 template <typename ChannelBase> 00358 struct element_reference_type : 00359 public kth_element_reference_type<ChannelBase, 0> {}; 00360 00367 template <typename ChannelBase> 00368 struct element_const_reference_type : 00369 public kth_element_const_reference_type<ChannelBase, 0> {}; 00370 00371 00372 namespace detail 00373 { 00374 00375 /* compile-time recursion for per-element operations on channel bases */ 00376 template <int N> 00377 struct element_recursion 00378 { 00379 // static_equal 00380 template <typename P1,typename P2> 00381 static bool static_equal (const P1& p1, const P2& p2) 00382 { 00383 return element_recursion<N-1>::static_equal(p1,p2) && 00384 semantic_at_c<N-1>(p1) == semantic_at_c<N-1>(p2); 00385 } 00386 00387 //static_copy 00388 template <typename P1,typename P2> 00389 static void static_copy(const P1& p1, P2& p2) 00390 { 00391 element_recursion<N-1>::static_copy(p1,p2); 00392 semantic_at_c<N-1>(p2) = semantic_at_c<N-1>(p1); 00393 } 00394 00395 //static_fill 00396 template <typename P,typename T2> 00397 static void static_fill(P& p, T2 v) 00398 { 00399 element_recursion<N-1>::static_fill (p,v); 00400 semantic_at_c<N-1>(p) = v; 00401 } 00402 00403 //static_generate 00404 template <typename Dst,typename Op> 00405 static void static_generate (Dst& dst, Op op) 00406 { 00407 element_recursion<N-1>::static_generate (dst, op); 00408 semantic_at_c<N-1>(dst) = op(); 00409 } 00410 00411 //static_for_each with one source 00412 template <typename P1,typename Op> 00413 static Op static_for_each (P1& p1, Op op) 00414 { 00415 Op op2 (element_recursion<N-1>::static_for_each (p1,op)); 00416 op2 (semantic_at_c<N-1> (p1)); 00417 return op2; 00418 } 00419 00420 template <typename P1,typename Op> 00421 static Op static_for_each (const P1& p1, Op op) 00422 { 00423 Op op2 (element_recursion<N-1>::static_for_each (p1,op)); 00424 op2 (semantic_at_c<N-1> (p1)); 00425 return op2; 00426 } 00427 00428 //static_for_each with two sources 00429 template <typename P1,typename P2,typename Op> 00430 static Op static_for_each (P1& p1, P2& p2, Op op) 00431 { 00432 Op op2(element_recursion<N-1>::static_for_each (p1, p2, op)); 00433 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2)); 00434 return op2; 00435 } 00436 00437 template <typename P1,typename P2,typename Op> 00438 static Op static_for_each(P1& p1, const P2& p2, Op op) 00439 { 00440 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op)); 00441 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2)); 00442 return op2; 00443 } 00444 00445 template <typename P1,typename P2,typename Op> 00446 static Op static_for_each(const P1& p1, P2& p2, Op op) 00447 { 00448 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op)); 00449 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2)); 00450 return op2; 00451 } 00452 00453 template <typename P1,typename P2,typename Op> 00454 static Op static_for_each(const P1& p1, const P2& p2, Op op) 00455 { 00456 Op op2(element_recursion<N-1>::static_for_each(p1,p2,op)); 00457 op2(semantic_at_c<N-1>(p1), semantic_at_c<N-1>(p2)); 00458 return op2; 00459 } 00460 00461 //static_for_each with three sources 00462 template <typename P1,typename P2,typename P3,typename Op> 00463 static Op static_for_each (P1& p1, P2& p2, P3& p3, Op op) 00464 { 00465 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op)); 00466 op2(semantic_at_c<N-1>(p1), 00467 semantic_at_c<N-1>(p2), 00468 semantic_at_c<N-1>(p3)); 00469 return op2; 00470 } 00471 00472 template <typename P1,typename P2,typename P3,typename Op> 00473 static Op static_for_each (P1& p1, P2& p2, const P3& p3, Op op) 00474 { 00475 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op)); 00476 op2 (semantic_at_c<N-1>(p1), 00477 semantic_at_c<N-1>(p2), 00478 semantic_at_c<N-1>(p3)); 00479 return op2; 00480 } 00481 00482 template <typename P1,typename P2,typename P3,typename Op> 00483 static Op static_for_each (P1& p1, const P2& p2, P3& p3, Op op) 00484 { 00485 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op)); 00486 op2 (semantic_at_c<N-1>(p1), 00487 semantic_at_c<N-1>(p2), 00488 semantic_at_c<N-1>(p3)); 00489 return op2; 00490 } 00491 00492 template <typename P1,typename P2,typename P3,typename Op> 00493 static Op static_for_each (P1& p1, const P2& p2, const P3& p3, Op op) 00494 { 00495 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op)); 00496 op2 (semantic_at_c<N-1>(p1), 00497 semantic_at_c<N-1>(p2), 00498 semantic_at_c<N-1>(p3)); 00499 return op2; 00500 } 00501 00502 template <typename P1,typename P2,typename P3,typename Op> 00503 static Op static_for_each (const P1& p1, P2& p2, P3& p3, Op op) 00504 { 00505 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op)); 00506 op2 (semantic_at_c<N-1>(p1), 00507 semantic_at_c<N-1>(p2), 00508 semantic_at_c<N-1>(p3)); 00509 return op2; 00510 } 00511 00512 template <typename P1,typename P2,typename P3,typename Op> 00513 static Op static_for_each (const P1& p1, P2& p2, const P3& p3, Op op) 00514 { 00515 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op)); 00516 op2 (semantic_at_c<N-1>(p1), 00517 semantic_at_c<N-1>(p2), 00518 semantic_at_c<N-1>(p3)); 00519 return op2; 00520 } 00521 00522 template <typename P1,typename P2,typename P3,typename Op> 00523 static Op static_for_each (const P1& p1, const P2& p2, P3& p3, Op op) 00524 { 00525 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op)); 00526 op2 (semantic_at_c<N-1>(p1), 00527 semantic_at_c<N-1>(p2), 00528 semantic_at_c<N-1>(p3)); 00529 return op2; 00530 } 00531 00532 template <typename P1,typename P2,typename P3,typename Op> 00533 static Op static_for_each (const P1& p1, const P2& p2, const P3& p3, Op op) 00534 { 00535 Op op2(element_recursion<N-1>::static_for_each(p1,p2,p3,op)); 00536 op2 (semantic_at_c<N-1>(p1), 00537 semantic_at_c<N-1>(p2), 00538 semantic_at_c<N-1>(p3)); 00539 return op2; 00540 } 00541 00542 //static_transform with one source 00543 template <typename P1,typename Dst,typename Op> 00544 static Op static_transform (P1& src, Dst& dst, Op op) 00545 { 00546 Op op2 (element_recursion<N-1>::static_transform (src,dst,op)); 00547 semantic_at_c<N-1> (dst) = op2 (semantic_at_c<N-1> (src)); 00548 return op2; 00549 } 00550 00551 template <typename P1,typename Dst,typename Op> 00552 static Op static_transform (const P1& src, Dst& dst, Op op) 00553 { 00554 Op op2(element_recursion<N-1>::static_transform(src,dst,op)); 00555 semantic_at_c<N-1>(dst)=op2(semantic_at_c<N-1>(src)); 00556 return op2; 00557 } 00558 00559 //static_transform with two sources 00560 template <typename P1,typename P2,typename Dst,typename Op> 00561 static Op static_transform (P1& src1, P2& src2, Dst& dst, Op op) 00562 { 00563 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op)); 00564 semantic_at_c<N-1>(dst) = op2 (semantic_at_c<N-1>(src1), 00565 semantic_at_c<N-1>(src2)); 00566 return op2; 00567 } 00568 00569 template <typename P1,typename P2,typename Dst,typename Op> 00570 static Op static_transform (P1& src1, const P2& src2, Dst& dst, Op op) { 00571 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op)); 00572 semantic_at_c<N-1>(dst) = op2 (semantic_at_c<N-1>(src1), 00573 semantic_at_c<N-1>(src2)); 00574 return op2; 00575 } 00576 00577 template <typename P1,typename P2,typename Dst,typename Op> 00578 static Op static_transform (const P1& src1, P2& src2, Dst& dst, Op op) 00579 { 00580 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op)); 00581 semantic_at_c<N-1>(dst) = op2 (semantic_at_c<N-1>(src1), 00582 semantic_at_c<N-1>(src2)); 00583 return op2; 00584 } 00585 00586 template <typename P1,typename P2,typename Dst,typename Op> 00587 static Op static_transform (const P1& src1, const P2& src2, Dst& dst, Op op) 00588 { 00589 Op op2(element_recursion<N-1>::static_transform(src1,src2,dst,op)); 00590 semantic_at_c<N-1>(dst) = op2 (semantic_at_c<N-1>(src1), 00591 semantic_at_c<N-1>(src2)); 00592 return op2; 00593 } 00594 }; 00595 00596 // Termination condition of the compile-time recursion for element 00597 // operations on a channel base 00598 template<> struct element_recursion<0> 00599 { 00600 //static_equal 00601 template <typename P1,typename P2> 00602 static bool static_equal(const P1&, const P2&) { return true; } 00603 //static_copy 00604 template <typename P1,typename P2> 00605 static void static_copy(const P1&, const P2&) {} 00606 //static_fill 00607 template <typename P, typename T2> 00608 static void static_fill(const P&, T2) {} 00609 //static_generate 00610 template <typename Dst,typename Op> 00611 static void static_generate(const Dst&,Op) {} 00612 //static_for_each with one source 00613 template <typename P1,typename Op> 00614 static Op static_for_each(const P1&,Op op) { return op; } 00615 //static_for_each with two sources 00616 template <typename P1,typename P2,typename Op> 00617 static Op static_for_each(const P1&,const P2&,Op op) { return op; } 00618 //static_for_each with three sources 00619 template <typename P1,typename P2,typename P3,typename Op> 00620 static Op static_for_each(const P1&,const P2&,const P3&,Op op) { return op; } 00621 //static_transform with one source 00622 template <typename P1,typename Dst,typename Op> 00623 static Op static_transform(const P1&,const Dst&,Op op) { return op; } 00624 //static_transform with two sources 00625 template <typename P1,typename P2,typename Dst,typename Op> 00626 static Op static_transform(const P1&,const P2&,const Dst&,Op op) { return op; } 00627 }; 00628 00629 // std::min and std::max don't have the mutable overloads... 00630 template <typename Q> inline const Q& mutable_min(const Q& x, const Q& y) 00631 { return x<y ? x : y; } 00632 template <typename Q> inline Q& mutable_min( Q& x, Q& y) 00633 { return x<y ? x : y; } 00634 template <typename Q> inline const Q& mutable_max(const Q& x, const Q& y) 00635 { return x<y ? y : x; } 00636 template <typename Q> inline Q& mutable_max( Q& x, Q& y) 00637 { return x<y ? y : x; } 00638 00639 // compile-time recursion for min/max element 00640 template <int N> 00641 struct min_max_recur 00642 { 00643 template <typename P> 00644 static typename element_const_reference_type<P>::type max_ (const P& p) 00645 { 00646 return mutable_max(min_max_recur<N-1>::max_(p), semantic_at_c<N-1>(p)); 00647 } 00648 00649 template <typename P> 00650 static typename element_reference_type<P>::type max_ (P& p) 00651 { 00652 return mutable_max(min_max_recur<N-1>::max_(p), semantic_at_c<N-1>(p)); 00653 } 00654 00655 template <typename P> 00656 static typename element_const_reference_type<P>::type min_ (const P& p) 00657 { 00658 return mutable_min(min_max_recur<N-1>::min_(p), semantic_at_c<N-1>(p)); 00659 } 00660 00661 template <typename P> 00662 static typename element_reference_type<P>::type min_ (P& p) 00663 { 00664 return mutable_min(min_max_recur<N-1>::min_(p), semantic_at_c<N-1>(p)); 00665 } 00666 }; 00667 00668 // termination condition of the compile-time recursion for min/max 00669 // element 00670 template <> 00671 struct min_max_recur<1> 00672 { 00673 template <typename P> 00674 static typename element_const_reference_type<P>::type max_(const P& p) 00675 { return semantic_at_c<0>(p); } 00676 template <typename P> 00677 static typename element_reference_type<P>::type max_(P& p) 00678 { return semantic_at_c<0>(p); } 00679 template <typename P> 00680 static typename element_const_reference_type<P>::type min_(const P& p) 00681 { return semantic_at_c<0>(p); } 00682 template <typename P> 00683 static typename element_reference_type<P>::type min_(P& p) 00684 { return semantic_at_c<0>(p); } 00685 }; 00686 00687 } /* namespace detail */ 00688 00689 00706 template <typename P> 00707 PSYNTH_FORCEINLINE 00708 typename element_const_reference_type<P>::type static_max (const P& p) 00709 { return detail::min_max_recur<size<P>::value>::max_(p); } 00710 00711 template <typename P> 00712 PSYNTH_FORCEINLINE 00713 typename element_reference_type<P>::type static_max (P& p) 00714 { return detail::min_max_recur<size<P>::value>::max_(p); } 00715 00716 template <typename P> 00717 PSYNTH_FORCEINLINE 00718 typename element_const_reference_type<P>::type static_min (const P& p) 00719 { return detail::min_max_recur<size<P>::value>::min_(p); } 00720 00721 template <typename P> 00722 PSYNTH_FORCEINLINE 00723 typename element_reference_type<P>::type static_min (P& p) 00724 { return detail::min_max_recur<size<P>::value>::min_(p); } 00725 00745 template <typename P1,typename P2> 00746 PSYNTH_FORCEINLINE 00747 bool static_equal (const P1& p1, const P2& p2) 00748 { return detail::element_recursion<size<P1>::value>::static_equal(p1,p2); } 00749 00769 template <typename Src,typename Dst> 00770 PSYNTH_FORCEINLINE 00771 void static_copy(const Src& src, Dst& dst) 00772 { detail::element_recursion<size<Dst>::value>::static_copy(src,dst); } 00773 00789 template <typename P,typename V> 00790 PSYNTH_FORCEINLINE 00791 void static_fill (P& p, const V& v) 00792 { detail::element_recursion<size<P>::value>::static_fill(p,v); } 00817 template <typename P1,typename Op> 00818 PSYNTH_FORCEINLINE void static_generate(P1& dst,Op op) 00819 { detail::element_recursion<size<P1>::value>::static_generate(dst,op); } 00820 00854 //static_transform with one source 00855 template <typename Src,typename Dst,typename Op> 00856 PSYNTH_FORCEINLINE 00857 Op static_transform (Src& src, Dst& dst,Op op) 00858 { 00859 return detail::element_recursion<size<Dst>::value>::static_transform ( 00860 src, dst, op); 00861 } 00862 00863 template <typename Src,typename Dst,typename Op> 00864 PSYNTH_FORCEINLINE 00865 Op static_transform (const Src& src, Dst& dst, Op op) 00866 { 00867 return detail::element_recursion<size<Dst>::value>::static_transform ( 00868 src, dst, op); 00869 } 00870 00871 //static_transform with two sources 00872 template <typename P2,typename P3,typename Dst,typename Op> 00873 PSYNTH_FORCEINLINE 00874 Op static_transform (P2& p2, P3& p3, Dst& dst, Op op) 00875 { 00876 return detail::element_recursion<size<Dst>::value>::static_transform ( 00877 p2, p3, dst, op); 00878 } 00879 00880 template <typename P2,typename P3,typename Dst,typename Op> 00881 PSYNTH_FORCEINLINE 00882 Op static_transform(P2& p2,const P3& p3,Dst& dst,Op op) 00883 { 00884 return detail::element_recursion<size<Dst>::value>::static_transform ( 00885 p2, p3, dst, op); 00886 } 00887 00888 template <typename P2,typename P3,typename Dst,typename Op> 00889 PSYNTH_FORCEINLINE 00890 Op static_transform (const P2& p2, P3& p3, Dst& dst, Op op) 00891 { 00892 return detail::element_recursion<size<Dst>::value>::static_transform ( 00893 p2, p3, dst, op); 00894 } 00895 00896 template <typename P2,typename P3,typename Dst,typename Op> 00897 PSYNTH_FORCEINLINE 00898 Op static_transform (const P2& p2, const P3& p3, Dst& dst, Op op) 00899 { 00900 return detail::element_recursion<size<Dst>::value>::static_transform ( 00901 p2, p3, dst, op); 00902 } 00903 00933 //static_for_each with one source 00934 template <typename P1,typename Op> 00935 PSYNTH_FORCEINLINE 00936 Op static_for_each (P1& p1, Op op) 00937 { return detail::element_recursion<size<P1>::value>::static_for_each (p1,op); } 00938 00939 template <typename P1,typename Op> 00940 PSYNTH_FORCEINLINE 00941 Op static_for_each (const P1& p1, Op op) 00942 { return detail::element_recursion<size<P1>::value>::static_for_each(p1,op); } 00943 00944 //static_for_each with two sources 00945 template <typename P1,typename P2,typename Op> 00946 PSYNTH_FORCEINLINE 00947 Op static_for_each (P1& p1, P2& p2, Op op) 00948 { 00949 return detail::element_recursion<size<P1>::value>::static_for_each ( 00950 p1, p2, op); 00951 } 00952 00953 template <typename P1,typename P2,typename Op> 00954 PSYNTH_FORCEINLINE 00955 Op static_for_each(P1& p1,const P2& p2, Op op) 00956 { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); } 00957 00958 template <typename P1,typename P2,typename Op> 00959 PSYNTH_FORCEINLINE 00960 Op static_for_each(const P1& p1, P2& p2, Op op) 00961 { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); } 00962 00963 template <typename P1,typename P2,typename Op> 00964 PSYNTH_FORCEINLINE 00965 Op static_for_each(const P1& p1,const P2& p2, Op op) 00966 { return detail::element_recursion<size<P1>::value>::static_for_each(p1,p2,op); } 00967 00968 //static_for_each with three sources 00969 template <typename P1,typename P2,typename P3,typename Op> 00970 PSYNTH_FORCEINLINE 00971 Op static_for_each(P1& p1,P2& p2,P3& p3,Op op) 00972 { 00973 return detail::element_recursion<size<P1>::value>::static_for_each( 00974 p1,p2,p3,op); 00975 } 00976 00977 template <typename P1,typename P2,typename P3,typename Op> 00978 PSYNTH_FORCEINLINE 00979 Op static_for_each(P1& p1,P2& p2,const P3& p3,Op op) 00980 { 00981 return detail::element_recursion<size<P1>::value>::static_for_each( 00982 p1,p2,p3,op); 00983 } 00984 00985 template <typename P1,typename P2,typename P3,typename Op> 00986 PSYNTH_FORCEINLINE 00987 Op static_for_each(P1& p1,const P2& p2,P3& p3,Op op) 00988 { 00989 return detail::element_recursion<size<P1>::value>::static_for_each( 00990 p1,p2,p3,op); 00991 } 00992 00993 template <typename P1,typename P2,typename P3,typename Op> 00994 PSYNTH_FORCEINLINE 00995 Op static_for_each(P1& p1,const P2& p2,const P3& p3,Op op) 00996 { 00997 return detail::element_recursion<size<P1>::value>::static_for_each ( 00998 p1,p2,p3,op); 00999 } 01000 01001 template <typename P1,typename P2,typename P3,typename Op> 01002 PSYNTH_FORCEINLINE 01003 Op static_for_each(const P1& p1,P2& p2,P3& p3,Op op) 01004 { 01005 return detail::element_recursion<size<P1>::value>::static_for_each ( 01006 p1,p2,p3,op); 01007 } 01008 01009 template <typename P1,typename P2,typename P3,typename Op> 01010 PSYNTH_FORCEINLINE 01011 Op static_for_each(const P1& p1,P2& p2,const P3& p3,Op op) 01012 { 01013 return detail::element_recursion<size<P1>::value>::static_for_each ( 01014 p1,p2,p3,op); 01015 } 01016 01017 template <typename P1,typename P2,typename P3,typename Op> 01018 PSYNTH_FORCEINLINE 01019 Op static_for_each(const P1& p1,const P2& p2,P3& p3,Op op) 01020 { 01021 return detail::element_recursion<size<P1>::value>::static_for_each( 01022 p1,p2,p3,op); 01023 } 01024 01025 template <typename P1,typename P2,typename P3,typename Op> 01026 PSYNTH_FORCEINLINE 01027 Op static_for_each(const P1& p1,const P2& p2,const P3& p3,Op op) 01028 { return detail::element_recursion<size<P1>::value>::static_for_each ( 01029 p1,p2,p3,op); 01030 } 01033 } /* namespace sound */ 01034 } /* namespace psynth */ 01035 01036 #endif /* PSYNTH_SOUND_CHANNEL_BASE_ALGORITHM */
1.7.4