1 // Copyright (c) 2016-2020 Antony Polukhin
2 //
3 // Distributed under the Boost Software License, Version 1.0. (See accompanying
4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5 
6 #ifndef BOOST_PFR_FUNCTORS_HPP
7 #define BOOST_PFR_FUNCTORS_HPP
8 #pragma once
9 
10 #include <boost/pfr/detail/config.hpp>
11 
12 #include <boost/pfr/ops.hpp>
13 
14 #include <boost/pfr/detail/functional.hpp>
15 
16 /// \file boost/pfr/functors.hpp
17 /// Contains functors that are close to the Standard Library ones.
18 /// Each functor calls corresponding Boost.PFR function from boost/pfr/ops.hpp
19 ///
20 /// \b Example:
21 /// \code
22 ///     #include <boost/pfr/functors.hpp>
23 ///     struct my_struct {      // No operators defined for that structure
24 ///         int i; short s; char data[7]; bool bl; int a,b,c,d,e,f;
25 ///     };
26 ///     // ...
27 ///
28 ///     std::unordered_set<
29 ///         my_struct,
30 ///         boost::pfr::hash<>,
31 ///         boost::pfr::equal_to<>
32 ///     > my_set;
33 /// \endcode
34 ///
35 /// \b Synopsis:
36 namespace boost { namespace pfr {
37 
38 ///////////////////// Comparisons
39 
40 /// \brief std::equal_to like comparator that returns \forcedlink{eq}(x, y)
41 template <class T = void> struct equal_to {
42     /// \return \b true if each field of \b x equals the field with same index of \b y.
operator ()boost::pfr::equal_to43     bool operator()(const T& x, const T& y) const {
44         return boost::pfr::eq(x, y);
45     }
46 
47 #ifdef BOOST_PFR_DOXYGEN_INVOKED
48     /// This typedef exists only if T \b is void
49     typedef std::true_type is_transparent;
50 
51     /// This operator allows comparison of \b x and \b y that have different type.
52     /// \pre Exists only if T \b is void.
53     template <class V, class U> bool operator()(const V& x, const U& y) const;
54 #endif
55 };
56 
57 /// @cond
58 template <> struct equal_to<void> {
59     template <class T, class U>
operator ()boost::pfr::equal_to60     bool operator()(const T& x, const U& y) const {
61         return boost::pfr::eq(x, y);
62     }
63 
64     typedef std::true_type is_transparent;
65 };
66 /// @endcond
67 
68 /// \brief std::not_equal like comparator that returns \forcedlink{ne}(x, y)
69 template <class T = void> struct not_equal {
70     /// \return \b true if at least one field \b x not equals the field with same index of \b y.
operator ()boost::pfr::not_equal71     bool operator()(const T& x, const T& y) const {
72         return boost::pfr::ne(x, y);
73     }
74 
75 #ifdef BOOST_PFR_DOXYGEN_INVOKED
76     /// This typedef exists only if T \b is void
77     typedef std::true_type is_transparent;
78 
79     /// This operator allows comparison of \b x and \b y that have different type.
80     /// \pre Exists only if T \b is void.
81     template <class V, class U> bool operator()(const V& x, const U& y) const;
82 #endif
83 };
84 
85 /// @cond
86 template <> struct not_equal<void> {
87     template <class T, class U>
operator ()boost::pfr::not_equal88     bool operator()(const T& x, const U& y) const {
89         return boost::pfr::ne(x, y);
90     }
91 
92     typedef std::true_type is_transparent;
93 };
94 /// @endcond
95 
96 /// \brief std::greater like comparator that returns \forcedlink{gt}(x, y)
97 template <class T = void> struct greater {
98     /// \return \b true if field of \b x greater than the field with same index of \b y and all previous fields of \b x equal to the same fields of \b y.
operator ()boost::pfr::greater99     bool operator()(const T& x, const T& y) const {
100         return boost::pfr::gt(x, y);
101     }
102 
103 #ifdef BOOST_PFR_DOXYGEN_INVOKED
104     /// This typedef exists only if T \b is void
105     typedef std::true_type is_transparent;
106 
107     /// This operator allows comparison of \b x and \b y that have different type.
108     /// \pre Exists only if T \b is void.
109     template <class V, class U> bool operator()(const V& x, const U& y) const;
110 #endif
111 };
112 
113 /// @cond
114 template <> struct greater<void> {
115     template <class T, class U>
operator ()boost::pfr::greater116     bool operator()(const T& x, const U& y) const {
117         return boost::pfr::gt(x, y);
118     }
119 
120     typedef std::true_type is_transparent;
121 };
122 /// @endcond
123 
124 /// \brief std::less like comparator that returns \forcedlink{lt}(x, y)
125 template <class T = void> struct less {
126     /// \return \b true if field of \b x less than the field with same index of \b y and all previous fields of \b x equal to the same fields of \b y.
operator ()boost::pfr::less127     bool operator()(const T& x, const T& y) const {
128         return boost::pfr::lt(x, y);
129     }
130 
131 #ifdef BOOST_PFR_DOXYGEN_INVOKED
132     /// This typedef exists only if T \b is void
133     typedef std::true_type is_transparent;
134 
135     /// This operator allows comparison of \b x and \b y that have different type.
136     /// \pre Exists only if T \b is void.
137     template <class V, class U> bool operator()(const V& x, const U& y) const;
138 #endif
139 };
140 
141 /// @cond
142 template <> struct less<void> {
143     template <class T, class U>
operator ()boost::pfr::less144     bool operator()(const T& x, const U& y) const {
145         return boost::pfr::lt(x, y);
146     }
147 
148     typedef std::true_type is_transparent;
149 };
150 /// @endcond
151 
152 /// \brief std::greater_equal like comparator that returns \forcedlink{ge}(x, y)
153 template <class T = void> struct greater_equal {
154     /// \return \b true if field of \b x greater than the field with same index of \b y and all previous fields of \b x equal to the same fields of \b y;
155     /// or if each field of \b x equals the field with same index of \b y.
operator ()boost::pfr::greater_equal156     bool operator()(const T& x, const T& y) const {
157         return boost::pfr::ge(x, y);
158     }
159 
160 #ifdef BOOST_PFR_DOXYGEN_INVOKED
161     /// This typedef exists only if T \b is void
162     typedef std::true_type is_transparent;
163 
164     /// This operator allows comparison of \b x and \b y that have different type.
165     /// \pre Exists only if T \b is void.
166     template <class V, class U> bool operator()(const V& x, const U& y) const;
167 #endif
168 };
169 
170 /// @cond
171 template <> struct greater_equal<void> {
172     template <class T, class U>
operator ()boost::pfr::greater_equal173     bool operator()(const T& x, const U& y) const {
174         return boost::pfr::ge(x, y);
175     }
176 
177     typedef std::true_type is_transparent;
178 };
179 /// @endcond
180 
181 /// \brief std::less_equal like comparator that returns \forcedlink{le}(x, y)
182 template <class T = void> struct less_equal {
183     /// \return \b true if field of \b x less than the field with same index of \b y and all previous fields of \b x equal to the same fields of \b y;
184     /// or if each field of \b x equals the field with same index of \b y.
operator ()boost::pfr::less_equal185     bool operator()(const T& x, const T& y) const {
186         return boost::pfr::le(x, y);
187     }
188 
189 #ifdef BOOST_PFR_DOXYGEN_INVOKED
190     /// This typedef exists only if T \b is void
191     typedef std::true_type is_transparent;
192 
193     /// This operator allows comparison of \b x and \b y that have different type.
194     /// \pre Exists only if T \b is void.
195     template <class V, class U> bool operator()(const V& x, const U& y) const;
196 #endif
197 };
198 
199 /// @cond
200 template <> struct less_equal<void> {
201     template <class T, class U>
operator ()boost::pfr::less_equal202     bool operator()(const T& x, const U& y) const {
203         return boost::pfr::le(x, y);
204     }
205 
206     typedef std::true_type is_transparent;
207 };
208 /// @endcond
209 
210 
211 /// \brief std::hash like functor that returns \forcedlink{hash_value}(x)
212 template <class T> struct hash {
213     /// \return hash value of \b x.
operator ()boost::pfr::hash214     std::size_t operator()(const T& x) const {
215         return boost::pfr::hash_value(x);
216     }
217 };
218 
219 }} // namespace boost::pfr
220 
221 #endif // BOOST_PFR_FUNCTORS_HPP
222