Boost.ConstrainedValue で小数を扱う
できたよー。
以前、Boost.Ratio でつくったこれを使いました。
とりあえず、bounded だけですが、Boost.ConstrainedValue を変更することなく小数が扱えると思います。
[ソース]
#define BOOST_RATIO_EXTENSIONS #include <boost/ratio/ratio.hpp> #include <boost/mpl/int.hpp> #include <boost/mpl/less_equal.hpp> #include <boost/mpl/plus.hpp> #include <boost/mpl/if.hpp> #include <boost/mpl/divides.hpp> #include <boost/mpl/multiplies.hpp> #include <boost/mpl/minus.hpp> namespace detail{ namespace mpl = boost::mpl; template<typename base, typename exponent> struct pow : mpl::if_< mpl::less_equal<exponent, mpl::int_<0> >, mpl::int_<1>, mpl::multiplies<pow<base, mpl::minus<exponent, mpl::int_<1> > >, base> >::type {}; template<std::size_t base, std::size_t exponent> struct pow_c : pow< mpl::integral_c<std::size_t, base>, mpl::integral_c<std::size_t, exponent> >{}; template<typename T> struct keta_impl : mpl::if_< mpl::less_equal<T, mpl::int_<0> >, mpl::int_<0>, mpl::plus<keta_impl<mpl::divides<T, mpl::int_<10> > >, mpl::int_<1> > >::type {}; } // namespace detai template<typename T> struct keta : detail::keta_impl<T>{}; namespace detail{ template<std::size_t N, std::size_t M, typename keta = detail::pow<mpl::int_<10>, keta<mpl::integral_c<std::size_t, M> > > > struct float_impl : boost::ratio< N * keta::value + M, keta::value > {}; } // namespace detail template<std::size_t N, std::size_t M> struct float_ : detail::float_impl<N, M>{ typedef detail::float_impl<N, M> base_type; operator float() const{ return float(base_type::num) / base_type::den; } }; #include <boost/constrained_value.hpp> #include <iostream> int main() try{ using boost::constrained_value::bounded; bounded<float, float_<0,0>, float_<1,5> >::type value(0.0f); for(int i = 0 ; i < 20 ; ++i){ std::cout << value << std::endl; value = value + 0.1f; } return 0; } catch(std::exception& exp){ std::cout << exp.what() << std::endl; }
[出力]
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 1.1 1.2 1.3 1.4 Attempt to give constrained object a value that is not constraint-conforming.
多分、他の奴にも対応出来そう。
あ、C++03 でも動きます。
Boost.ConstrainedValue は思ったよりも応用が出来そうなので、ちょっと欲しくなってきました。
[boost]
- ver 1.48.0