|
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 #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 */
1.7.4