Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:43:38

0001 // Copyright (c) 2016-2023 Antony Polukhin
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 #ifndef BOOST_PFR_OPS_HPP
0007 #define BOOST_PFR_OPS_HPP
0008 #pragma once
0009 
0010 #include <boost/pfr/detail/config.hpp>
0011 
0012 #include <boost/pfr/detail/detectors.hpp>
0013 #include <boost/pfr/ops_fields.hpp>
0014 
0015 /// \file boost/pfr/ops.hpp
0016 /// Contains comparison and hashing functions.
0017 /// If type is comparable using its own operator or its conversion operator, then the types operator is used. Otherwise
0018 /// the operation is done via corresponding function from boost/pfr/ops.hpp header.
0019 ///
0020 /// \b Example:
0021 /// \code
0022 ///     #include <boost/pfr/ops.hpp>
0023 ///     struct comparable_struct {      // No operators defined for that structure
0024 ///         int i; short s; char data[7]; bool bl; int a,b,c,d,e,f;
0025 ///     };
0026 ///     // ...
0027 ///
0028 ///     comparable_struct s1 {0, 1, "Hello", false, 6,7,8,9,10,11};
0029 ///     comparable_struct s2 {0, 1, "Hello", false, 6,7,8,9,10,11111};
0030 ///     assert(boost::pfr::lt(s1, s2));
0031 /// \endcode
0032 ///
0033 /// \podops for other ways to define operators and more details.
0034 ///
0035 /// \b Synopsis:
0036 namespace boost { namespace pfr {
0037 
0038 namespace detail {
0039 
0040 ///////////////////// Helper typedefs that are used by all the ops
0041     template <template <class, class> class Detector, class T, class U>
0042     using enable_not_comp_base_t = std::enable_if_t<
0043         not_appliable<Detector, T const&, U const&>::value,
0044         bool
0045     >;
0046 
0047     template <template <class, class> class Detector, class T, class U>
0048     using enable_comp_base_t = std::enable_if_t<
0049         !not_appliable<Detector, T const&, U const&>::value,
0050         bool
0051     >;
0052 ///////////////////// std::enable_if_t like functions that enable only if types do not support operation
0053 
0054     template <class T, class U> using enable_not_eq_comp_t = enable_not_comp_base_t<comp_eq_detector, T, U>;
0055     template <class T, class U> using enable_not_ne_comp_t = enable_not_comp_base_t<comp_ne_detector, T, U>;
0056     template <class T, class U> using enable_not_lt_comp_t = enable_not_comp_base_t<comp_lt_detector, T, U>;
0057     template <class T, class U> using enable_not_le_comp_t = enable_not_comp_base_t<comp_le_detector, T, U>;
0058     template <class T, class U> using enable_not_gt_comp_t = enable_not_comp_base_t<comp_gt_detector, T, U>;
0059     template <class T, class U> using enable_not_ge_comp_t = enable_not_comp_base_t<comp_ge_detector, T, U>;
0060 
0061     template <class T> using enable_not_hashable_t = std::enable_if_t<
0062         not_appliable<hash_detector, const T&, const T&>::value,
0063         std::size_t
0064     >;
0065 ///////////////////// std::enable_if_t like functions that enable only if types do support operation
0066 
0067     template <class T, class U> using enable_eq_comp_t = enable_comp_base_t<comp_eq_detector, T, U>;
0068     template <class T, class U> using enable_ne_comp_t = enable_comp_base_t<comp_ne_detector, T, U>;
0069     template <class T, class U> using enable_lt_comp_t = enable_comp_base_t<comp_lt_detector, T, U>;
0070     template <class T, class U> using enable_le_comp_t = enable_comp_base_t<comp_le_detector, T, U>;
0071     template <class T, class U> using enable_gt_comp_t = enable_comp_base_t<comp_gt_detector, T, U>;
0072     template <class T, class U> using enable_ge_comp_t = enable_comp_base_t<comp_ge_detector, T, U>;
0073 
0074     template <class T> using enable_hashable_t = std::enable_if_t<
0075         !not_appliable<hash_detector, const T&, const T&>::value,
0076         std::size_t
0077     >;
0078 } // namespace detail
0079 
0080 
0081 /// \brief Compares lhs and rhs for equality using their own comparison and conversion operators; if no operators available returns \forcedlink{eq_fields}(lhs, rhs).
0082 ///
0083 /// \returns true if lhs is equal to rhs; false otherwise
0084 template <class T, class U>
0085 constexpr detail::enable_not_eq_comp_t<T, U> eq(const T& lhs, const U& rhs) noexcept {
0086     return boost::pfr::eq_fields(lhs, rhs);
0087 }
0088 
0089 /// \overload eq
0090 template <class T, class U>
0091 constexpr detail::enable_eq_comp_t<T, U> eq(const T& lhs, const U& rhs) {
0092     return lhs == rhs;
0093 }
0094 
0095 
0096 /// \brief Compares lhs and rhs for inequality using their own comparison and conversion operators; if no operators available returns \forcedlink{ne_fields}(lhs, rhs).
0097 ///
0098 /// \returns true if lhs is not equal to rhs; false otherwise
0099 template <class T, class U>
0100 constexpr detail::enable_not_ne_comp_t<T, U> ne(const T& lhs, const U& rhs) noexcept {
0101     return boost::pfr::ne_fields(lhs, rhs);
0102 }
0103 
0104 /// \overload ne
0105 template <class T, class U>
0106 constexpr detail::enable_ne_comp_t<T, U> ne(const T& lhs, const U& rhs) {
0107     return lhs != rhs;
0108 }
0109 
0110 
0111 /// \brief Compares lhs and rhs for less-than using their own comparison and conversion operators; if no operators available returns \forcedlink{lt_fields}(lhs, rhs).
0112 ///
0113 /// \returns true if lhs is less than rhs; false otherwise
0114 template <class T, class U>
0115 constexpr detail::enable_not_lt_comp_t<T, U> lt(const T& lhs, const U& rhs) noexcept {
0116     return boost::pfr::lt_fields(lhs, rhs);
0117 }
0118 
0119 /// \overload lt
0120 template <class T, class U>
0121 constexpr detail::enable_lt_comp_t<T, U> lt(const T& lhs, const U& rhs) {
0122     return lhs < rhs;
0123 }
0124 
0125 
0126 /// \brief Compares lhs and rhs for greater-than using their own comparison and conversion operators; if no operators available returns \forcedlink{lt_fields}(lhs, rhs).
0127 ///
0128 /// \returns true if lhs is greater than rhs; false otherwise
0129 template <class T, class U>
0130 constexpr detail::enable_not_gt_comp_t<T, U> gt(const T& lhs, const U& rhs) noexcept {
0131     return boost::pfr::gt_fields(lhs, rhs);
0132 }
0133 
0134 /// \overload gt
0135 template <class T, class U>
0136 constexpr detail::enable_gt_comp_t<T, U> gt(const T& lhs, const U& rhs) {
0137     return lhs > rhs;
0138 }
0139 
0140 
0141 /// \brief Compares lhs and rhs for less-equal using their own comparison and conversion operators; if no operators available returns \forcedlink{le_fields}(lhs, rhs).
0142 ///
0143 /// \returns true if lhs is less or equal to rhs; false otherwise
0144 template <class T, class U>
0145 constexpr detail::enable_not_le_comp_t<T, U> le(const T& lhs, const U& rhs) noexcept {
0146     return boost::pfr::le_fields(lhs, rhs);
0147 }
0148 
0149 /// \overload le
0150 template <class T, class U>
0151 constexpr detail::enable_le_comp_t<T, U> le(const T& lhs, const U& rhs) {
0152     return lhs <= rhs;
0153 }
0154 
0155 
0156 /// \brief Compares lhs and rhs for greater-equal using their own comparison and conversion operators; if no operators available returns \forcedlink{ge_fields}(lhs, rhs).
0157 ///
0158 /// \returns true if lhs is greater or equal to rhs; false otherwise
0159 template <class T, class U>
0160 constexpr detail::enable_not_ge_comp_t<T, U> ge(const T& lhs, const U& rhs) noexcept {
0161     return boost::pfr::ge_fields(lhs, rhs);
0162 }
0163 
0164 /// \overload ge
0165 template <class T, class U>
0166 constexpr detail::enable_ge_comp_t<T, U> ge(const T& lhs, const U& rhs) {
0167     return lhs >= rhs;
0168 }
0169 
0170 
0171 /// \brief Hashes value using its own std::hash specialization; if no std::hash specialization available returns \forcedlink{hash_fields}(value).
0172 ///
0173 /// \returns std::size_t with hash of the value
0174 template <class T>
0175 constexpr detail::enable_not_hashable_t<T> hash_value(const T& value) noexcept {
0176     return boost::pfr::hash_fields(value);
0177 }
0178 
0179 /// \overload hash_value
0180 template <class T>
0181 constexpr detail::enable_hashable_t<T> hash_value(const T& value) {
0182     return std::hash<T>{}(value);
0183 }
0184 
0185 }} // namespace boost::pfr
0186 
0187 #endif // BOOST_PFR_OPS_HPP