RAPI
|
00001 /* 00002 * R : A Computer Language for Statistical Data Analysis 00003 * Copyright (C) 2001-12 The R Core Team. 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU Lesser General Public License as published by 00007 * the Free Software Foundation; either version 2.1 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public License 00016 * along with this program; if not, a copy is available at 00017 * https://www.R-project.org/Licenses/ 00018 */ 00019 00020 /* 00021 Macros to help defining vectorized functions with proper recycling 00022 and periodic interrupt checks. 00023 */ 00024 00025 #ifndef R_EXT_ITERMACROS_H_ 00026 #define R_EXT_ITERMACROS_H_ 00027 00028 #define LOOP_WITH_INTERRUPT_CHECK(LOOP, ncheck, n, ...) do { \ 00029 for (size_t __intr_threshold__ = ncheck; \ 00030 TRUE; \ 00031 __intr_threshold__ += ncheck) { \ 00032 size_t __intr_end__ = n < __intr_threshold__ ? \ 00033 n : __intr_threshold__; \ 00034 LOOP(__intr_end__, __VA_ARGS__); \ 00035 if (__intr_end__ == n) break; \ 00036 else R_CheckUserInterrupt(); \ 00037 } \ 00038 } while (0) 00039 00040 #define R_ITERATE_CORE(n, i, loop_body) do { \ 00041 for (; i < n; ++i) { loop_body } \ 00042 } while (0) 00043 00044 #define R_ITERATE(n, i, loop_body) do { \ 00045 i = 0; \ 00046 R_ITERATE_CORE(n, i, loop_body); \ 00047 } while (0) 00048 00049 #define R_ITERATE_CHECK(ncheck, n, i, loop_body) do { \ 00050 i = 0; \ 00051 LOOP_WITH_INTERRUPT_CHECK(R_ITERATE_CORE, ncheck, n, i, loop_body); \ 00052 } while (0) 00053 00054 00055 #define MOD_ITERATE1_CORE(n, n1, i, i1, loop_body) do { \ 00056 for (; i < n; \ 00057 i1 = (++i1 == n1) ? 0 : i1, \ 00058 ++i) { \ 00059 loop_body \ 00060 } \ 00061 } while (0) 00062 00063 #define MOD_ITERATE1(n, n1, i, i1, loop_body) do { \ 00064 i = i1 = 0; \ 00065 MOD_ITERATE1_CORE(n, n1, i, i1, loop_body); \ 00066 } while (0) 00067 00068 #define MOD_ITERATE1_CHECK(ncheck, n, n1, i, i1, loop_body) do { \ 00069 i = i1 = 0; \ 00070 LOOP_WITH_INTERRUPT_CHECK(MOD_ITERATE1_CORE, ncheck, n, \ 00071 n1, i, i1, loop_body); \ 00072 } while (0) 00073 00074 #define MOD_ITERATE2_CORE(n, n1, n2, i, i1, i2, loop_body) do { \ 00075 for (; i < n; \ 00076 i1 = (++i1 == n1) ? 0 : i1, \ 00077 i2 = (++i2 == n2) ? 0 : i2, \ 00078 ++i) { \ 00079 loop_body \ 00080 } \ 00081 } while (0) 00082 00083 #define MOD_ITERATE2(n, n1, n2, i, i1, i2, loop_body) do { \ 00084 i = i1 = i2 = 0; \ 00085 MOD_ITERATE2_CORE(n, n1, n2, i, i1, i2, loop_body); \ 00086 } while (0) 00087 00088 #define MOD_ITERATE2_CHECK(ncheck, n, n1, n2, i, i1, i2, loop_body) do { \ 00089 i = i1 = i2 = 0; \ 00090 LOOP_WITH_INTERRUPT_CHECK(MOD_ITERATE2_CORE, ncheck, n, \ 00091 n1, n2, i, i1, i2, loop_body); \ 00092 } while (0) 00093 00094 #define MOD_ITERATE MOD_ITERATE2 00095 #define MOD_ITERATE_CORE MOD_ITERATE2_CORE 00096 #define MOD_ITERATE_CHECK MOD_ITERATE2_CHECK 00097 00098 #define MOD_ITERATE3_CORE(n, n1, n2, n3, i, i1, i2, i3, loop_body) do { \ 00099 for (; i < n; \ 00100 i1 = (++i1 == n1) ? 0 : i1, \ 00101 i2 = (++i2 == n2) ? 0 : i2, \ 00102 i3 = (++i3 == n3) ? 0 : i3, \ 00103 ++i) { \ 00104 loop_body \ 00105 } \ 00106 } while (0) 00107 00108 #define MOD_ITERATE3(n, n1, n2, n3, i, i1, i2, i3, loop_body) do { \ 00109 i = i1 = i2 = i3 = 0; \ 00110 MOD_ITERATE3_CORE(n, n1, n2, n3, i, i1, i2, i3, loop_body); \ 00111 } while (0) 00112 00113 #define MOD_ITERATE3_CHECK(ncheck, n, n1, n2, n3, i, i1, i2, i3, loop_body) \ 00114 do { \ 00115 i = i1 = i2 = i3 = 0; \ 00116 LOOP_WITH_INTERRUPT_CHECK(MOD_ITERATE3_CORE, ncheck, n, \ 00117 n1, n2, n3, i, i1, i2, i3, loop_body); \ 00118 } while (0) 00119 00120 #define MOD_ITERATE4_CORE(n, n1, n2, n3, n4, i, i1, i2, i3, i4, loop_body) \ 00121 do { \ 00122 for (; i < n; \ 00123 i1 = (++i1 == n1) ? 0 : i1, \ 00124 i2 = (++i2 == n2) ? 0 : i2, \ 00125 i3 = (++i3 == n3) ? 0 : i3, \ 00126 i4 = (++i4 == n4) ? 0 : i4, \ 00127 ++i) { \ 00128 loop_body \ 00129 } \ 00130 } while (0) 00131 00132 #define MOD_ITERATE4(n, n1, n2, n3, n4, i, i1, i2, i3, i4, loop_body) do { \ 00133 i = i1 = i2 = i3 = i4 = 0; \ 00134 MOD_ITERATE4_CORE(n, n1, n2, n3, n4, i, i1, i2, i3, i4, loop_body); \ 00135 } while (0) 00136 00137 #define MOD_ITERATE4_CHECK(ncheck, n, n1, n2, n3, n4, i, i1, i2, i3, i4, \ 00138 loop_body) \ 00139 do { \ 00140 i = i1 = i2 = i3 = i4 = 0; \ 00141 LOOP_WITH_INTERRUPT_CHECK(MOD_ITERATE4_CORE, ncheck, n, \ 00142 n1, n2, n3, n4, \ 00143 i, i1, i2, i3, i4, loop_body); \ 00144 } while (0) 00145 00146 #define MOD_ITERATE5_CORE(n, n1, n2, n3, n4, n5, i, i1, i2, i3, i4, i5, \ 00147 loop_body) \ 00148 do { \ 00149 for (; i < n; \ 00150 i1 = (++i1 == n1) ? 0 : i1, \ 00151 i2 = (++i2 == n2) ? 0 : i2, \ 00152 i3 = (++i3 == n3) ? 0 : i3, \ 00153 i4 = (++i4 == n4) ? 0 : i4, \ 00154 i5 = (++i5 == n5) ? 0 : i5, \ 00155 ++i) { \ 00156 loop_body \ 00157 } \ 00158 } while (0) 00159 00160 #define MOD_ITERATE5(n, n1, n2, n3, n4, n5, i, i1, i2, i3, i4, i5, loop_body) \ 00161 do { \ 00162 i = i1 = i2 = i3 = i4 = i5 = 0; \ 00163 MOD_ITERATE5_CORE(n, n1, n2, n3, n4, n5, i, i1, i2, i3, i4, i5, \ 00164 loop_body); \ 00165 } while (0) 00166 00167 #define MOD_ITERATE5_CHECK(ncheck, n, n1, n2, n3, n4, n5, \ 00168 i, i1, i2, i3, i4, i5, \ 00169 loop_body) \ 00170 do { \ 00171 i = i1 = i2 = i3 = i4 = i5 = 0; \ 00172 LOOP_WITH_INTERRUPT_CHECK(MOD_ITERATE5_CORE, ncheck, n, \ 00173 n1, n2, n3, n4, n5, \ 00174 i, i1, i2, i3, i4, i5, loop_body); \ 00175 } while (0) 00176 00177 #endif /* R_EXT_ITERMACROS_H_ */