SCM Repositories - quan


Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.2.5 - (download) (annotate)
Sun Aug 27 10:45:00 2006 UTC (2 years, 10 months ago) by kwikius
Branch: two_param-branch
CVS Tags: two_param_pre_merge_28_Aug_2006-tag
Changes since 1.1.2.4: +5 -0 lines
add allow_unit_conversions function
    1 #ifndef QUAN_META_MPL_UNIT_HPP_INCLUDED
    2 #define QUAN_META_MPL_UNIT_HPP_INCLUDED
    3 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
    4 #  pragma once
    5 #endif
    6 
    7 // Copyright Andrew Little 2005
    8 //
    9 // Distributed under the Boost Software License, Version 1.0.
   10 // (See accompanying file LICENSE_1_0.txt or copy at
   11 // http://www.boost.org/LICENSE_1_0.txt)
   12 //
   13 // See http://www.boost.org/libs/mpl for documentation.
   14 
   15 /*
   16   simple model of StaticUnit using the Boost.Mpl library
   17 */
   18 
   19 #include <quan/config.hpp>
   20 //#include <quan/meta/mpl/reciprocal.hpp>
   21 //#include <quan/meta/mpl/pow.hpp>
   22 #include <quan/meta/si_unit_system.hpp>
   23 #include <quan/meta/static_unit_concept.hpp>
   24 #include <quan/meta/conversion_factor.hpp>
   25 
   26 #include <boost/mpl/arithmetic.hpp>
   27 #include <boost/mpl/bool.hpp>
   28 #include <boost/mpl/if.hpp>
   29 #include <boost/mpl/equal.hpp>
   30 #include <boost/mpl/equal_to.hpp>
   31 #include <boost/mpl/not_equal_to.hpp>
   32 #include <boost/mpl/int.hpp>
   33 #include <boost/mpl/eval_if.hpp>
   34 #include <boost/mpl/transform.hpp>
   35 #include <boost/mpl/placeholders.hpp>
   36 #include <boost/mpl/find_if.hpp>
   37 #include <boost/mpl/at.hpp>
   38 #include <boost/mpl/assert.hpp>
   39 
   40 #include <boost/type_traits/is_same.hpp>
   41 #include <boost/typeof/typeof.hpp>
   42 
   43 #ifdef QUAN_USE_BOOST_TYPEOF_BINARY_OPERATION
   44 #include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
   45 BOOST_TYPEOF_REGISTER_TEMPLATE(quan::meta::mpl::unit, 1);
   46 #endif
   47 
   48 namespace quan{ namespace meta{namespace mpl{
   49 
   50     template<
   51         typename Dimension
   52     >
   53     struct unit{
   54         typedef Dimension  dimension;
   55         typedef unit       type;
   56     };
   57 
   58 }}}// quan::meta::mpl
   59 
   60 namespace quan{ namespace meta{
   61 
   62     template <
   63         typename DimensionL,
   64         typename DimensionR
   65     >
   66     struct dimensionally_equivalent<
   67         quan::meta::mpl::unit<
   68             DimensionL
   69         >,
   70         quan::meta::mpl::unit<
   71             DimensionR
   72         >
   73     > : boost::mpl::equal<
   74         DimensionL,
   75         DimensionR,
   76         boost::mpl::equal_to<
   77             boost::mpl::_1,
   78             boost::mpl::_2
   79         >
   80     >{};
   81 
   82     template <typename Dimension>
   83     struct is_dimensionless<
   84         quan::meta::mpl::unit<Dimension>
   85     > : boost::is_same <
   86         typename ::boost::mpl::find_if<
   87             Dimension,
   88             boost::mpl::not_equal_to<
   89                 boost::mpl::_1,
   90                 boost::mpl::minus<boost::mpl::_1,boost::mpl::_1>
   91             >
   92         >::type ,
   93         typename boost::mpl::end<Dimension>::type
   94     >{};
   95 
   96     template <typename Dimension>
   97     struct make_anonymous<
   98         quan::meta::mpl::unit<Dimension>
   99     > : quan::meta::mpl::unit<Dimension>{};
  100 
  101     template <typename Dimension>
  102     struct get_quantity_system<
  103         quan::meta::mpl::unit<Dimension>
  104     > : quan::meta::si_unit_system {};
  105 
  106     template <typename Dimension>
  107     struct is_si <
  108         quan::meta::mpl::unit<Dimension>
  109     > : boost::mpl::true_{};
  110 
  111     template <typename Dimension>
  112     struct is_named_quantity <
  113         quan::meta::mpl::unit<Dimension>
  114     > : boost::mpl::false_{};
  115 
  116     template <
  117         typename DimensionL,
  118         typename DimensionR
  119     >
  120     struct is_same_quantity <
  121         quan::meta::mpl::unit<DimensionL>,
  122         quan::meta::mpl::unit<DimensionR>
  123     > : dimensionally_equivalent<
  124         quan::meta::mpl::unit<DimensionL>,
  125         quan::meta::mpl::unit<DimensionR>
  126     >{};
  127 
  128     template <typename Dimension>
  129     struct get_conversion_factor <
  130         quan::meta::mpl::unit<Dimension>
  131     > : quan::meta::conversion_factor<>{};
  132 
  133     template <typename Dimension>
  134     struct allow_implicit_unit_conversions<
  135         quan::meta::mpl::unit<Dimension>
  136     > : boost::mpl::false_{};
  137 
  138     template <typename Dimension>
  139     struct get_nearest_si <
  140         quan::meta::mpl::unit<Dimension>
  141     > : quan::meta::mpl::unit<Dimension>{};
  142 
  143     template <typename Dimension>
  144     struct get_named_quantity_traits<
  145         quan::meta::mpl::unit<Dimension>
  146     > : anonymous_quantity_traits{};
  147 
  148     #define QUAN_META_GET_DIMENSION(Q,Pos) \
  149     template <typename Dimension> \
  150     struct  BOOST_PP_CAT(BOOST_PP_CAT(get_,Q),_dimension) <\
  151         quan::meta::mpl::unit<Dimension> \
  152     > : boost::mpl::at_c<Dimension, Pos >{};
  153     QUAN_META_GET_DIMENSION(length,0)
  154     QUAN_META_GET_DIMENSION(time,1)
  155     QUAN_META_GET_DIMENSION(mass,2)
  156     QUAN_META_GET_DIMENSION(temperature,3)
  157     QUAN_META_GET_DIMENSION(current,4)
  158     QUAN_META_GET_DIMENSION(substance,5)
  159     QUAN_META_GET_DIMENSION(intensity,6)
  160     #undef QUAN_META_GET_DIMENSION
  161 
  162 
  163 }}//quan::meta
  164 
  165 namespace boost{namespace mpl{
  166 
  167     template<
  168         typename DimensionL,
  169         typename DimensionR
  170     >
  171     struct plus<
  172         quan::meta::mpl::unit<DimensionL>,
  173         quan::meta::mpl::unit<DimensionR>
  174     > : quan::meta::mpl::unit<
  175         typename transform<
  176             DimensionL,
  177             DimensionR,
  178             plus<_1,_2>
  179         >::type
  180     >{};
  181 
  182     template<
  183         typename DimensionL,
  184         typename DimensionR
  185     >
  186     struct minus<
  187         quan::meta::mpl::unit<DimensionL>,
  188         quan::meta::mpl::unit<DimensionR>
  189     > : quan::meta::mpl::unit<
  190         typename transform<
  191             DimensionL,
  192             DimensionR,
  193             minus<_1,_2>
  194         >::type
  195     >{};
  196 
  197     template<
  198         typename Dimension
  199     >
  200     struct negate<
  201         quan::meta::mpl::unit<Dimension>
  202     > : quan::meta::mpl::unit<
  203          typename transform<
  204             Dimension,
  205            negate<_1>
  206         >::type
  207     >{};
  208 
  209     template<
  210         typename Dimension,
  211         typename C
  212     >
  213     struct times<
  214         quan::meta::mpl::unit<Dimension>,C
  215     > : quan::meta::mpl::unit<
  216          typename transform<
  217             Dimension,
  218             times<_1,typename quan::meta::numerator<C>::type>
  219         >::type
  220     >{
  221          BOOST_MPL_ASSERT((
  222             boost::mpl::equal_to<
  223                 quan::meta::denominator<C>::type,
  224                 boost::mpl::int_<1>
  225             >
  226         ));
  227     };
  228 // not required?
  229    /* template<
  230         typename Dimension,
  231         typename C
  232     >
  233     struct divides<
  234         quan::meta::mpl::unit<Dimension>,C
  235     > : quan::meta::mpl::unit<
  236          typename  transform<
  237             Dimension,
  238             divides<_1,typename quan::meta::numerator<C>::type>
  239         >::type
  240     >{
  241         BOOST_MPL_ASSERT(( boost::mpl::equal_to<
  242             quan::meta::denominator<C>::type
  243             boost::mpl::int_<1>
  244         ));
  245     };*/
  246 
  247 }}//boost::mpl
  248 
  249 namespace quan{ namespace meta{
  250 
  251     template <typename DL, typename DR>
  252     struct binary_operation<
  253         quan::meta::mpl::unit<DL>,plus,quan::meta::mpl::unit<DR>
  254     > {
  255 
  256         BOOST_MPL_ASSERT((
  257             dimensionally_equivalent<
  258                 quan::meta::mpl::unit<DL>,quan::meta::mpl::unit<DR>
  259             >
  260         ));
  261         typedef quan::meta::mpl::unit<DL> type;
  262     };
  263 
  264     template <typename DL, typename DR>
  265     struct binary_operation<
  266         quan::meta::mpl::unit<DL>,minus,quan::meta::mpl::unit<DR>
  267     > {
  268 
  269         BOOST_MPL_ASSERT((
  270             dimensionally_equivalent<
  271                 quan::meta::mpl::unit<DL>,quan::meta::mpl::unit<DR>
  272             >
  273         ));
  274         typedef quan::meta::mpl::unit<DL> type;
  275     };
  276 
  277     template <typename DL, typename DR>
  278     struct binary_operation<
  279         quan::meta::mpl::unit<DL>,times,quan::meta::mpl::unit<DR>
  280     > {
  281         typedef  typename boost::mpl::plus<
  282             quan::meta::mpl::unit<DL>,quan::meta::mpl::unit<DR>
  283         >::type type;
  284     };
  285 
  286     template <typename DL, typename DR>
  287     struct binary_operation<
  288         quan::meta::mpl::unit<DL>,divides,quan::meta::mpl::unit<DR>
  289     > {
  290         typedef  typename boost::mpl::minus<
  291             quan::meta::mpl::unit<DL>,quan::meta::mpl::unit<DR>
  292         >::type type;
  293     };
  294 
  295     template <typename DL, typename Exp>
  296     struct binary_operation<
  297         quan::meta::mpl::unit<DL>,pow, Exp
  298     > {
  299         typedef  typename boost::mpl::times<
  300             quan::meta::mpl::unit<DL>,Exp
  301         >::type type;
  302     };
  303 
  304     template <typename D>
  305     struct unary_operation<
  306         reciprocal,quan::meta::mpl::unit<D>
  307     > {
  308         typedef  typename boost::mpl::negate<
  309             quan::meta::mpl::unit<D>
  310         >::type type;
  311     };
  312 
  313 }}
  314 
  315 // add binary and unary ops
  316 
  317 #endif