#ifndef MCS_DIMENSION_HPP #define MCS_DIMENSION_HPP #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mcs { namespace units { using namespace boost::mpl; // type resolving to dimensionless struct dimensionless_type { }; // append one sequence to another template struct append { typedef typename insert_range< S1, typename end::type, S2 >::type type; }; // determine if two sequences are the same size template struct same_size { typedef typename equal_to< size, size >::type type; }; // get the dim tag at position N template struct dim_at_c { typedef typename get_dim< typename at_c::type >::type type; }; // get the value at position N template struct value_at_c { typedef typename get_value< typename at_c::type >::type type; }; // determine if two sequences are commensurate; i.e. same size // and containing the same elements, order irrelevant template struct is_commensurate { typedef typename and_< same_size, fold< S1, true_, if_< contains, and_<_1,true_>, and_<_1,false_> > > >::type type; static const bool value = boost::is_same::value; }; template struct add_collapse_dims { typedef typename next::type>::type start_iter; typedef typename end::type end_iter; typedef typename iterator_range::type iter; typedef typename iter_fold::type, Add<_1,deref<_2> > >::type type; }; template struct subtract_collapse_dims { typedef typename next::type>::type start_iter; typedef typename end::type end_iter; typedef typename iterator_range::type iter; typedef typename iter_fold::type, Subtract<_1,deref<_2> > >::type type; }; // returns a sequence with the distinct dimension tags in the input sequence template struct distinct_dims { typedef typename begin::type start_iter; typedef typename end::type end_iter; typedef typename iterator_range::type rng; typedef typename iter_fold::type, if_< not_ > > >, push_front<_1,get_dim > >, _1 > >::type type; }; // extract all dims having a specified tag template struct get_by_dim { typedef typename remove_if,T> > >::type type; }; // extract all dimensionless dimensions template struct strip_zero_dims { typedef typename remove_if,Rational<0> > >::type type; }; // reduce dimension list, collapsing duplicates and stripping dimensionless tags template struct reduce_dimension { typedef Seq sequence; typedef typename distinct_dims::type distinct_type; typedef typename begin::type start_iter; typedef typename end::type end_iter; typedef typename iterator_range::type rng; typedef typename iter_fold::type, push_front< _1, add_collapse_dims< get_by_dim > > > >::type type1; typedef typename strip_zero_dims::type type2; typedef typename if_,dimensionless_type,type2>::type type; }; // negate dimension list, collapsing duplicates // and stripping dimensionless tags template struct Negate { typedef Seq sequence; typedef typename transform >::type type1; typedef typename reduce_dimension::type type; }; template struct Add { typedef typename strip_zero_dims::type seq1; typedef typename strip_zero_dims::type seq2; BOOST_STATIC_ASSERT((equal_to< typename is_commensurate::type, true_ >::value == true)); typedef seq1 type; }; template struct Subtract { typedef typename strip_zero_dims::type seq1; typedef typename strip_zero_dims::type seq2; BOOST_STATIC_ASSERT((equal_to< typename is_commensurate::type, true_ >::value == true)); typedef seq1 type; }; template struct Multiply { typedef typename append::type sequence; typedef typename reduce_dimension::type type; }; template struct Divide { typedef typename append::type>::type sequence; typedef typename reduce_dimension::type type; }; template struct Power { typedef Seq sequence; typedef typename transform >::type type1; typedef typename reduce_dimension::type type; }; template struct Root { typedef Seq sequence; typedef typename transform >::type type1; typedef typename reduce_dimension::type type; }; } // namespace units } // namespace mcs #endif // MCS_DIMENSION_HPP