libpsynth 0.2.1
/home/raskolnikov/dev/psynth/trunk/src/psynth/sound/dynamic_at_c.hpp
Go to the documentation of this file.
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 #ifndef PSYNTH_SOUND_DYNAMIC_AT_C_HPP
00040 #define PSYNTH_SOUND_DYNAMIC_AT_C_HPP
00041 
00042 #include <psynth/base/compat.hpp>
00043 
00044 #include <cassert>
00045 #include <stdexcept>
00046 #include <boost/mpl/at.hpp>
00047 #include <boost/mpl/size.hpp>
00048 
00049 namespace psynth
00050 {
00051 namespace base
00052 {
00053 
00054 #define PSYNTH_AT_C_VALUE(z, N, text)                   \
00055     boost::mpl::at_c<IntTypes, S+N>::type::value,
00056 
00057 #define PSYNTH_DYNAMIC_AT_C_LIMIT        226
00058 // size of the maximum vector to handle
00059 
00060 #define PSYNTH_AT_C_LOOKUP(z, NUM, text)                                \
00061     template<std::size_t S>                                             \
00062     struct at_c_fn<S,NUM>                                               \
00063     {                                                                   \
00064         template <typename IntTypes, typename ValueType> inline         \
00065             static ValueType apply(std::size_t index)                   \
00066         {                                                               \
00067             static ValueType table[] = {                                \
00068                 BOOST_PP_REPEAT(NUM, PSYNTH_AT_C_VALUE, BOOST_PP_EMPTY) \
00069             };                                                          \
00070             return table[index];                                        \
00071         }                                                               \
00072     };
00073 
00074 namespace detail
00075 {
00076 namespace at_c
00077 {
00078 
00079 template <std::size_t START, std::size_t NUM> struct at_c_fn;
00080 BOOST_PP_REPEAT(PSYNTH_DYNAMIC_AT_C_LIMIT, PSYNTH_AT_C_LOOKUP, BOOST_PP_EMPTY)
00081 
00082 template <std::size_t QUOT> struct at_c_impl;
00083 
00084 template <>
00085 struct at_c_impl<0>
00086 {
00087     template <typename IntTypes, typename ValueType> inline
00088     static ValueType apply(std::size_t index)
00089     {
00090         return at_c_fn<0, boost::mpl::size<IntTypes>::value>::template apply<
00091             IntTypes, ValueType>(index);
00092     }
00093 };
00094 
00095 template <>
00096 struct at_c_impl<1>
00097 {
00098     template <typename IntTypes, typename ValueType> inline
00099     static ValueType apply (std::size_t index)
00100     {
00101         const std::size_t SIZE = boost::mpl::size<IntTypes>::value;
00102         const std::size_t REM  = SIZE % PSYNTH_DYNAMIC_AT_C_LIMIT;
00103 
00104         switch (index / PSYNTH_DYNAMIC_AT_C_LIMIT)
00105         {
00106         case 0: return at_c_fn<0, PSYNTH_DYNAMIC_AT_C_LIMIT-1>::template apply<
00107             IntTypes, ValueType> (index);
00108         case 1: return at_c_fn<PSYNTH_DYNAMIC_AT_C_LIMIT, REM>::template apply<
00109             IntTypes,ValueType> (index - PSYNTH_DYNAMIC_AT_C_LIMIT);
00110         };
00111         throw;
00112     }
00113 };
00114 
00115 template <>
00116 struct at_c_impl<2>
00117 {
00118     template <typename IntTypes, typename ValueType> inline
00119     static ValueType apply (std::size_t index)
00120     {
00121         const std::size_t SIZE = boost::mpl::size<IntTypes>::value;
00122         const std::size_t REM  = SIZE % PSYNTH_DYNAMIC_AT_C_LIMIT;
00123 
00124         switch (index / PSYNTH_DYNAMIC_AT_C_LIMIT)
00125         {
00126         case 0: return at_c_fn<0, PSYNTH_DYNAMIC_AT_C_LIMIT-1>::template apply<
00127             IntTypes, ValueType> (index);
00128         case 1: return at_c_fn<
00129             PSYNTH_DYNAMIC_AT_C_LIMIT,
00130             PSYNTH_DYNAMIC_AT_C_LIMIT-1>::template apply<IntTypes,ValueType>(
00131                 index - PSYNTH_DYNAMIC_AT_C_LIMIT);
00132         case 2: return at_c_fn<PSYNTH_DYNAMIC_AT_C_LIMIT*2, REM>::template apply<
00133             IntTypes, ValueType>(index - PSYNTH_DYNAMIC_AT_C_LIMIT*2);
00134         };
00135         throw;
00136     }
00137 };
00138 
00139 template <>
00140 struct at_c_impl<3>
00141 {
00142     template <typename IntTypes, typename ValueType> inline
00143     static ValueType apply(std::size_t index)
00144     {
00145         const std::size_t SIZE = boost::mpl::size<IntTypes>::value;
00146         const std::size_t REM  = SIZE % PSYNTH_DYNAMIC_AT_C_LIMIT;
00147         switch (index / PSYNTH_DYNAMIC_AT_C_LIMIT)
00148         {
00149         case 0: return at_c_fn<0, PSYNTH_DYNAMIC_AT_C_LIMIT-1>::template apply<
00150             IntTypes, ValueType> (index);
00151         case 1: return at_c_fn<
00152             PSYNTH_DYNAMIC_AT_C_LIMIT,
00153             PSYNTH_DYNAMIC_AT_C_LIMIT-1>::template apply<
00154                 IntTypes, ValueType> (index - PSYNTH_DYNAMIC_AT_C_LIMIT);
00155         case 2: return at_c_fn <
00156             PSYNTH_DYNAMIC_AT_C_LIMIT*2,
00157             PSYNTH_DYNAMIC_AT_C_LIMIT-1>::template apply<
00158                 IntTypes, ValueType> (index - PSYNTH_DYNAMIC_AT_C_LIMIT*2);
00159         case 3: return at_c_fn<PSYNTH_DYNAMIC_AT_C_LIMIT*3, REM>::template apply<
00160             IntTypes, ValueType> (index - PSYNTH_DYNAMIC_AT_C_LIMIT*3);
00161         };
00162         throw;
00163     }
00164 };
00165 
00166 } /* namespace detail */
00167 } /* namespace at_c */
00168 
00176 template <typename IntTypes, typename ValueType> inline 
00177 ValueType at_c (std::size_t index)
00178 { 
00179     const std::size_t Size = boost::mpl::size<IntTypes>::value;
00180     return detail::at_c::at_c_impl<
00181         Size / PSYNTH_DYNAMIC_AT_C_LIMIT>::template apply<
00182             IntTypes, ValueType> (index);
00183 }    
00184 
00185 #undef PSYNTH_AT_C_VALUE
00186 #undef PSYNTH_DYNAMIC_AT_C_LIMIT
00187 #undef PSYNTH_AT_C_LOOKUP
00188 
00189 } /* namespace sound */
00190 } /* namespace psynth */
00191 
00192 #endif /* namespace PSYNTH_SOUND_DYNAMIC_AT_C */