| // 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) |
| |
| /// \file |
| /// \brief base unit (meter, kg, sec...). |
| /// \details base unit definition registration. |
| |
| #ifndef BOOST_UNITS_BASE_UNIT_HPP |
| #define BOOST_UNITS_BASE_UNIT_HPP |
| |
| #include <boost/units/config.hpp> |
| #include <boost/units/heterogeneous_system.hpp> |
| #include <boost/units/static_rational.hpp> |
| #include <boost/units/units_fwd.hpp> |
| #include <boost/units/unit.hpp> |
| #include <boost/units/detail/dimension_list.hpp> |
| #include <boost/units/detail/ordinal.hpp> |
| #include <boost/units/detail/prevent_redefinition.hpp> |
| |
| namespace boost { |
| |
| namespace units { |
| |
| /// This must be in namespace boost::units so that ADL |
| /// will work with friend functions defined inline. |
| /// Base dimensions and base units are independent. |
| /// INTERNAL ONLY |
| template<long N> struct base_unit_ordinal { }; |
| |
| /// INTERNAL ONLY |
| template<class T, long N> struct base_unit_pair { }; |
| |
| /// INTERNAL ONLY |
| template<class T, long N> |
| struct check_base_unit { |
| enum { |
| value = |
| sizeof(boost_units_unit_is_registered(units::base_unit_ordinal<N>())) == sizeof(detail::yes) && |
| sizeof(boost_units_unit_is_registered(units::base_unit_pair<T, N>())) != sizeof(detail::yes) |
| }; |
| }; |
| |
| /// Defines a base unit. To define a unit you need to provide |
| /// the derived class (CRTP), a dimension list and a unique integer. |
| /// @code |
| /// struct my_unit : boost::units::base_unit<my_unit, length_dimension, 1> {}; |
| /// @endcode |
| /// It is designed so that you will get an error message if you try |
| /// to use the same value in multiple definitions. |
| template<class Derived, |
| class Dim, |
| long N |
| #if !defined(BOOST_UNITS_DOXYGEN) && !defined(__BORLANDC__) |
| , |
| class = typename detail::ordinal_has_already_been_defined< |
| check_base_unit<Derived, N>::value |
| >::type |
| #endif |
| > |
| class base_unit : |
| public ordinal<N> |
| { |
| public: |
| /// INTERNAL ONLY |
| typedef void boost_units_is_base_unit_type; |
| /// INTERNAL ONLY |
| typedef base_unit this_type; |
| /// The dimensions of this base unit. |
| typedef Dim dimension_type; |
| |
| /// Provided for mpl compatability. |
| typedef Derived type; |
| |
| /// The unit corresponding to this base unit. |
| #ifndef BOOST_UNITS_DOXYGEN |
| typedef unit< |
| Dim, |
| heterogeneous_system< |
| heterogeneous_system_impl< |
| list< |
| heterogeneous_system_dim<Derived,static_rational<1> >, |
| dimensionless_type |
| >, |
| Dim, |
| no_scale |
| > |
| > |
| > unit_type; |
| #else |
| typedef detail::unspecified unit_type; |
| #endif |
| |
| private: |
| /// Register this ordinal |
| /// INTERNAL ONLY |
| friend detail::yes |
| boost_units_unit_is_registered(const units::base_unit_ordinal<N>&) |
| { detail::yes result; return(result); } |
| |
| /// But make sure we can identify the current instantiation! |
| /// INTERNAL ONLY |
| friend detail::yes |
| boost_units_unit_is_registered(const units::base_unit_pair<Derived, N>&) |
| { detail::yes result; return(result); } |
| }; |
| |
| } // namespace units |
| |
| } // namespace boost |
| |
| #endif // BOOST_UNITS_BASE_UNIT_HPP |