同じような内容が続きますが、今回はC言語の標準ライブラリにあるdiv関数をテンプレート化したものです。
C++ではdiv関数が引数の型によって多重定義されています。しかし、返却値の型はC言語と同じで、div_t、ldiv_t、lldiv_tのようにバラバラの型になっています。これを前回までも登場したxdiv_t構造体テンプレートに置き換えることで、使い勝手を向上させてみます。
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
template <typename T> struct xdiv_t { T quot; T rem; }; template<class T> xdiv_t<T> xdiv(T dividend, T divisor) { assert(is_integral<T>::value); T lhs = dividend; T rhs = divisor; bool negative_quot = false; bool negative_rem = false; if (rhs < 0) { rhs = -rhs; negative_quot = true; } if (lhs < 0) { lhs = -lhs; negative_quot = !negative_quot; negative_rem = true; } xdiv_t<T> r; r.quot = lhs / rhs; r.rem = lhs - r.quot * rhs; if (negative_quot) r.quot = -r.quot; if (negative_rem) r.rem = -r.rem; return r; } |
例によってC++98以降で使えるようにしていますのが、assertの引数に使っているis_signedはTR1かBoost C++ Librariesのものを使用してください。NDEBUGマクロを定義してassertを無効にしてもいいでしょう。