summaryrefslogtreecommitdiff
path: root/boost/units/detail/dimension_list.hpp
blob: fc0554776583338249791d7988341ee458fd87e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
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