|
||||
File indexing completed on 2025-01-18 09:37:58
0001 /*! 0002 @file 0003 Forward declares `boost::hana::Orderable`. 0004 0005 Copyright Louis Dionne 2013-2022 0006 Distributed under the Boost Software License, Version 1.0. 0007 (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt) 0008 */ 0009 0010 #ifndef BOOST_HANA_FWD_CONCEPT_ORDERABLE_HPP 0011 #define BOOST_HANA_FWD_CONCEPT_ORDERABLE_HPP 0012 0013 #include <boost/hana/config.hpp> 0014 0015 0016 namespace boost { namespace hana { 0017 //! @ingroup group-concepts 0018 //! @defgroup group-Orderable Orderable 0019 //! The `Orderable` concept represents totally ordered data types. 0020 //! 0021 //! Intuitively, `Orderable` objects must define a binary predicate named 0022 //! `less` returning whether the first argument is to be considered less 0023 //! than the second argument. The word "total" means that _distinct_ 0024 //! objects must always be ordered; if `a` and `b` are not equal, then 0025 //! exactly one of `less(a, b)` and `less(b, a)` must be true. This is 0026 //! a contrast with weaker kinds of orders that would allow some objects 0027 //! to be incomparable (neither less than nor greater than). Also note 0028 //! that a non-strict total order may always be obtained from a strict 0029 //! total order (and vice-versa) by setting 0030 //! @code 0031 //! a <= b = !(b < a) 0032 //! a < b = !(b <= a) 0033 //! @endcode 0034 //! The non-strict version is used in the description of the laws because 0035 //! it makes them easier to parse for humans, but they could be formulated 0036 //! equivalently using the strict order. 0037 //! 0038 //! 0039 //! Minimal complete definition 0040 //! --------------------------- 0041 //! `less` 0042 //! 0043 //! When `less` is defined, the other methods are defined from it using 0044 //! the same definition as mandated in the laws below. 0045 //! 0046 //! 0047 //! Laws 0048 //! ---- 0049 //! Rigorously speaking, a [total order][1] `<=` on a set `S` is a binary 0050 //! predicate @f$ <= \;: S \times S \to bool @f$ such that for all 0051 //! `a`, `b`, `c` in `S`, 0052 //! @code 0053 //! if a <= b and b <= a then a == b // Antisymmetry 0054 //! if a <= b and b <= c then a <= c // Transitivity 0055 //! either a <= b or b <= a // Totality 0056 //! @endcode 0057 //! Additionally, the `less`, `greater` and `greater_equal` methods should 0058 //! have the following intuitive meanings: 0059 //! @code 0060 //! a < b if and only if !(b <= a) 0061 //! a > b if and only if b < a 0062 //! a >= b if and only if !(a < b) 0063 //! @endcode 0064 //! 0065 //! 0066 //! Refined concept 0067 //! --------------- 0068 //! 1. `Comparable` (free model)\n 0069 //! Since `Orderable` requires `less_equal` to be a total order, a model 0070 //! of `Comparable` may always be obtained by setting 0071 //! @code 0072 //! equal(x, y) = less_equal(x, y) && less_equal(y, x) 0073 //! @endcode 0074 //! 0075 //! 0076 //! Concrete models 0077 //! --------------- 0078 //! `hana::integral_constant`, `hana::optional`, `hana::pair`, 0079 //! `hana::string`, `hana::tuple` 0080 //! 0081 //! 0082 //! Free model for `LessThanComparable` data types 0083 //! ---------------------------------------------- 0084 //! Two data types `T` and `U` that model the cross-type version of the 0085 //! usual [LessThanComparable][2] C++ concept are automatically a model 0086 //! of `Orderable` by setting 0087 //! @code 0088 //! less(x, y) = (x < y) 0089 //! @endcode 0090 //! The cross-type version of the LessThanComparable concept is analogous 0091 //! to the cross-type version of the EqualityComparable concept presented 0092 //! in [N3351][3], which is compatible with the usual single type 0093 //! definition. 0094 //! However, note that the LessThanComparable concept only requires `<` 0095 //! to be a [strict weak ordering][4], which is a weaker requirement 0096 //! than being a total order. Hence, if `less` is used with objects 0097 //! of a LessThanComparable data type that do not define a total order, 0098 //! some algorithms may have an unexpected behavior. It is the author's 0099 //! opinion that defining `operator<` as a non-total order is a bad idea, 0100 //! but this is debatable and so the design choice of providing a model 0101 //! for LessThanComparable data types is open to debate. Waiting for 0102 //! some user input. 0103 //! 0104 //! 0105 //! Order-preserving functions 0106 //! -------------------------- 0107 //! Let `A` and `B` be two `Orderable` data types. A function 0108 //! @f$ f : A \to B@f$ is said to be order-preserving (also called 0109 //! monotone) if it preserves the structure of the `Orderable` concept, 0110 //! which can be rigorously stated as follows. For all objects `x`, `y` 0111 //! of data type `A`, 0112 //! @code 0113 //! if less(x, y) then less(f(x), f(y)) 0114 //! @endcode 0115 //! Another important property is that of being order-reflecting, which 0116 //! can be stated as 0117 //! @code 0118 //! if less(f(x), f(y)) then less(x, y) 0119 //! @endcode 0120 //! We say that a function is an order-embedding if it is both 0121 //! order-preserving and order-reflecting, i.e. if 0122 //! @code 0123 //! less(x, y) if and only if less(f(x), f(y)) 0124 //! @endcode 0125 //! 0126 //! 0127 //! Cross-type version of the methods 0128 //! --------------------------------- 0129 //! The comparison methods (`less`, `less_equal`, `greater` and 0130 //! `greater_equal`) are "overloaded" to handle distinct data types 0131 //! with certain properties. Specifically, they are defined for 0132 //! _distinct_ data types `A` and `B` such that 0133 //! 1. `A` and `B` share a common data type `C`, as determined by the 0134 //! `common` metafunction 0135 //! 2. `A`, `B` and `C` are all `Orderable` when taken individually 0136 //! 3. @f$\mathrm{to<C>} : A \to C@f$ and @f$\mathrm{to<C>} : B \to C@f$ 0137 //! are both order-embeddings as determined by the `is_embedding` 0138 //! metafunction. 0139 //! 0140 //! The method definitions for data types satisfying the above 0141 //! properties are 0142 //! @code 0143 //! less(x, y) = less(to<C>(x), to<C>(y)) 0144 //! less_equal(x, y) = less_equal(to<C>(x), to<C>(y)) 0145 //! greater_equal(x, y) = greater_equal(to<C>(x), to<C>(y)) 0146 //! greater(x, y) = greater(to<C>(x), to<C>(y)) 0147 //! @endcode 0148 //! 0149 //! 0150 //! Partial application of the methods 0151 //! ---------------------------------- 0152 //! The `less`, `greater`, `less_equal` and `greater_equal` methods can 0153 //! be called in two different ways. First, they can be called like 0154 //! normal functions: 0155 //! @code 0156 //! less(x, y) 0157 //! greater(x, y) 0158 //! 0159 //! less_equal(x, y) 0160 //! greater_equal(x, y) 0161 //! @endcode 0162 //! 0163 //! However, they may also be partially applied to an argument as follows: 0164 //! @code 0165 //! less.than(x)(y) == less(y, x) 0166 //! greater.than(x)(y) == greater(y, x) 0167 //! 0168 //! less_equal.than(x)(y) == less_equal(y, x) 0169 //! greater_equal.than(x)(y) == greater_equal(y, x) 0170 //! @endcode 0171 //! 0172 //! Take good note that the order of the arguments is reversed, so 0173 //! for example `less.than(x)(y)` is equivalent to `less(y, x)`, not 0174 //! `less(x, y)`. This is because those variants are meant to be used 0175 //! with higher order algorithms, where the chosen application order 0176 //! makes sense. 0177 //! 0178 //! 0179 //! [1]: http://en.wikipedia.org/wiki/Total_order 0180 //! [2]: http://en.cppreference.com/w/cpp/named_req/LessThanComparable 0181 //! [3]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf 0182 //! [4]: http://en.wikipedia.org/wiki/Strict_weak_ordering 0183 template <typename Ord> 0184 struct Orderable; 0185 }} // end namespace boost::hana 0186 0187 #endif // !BOOST_HANA_FWD_CONCEPT_ORDERABLE_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |