1 /* 2 * Copyright Andrey Semashev 2007 - 2015. 3 * Distributed under the Boost Software License, Version 1.0. 4 * (See accompanying file LICENSE_1_0.txt or copy at 5 * http://www.boost.org/LICENSE_1_0.txt) 6 */ 7 /*! 8 * \file logical.hpp 9 * \author Andrey Semashev 10 * \date 30.03.2008 11 * 12 * This header contains logical predicates for value comparison, analogous to \c std::less, \c std::greater 13 * and others. The main difference from the standard equivalents is that the predicates defined in this 14 * header are not templates and therefore do not require a fixed argument type. Furthermore, both arguments 15 * may have different types, in which case the comparison is performed without type conversion. 16 * 17 * \note In case if arguments are integral, the conversion is performed according to the standard C++ rules 18 * in order to avoid warnings from the compiler. 19 */ 20 21 #ifndef BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_ 22 #define BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_ 23 24 #include <boost/type_traits/is_integral.hpp> 25 #include <boost/type_traits/is_unsigned.hpp> 26 #include <boost/type_traits/conditional.hpp> 27 #include <boost/type_traits/integral_constant.hpp> 28 #include <boost/log/detail/config.hpp> 29 #include <boost/log/detail/header.hpp> 30 31 #ifdef BOOST_HAS_PRAGMA_ONCE 32 #pragma once 33 #endif 34 35 namespace boost { 36 37 BOOST_LOG_OPEN_NAMESPACE 38 39 namespace aux { 40 41 //! The trait creates a common integral type suitable for comparison. This is mostly to silence compiler warnings like 'signed/unsigned mismatch'. 42 template< typename T, typename U, unsigned int TSizeV = sizeof(T), unsigned int USizeV = sizeof(U), bool TSmallerThanU = (sizeof(T) < sizeof(U)) > 43 struct make_common_integral_type 44 { 45 typedef T type; 46 }; 47 48 //! Specialization for case when \c T is smaller than \c U 49 template< typename T, typename U, unsigned int TSizeV, unsigned int USizeV > 50 struct make_common_integral_type< T, U, TSizeV, USizeV, true > 51 { 52 typedef U type; 53 }; 54 55 //! Specialization for the case when both types have the same size 56 template< typename T, typename U, unsigned int SizeV > 57 struct make_common_integral_type< T, U, SizeV, SizeV, false > : 58 public boost::conditional< 59 is_unsigned< T >::value, 60 T, 61 U 62 > 63 { 64 }; 65 66 } // namespace aux 67 68 //! Equality predicate 69 struct equal_to 70 { 71 typedef bool result_type; 72 73 template< typename T, typename U > operator ()boost::equal_to74 bool operator() (T const& left, U const& right) const 75 { 76 return op(left, right, integral_constant< bool, is_integral< T >::value && is_integral< U >::value >()); 77 } 78 79 private: 80 template< typename T, typename U > opboost::equal_to81 static bool op(T const& left, U const& right, false_type) 82 { 83 return (left == right); 84 } 85 template< typename T, typename U > opboost::equal_to86 static bool op(T const& left, U const& right, true_type) 87 { 88 typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; 89 return static_cast< common_integral_type >(left) == static_cast< common_integral_type >(right); 90 } 91 }; 92 93 //! Inequality predicate 94 struct not_equal_to 95 { 96 typedef bool result_type; 97 98 template< typename T, typename U > operator ()boost::not_equal_to99 bool operator() (T const& left, U const& right) const 100 { 101 return op(left, right, integral_constant< bool, is_integral< T >::value && is_integral< U >::value >()); 102 } 103 104 private: 105 template< typename T, typename U > opboost::not_equal_to106 static bool op(T const& left, U const& right, false_type) 107 { 108 return (left != right); 109 } 110 template< typename T, typename U > opboost::not_equal_to111 static bool op(T const& left, U const& right, true_type) 112 { 113 typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; 114 return static_cast< common_integral_type >(left) != static_cast< common_integral_type >(right); 115 } 116 }; 117 118 //! Less predicate 119 struct less 120 { 121 typedef bool result_type; 122 123 template< typename T, typename U > operator ()boost::less124 bool operator() (T const& left, U const& right) const 125 { 126 return op(left, right, integral_constant< bool, is_integral< T >::value && is_integral< U >::value >()); 127 } 128 129 private: 130 template< typename T, typename U > opboost::less131 static bool op(T const& left, U const& right, false_type) 132 { 133 return (left < right); 134 } 135 template< typename T, typename U > opboost::less136 static bool op(T const& left, U const& right, true_type) 137 { 138 typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; 139 return static_cast< common_integral_type >(left) < static_cast< common_integral_type >(right); 140 } 141 }; 142 143 //! Greater predicate 144 struct greater 145 { 146 typedef bool result_type; 147 148 template< typename T, typename U > operator ()boost::greater149 bool operator() (T const& left, U const& right) const 150 { 151 return op(left, right, integral_constant< bool, is_integral< T >::value && is_integral< U >::value >()); 152 } 153 154 private: 155 template< typename T, typename U > opboost::greater156 static bool op(T const& left, U const& right, false_type) 157 { 158 return (left > right); 159 } 160 template< typename T, typename U > opboost::greater161 static bool op(T const& left, U const& right, true_type) 162 { 163 typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; 164 return static_cast< common_integral_type >(left) > static_cast< common_integral_type >(right); 165 } 166 }; 167 168 //! Less or equal predicate 169 struct less_equal 170 { 171 typedef bool result_type; 172 173 template< typename T, typename U > operator ()boost::less_equal174 bool operator() (T const& left, U const& right) const 175 { 176 return op(left, right, integral_constant< bool, is_integral< T >::value && is_integral< U >::value >()); 177 } 178 179 private: 180 template< typename T, typename U > opboost::less_equal181 static bool op(T const& left, U const& right, false_type) 182 { 183 return (left <= right); 184 } 185 template< typename T, typename U > opboost::less_equal186 static bool op(T const& left, U const& right, true_type) 187 { 188 typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; 189 return static_cast< common_integral_type >(left) <= static_cast< common_integral_type >(right); 190 } 191 }; 192 193 //! Greater or equal predicate 194 struct greater_equal 195 { 196 typedef bool result_type; 197 198 template< typename T, typename U > operator ()boost::greater_equal199 bool operator() (T const& left, U const& right) const 200 { 201 return op(left, right, integral_constant< bool, is_integral< T >::value && is_integral< U >::value >()); 202 } 203 204 private: 205 template< typename T, typename U > opboost::greater_equal206 static bool op(T const& left, U const& right, false_type) 207 { 208 return (left >= right); 209 } 210 template< typename T, typename U > opboost::greater_equal211 static bool op(T const& left, U const& right, true_type) 212 { 213 typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; 214 return static_cast< common_integral_type >(left) >= static_cast< common_integral_type >(right); 215 } 216 }; 217 218 BOOST_LOG_CLOSE_NAMESPACE // namespace log 219 220 } // namespace boost 221 222 #include <boost/log/detail/footer.hpp> 223 224 #endif // BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_ 225