Chris@16: /* Chris@101: * Copyright Andrey Semashev 2007 - 2015. Chris@16: * Distributed under the Boost Software License, Version 1.0. Chris@16: * (See accompanying file LICENSE_1_0.txt or copy at Chris@16: * http://www.boost.org/LICENSE_1_0.txt) Chris@16: */ Chris@16: /*! Chris@16: * \file logical.hpp Chris@16: * \author Andrey Semashev Chris@16: * \date 30.03.2008 Chris@16: * Chris@16: * This header contains logical predicates for value comparison, analogous to \c std::less, \c std::greater Chris@16: * and others. The main difference from the standard equivalents is that the predicates defined in this Chris@16: * header are not templates and therefore do not require a fixed argument type. Furthermore, both arguments Chris@16: * may have different types, in which case the comparison is performed without type conversion. Chris@16: * Chris@16: * \note In case if arguments are integral, the conversion is performed according to the standard C++ rules Chris@16: * in order to avoid warnings from the compiler. Chris@16: */ Chris@16: Chris@16: #ifndef BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_ Chris@16: #define BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_ Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #ifdef BOOST_HAS_PRAGMA_ONCE Chris@16: #pragma once Chris@16: #endif Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: BOOST_LOG_OPEN_NAMESPACE Chris@16: Chris@16: namespace aux { Chris@16: Chris@16: //! The trait creates a common integral type suitable for comparison. This is mostly to silence compiler warnings like 'signed/unsigned mismatch'. Chris@16: template< typename T, typename U, unsigned int TSizeV = sizeof(T), unsigned int USizeV = sizeof(U), bool TSmallerThanU = (sizeof(T) < sizeof(U)) > Chris@16: struct make_common_integral_type Chris@16: { Chris@16: typedef T type; Chris@16: }; Chris@16: Chris@16: //! Specialization for case when \c T is smaller than \c U Chris@16: template< typename T, typename U, unsigned int TSizeV, unsigned int USizeV > Chris@16: struct make_common_integral_type< T, U, TSizeV, USizeV, true > Chris@16: { Chris@16: typedef U type; Chris@16: }; Chris@16: Chris@16: //! Specialization for the case when both types have the same size Chris@16: template< typename T, typename U, unsigned int SizeV > Chris@16: struct make_common_integral_type< T, U, SizeV, SizeV, false > : Chris@16: public mpl::if_< Chris@16: is_unsigned< T >, Chris@16: T, Chris@16: U Chris@16: > Chris@16: { Chris@16: }; Chris@16: Chris@16: } // namespace aux Chris@16: Chris@16: //! Equality predicate Chris@16: struct equal_to Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template< typename T, typename U > Chris@16: bool operator() (T const& left, U const& right) const Chris@16: { Chris@16: return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type()); Chris@16: } Chris@16: Chris@16: private: Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::false_ const&) Chris@16: { Chris@16: return (left == right); Chris@16: } Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::true_ const&) Chris@16: { Chris@16: typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; Chris@16: return static_cast< common_integral_type >(left) == static_cast< common_integral_type >(right); Chris@16: } Chris@16: }; Chris@16: Chris@16: //! Inequality predicate Chris@16: struct not_equal_to Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template< typename T, typename U > Chris@16: bool operator() (T const& left, U const& right) const Chris@16: { Chris@16: return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type()); Chris@16: } Chris@16: Chris@16: private: Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::false_ const&) Chris@16: { Chris@16: return (left != right); Chris@16: } Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::true_ const&) Chris@16: { Chris@16: typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; Chris@16: return static_cast< common_integral_type >(left) != static_cast< common_integral_type >(right); Chris@16: } Chris@16: }; Chris@16: Chris@16: //! Less predicate Chris@16: struct less Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template< typename T, typename U > Chris@16: bool operator() (T const& left, U const& right) const Chris@16: { Chris@16: return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type()); Chris@16: } Chris@16: Chris@16: private: Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::false_ const&) Chris@16: { Chris@16: return (left < right); Chris@16: } Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::true_ const&) Chris@16: { Chris@16: typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; Chris@16: return static_cast< common_integral_type >(left) < static_cast< common_integral_type >(right); Chris@16: } Chris@16: }; Chris@16: Chris@16: //! Greater predicate Chris@16: struct greater Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template< typename T, typename U > Chris@16: bool operator() (T const& left, U const& right) const Chris@16: { Chris@16: return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type()); Chris@16: } Chris@16: Chris@16: private: Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::false_ const&) Chris@16: { Chris@16: return (left > right); Chris@16: } Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::true_ const&) Chris@16: { Chris@16: typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; Chris@16: return static_cast< common_integral_type >(left) > static_cast< common_integral_type >(right); Chris@16: } Chris@16: }; Chris@16: Chris@16: //! Less or equal predicate Chris@16: struct less_equal Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template< typename T, typename U > Chris@16: bool operator() (T const& left, U const& right) const Chris@16: { Chris@16: return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type()); Chris@16: } Chris@16: Chris@16: private: Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::false_ const&) Chris@16: { Chris@16: return (left <= right); Chris@16: } Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::true_ const&) Chris@16: { Chris@16: typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; Chris@16: return static_cast< common_integral_type >(left) <= static_cast< common_integral_type >(right); Chris@16: } Chris@16: }; Chris@16: Chris@16: //! Greater or equal predicate Chris@16: struct greater_equal Chris@16: { Chris@16: typedef bool result_type; Chris@16: Chris@16: template< typename T, typename U > Chris@16: bool operator() (T const& left, U const& right) const Chris@16: { Chris@16: return op(left, right, typename mpl::and_< is_integral< T >, is_integral< U > >::type()); Chris@16: } Chris@16: Chris@16: private: Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::false_ const&) Chris@16: { Chris@16: return (left >= right); Chris@16: } Chris@16: template< typename T, typename U > Chris@16: static bool op(T const& left, U const& right, mpl::true_ const&) Chris@16: { Chris@16: typedef typename aux::make_common_integral_type< T, U >::type common_integral_type; Chris@16: return static_cast< common_integral_type >(left) >= static_cast< common_integral_type >(right); Chris@16: } Chris@16: }; Chris@16: Chris@16: BOOST_LOG_CLOSE_NAMESPACE // namespace log Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_LOG_UTILITY_FUNCTIONAL_LOGICAL_HPP_INCLUDED_