diff --git a/src/lib/time.cpp b/src/lib/time.cpp index ff9815f95..d68b883cb 100644 --- a/src/lib/time.cpp +++ b/src/lib/time.cpp @@ -22,7 +22,7 @@ #include "lib/time.h" #include "lib/error.hpp" -#include "lib/util.hpp" +#include "lib/util-quant.hpp" extern "C" { #include "lib/tmpbuf.h" diff --git a/src/lib/time/mutation.cpp b/src/lib/time/mutation.cpp index a6fd96e50..718af5244 100644 --- a/src/lib/time/mutation.cpp +++ b/src/lib/time/mutation.cpp @@ -27,6 +27,7 @@ #include "lib/time/timecode.hpp" #include "lib/time/mutation.hpp" //#include "lib/time.h" +#include "lib/util-quant.hpp" #include "lib/util.hpp" //#include diff --git a/src/lib/time/timecode.cpp b/src/lib/time/timecode.cpp index 857179461..53faef575 100644 --- a/src/lib/time/timecode.cpp +++ b/src/lib/time/timecode.cpp @@ -27,6 +27,7 @@ #include "lib/time/formats.hpp" #include "lib/time.h" #include "lib/util.hpp" +#include "lib/util-quant.hpp" #include #include diff --git a/src/lib/util-quant.hpp b/src/lib/util-quant.hpp new file mode 100644 index 000000000..361edace7 --- /dev/null +++ b/src/lib/util-quant.hpp @@ -0,0 +1,119 @@ +/* + UTIL-QUANT.hpp - helper functions to deal with division and quantisation + + Copyright (C) Lumiera.org + 2011, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + + +#ifndef LIB_UTIL_QUANT_H +#define LIB_UTIL_QUANT_H + +#include + + + +namespace util { + + + /** helper to treat int or long division uniformly */ + template + struct IDiv + { + I quot; + I rem; + + IDiv (I num, I den) + : quot(num/den) + , rem(num - quot*den) + { } + }; + + template<> + struct IDiv + : div_t + { + IDiv (int num, int den) + : div_t(div (num,den)) + { } + }; + + template<> + struct IDiv + : ldiv_t + { + IDiv (long num, long den) + : ldiv_t(ldiv (num,den)) + { } + }; + + template<> + struct IDiv + : lldiv_t + { + IDiv (long long num, long long den) + : lldiv_t(lldiv (num,den)) + { } + }; + + + /** floor function for integer arithmetics. + * Unlike the built-in integer division, this function + * always rounds towards the next \em smaller integer, + * even for negative numbers. + * @warning floor on doubles performs way better + * @see UtilFloordiv_test + */ + template + inline I + floordiv (I num, I den) + { + if (0 < (num^den)) + return num/den; + else + { // truncate similar to floor() + IDiv res(num,den); + return (res.rem)? res.quot-1 // negative results truncated towards next smaller int + : res.quot; //..unless the division result not truncated at all + } + } + + /** scale wrapping operation. + * Quantises the numerator value into the scale given by the denominator. + * Unlike the built-in integer division, this function always rounds towards + * the next \em smaller integer and also relates the remainder (=modulo) to + * this next lower scale grid point. + * @return quotient and remainder packed into a struct + * @see UtilFloorwarp_test + */ + template + inline IDiv + floorwrap (I num, I den) + { + IDiv res(num,den); + if (0 > (num^den) && res.rem) + { // negative results + // wrapped similar to floor() + --res.quot; + res.rem = den - (-res.rem); + } + return res; + } + +} // namespace util +#endif /*UTIL_QUANT_H*/ diff --git a/src/lib/util.hpp b/src/lib/util.hpp index 037881883..a629de195 100644 --- a/src/lib/util.hpp +++ b/src/lib/util.hpp @@ -21,8 +21,8 @@ */ -#ifndef UTIL_HPP_ -#define UTIL_HPP_ +#ifndef LIB_UTIL_H +#define LIB_UTIL_H #include #include @@ -57,90 +57,6 @@ namespace util { } - /** helper to treat int or long division uniformly */ - template - struct IDiv - { - I quot; - I rem; - - IDiv (I num, I den) - : quot(num/den) - , rem(num - quot*den) - { } - }; - - template<> - struct IDiv - : div_t - { - IDiv (int num, int den) - : div_t(div (num,den)) - { } - }; - - template<> - struct IDiv - : ldiv_t - { - IDiv (long num, long den) - : ldiv_t(ldiv (num,den)) - { } - }; - - template<> - struct IDiv - : lldiv_t - { - IDiv (long long num, long long den) - : lldiv_t(lldiv (num,den)) - { } - }; - - - /** floor function for integer arithmetics. - * Unlike the built-in integer division, this function - * always rounds towards the next \em smaller integer, - * even for negative numbers. - * @warning floor on doubles performs way better - * @see UtilFloordiv_test - */ - template - inline I - floordiv (I num, I den) - { - if (0 < (num^den)) - return num/den; - else - { // truncate similar to floor() - IDiv res(num,den); - return (res.rem)? res.quot-1 // negative results truncated towards next smaller int - : res.quot; //..unless the division result not truncated at all - } - } - - /** scale wrapping operation. - * Quantises the numerator value into the scale given by the denominator. - * Unlike the built-in integer division, this function always rounds towards - * the next \em smaller integer and also relates the remainder (=modulo) to - * this next lower scale grid point. - * @return quotient and remainder packed into a struct - * @see UtilFloorwarp_test - */ - template - inline IDiv - floorwrap (I num, I den) - { - IDiv res(num,den); - if (0 > (num^den) && res.rem) - { // negative results - // wrapped similar to floor() - --res.quot; - res.rem = den - (-res.rem); - } - return res; - } - /* ======== generic empty check ========= */ diff --git a/tests/lib/util-floordiv-test.cpp b/tests/lib/util-floordiv-test.cpp index 63c14a1a6..256498cef 100644 --- a/tests/lib/util-floordiv-test.cpp +++ b/tests/lib/util-floordiv-test.cpp @@ -22,6 +22,7 @@ #include "lib/test/run.hpp" +#include "lib/util-quant.hpp" #include "lib/util.hpp" #include diff --git a/tests/lib/util-floorwrap-test.cpp b/tests/lib/util-floorwrap-test.cpp index c42f37593..7e66cc10b 100644 --- a/tests/lib/util-floorwrap-test.cpp +++ b/tests/lib/util-floorwrap-test.cpp @@ -23,7 +23,7 @@ #include "lib/test/run.hpp" #include "lib/test/test-helper.hpp" -#include "lib/util.hpp" +#include "lib/util-quant.hpp" #include #include @@ -36,6 +36,7 @@ using std::endl; using boost::format; using boost::lexical_cast; using lib::test::showType; +using util::floorwrap; namespace util {