Added boost header

This commit is contained in:
Christophe Riccio
2012-01-08 01:26:07 +00:00
parent 9c3faaca40
commit c7d752cdf8
8946 changed files with 1732316 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_ABSOLUTE_IMPL_HPP
#define BOOST_UNITS_ABSOLUTE_IMPL_HPP
#include <iosfwd>
#include <boost/units/config.hpp>
#include <boost/units/conversion.hpp>
#include <boost/units/heterogeneous_system.hpp>
#include <boost/units/units_fwd.hpp>
namespace boost {
namespace units {
/// INTERNAL ONLY
template<class D, class S>
struct reduce_unit<absolute<unit<D, S> > >
{
typedef absolute<typename reduce_unit<unit<D, S> >::type> type;
};
namespace detail {
struct undefined_affine_conversion_base {
static const bool is_defined = false;
};
} // namespace detail
/// INTERNAL ONLY
template<class From, class To>
struct affine_conversion_helper : detail::undefined_affine_conversion_base { };
namespace detail {
template<bool IsDefined, bool ReverseIsDefined>
struct affine_conversion_impl;
template<bool ReverseIsDefined>
struct affine_conversion_impl<true, ReverseIsDefined>
{
template<class Unit1, class Unit2, class T0, class T1>
struct apply {
static T1 value(const T0& t0)
{
return(
t0 *
conversion_factor(Unit1(), Unit2()) +
affine_conversion_helper<typename reduce_unit<Unit1>::type, typename reduce_unit<Unit2>::type>::value());
}
};
};
template<>
struct affine_conversion_impl<false, true>
{
template<class Unit1, class Unit2, class T0, class T1>
struct apply
{
static T1 value(const T0& t0)
{
return(
(t0 - affine_conversion_helper<typename reduce_unit<Unit2>::type, typename reduce_unit<Unit1>::type>::value()) *
conversion_factor(Unit1(), Unit2()));
}
};
};
} // namespace detail
/// INTERNAL ONLY
template<class Unit1, class T1, class Unit2, class T2>
struct conversion_helper<quantity<absolute<Unit1>, T1>, quantity<absolute<Unit2>, T2> >
{
typedef quantity<absolute<Unit1>, T1> from_quantity_type;
typedef quantity<absolute<Unit2>, T2> to_quantity_type;
static to_quantity_type convert(const from_quantity_type& source)
{
return(
to_quantity_type::from_value(
detail::affine_conversion_impl<
affine_conversion_helper<typename reduce_unit<Unit1>::type, typename reduce_unit<Unit2>::type>::is_defined,
affine_conversion_helper<typename reduce_unit<Unit2>::type, typename reduce_unit<Unit1>::type>::is_defined
>::template apply<Unit1, Unit2, T1, T2>::value(source.value())
)
);
}
};
} // namespace units
} // namespace boost
#endif // BOOST_UNITS_ABSOLUTE_IMPL_HPP

View File

@@ -0,0 +1,154 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_CMATH_IMPL_HPP
#define BOOST_UNITS_CMATH_IMPL_HPP
#include <boost/config.hpp>
#include <boost/math/special_functions/fpclassify.hpp>
namespace boost {
namespace units {
namespace detail {
template<class Y>
inline bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
else return v1 > v2;
}
template<class Y>
inline bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
else return v1 >= v2;
}
template<class Y>
inline bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
else return v1 < v2;
}
template<class Y>
inline bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
else return v1 <= v2;
}
template<class Y>
inline bool islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
if((boost::math::isnan)(v1) || (boost::math::isnan)(v2)) return false;
else return v1 < v2 || v1 > v2;
}
template<class Y>
inline bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
return (boost::math::isnan)(v1) || (boost::math::isnan)(v2);
}
template<class Y>
inline Y fdim BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
if((boost::math::isnan)(v1)) return v1;
else if((boost::math::isnan)(v2)) return v2;
else if(v1 > v2) return(v1 - v2);
else return(Y(0));
}
#if 0
template<class T>
struct fma_issue_warning {
enum { value = false };
};
template<class Y>
inline Y fma(const Y& v1,const Y& v2,const Y& v3)
{
//this implementation does *not* meet the
//requirement of infinite intermediate precision
BOOST_STATIC_WARNING((fma_issue_warning<Y>::value));
return v1 * v2 + v3;
}
#endif
template<class Y>
inline Y fmax BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
if((boost::math::isnan)(v1)) return(v2);
else if((boost::math::isnan)(v2)) return(v1);
else if(v1 > v2) return(v1);
else return(v2);
}
template<class Y>
inline Y fmin BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& v1,const Y& v2)
{
if((boost::math::isnan)(v1)) return(v2);
else if((boost::math::isnan)(v2)) return(v1);
else if(v1 < v2) return(v1);
else return(v2);
}
//template<class Y>
//inline long long llrint(const Y& val)
//{
// return static_cast<long long>(rint(val));
//}
//
//template<class Y>
//inline long long llround(const Y& val)
//{
// return static_cast<long long>(round(val));
//}
#if 0
template<class Y>
inline Y nearbyint(const Y& val)
{
//this is not really correct.
//the result should be according to the
//current rounding mode.
using boost::math::round;
return round(val);
}
template<class Y>
inline Y rint(const Y& val)
{
//I don't feel like trying to figure out
//how to raise a floating pointer exception
return nearbyint(val);
}
#endif
template<class Y>
inline Y trunc BOOST_PREVENT_MACRO_SUBSTITUTION(const Y& val)
{
if(val > 0) return std::floor(val);
else if(val < 0) return std::ceil(val);
else return val;
}
}
}
}
#endif // BOOST_UNITS_CMATH_IMPL_HPP

View File

@@ -0,0 +1,458 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2007-2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_CONVERSION_IMPL_HPP
#define BOOST_UNITS_DETAIL_CONVERSION_IMPL_HPP
#include <boost/mpl/bool.hpp>
#include <boost/mpl/and.hpp>
#include <boost/mpl/divides.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/units/heterogeneous_system.hpp>
#include <boost/units/homogeneous_system.hpp>
#include <boost/units/reduce_unit.hpp>
#include <boost/units/static_rational.hpp>
#include <boost/units/units_fwd.hpp>
#include <boost/units/detail/dimension_list.hpp>
#include <boost/units/detail/heterogeneous_conversion.hpp>
#include <boost/units/detail/one.hpp>
#include <boost/units/detail/static_rational_power.hpp>
#include <boost/units/detail/unscale.hpp>
#include <boost/units/units_fwd.hpp>
namespace boost {
namespace units {
namespace detail {
template<class Source, class Dest>
struct conversion_factor_helper;
template<class Source, class Dest>
struct call_base_unit_converter;
}
/// INTERNAL ONLY
struct undefined_base_unit_converter_base {
static const bool is_defined = false;
};
/// INTERNAL ONLY
struct no_default_conversion {
static const bool is_defined = false;
};
/// INTERNAL ONLY
template<class BaseUnit>
struct unscaled_get_default_conversion : no_default_conversion { };
/// INTERNAL ONLY
template<bool is_defined>
struct unscaled_get_default_conversion_impl;
/// INTERNAL ONLY
template<>
struct unscaled_get_default_conversion_impl<true>
{
template<class T>
struct apply
{
typedef typename unscaled_get_default_conversion<typename unscale<T>::type>::type type;
};
};
/// INTERNAL ONLY
template<>
struct unscaled_get_default_conversion_impl<false>
{
template<class T>
struct apply
{
typedef typename T::unit_type type;
};
};
/// INTERNAL ONLY
template<class BaseUnit>
struct get_default_conversion
{
typedef typename unscaled_get_default_conversion_impl<
unscaled_get_default_conversion<typename unscale<BaseUnit>::type>::is_defined
>::template apply<BaseUnit>::type type;
};
/// INTERNAL ONLY
template<class Source, class Destination>
struct select_base_unit_converter
{
typedef Source source_type;
typedef Destination destination_type;
};
/// INTERNAL ONLY
template<class Source, class Dest>
struct base_unit_converter_base : undefined_base_unit_converter_base {
};
/// INTERNAL ONLY
template<class Source>
struct base_unit_converter_base<Source, BOOST_UNITS_MAKE_HETEROGENEOUS_UNIT(Source, typename Source::dimension_type)>
{
static const bool is_defined = true;
typedef one type;
static type value() {
one result;
return(result);
}
};
/// INTERNAL ONLY
template<class Source, class Dest>
struct base_unit_converter : base_unit_converter_base<Source, Dest> { };
namespace detail {
template<class Source, class Dest>
struct do_call_base_unit_converter {
typedef select_base_unit_converter<typename unscale<Source>::type, typename unscale<Dest>::type> selector;
typedef typename selector::source_type source_type;
typedef typename selector::destination_type destination_type;
typedef base_unit_converter<source_type, destination_type> converter;
typedef typename mpl::divides<typename get_scale_list<Source>::type, typename get_scale_list<source_type>::type>::type source_factor;
typedef typename mpl::divides<typename get_scale_list<Dest>::type, typename get_scale_list<destination_type>::type>::type destination_factor;
typedef typename mpl::divides<source_factor, destination_factor>::type factor;
typedef eval_scale_list<factor> eval_factor;
typedef typename multiply_typeof_helper<typename converter::type, typename eval_factor::type>::type type;
static type value()
{
return(converter::value() * eval_factor::value());
}
};
template<bool forward_is_defined, bool reverse_is_defined>
struct call_base_unit_converter_base_unit_impl;
template<>
struct call_base_unit_converter_base_unit_impl<true, true>
{
template<class Source, class Dest>
struct apply
: do_call_base_unit_converter<Source, typename Dest::unit_type>
{
};
};
template<>
struct call_base_unit_converter_base_unit_impl<true, false>
{
template<class Source, class Dest>
struct apply
: do_call_base_unit_converter<Source, typename Dest::unit_type>
{
};
};
template<>
struct call_base_unit_converter_base_unit_impl<false, true>
{
template<class Source, class Dest>
struct apply
{
typedef do_call_base_unit_converter<Dest, typename Source::unit_type> converter;
typedef typename divide_typeof_helper<one, typename converter::type>::type type;
static type value() {
one numerator;
return(numerator / converter::value());
}
};
};
template<>
struct call_base_unit_converter_base_unit_impl<false, false>
{
template<class Source, class Dest>
struct apply
{
typedef typename reduce_unit<typename get_default_conversion<Source>::type>::type new_source;
typedef typename reduce_unit<typename get_default_conversion<Dest>::type>::type new_dest;
typedef call_base_unit_converter<Source, new_source> start;
typedef detail::conversion_factor_helper<
new_source,
new_dest
> conversion;
typedef call_base_unit_converter<Dest, new_dest> end;
typedef typename divide_typeof_helper<
typename multiply_typeof_helper<
typename start::type,
typename conversion::type
>::type,
typename end::type
>::type type;
static type value() {
return(start::value() * conversion::value() / end::value());
}
};
};
template<int N>
struct get_default_conversion_impl
{
template<class Begin>
struct apply
{
typedef typename Begin::item source_pair;
typedef typename source_pair::value_type exponent;
typedef typename source_pair::tag_type source;
typedef typename reduce_unit<typename get_default_conversion<source>::type>::type new_source;
typedef typename get_default_conversion_impl<N-1>::template apply<typename Begin::next> next_iteration;
typedef typename multiply_typeof_helper<typename power_typeof_helper<new_source, exponent>::type, typename next_iteration::unit_type>::type unit_type;
typedef call_base_unit_converter<source, new_source> conversion;
typedef typename multiply_typeof_helper<typename conversion::type, typename next_iteration::type>::type type;
static type value() {
return(static_rational_power<exponent>(conversion::value()) * next_iteration::value());
}
};
};
template<>
struct get_default_conversion_impl<0>
{
template<class Begin>
struct apply
{
typedef unit<dimensionless_type, heterogeneous_system<heterogeneous_system_impl<dimensionless_type, dimensionless_type, no_scale> > > unit_type;
typedef one type;
static one value() {
one result;
return(result);
}
};
};
template<bool is_defined>
struct call_base_unit_converter_impl;
template<>
struct call_base_unit_converter_impl<true>
{
template<class Source, class Dest>
struct apply
: do_call_base_unit_converter<Source, Dest>
{
};
};
template<>
struct call_base_unit_converter_impl<false>
{
template<class Source, class Dest>
struct apply {
typedef typename reduce_unit<typename get_default_conversion<Source>::type>::type new_source;
typedef typename Dest::system_type::type system_list;
typedef typename get_default_conversion_impl<system_list::size::value>::template apply<system_list> impl;
typedef typename impl::unit_type new_dest;
typedef call_base_unit_converter<Source, new_source> start;
typedef conversion_factor_helper<new_source, new_dest> conversion;
typedef typename divide_typeof_helper<
typename multiply_typeof_helper<
typename start::type,
typename conversion::type
>::type,
typename impl::type
>::type type;
static type value() {
return(start::value() * conversion::value() / impl::value());
}
};
};
#define BOOST_UNITS_DETAIL_BASE_UNIT_CONVERTER_IS_DEFINED(Source, Dest)\
base_unit_converter<\
typename select_base_unit_converter<typename unscale<Source>::type, typename unscale<Dest>::type>::source_type,\
typename select_base_unit_converter<typename unscale<Source>::type, typename unscale<Dest>::type>::destination_type\
>::is_defined
template<class Source, class Dest>
struct call_base_unit_converter : call_base_unit_converter_impl<BOOST_UNITS_DETAIL_BASE_UNIT_CONVERTER_IS_DEFINED(Source, Dest)>::template apply<Source, Dest>
{
};
template<class Source, class Dest>
struct call_base_unit_converter<Source, BOOST_UNITS_MAKE_HETEROGENEOUS_UNIT(Dest, typename Source::dimension_type)> :
call_base_unit_converter_base_unit_impl<
BOOST_UNITS_DETAIL_BASE_UNIT_CONVERTER_IS_DEFINED(Source, typename Dest::unit_type),
BOOST_UNITS_DETAIL_BASE_UNIT_CONVERTER_IS_DEFINED(Dest, typename Source::unit_type)
>::template apply<Source, Dest>
{
};
template<int N>
struct conversion_impl
{
template<class Begin, class DestinationSystem>
struct apply
{
typedef typename conversion_impl<N-1>::template apply<
typename Begin::next,
DestinationSystem
> next_iteration;
typedef typename Begin::item unit_pair;
typedef typename unit_pair::tag_type unit;
typedef typename unit::dimension_type dimensions;
typedef typename reduce_unit<units::unit<dimensions, DestinationSystem> >::type reduced_unit;
typedef detail::call_base_unit_converter<unit, reduced_unit> converter;
typedef typename multiply_typeof_helper<typename converter::type, typename next_iteration::type>::type type;
static type value() { return(static_rational_power<typename unit_pair::value_type>(converter::value()) * next_iteration::value()); }
};
};
template<>
struct conversion_impl<0>
{
template<class Begin, class DestinationSystem>
struct apply
{
typedef one type;
static type value() { one result; return(result); }
};
};
} // namespace detail
/// forward to conversion_factor (intentionally allowing ADL)
/// INTERNAL ONLY
template<class Unit1, class T1, class Unit2, class T2>
struct conversion_helper<quantity<Unit1, T1>, quantity<Unit2, T2> >
{
/// INTERNAL ONLY
typedef quantity<Unit2, T2> destination_type;
static destination_type convert(const quantity<Unit1, T1>& source)
{
Unit1 u1;
Unit2 u2;
return(destination_type::from_value(static_cast<T2>(source.value() * conversion_factor(u1, u2))));
}
};
namespace detail {
template<class Source, class Dest>
struct conversion_factor_helper;
template<class D, class L1, class L2>
struct conversion_factor_helper<unit<D, homogeneous_system<L1> >, unit<D, homogeneous_system<L2> > >
: conversion_factor_helper<
typename reduce_unit<unit<D, homogeneous_system<L1> > >::type,
typename reduce_unit<unit<D, homogeneous_system<L2> > >::type
>
{
//typedef typename reduce_unit<unit<D, homogeneous_system<L1> > >::type source_unit;
//typedef typename source_unit::system_type::type unit_list;
//typedef typename detail::conversion_impl<unit_list::size::value>::template apply<
// unit_list,
// homogeneous_system<L2>
//> impl;
//typedef typename impl::type type;
//static type value()
//{
// return(impl::value());
//}
};
template<class D, class L1, class L2>
struct conversion_factor_helper<unit<D, heterogeneous_system<L1> >, unit<D, homogeneous_system<L2> > >
: conversion_factor_helper<
typename reduce_unit<unit<D, heterogeneous_system<L1> > >::type,
typename reduce_unit<unit<D, homogeneous_system<L2> > >::type
>
{
//typedef typename detail::conversion_impl<L1::type::size::value>::template apply<
// typename L1::type,
// homogeneous_system<L2>
//> impl;
//typedef eval_scale_list<typename L1::scale> scale;
//typedef typename multiply_typeof_helper<typename impl::type, typename scale::type>::type type;
//static type value()
//{
// return(impl::value() * scale::value());
//}
};
// There is no simple algorithm for doing this conversion
// other than just defining it as the reverse of the
// heterogeneous->homogeneous case
template<class D, class L1, class L2>
struct conversion_factor_helper<unit<D, homogeneous_system<L1> >, unit<D, heterogeneous_system<L2> > >
: conversion_factor_helper<
typename reduce_unit<unit<D, homogeneous_system<L1> > >::type,
typename reduce_unit<unit<D, heterogeneous_system<L2> > >::type
>
{
//typedef typename detail::conversion_impl<L2::type::size::value>::template apply<
// typename L2::type,
// homogeneous_system<L1>
//> impl;
//typedef eval_scale_list<typename L2::scale> scale;
//typedef typename multiply_typeof_helper<typename impl::type, typename scale::type>::type type;
//static type value()
//{
// one numerator;
// return(numerator / (impl::value() * scale::value()));
//}
};
/// Requires that all possible conversions
/// between base units are defined.
template<class D, class S1, class S2>
struct conversion_factor_helper<unit<D, heterogeneous_system<S1> >, unit<D, heterogeneous_system<S2> > >
{
/// INTERNAL ONLY
typedef typename detail::extract_base_units<S1::type::size::value>::template apply<
typename S1::type,
dimensionless_type
>::type from_base_units;
/// INTERNAL ONLY
typedef typename detail::extract_base_units<S2::type::size::value>::template apply<
typename S2::type,
from_base_units
>::type all_base_units;
/// INTERNAL ONLY
typedef typename detail::make_homogeneous_system<all_base_units>::type system;
typedef typename detail::conversion_impl<S1::type::size::value>::template apply<
typename S1::type,
system
> conversion1;
typedef typename detail::conversion_impl<S2::type::size::value>::template apply<
typename S2::type,
system
> conversion2;
typedef eval_scale_list<typename mpl::divides<typename S1::scale, typename S2::scale>::type> scale;
typedef typename multiply_typeof_helper<
typename conversion1::type,
typename divide_typeof_helper<typename scale::type, typename conversion2::type>::type
>::type type;
static type value()
{
return(conversion1::value() * (scale::value() / conversion2::value()));
}
};
} // namespace detail
} // namespace units
} // namespace boost
#endif // BOOST_UNITS_CONVERSION_IMPL_HPP

View File

@@ -0,0 +1,90 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DIM_IMPL_HPP
#define BOOST_UNITS_DIM_IMPL_HPP
#include <boost/mpl/bool.hpp>
#include <boost/mpl/less.hpp>
#include <boost/units/units_fwd.hpp>
/// \file
/// \brief Class encapsulating a dimension tag/value pair
namespace boost {
namespace units {
namespace detail {
struct dim_tag;
}
}
namespace mpl {
/// Less than comparison for sorting @c dim.
template<>
struct less_impl<boost::units::detail::dim_tag, boost::units::detail::dim_tag>
{
template<class T0, class T1>
struct apply : mpl::less<typename T0::tag_type, typename T1::tag_type> {};
};
}
namespace units {
template<class Tag, class Exponent>
struct dim;
template<long N, long D>
class static_rational;
namespace detail {
/// Extract @c tag_type from a @c dim.
template<typename T>
struct get_tag
{
typedef typename T::tag_type type;
};
/// Extract @c value_type from a @c dim.
template<typename T>
struct get_value
{
typedef typename T::value_type type;
};
/// Determine if a @c dim is empty (has a zero exponent).
template<class T>
struct is_empty_dim;
template<typename T>
struct is_empty_dim< dim<T, static_rational<0, 1> > > :
mpl::true_
{ };
template<typename T, typename V>
struct is_empty_dim< dim<T, V> > :
mpl::false_
{ };
} // namespace detail
} // namespace units
} // namespace boost
#endif // BOOST_UNITS_DIM_IMPL_HPP

View File

@@ -0,0 +1,347 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DIMENSION_IMPL_HPP
#define BOOST_UNITS_DIMENSION_IMPL_HPP
#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/list.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/less.hpp>
#include <boost/units/config.hpp>
#include <boost/units/dimensionless_type.hpp>
#include <boost/units/static_rational.hpp>
#include <boost/units/units_fwd.hpp>
#include <boost/units/detail/dimension_list.hpp>
#include <boost/units/detail/push_front_if.hpp>
#include <boost/units/detail/push_front_or_add.hpp>
/// \file
/// \brief Core class and metaprogramming utilities for compile-time dimensional analysis.
namespace boost {
namespace units {
namespace detail {
template<int N>
struct insertion_sort_dims_insert;
template<bool is_greater>
struct insertion_sort_dims_comparison_impl;
// have to recursively add the element to the next sequence.
template<>
struct insertion_sort_dims_comparison_impl<true> {
template<class Begin, int N, class T>
struct apply {
typedef list<
typename Begin::item,
typename insertion_sort_dims_insert<N - 1>::template apply<
typename Begin::next,
T
>::type
> type;
};
};
// either prepend the current element or join it to
// the first remaining element of the sequence.
template<>
struct insertion_sort_dims_comparison_impl<false> {
template<class Begin, int N, class T>
struct apply {
typedef typename push_front_or_add<Begin, T>::type type;
};
};
template<int N>
struct insertion_sort_dims_insert {
template<class Begin, class T>
struct apply {
typedef typename insertion_sort_dims_comparison_impl<mpl::less<typename Begin::item, T>::value>::template apply<
Begin,
N,
T
>::type type;
};
};
template<>
struct insertion_sort_dims_insert<0> {
template<class Begin, class T>
struct apply {
typedef list<T, dimensionless_type> type;
};
};
template<int N>
struct insertion_sort_dims_mpl_sequence {
template<class Begin>
struct apply {
typedef typename insertion_sort_dims_mpl_sequence<N - 1>::template apply<typename mpl::next<Begin>::type>::type next;
typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply<next, typename mpl::deref<Begin>::type>::type type;
};
};
template<>
struct insertion_sort_dims_mpl_sequence<0> {
template<class Begin>
struct apply {
typedef dimensionless_type type;
};
};
template<int N>
struct insertion_sort_dims_impl {
template<class Begin>
struct apply {
typedef typename insertion_sort_dims_impl<N - 1>::template apply<typename Begin::next>::type next;
typedef typename insertion_sort_dims_insert<(next::size::value)>::template apply<next, typename Begin::item>::type type;
};
};
template<>
struct insertion_sort_dims_impl<0> {
template<class Begin>
struct apply {
typedef dimensionless_type type;
};
};
template<class T>
struct sort_dims
{
typedef typename insertion_sort_dims_mpl_sequence<mpl::size<T>::value>::template apply<typename mpl::begin<T>::type>::type type;
};
template<class T, class Next>
struct sort_dims<list<T, Next> >
{
typedef typename insertion_sort_dims_impl<list<T, Next>::size::value>::template apply<list<T, Next> >::type type;
};
/// sorted sequences can be merged in linear time
template<bool less, bool greater>
struct merge_dimensions_func;
template<int N1, int N2>
struct merge_dimensions_impl;
template<>
struct merge_dimensions_func<true, false>
{
template<typename Begin1, typename Begin2, int N1, int N2>
struct apply
{
typedef list<
typename Begin1::item,
typename merge_dimensions_impl<N1 - 1, N2>::template apply<
typename Begin1::next,
Begin2
>::type
> type;
};
};
template<>
struct merge_dimensions_func<false, true> {
template<typename Begin1, typename Begin2, int N1, int N2>
struct apply
{
typedef list<
typename Begin2::item,
typename merge_dimensions_impl<N2 - 1, N1>::template apply<
typename Begin2::next,
Begin1
>::type
> type;
};
};
template<>
struct merge_dimensions_func<false, false> {
template<typename Begin1, typename Begin2, int N1, int N2>
struct apply
{
typedef typename mpl::plus<typename Begin1::item, typename Begin2::item>::type combined;
typedef typename push_front_if<!is_empty_dim<combined>::value>::template apply<
typename merge_dimensions_impl<N1 - 1, N2 - 1>::template apply<
typename Begin1::next,
typename Begin2::next
>::type,
combined
>::type type;
};
};
template<int N1, int N2>
struct merge_dimensions_impl {
template<typename Begin1, typename Begin2>
struct apply
{
typedef typename Begin1::item dim1;
typedef typename Begin2::item dim2;
typedef typename merge_dimensions_func<(mpl::less<dim1,dim2>::value == true),
(mpl::less<dim2,dim1>::value == true)>::template apply<
Begin1,
Begin2,
N1,
N2
>::type type;
};
};
template<typename Sequence1, typename Sequence2>
struct merge_dimensions
{
typedef typename detail::merge_dimensions_impl<Sequence1::size::value,
Sequence2::size::value>::template
apply<
Sequence1,
Sequence2
>::type type;
};
template<int N>
struct iterator_to_list
{
template<typename Begin>
struct apply
{
typedef list<
typename Begin::item,
typename iterator_to_list<N - 1>::template apply<
typename Begin::next
>::type
> type;
};
};
template<>
struct iterator_to_list<0>
{
template<typename Begin>
struct apply {
typedef dimensionless_type type;
};
};
template<int N>
struct merge_dimensions_impl<N, 0>
{
template<typename Begin1, typename Begin2>
struct apply
{
typedef typename iterator_to_list<N>::template apply<Begin1>::type type;
};
};
template<int N>
struct merge_dimensions_impl<0, N>
{
template<typename Begin1, typename Begin2>
struct apply
{
typedef typename iterator_to_list<N>::template apply<Begin2>::type type;
};
};
template<>
struct merge_dimensions_impl<0, 0>
{
template<typename Begin1, typename Begin2>
struct apply
{
typedef dimensionless_type type;
};
};
template<int N>
struct static_inverse_impl
{
template<typename Begin>
struct apply {
typedef list<
typename mpl::negate<typename Begin::item>::type,
typename static_inverse_impl<N - 1>::template apply<
typename Begin::next
>::type
> type;
};
};
template<>
struct static_inverse_impl<0>
{
template<typename Begin>
struct apply
{
typedef dimensionless_type type;
};
};
template<int N>
struct static_power_impl
{
template<typename Begin, typename Ex>
struct apply
{
typedef list<
typename mpl::times<typename Begin::item, Ex>::type,
typename detail::static_power_impl<N - 1>::template apply<typename Begin::next, Ex>::type
> type;
};
};
template<>
struct static_power_impl<0>
{
template<typename Begin, typename Ex>
struct apply
{
typedef dimensionless_type type;
};
};
template<int N>
struct static_root_impl {
template<class Begin, class Ex>
struct apply {
typedef list<
typename mpl::divides<typename Begin::item, Ex>::type,
typename detail::static_root_impl<N - 1>::template apply<typename Begin::next, Ex>::type
> type;
};
};
template<>
struct static_root_impl<0> {
template<class Begin, class Ex>
struct apply
{
typedef dimensionless_type type;
};
};
} // namespace detail
} // namespace units
} // namespace boost
#endif // BOOST_UNITS_DIMENSION_IMPL_HPP

View File

@@ -0,0 +1,133 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DIMENSION_LIST_HPP
#define BOOST_UNITS_DIMENSION_LIST_HPP
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/push_front_fwd.hpp>
#include <boost/mpl/pop_front_fwd.hpp>
#include <boost/mpl/size_fwd.hpp>
#include <boost/mpl/begin_end_fwd.hpp>
#include <boost/mpl/front_fwd.hpp>
#include <boost/units/config.hpp>
namespace boost {
namespace units {
struct dimensionless_type;
namespace detail {
struct dimension_list_tag { };
} // namespace detail
template<class Item, class Next>
struct list
{
typedef detail::dimension_list_tag tag;
typedef list type;
typedef Item item;
typedef Next next;
typedef typename mpl::next<typename Next::size>::type size;
};
} // namespace units
namespace mpl {
// INTERNAL ONLY
template<>
struct size_impl<units::detail::dimension_list_tag>
{
template<class L> struct apply : public L::size { };
};
// INTERNAL ONLY
template<>
struct begin_impl<units::detail::dimension_list_tag>
{
template<class L>
struct apply
{
typedef L type;
};
};
// INTERNAL ONLY
template<>
struct end_impl<units::detail::dimension_list_tag>
{
template<class L>
struct apply
{
typedef units::dimensionless_type type;
};
};
// INTERNAL ONLY
template<>
struct push_front_impl<units::detail::dimension_list_tag>
{
template<class L, class T>
struct apply
{
typedef units::list<T, L> type;
};
};
// INTERNAL ONLY
template<>
struct pop_front_impl<units::detail::dimension_list_tag>
{
template<class L>
struct apply
{
typedef typename L::next type;
};
};
// INTERNAL ONLY
template<>
struct front_impl<units::detail::dimension_list_tag>
{
template<class L>
struct apply
{
typedef typename L::item type;
};
};
// INTERNAL ONLY
template<class Item, class Next>
struct deref<units::list<Item, Next> >
{
typedef Item type;
};
} // namespace mpl
} // namespace boost
#if BOOST_UNITS_HAS_BOOST_TYPEOF
#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
BOOST_TYPEOF_REGISTER_TEMPLATE(boost::units::list, 2)
#endif
#include <boost/units/dimensionless_type.hpp>
#endif // BOOST_UNITS_DIMENSION_LIST_HPP

View File

@@ -0,0 +1,88 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2007-2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_DIMENSIONLESS_UNIT_HPP
#define BOOST_UNITS_DETAIL_DIMENSIONLESS_UNIT_HPP
#include <boost/mpl/bool.hpp>
#include <boost/units/units_fwd.hpp>
namespace boost {
namespace units {
template<class T>
struct heterogeneous_system;
template<class T>
struct homogeneous_system;
template<class T1, class T2, class Scale>
struct heterogeneous_system_impl;
typedef boost::units::heterogeneous_system<
boost::units::heterogeneous_system_impl<
boost::units::dimensionless_type,
boost::units::dimensionless_type,
boost::units::dimensionless_type
>
> heterogeneous_dimensionless_system;
namespace detail {
template<class System>
struct void_if_dimensionless {
typedef int type;
};
template<class T>
struct void_if_dimensionless<boost::units::homogeneous_system<T> > {
typedef void type;
};
template<>
struct void_if_dimensionless<heterogeneous_dimensionless_system> {
typedef void type;
};
template<class System, class Test = void>
struct void_if_heterogeneous {
typedef void type;
};
template<class System>
struct void_if_heterogeneous<System, typename void_if_dimensionless<System>::type> {
typedef int type;
};
template<class System, class Enable=void>
struct is_dimensionless_system : mpl::false_ {};
template<class System>
struct is_dimensionless_system<System, typename void_if_dimensionless<System>::type> : mpl::true_ {};
#define BOOST_UNITS_DIMENSIONLESS_UNIT(T)\
boost::units::unit<\
boost::units::dimensionless_type,\
T,\
typename ::boost::units::detail::void_if_dimensionless<T>::type\
>
#define BOOST_UNITS_HETEROGENEOUS_DIMENSIONLESS_UNIT(T)\
boost::units::unit<\
boost::units::dimensionless_type,\
T,\
typename ::boost::units::detail::void_if_heterogeneous<T>::type\
>
}
}
}
#endif

View File

@@ -0,0 +1,309 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_HETEROGENEOUS_CONVERSION_HPP
#define BOOST_UNITS_DETAIL_HETEROGENEOUS_CONVERSION_HPP
#include <boost/mpl/minus.hpp>
#include <boost/mpl/times.hpp>
#include <boost/units/static_rational.hpp>
#include <boost/units/homogeneous_system.hpp>
#include <boost/units/detail/linear_algebra.hpp>
namespace boost {
namespace units {
namespace detail {
struct solve_end {
template<class Begin, class Y>
struct apply {
typedef dimensionless_type type;
};
};
struct no_solution {};
template<class X1, class X2, class Next>
struct solve_normal {
template<class Begin, class Y>
struct apply {
typedef typename Begin::next next;
typedef list<
typename mpl::minus<
typename mpl::times<X1, Y>::type,
typename mpl::times<X2, typename Begin::item>::type
>::type,
typename Next::template apply<next, Y>::type
> type;
};
};
template<class Next>
struct solve_leading_zeroes {
template<class Begin>
struct apply {
typedef list<
typename Begin::item,
typename Next::template apply<typename Begin::next>::type
> type;
};
typedef solve_leading_zeroes type;
};
template<>
struct solve_leading_zeroes<no_solution> {
typedef no_solution type;
};
template<class Next>
struct solve_first_non_zero {
template<class Begin>
struct apply {
typedef typename Next::template apply<
typename Begin::next,
typename Begin::item
>::type type;
};
};
template<class Next>
struct solve_internal_zero {
template<class Begin, class Y>
struct apply {
typedef list<
typename Begin::item,
typename Next::template apply<typename Begin::next, Y>::type
> type;
};
};
template<class T>
struct make_solve_list_internal_zero {
template<class Next, class X>
struct apply {
typedef solve_normal<T, X, Next> type;
};
};
template<>
struct make_solve_list_internal_zero<static_rational<0> > {
template<class Next, class X>
struct apply {
typedef solve_internal_zero<Next> type;
};
};
template<int N>
struct make_solve_list_normal {
template<class Begin, class X>
struct apply {
typedef typename make_solve_list_internal_zero<
typename Begin::item
>::template apply<
typename make_solve_list_normal<N-1>::template apply<typename Begin::next, X>::type,
X
>::type type;
};
};
template<>
struct make_solve_list_normal<0> {
template<class Begin, class X>
struct apply {
typedef solve_end type;
};
};
template<int N>
struct make_solve_list_leading_zeroes;
template<class T>
struct make_solve_list_first_non_zero {
template<class Begin, int N>
struct apply {
typedef solve_first_non_zero<
typename make_solve_list_normal<N-1>::template apply<
typename Begin::next,
typename Begin::item
>::type
> type;
};
};
template<>
struct make_solve_list_first_non_zero<static_rational<0> > {
template<class Begin, int N>
struct apply {
typedef typename solve_leading_zeroes<
typename make_solve_list_leading_zeroes<N-1>::template apply<
typename Begin::next
>::type
>::type type;
};
};
template<int N>
struct make_solve_list_leading_zeroes {
template<class Begin>
struct apply {
typedef typename make_solve_list_first_non_zero<typename Begin::item>::template apply<Begin, N>::type type;
};
};
template<>
struct make_solve_list_leading_zeroes<0> {
template<class Begin>
struct apply {
typedef no_solution type;
};
};
template<int N>
struct try_add_unit_impl {
template<class Begin, class L>
struct apply {
typedef typename try_add_unit_impl<N-1>::template apply<typename Begin::next, L>::type next;
typedef typename Begin::item::template apply<next>::type type;
BOOST_STATIC_ASSERT((next::size::value - 1 == type::size::value));
};
};
template<>
struct try_add_unit_impl<0> {
template<class Begin, class L>
struct apply {
typedef L type;
};
};
template<int N>
struct make_homogeneous_system_impl;
template<class T, bool is_done>
struct make_homogeneous_system_func;
template<class T>
struct make_homogeneous_system_func<T, false> {
template<class Begin, class Current, class Units, class Dimensions, int N>
struct apply {
typedef typename make_homogeneous_system_impl<N-1>::template apply<
typename Begin::next,
list<T, Current>,
list<typename Begin::item, Units>,
Dimensions
>::type type;
};
};
template<class T>
struct make_homogeneous_system_func<T, true> {
template<class Begin, class Current, class Units, class Dimensions, int N>
struct apply {
typedef list<typename Begin::item, Units> type;
};
};
template<>
struct make_homogeneous_system_func<no_solution, false> {
template<class Begin, class Current, class Units, class Dimensions, int N>
struct apply {
typedef typename make_homogeneous_system_impl<N-1>::template apply<
typename Begin::next,
Current,
Units,
Dimensions
>::type type;
};
};
template<>
struct make_homogeneous_system_func<no_solution, true> {
template<class Begin, class Current, class Units, class Dimensions, int N>
struct apply {
typedef typename make_homogeneous_system_impl<N-1>::template apply<
typename Begin::next,
Current,
Units,
Dimensions
>::type type;
};
};
template<int N>
struct make_homogeneous_system_impl {
template<class Begin, class Current, class Units, class Dimensions>
struct apply {
typedef typename expand_dimensions<Dimensions::size::value>::template apply<
Dimensions,
typename Begin::item::dimension_type
>::type dimensions;
typedef typename try_add_unit_impl<Current::size::value>::template apply<Current, dimensions>::type new_element;
typedef typename make_solve_list_leading_zeroes<new_element::size::value>::template apply<new_element>::type new_func;
typedef typename make_homogeneous_system_func<
new_func,
((Current::size::value)+1) == (Dimensions::size::value)
>::template apply<Begin, Current, Units, Dimensions, N>::type type;
};
};
template<>
struct make_homogeneous_system_impl<0> {
template<class Begin, class Current, class Units, class Dimensions>
struct apply {
typedef Units type;
};
};
template<class Units>
struct make_homogeneous_system {
typedef typename find_base_dimensions<Units>::type base_dimensions;
typedef homogeneous_system<
typename insertion_sort<
typename make_homogeneous_system_impl<
Units::size::value
>::template apply<
Units,
dimensionless_type,
dimensionless_type,
base_dimensions
>::type
>::type
> type;
};
template<int N>
struct extract_base_units {
template<class Begin, class T>
struct apply {
typedef list<
typename Begin::item::tag_type,
typename extract_base_units<N-1>::template apply<typename Begin::next, T>::type
> type;
};
};
template<>
struct extract_base_units<0> {
template<class Begin, class T>
struct apply {
typedef T type;
};
};
}
}
}
#endif

File diff suppressed because it is too large Load Diff

109
test/external/boost/units/detail/one.hpp vendored Normal file
View File

@@ -0,0 +1,109 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_ONE_HPP
#define BOOST_UNITS_DETAIL_ONE_HPP
#include <boost/units/operators.hpp>
namespace boost {
namespace units {
struct one { one() {} };
// workaround for pathscale.
inline one make_one() {
one result;
return(result);
}
template<class T>
struct multiply_typeof_helper<one, T>
{
typedef T type;
};
template<class T>
struct multiply_typeof_helper<T, one>
{
typedef T type;
};
template<>
struct multiply_typeof_helper<one, one>
{
typedef one type;
};
template<class T>
inline T operator*(const one&, const T& t)
{
return(t);
}
template<class T>
inline T operator*(const T& t, const one&)
{
return(t);
}
inline one operator*(const one&, const one&)
{
one result;
return(result);
}
template<class T>
struct divide_typeof_helper<T, one>
{
typedef T type;
};
template<class T>
struct divide_typeof_helper<one, T>
{
typedef T type;
};
template<>
struct divide_typeof_helper<one, one>
{
typedef one type;
};
template<class T>
inline T operator/(const T& t, const one&)
{
return(t);
}
template<class T>
inline T operator/(const one&, const T& t)
{
return(1/t);
}
inline one operator/(const one&, const one&)
{
one result;
return(result);
}
template<class T>
inline bool operator>(const boost::units::one&, const T& t) {
return(1 > t);
}
} // namespace units
} // namespace boost
#endif

View File

@@ -0,0 +1,49 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2007-2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_ORDINAL_HPP_INCLUDED
#define BOOST_UNITS_DETAIL_ORDINAL_HPP_INCLUDED
#include <boost/mpl/less.hpp>
#include <boost/mpl/bool.hpp>
namespace boost {
namespace units {
namespace detail {
struct ordinal_tag {};
}
template<int N>
struct ordinal {
typedef detail::ordinal_tag tag;
static const long value = N;
};
template<int N>
const long ordinal<N>::value;
}
namespace mpl {
template<>
struct less_impl<units::detail::ordinal_tag, units::detail::ordinal_tag> {
template<class T1, class T2>
struct apply : bool_<(T1::value) < (T2::value)> {};
};
}
}
#endif

View File

@@ -0,0 +1,54 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2007-2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_PREVENT_REDEFINITION_HPP
#define BOOST_UNITS_DETAIL_PREVENT_REDEFINITION_HPP
#include <boost/mpl/long.hpp>
namespace boost {
namespace units {
namespace detail {
struct no { no() {} char dummy; };
struct yes { no dummy[2]; };
template<bool> struct ordinal_has_already_been_defined;
template<>
struct ordinal_has_already_been_defined<true> { };
template<>
struct ordinal_has_already_been_defined<false> { typedef void type; };
}
/// This must be in namespace boost::units so that ADL
/// will work. we need a mangled name because it must
/// be found by ADL
/// INTERNAL ONLY
template<class T>
detail::no
boost_units_is_registered(const T&)
{ detail::no result; return(result); }
/// INTERNAL ONLY
template<class T>
detail::no
boost_units_unit_is_registered(const T&)
{ detail::no result; return(result); }
} // namespace units
} // namespace boost
#endif // BOOST_UNITS_PREVENT_ORDINAL_REDEFINITION_IMPL_HPP

View File

@@ -0,0 +1,48 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_PUSH_FRONT_IF_HPP
#define BOOST_UNITS_DETAIL_PUSH_FRONT_IF_HPP
namespace boost {
namespace units {
template<class T, class Next>
struct list;
namespace detail {
template<bool>
struct push_front_if;
template<>
struct push_front_if<true> {
template<class L, class T>
struct apply {
typedef list<T, L> type;
};
};
template<>
struct push_front_if<false> {
template<class L, class T>
struct apply {
typedef L type;
};
};
}
}
}
#endif

View File

@@ -0,0 +1,84 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_PUSH_FRONT_OR_ADD_HPP
#define BOOST_UNITS_DETAIL_PUSH_FRONT_OR_ADD_HPP
#include <boost/mpl/plus.hpp>
#include <boost/mpl/front.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/pop_front.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/units/units_fwd.hpp>
#include <boost/units/detail/push_front_if.hpp>
namespace boost {
namespace units {
template<class Item, class Next>
struct list;
namespace detail {
template<class T>
struct is_empty_dim;
/// add an instantiation of dim to Sequence.
template<bool>
struct push_front_or_add_impl;
template<>
struct push_front_or_add_impl<true>
{
template<typename Sequence, typename T>
struct apply
{
typedef typename mpl::plus<T, typename Sequence::item>::type item;
typedef typename push_front_if<!is_empty_dim<item>::value>::template apply<
typename Sequence::next,
item
> type;
};
};
template<>
struct push_front_or_add_impl<false>
{
template<typename Sequence, typename T>
struct apply
{
typedef list<T, Sequence> type;
};
};
template<typename Sequence, typename T>
struct push_front_or_add
{
typedef typename push_front_or_add_impl<boost::is_same<typename T::tag_type, typename Sequence::item::tag_type>::value>::template apply<
Sequence,
T
>::type type;
};
template<typename T>
struct push_front_or_add<dimensionless_type, T>
{
typedef list<T, dimensionless_type> type;
};
} // namespace detail
} // namespace units
} // namespace boost
#endif

View File

@@ -0,0 +1,109 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_SORT_HPP
#define BOOST_UNITS_DETAIL_SORT_HPP
#include <boost/mpl/size.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/push_front.hpp>
#include <boost/mpl/less.hpp>
#include <boost/units/dimensionless_type.hpp>
#include <boost/units/detail/dimension_list.hpp>
namespace boost {
namespace units {
namespace detail {
template<int N>
struct insertion_sort_insert;
template<bool is_greater>
struct insertion_sort_comparison_impl;
// have to recursively add the element to the next sequence.
template<>
struct insertion_sort_comparison_impl<true> {
template<class Begin, int N, class T>
struct apply {
typedef list<
typename Begin::item,
typename insertion_sort_insert<N - 1>::template apply<
typename Begin::next,
T
>::type
> type;
};
};
// prepend the current element
template<>
struct insertion_sort_comparison_impl<false> {
template<class Begin, int N, class T>
struct apply {
typedef list<T, Begin> type;
};
};
template<int N>
struct insertion_sort_insert {
template<class Begin, class T>
struct apply {
typedef typename insertion_sort_comparison_impl<mpl::less<typename Begin::item, T>::value>::template apply<
Begin,
N,
T
>::type type;
};
};
template<>
struct insertion_sort_insert<0> {
template<class Begin, class T>
struct apply {
typedef list<T, dimensionless_type> type;
};
};
template<int N>
struct insertion_sort_impl {
template<class Begin>
struct apply {
typedef typename insertion_sort_impl<N - 1>::template apply<typename Begin::next>::type next;
typedef typename insertion_sort_insert<(next::size::value)>::template apply<next, typename Begin::item>::type type;
};
};
template<>
struct insertion_sort_impl<0> {
template<class Begin>
struct apply {
typedef dimensionless_type type;
};
};
template<class T>
struct insertion_sort
{
typedef typename insertion_sort_impl<T::size::value>::template apply<T>::type type;
};
} // namespace detail
} // namespace units
} // namespace boost
#endif

View File

@@ -0,0 +1,206 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2007-2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_STATIC_RATIONAL_POWER_HPP
#define BOOST_UNITS_DETAIL_STATIC_RATIONAL_POWER_HPP
#include <boost/config/no_tr1/cmath.hpp>
#include <boost/units/detail/one.hpp>
#include <boost/units/operators.hpp>
namespace boost {
namespace units {
template<long N,long D>
class static_rational;
namespace detail {
namespace typeof_pow_adl_barrier {
using std::pow;
template<class Y>
struct typeof_pow
{
#if defined(BOOST_UNITS_HAS_BOOST_TYPEOF)
BOOST_TYPEOF_NESTED_TYPEDEF_TPL(nested, pow(typeof_::make<Y>(), 0.0))
typedef typename nested::type type;
#elif defined(BOOST_UNITS_HAS_MWERKS_TYPEOF)
typedef __typeof__(pow(typeof_::make<Y>(), 0.0)) type;
#elif defined(BOOST_UNITS_HAS_GNU_TYPEOF)
typedef typeof(pow(typeof_::make<Y>(), 0.0)) type;
#else
typedef Y type;
#endif
};
}
template<class R, class Y>
struct static_rational_power_impl
{
typedef typename typeof_pow_adl_barrier::typeof_pow<Y>::type type;
static type call(const Y& y)
{
using std::pow;
return(pow(y, static_cast<double>(R::Numerator) / static_cast<double>(R::Denominator)));
}
};
template<class R>
struct static_rational_power_impl<R, one>
{
typedef one type;
static one call(const one&)
{
one result;
return(result);
}
};
template<long N>
struct static_rational_power_impl<static_rational<N, 1>, one>
{
typedef one type;
static one call(const one&)
{
one result;
return(result);
}
};
template<long N, bool = (N % 2 == 0)>
struct static_int_power_impl;
template<long N>
struct static_int_power_impl<N, true>
{
template<class Y, class R>
struct apply
{
typedef typename multiply_typeof_helper<Y, Y>::type square_type;
typedef typename static_int_power_impl<(N >> 1)>::template apply<square_type, R> next;
typedef typename next::type type;
static type call(const Y& y, const R& r)
{
const Y square = y * y;
return(next::call(square, r));
}
};
};
template<long N>
struct static_int_power_impl<N, false>
{
template<class Y, class R>
struct apply
{
typedef typename multiply_typeof_helper<Y, Y>::type square_type;
typedef typename multiply_typeof_helper<Y, R>::type new_r;
typedef typename static_int_power_impl<(N >> 1)>::template apply<square_type, new_r> next;
typedef typename next::type type;
static type call(const Y& y, const R& r)
{
const Y square = y * y;
return(next::call(square, y * r));
}
};
};
template<>
struct static_int_power_impl<1, false>
{
template<class Y, class R>
struct apply
{
typedef typename multiply_typeof_helper<Y, R>::type type;
static type call(const Y& y, const R& r)
{
return(y * r);
}
};
};
template<>
struct static_int_power_impl<0, true>
{
template<class Y, class R>
struct apply
{
typedef R type;
static R call(const Y&, const R& r)
{
return(r);
}
};
};
template<int N, bool = (N < 0)>
struct static_int_power_sign_impl;
template<int N>
struct static_int_power_sign_impl<N, false>
{
template<class Y>
struct apply
{
typedef typename static_int_power_impl<N>::template apply<Y, one> impl;
typedef typename impl::type type;
static type call(const Y& y)
{
one result;
return(impl::call(y, result));
}
};
};
template<int N>
struct static_int_power_sign_impl<N, true>
{
template<class Y>
struct apply
{
typedef typename static_int_power_impl<-N>::template apply<Y, one> impl;
typedef typename divide_typeof_helper<one, typename impl::type>::type type;
static type call(const Y& y)
{
one result;
return(result/impl::call(y, result));
}
};
};
template<long N, class Y>
struct static_rational_power_impl<static_rational<N, 1>, Y>
{
typedef typename static_int_power_sign_impl<N>::template apply<Y> impl;
typedef typename impl::type type;
static Y call(const Y& y)
{
return(impl::call(y));
}
};
template<class R, class Y>
typename detail::static_rational_power_impl<R, Y>::type static_rational_power(const Y& y)
{
return(detail::static_rational_power_impl<R, Y>::call(y));
}
} // namespace detail
} // namespace units
} // namespace boost
#endif

View File

@@ -0,0 +1,234 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2007-2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_DETAIL_UNSCALE_HPP_INCLUDED
#define BOOST_UNITS_DETAIL_UNSCALE_HPP_INCLUDED
#include <string>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/size.hpp>
#include <boost/mpl/begin.hpp>
#include <boost/mpl/next.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/times.hpp>
#include <boost/mpl/negate.hpp>
#include <boost/mpl/less.hpp>
#include <boost/units/config.hpp>
#include <boost/units/dimension.hpp>
#include <boost/units/scale.hpp>
#include <boost/units/static_rational.hpp>
#include <boost/units/units_fwd.hpp>
#include <boost/units/detail/one.hpp>
namespace boost {
namespace units {
template<class T>
struct heterogeneous_system;
template<class T, class D, class Scale>
struct heterogeneous_system_impl;
template<class T, class E>
struct heterogeneous_system_dim;
template<class S, class Scale>
struct scaled_base_unit;
/// removes all scaling from a unit or a base unit.
template<class T>
struct unscale
{
#ifndef BOOST_UNITS_DOXYGEN
typedef T type;
#else
typedef detail::unspecified type;
#endif
};
/// INTERNAL ONLY
template<class S, class Scale>
struct unscale<scaled_base_unit<S, Scale> >
{
typedef typename unscale<S>::type type;
};
/// INTERNAL ONLY
template<class D, class S>
struct unscale<unit<D, S> >
{
typedef unit<D, typename unscale<S>::type> type;
};
/// INTERNAL ONLY
template<class Scale>
struct scale_list_dim;
/// INTERNAL ONLY
template<class T>
struct get_scale_list
{
typedef dimensionless_type type;
};
/// INTERNAL ONLY
template<class S, class Scale>
struct get_scale_list<scaled_base_unit<S, Scale> >
{
typedef typename mpl::times<list<scale_list_dim<Scale>, dimensionless_type>, typename get_scale_list<S>::type>::type type;
};
/// INTERNAL ONLY
template<class D, class S>
struct get_scale_list<unit<D, S> >
{
typedef typename get_scale_list<S>::type type;
};
/// INTERNAL ONLY
struct scale_dim_tag {};
/// INTERNAL ONLY
template<class Scale>
struct scale_list_dim : Scale
{
typedef scale_dim_tag tag;
typedef scale_list_dim type;
};
} // namespace units
#ifndef BOOST_UNITS_DOXYGEN
namespace mpl {
/// INTERNAL ONLY
template<>
struct less_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag>
{
template<class T0, class T1>
struct apply : mpl::bool_<((T0::base) < (T1::base))> {};
};
}
#endif
namespace units {
namespace detail {
template<class Scale>
struct is_empty_dim<scale_list_dim<Scale> > : mpl::false_ {};
template<long N>
struct is_empty_dim<scale_list_dim<scale<N, static_rational<0, 1> > > > : mpl::true_ {};
template<int N>
struct eval_scale_list_impl
{
template<class Begin>
struct apply
{
typedef typename eval_scale_list_impl<N-1>::template apply<typename Begin::next> next_iteration;
typedef typename multiply_typeof_helper<typename next_iteration::type, typename Begin::item::value_type>::type type;
static type value()
{
return(next_iteration::value() * Begin::item::value());
}
};
};
template<>
struct eval_scale_list_impl<0>
{
template<class Begin>
struct apply
{
typedef one type;
static one value()
{
one result;
return(result);
}
};
};
}
/// INTERNAL ONLY
template<class T>
struct eval_scale_list : detail::eval_scale_list_impl<T::size::value>::template apply<T> {};
} // namespace units
#ifndef BOOST_UNITS_DOXYGEN
namespace mpl {
/// INTERNAL ONLY
template<>
struct plus_impl<boost::units::scale_dim_tag, boost::units::scale_dim_tag>
{
template<class T0, class T1>
struct apply
{
typedef boost::units::scale_list_dim<
boost::units::scale<
(T0::base),
typename mpl::plus<typename T0::exponent, typename T1::exponent>::type
>
> type;
};
};
/// INTERNAL ONLY
template<>
struct negate_impl<boost::units::scale_dim_tag>
{
template<class T0>
struct apply
{
typedef boost::units::scale_list_dim<
boost::units::scale<
(T0::base),
typename mpl::negate<typename T0::exponent>::type
>
> type;
};
};
/// INTERNAL ONLY
template<>
struct times_impl<boost::units::scale_dim_tag, boost::units::detail::static_rational_tag>
{
template<class T0, class T1>
struct apply
{
typedef boost::units::scale_list_dim<
boost::units::scale<
(T0::base),
typename mpl::times<typename T0::exponent, T1>::type
>
> type;
};
};
} // namespace mpl
#endif
} // namespace boost
#endif

View File

@@ -0,0 +1,104 @@
// Boost.Units - A C++ library for zero-overhead dimensional analysis and
// unit/quantity manipulation and conversion
//
// Copyright (C) 2003-2008 Matthias Christian Schabel
// Copyright (C) 2008 Steven Watanabe
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#ifndef BOOST_UNITS_UTILITY_HPP
#define BOOST_UNITS_UTILITY_HPP
#include <cstdlib>
#include <typeinfo>
#include <string>
#if defined(__GLIBCXX__) || defined(__GLIBCPP__)
#define BOOST_UNITS_USE_DEMANGLING
#include <cxxabi.h>
#endif // __GNUC__
#ifdef BOOST_UNITS_USE_DEMANGLING
#include <boost/algorithm/string/replace.hpp>
namespace boost {
namespace units {
namespace detail {
inline
std::string
demangle(const char* name)
{
// need to demangle C++ symbols
char* realname;
std::size_t len;
int stat;
realname = abi::__cxa_demangle(name,NULL,&len,&stat);
if (realname != NULL)
{
std::string out(realname);
std::free(realname);
boost::replace_all(out,"boost::units::","");
return out;
}
return std::string("demangle :: error - unable to demangle specified symbol");
}
} // namespace detail
template<class L>
std::string simplify_typename(const L& /*source*/)
{
const std::string demangled = detail::demangle(typeid(L).name());
return demangled;
}
} // namespace units
} // namespace boost
#else // BOOST_UNITS_USE_DEMANGLING
namespace boost {
namespace units {
namespace detail {
inline
std::string
demangle(const char* name)
{
return name;
}
} // namespace detail
template<class L>
std::string simplify_typename(const L& /*source*/)
{
return std::string(typeid(L).name());
}
} // namespace units
} // namespace boost
// To get system-specific predefined macros:
// gcc -arch ppc -dM -E - < /dev/null | sort
#endif // BOOST_UNITS_USE_DEMANGLING
#endif // BOOST_UNITS_UTILITY_HPP