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