]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // Boost.Units - A C++ library for zero-overhead dimensional analysis and |
2 | // unit/quantity manipulation and conversion | |
3 | // | |
4 | // Copyright (C) 2003-2008 Matthias Christian Schabel | |
5 | // Copyright (C) 2007-2008 Steven Watanabe | |
6 | // | |
7 | // Distributed under the Boost Software License, Version 1.0. (See | |
8 | // accompanying file LICENSE_1_0.txt or copy at | |
9 | // http://www.boost.org/LICENSE_1_0.txt) | |
10 | ||
11 | /// \file | |
12 | /// \brief base unit (meter, kg, sec...). | |
13 | /// \details base unit definition registration. | |
14 | ||
15 | #ifndef BOOST_UNITS_BASE_UNIT_HPP | |
16 | #define BOOST_UNITS_BASE_UNIT_HPP | |
17 | ||
18 | #include <boost/units/config.hpp> | |
19 | #include <boost/units/heterogeneous_system.hpp> | |
20 | #include <boost/units/static_rational.hpp> | |
21 | #include <boost/units/units_fwd.hpp> | |
22 | #include <boost/units/unit.hpp> | |
23 | #include <boost/units/detail/dimension_list.hpp> | |
24 | #include <boost/units/detail/ordinal.hpp> | |
25 | #include <boost/units/detail/prevent_redefinition.hpp> | |
26 | ||
27 | namespace boost { | |
28 | ||
29 | namespace units { | |
30 | ||
31 | /// This must be in namespace boost::units so that ADL | |
32 | /// will work with friend functions defined inline. | |
33 | /// Base dimensions and base units are independent. | |
34 | /// INTERNAL ONLY | |
35 | template<long N> struct base_unit_ordinal { }; | |
36 | ||
37 | /// INTERNAL ONLY | |
38 | template<class T, long N> struct base_unit_pair { }; | |
39 | ||
40 | /// INTERNAL ONLY | |
41 | template<class T, long N> | |
42 | struct check_base_unit { | |
43 | enum { | |
44 | value = | |
45 | sizeof(boost_units_unit_is_registered(units::base_unit_ordinal<N>())) == sizeof(detail::yes) && | |
46 | sizeof(boost_units_unit_is_registered(units::base_unit_pair<T, N>())) != sizeof(detail::yes) | |
47 | }; | |
48 | }; | |
49 | ||
50 | /// Defines a base unit. To define a unit you need to provide | |
51 | /// the derived class (CRTP), a dimension list and a unique integer. | |
52 | /// @code | |
53 | /// struct my_unit : boost::units::base_unit<my_unit, length_dimension, 1> {}; | |
54 | /// @endcode | |
55 | /// It is designed so that you will get an error message if you try | |
56 | /// to use the same value in multiple definitions. | |
57 | template<class Derived, | |
58 | class Dim, | |
59 | long N | |
60 | #if !defined(BOOST_UNITS_DOXYGEN) && !defined(__BORLANDC__) | |
61 | , | |
62 | class = typename detail::ordinal_has_already_been_defined< | |
63 | check_base_unit<Derived, N>::value | |
64 | >::type | |
65 | #endif | |
66 | > | |
67 | class base_unit : | |
68 | public ordinal<N> | |
69 | { | |
70 | public: | |
71 | /// INTERNAL ONLY | |
72 | typedef void boost_units_is_base_unit_type; | |
73 | /// INTERNAL ONLY | |
74 | typedef base_unit this_type; | |
75 | /// The dimensions of this base unit. | |
76 | typedef Dim dimension_type; | |
77 | ||
78 | /// Provided for mpl compatability. | |
79 | typedef Derived type; | |
80 | ||
81 | /// The unit corresponding to this base unit. | |
82 | #ifndef BOOST_UNITS_DOXYGEN | |
83 | typedef unit< | |
84 | Dim, | |
85 | heterogeneous_system< | |
86 | heterogeneous_system_impl< | |
87 | list< | |
88 | heterogeneous_system_dim<Derived,static_rational<1> >, | |
89 | dimensionless_type | |
90 | >, | |
91 | Dim, | |
92 | no_scale | |
93 | > | |
94 | > | |
95 | > unit_type; | |
96 | #else | |
97 | typedef detail::unspecified unit_type; | |
98 | #endif | |
99 | ||
100 | private: | |
101 | /// Check for C++0x. In C++0x, we have to have identical | |
102 | /// arguments but a different return type to trigger an | |
103 | /// error. Note that this is only needed for clang as | |
104 | /// check_base_unit will trigger an error earlier | |
105 | /// for compilers with less strict name lookup. | |
106 | /// INTERNAL ONLY | |
107 | friend Derived* | |
108 | check_double_register(const units::base_unit_ordinal<N>&) | |
109 | { return(0); } | |
110 | ||
111 | /// Register this ordinal | |
112 | /// INTERNAL ONLY | |
113 | friend detail::yes | |
114 | boost_units_unit_is_registered(const units::base_unit_ordinal<N>&) | |
115 | { detail::yes result; return(result); } | |
116 | ||
117 | /// But make sure we can identify the current instantiation! | |
118 | /// INTERNAL ONLY | |
119 | friend detail::yes | |
120 | boost_units_unit_is_registered(const units::base_unit_pair<Derived, N>&) | |
121 | { detail::yes result; return(result); } | |
122 | }; | |
123 | ||
124 | } // namespace units | |
125 | ||
126 | } // namespace boost | |
127 | ||
128 | #endif // BOOST_UNITS_BASE_UNIT_HPP |