• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 ///////////////////////////////////////////////////////////////////////////////
2 /// \file functional_fwd.hpp
3 ///
4 //  Copyright 2005 Eric Niebler. Distributed under the Boost
5 //  Software License, Version 1.0. (See accompanying file
6 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
7 
8 #ifndef BOOST_NUMERIC_FUNCTIONAL_FWD_HPP_EAN_08_12_2005
9 #define BOOST_NUMERIC_FUNCTIONAL_FWD_HPP_EAN_08_12_2005
10 
11 #include <boost/mpl/if.hpp>
12 #include <boost/mpl/placeholders.hpp>
13 #include <boost/utility/enable_if.hpp>
14 #include <boost/type_traits/is_same.hpp>
15 #include <boost/type_traits/is_const.hpp>
16 
17 namespace boost { namespace numeric
18 {
19     // For using directives -- this namespace may be re-opened elsewhere
20     namespace operators
21     {}
22 
23     namespace op
24     {
25         using mpl::_;
26         using mpl::_1;
27         using mpl::_2;
28     }
29 
30     namespace functional
31     {
32         using namespace operators;
33 
34         template<typename T>
35         struct tag
36         {
37             typedef void type;
38         };
39 
40         template<typename T>
41         struct tag<T const>
42           : tag<T>
43         {};
44 
45         template<typename T>
46         struct tag<T volatile>
47           : tag<T>
48         {};
49 
50         template<typename T>
51         struct tag<T const volatile>
52           : tag<T>
53         {};
54 
55         template<typename T>
56         struct static_;
57 
58         template<typename A0, typename A1>
59         struct are_integral;
60     }
61 
62     /// INTERNAL ONLY
63     ///
64 #define BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(Name, Op)                                     \
65     namespace functional                                                                        \
66     {                                                                                           \
67         template<typename Arg, typename EnableIf = void>                                        \
68         struct Name ## _base;                                                                   \
69         template<typename Arg, typename ArgTag = typename tag<Arg>::type>                       \
70         struct Name;                                                                            \
71     }                                                                                           \
72     namespace op                                                                                \
73     {                                                                                           \
74         struct Name;                                                                            \
75     }                                                                                           \
76     namespace                                                                                   \
77     {                                                                                           \
78         extern op::Name const &Name;                                                            \
79     }
80 
81     /// INTERNAL ONLY
82     ///
83 #define BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(Name)                                        \
84     namespace functional                                                                        \
85     {                                                                                           \
86         template<typename Left, typename Right, typename EnableIf = void>                       \
87         struct result_of_ ## Name;                                                              \
88         template<typename Left, typename Right, typename EnableIf = void>                       \
89         struct Name ## _base;                                                                   \
90         template<                                                                               \
91             typename Left                                                                       \
92           , typename Right                                                                      \
93           , typename LeftTag = typename tag<Left>::type                                         \
94           , typename RightTag = typename tag<Right>::type                                       \
95         >                                                                                       \
96         struct Name;                                                                            \
97     }                                                                                           \
98     namespace op                                                                                \
99     {                                                                                           \
100         struct Name;                                                                            \
101     }                                                                                           \
102     namespace                                                                                   \
103     {                                                                                           \
104         extern op::Name const &Name;                                                            \
105     }
106 
107     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(plus)
108     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(minus)
109     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(multiplies)
110     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(divides)
111     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(modulus)
112     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(greater)
113     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(greater_equal)
114     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(less)
115     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(less_equal)
116     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(equal_to)
117     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(not_equal_to)
118 
119     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(assign)
120     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(plus_assign)
121     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(minus_assign)
122     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(multiplies_assign)
123     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(divides_assign)
124     BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP(modulus_assign)
125 
126     BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(unary_plus, +)
127     BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(unary_minus, -)
128     BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(complement, ~)
129     BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP(logical_not, !)
130 
131 #undef BOOST_NUMERIC_FUNCTIONAL_DECLARE_UNARY_OP
132 #undef BOOST_NUMERIC_FUNCTIONAL_DECLARE_BINARY_OP
133 
134 
135     namespace functional
136     {
137         template<typename To, typename From, typename EnableIf = void>
138         struct promote_base;
139         template<typename Left, typename Right, typename EnableIf = void>
140         struct min_assign_base;
141         template<typename Left, typename Right, typename EnableIf = void>
142         struct max_assign_base;
143         template<typename Left, typename Right, typename EnableIf = void>
144         struct fdiv_base;
145         template<typename Arg, typename EnableIf = void>
146         struct as_min_base;
147         template<typename Arg, typename EnableIf = void>
148         struct as_max_base;
149         template<typename Arg, typename EnableIf = void>
150         struct as_zero_base;
151         template<typename Arg, typename EnableIf = void>
152         struct as_one_base;
153 
154         template<typename To, typename From, typename ToTag = typename tag<To>::type, typename FromTag = typename tag<From>::type>
155         struct promote;
156         template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
157         struct min_assign;
158         template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
159         struct max_assign;
160         template<typename Left, typename Right, typename LeftTag = typename tag<Left>::type, typename RightTag = typename tag<Right>::type>
161         struct fdiv;
162         template<typename Arg, typename Tag = typename tag<Arg>::type>
163         struct as_min;
164         template<typename Arg, typename Tag = typename tag<Arg>::type>
165         struct as_max;
166         template<typename Arg, typename Tag = typename tag<Arg>::type>
167         struct as_zero;
168         template<typename Arg, typename Tag = typename tag<Arg>::type>
169         struct as_one;
170     }
171 
172     namespace op
173     {
174         template<typename To>
175         struct promote;
176         struct min_assign;
177         struct max_assign;
178         struct fdiv;
179         struct as_min;
180         struct as_max;
181         struct as_zero;
182         struct as_one;
183     }
184 
185     namespace
186     {
187         extern op::min_assign const &min_assign;
188         extern op::max_assign const &max_assign;
189         extern op::fdiv const &fdiv;
190         extern op::as_min const &as_min;
191         extern op::as_max const &as_max;
192         extern op::as_zero const &as_zero;
193         extern op::as_one const &as_one;
194     }
195 
196     template<typename To, typename From>
197     typename lazy_disable_if<is_const<From>, mpl::if_<is_same<To, From>, To &, To> >::type
198     promote(From &from);
199 
200     template<typename To, typename From>
201     typename mpl::if_<is_same<To const, From const>, To const &, To const>::type
202     promote(From const &from);
203 
204     template<typename T>
205     struct default_;
206 
207     template<typename T>
208     struct one;
209 
210     template<typename T>
211     struct zero;
212 
213     template<typename T>
214     struct one_or_default;
215 
216     template<typename T>
217     struct zero_or_default;
218 
219 }} // namespace boost::numeric
220 
221 #endif
222