1 /*-----------------------------------------------------------------------------+
2 Copyright (c) 2010-2011: Joachim Faulhaber
3 +------------------------------------------------------------------------------+
4    Distributed under the Boost Software License, Version 1.0.
5       (See accompanying file LICENCE.txt or copy at
6            http://www.boost.org/LICENSE_1_0.txt)
7 +-----------------------------------------------------------------------------*/
8 #ifndef BOOST_ICL_TYPE_TRAITS_INFINITY_HPP_JOFA_100322
9 #define BOOST_ICL_TYPE_TRAITS_INFINITY_HPP_JOFA_100322
10 
11 #include <string>
12 #include <boost/static_assert.hpp>
13 #include <boost/type_traits/ice.hpp>
14 #include <boost/icl/type_traits/is_numeric.hpp>
15 #include <boost/icl/type_traits/rep_type_of.hpp>
16 #include <boost/icl/type_traits/size_type_of.hpp>
17 #include <boost/mpl/and.hpp>
18 #include <boost/mpl/if.hpp>
19 
20 namespace boost{ namespace icl
21 {
22 
23 template<class Type> struct has_std_infinity
24 {
25     typedef has_std_infinity type;
26     BOOST_STATIC_CONSTANT(bool,
27         value = (type_traits::ice_and
28                       < is_numeric<Type>::value
29                       , std::numeric_limits<Type>::has_infinity
30                       >::value)
31        );
32 };
33 
34 template<class Type> struct has_max_infinity
35 {
36     typedef has_max_infinity type;
37     BOOST_STATIC_CONSTANT(bool,
38         value = (type_traits::ice_and
39                       < is_numeric<Type>::value
40                       , type_traits::ice_not<std::numeric_limits<Type>::has_infinity>::value
41                       >::value)
42        );
43 };
44 
45 //------------------------------------------------------------------------------
46 template <class Type, bool has_std_inf=false, bool has_std_max=false>
47 struct get_numeric_infinity;
48 
49 template <class Type, bool has_std_max>
50 struct get_numeric_infinity<Type, true, has_std_max>
51 {
52     typedef get_numeric_infinity type;
valueboost::icl::get_numeric_infinity53     static Type value()
54     {
55         return (std::numeric_limits<Type>::infinity)();
56     }
57 };
58 
59 template <class Type>
60 struct get_numeric_infinity<Type, false, true>
61 {
62     typedef get_numeric_infinity type;
valueboost::icl::get_numeric_infinity63     static Type value()
64     {
65         return (std::numeric_limits<Type>::max)();
66     }
67 };
68 
69 template <class Type>
70 struct get_numeric_infinity<Type, false, false>
71 {
72     typedef get_numeric_infinity type;
valueboost::icl::get_numeric_infinity73     static Type value()
74     {
75         return Type();
76     }
77 };
78 
79 template <class Type>
80 struct numeric_infinity
81 {
82     typedef numeric_infinity type;
valueboost::icl::numeric_infinity83     static Type value()
84     {
85         return get_numeric_infinity< Type
86                                    , has_std_infinity<Type>::value
87                                    , has_max_infinity<Type>::value >::value();
88     }
89 };
90 
91 
92 //------------------------------------------------------------------------------
93 template<class Type, bool has_numeric_inf, bool has_repr_inf, bool has_size, bool has_diff>
94 struct get_infinity;
95 
96 template<class Type, bool has_repr_inf, bool has_size, bool has_diff>
97 struct get_infinity<Type, true, has_repr_inf, has_size, has_diff>
98 {
99     typedef get_infinity type;
100 
valueboost::icl::get_infinity101     static Type value()
102     {
103         return  numeric_infinity<Type>::value();
104     }
105 };
106 
107 template<class Type, bool has_size, bool has_diff>
108 struct get_infinity<Type, false, true, has_size, has_diff>
109 {
110     typedef get_infinity type;
111 
valueboost::icl::get_infinity112     static Type value()
113     {
114         return Type(numeric_infinity<typename Type::rep>::value());
115     }
116 };
117 
118 template<class Type, bool has_diff>
119 struct get_infinity<Type, false, false, true, has_diff>
120 {
121     typedef get_infinity type;
122     typedef typename Type::size_type size_type;
123 
valueboost::icl::get_infinity124     static Type value()
125     {
126         return Type(numeric_infinity<size_type>::value());
127     }
128 };
129 
130 template<class Type>
131 struct get_infinity<Type, false, false, false, true>
132 {
133     typedef get_infinity type;
134     typedef typename Type::difference_type difference_type;
135 
valueboost::icl::get_infinity136     static Type value()
137     {
138         return identity_element<difference_type>::value();
139     }
140 };
141 
142 template<class Type>
143 struct get_infinity<Type, false, false, false, false>
144 {
145     typedef get_infinity type;
146 
valueboost::icl::get_infinity147     static Type value()
148     {
149         return identity_element<Type>::value();
150     }
151 };
152 
153 template <class Type> struct infinity
154 {
155     typedef infinity type;
156 
valueboost::icl::infinity157     static Type value()
158     {
159         return
160             get_infinity< Type
161                         , is_numeric<Type>::value
162                         , has_rep_type<Type>::value
163                         , has_size_type<Type>::value
164                         , has_difference_type<Type>::value
165                         >::value();
166     }
167 };
168 
169 template <>
170 struct infinity<std::string>
171 {
172     typedef infinity type;
173 
valueboost::icl::infinity174     static std::string value()
175     {
176         return std::string();
177     }
178 };
179 
180 }} // namespace boost icl
181 
182 #endif
183 
184 
185