orderable.hpp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*!
  2. @file
  3. Forward declares `boost::hana::Orderable`.
  4. @copyright Louis Dionne 2013-2017
  5. Distributed under the Boost Software License, Version 1.0.
  6. (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
  7. */
  8. #ifndef BOOST_HANA_FWD_CONCEPT_ORDERABLE_HPP
  9. #define BOOST_HANA_FWD_CONCEPT_ORDERABLE_HPP
  10. #include <boost/hana/config.hpp>
  11. BOOST_HANA_NAMESPACE_BEGIN
  12. //! @ingroup group-concepts
  13. //! @defgroup group-Orderable Orderable
  14. //! The `Orderable` concept represents totally ordered data types.
  15. //!
  16. //! Intuitively, `Orderable` objects must define a binary predicate named
  17. //! `less` returning whether the first argument is to be considered less
  18. //! than the second argument. The word "total" means that _distinct_
  19. //! objects must always be ordered; if `a` and `b` are not equal, then
  20. //! exactly one of `less(a, b)` and `less(b, a)` must be true. This is
  21. //! a contrast with weaker kinds of orders that would allow some objects
  22. //! to be incomparable (neither less than nor greater than). Also note
  23. //! that a non-strict total order may always be obtained from a strict
  24. //! total order (and vice-versa) by setting
  25. //! @code
  26. //! a <= b = !(b < a)
  27. //! a < b = !(b <= a)
  28. //! @endcode
  29. //! The non-strict version is used in the description of the laws because
  30. //! it makes them easier to parse for humans, but they could be formulated
  31. //! equivalently using the strict order.
  32. //!
  33. //!
  34. //! Minimal complete definition
  35. //! ---------------------------
  36. //! `less`
  37. //!
  38. //! When `less` is defined, the other methods are defined from it using
  39. //! the same definition as mandated in the laws below.
  40. //!
  41. //!
  42. //! Laws
  43. //! ----
  44. //! Rigorously speaking, a [total order][1] `<=` on a set `S` is a binary
  45. //! predicate @f$ <= \;: S \times S \to bool @f$ such that for all
  46. //! `a`, `b`, `c` in `S`,
  47. //! @code
  48. //! if a <= b and b <= a then a == b // Antisymmetry
  49. //! if a <= b and b <= c then a <= c // Transitivity
  50. //! either a <= b or b <= a // Totality
  51. //! @endcode
  52. //! Additionally, the `less`, `greater` and `greater_equal` methods should
  53. //! have the following intuitive meanings:
  54. //! @code
  55. //! a < b if and only if !(b <= a)
  56. //! a > b if and only if b < a
  57. //! a >= b if and only if !(a < b)
  58. //! @endcode
  59. //!
  60. //!
  61. //! Refined concept
  62. //! ---------------
  63. //! 1. `Comparable` (free model)\n
  64. //! Since `Orderable` requires `less_equal` to be a total order, a model
  65. //! of `Comparable` may always be obtained by setting
  66. //! @code
  67. //! equal(x, y) = less_equal(x, y) && less_equal(y, x)
  68. //! @endcode
  69. //!
  70. //!
  71. //! Concrete models
  72. //! ---------------
  73. //! `hana::integral_constant`, `hana::optional`, `hana::pair`,
  74. //! `hana::string`, `hana::tuple`
  75. //!
  76. //!
  77. //! Free model for `LessThanComparable` data types
  78. //! ----------------------------------------------
  79. //! Two data types `T` and `U` that model the cross-type version of the
  80. //! usual [LessThanComparable][2] C++ concept are automatically a model
  81. //! of `Orderable` by setting
  82. //! @code
  83. //! less(x, y) = (x < y)
  84. //! @endcode
  85. //! The cross-type version of the LessThanComparable concept is analogous
  86. //! to the cross-type version of the EqualityComparable concept presented
  87. //! in [N3351][3], which is compatible with the usual single type
  88. //! definition.
  89. //! However, note that the LessThanComparable concept only requires `<`
  90. //! to be a [strict weak ordering][4], which is a weaker requirement
  91. //! than being a total order. Hence, if `less` is used with objects
  92. //! of a LessThanComparable data type that do not define a total order,
  93. //! some algorithms may have an unexpected behavior. It is the author's
  94. //! opinion that defining `operator<` as a non-total order is a bad idea,
  95. //! but this is debatable and so the design choice of providing a model
  96. //! for LessThanComparable data types is open to debate. Waiting for
  97. //! some user input.
  98. //!
  99. //!
  100. //! Order-preserving functions
  101. //! --------------------------
  102. //! Let `A` and `B` be two `Orderable` data types. A function
  103. //! @f$ f : A \to B@f$ is said to be order-preserving (also called
  104. //! monotone) if it preserves the structure of the `Orderable` concept,
  105. //! which can be rigorously stated as follows. For all objects `x`, `y`
  106. //! of data type `A`,
  107. //! @code
  108. //! if less(x, y) then less(f(x), f(y))
  109. //! @endcode
  110. //! Another important property is that of being order-reflecting, which
  111. //! can be stated as
  112. //! @code
  113. //! if less(f(x), f(y)) then less(x, y)
  114. //! @endcode
  115. //! We say that a function is an order-embedding if it is both
  116. //! order-preserving and order-reflecting, i.e. if
  117. //! @code
  118. //! less(x, y) if and only if less(f(x), f(y))
  119. //! @endcode
  120. //!
  121. //!
  122. //! Cross-type version of the methods
  123. //! ---------------------------------
  124. //! The comparison methods (`less`, `less_equal`, `greater` and
  125. //! `greater_equal`) are "overloaded" to handle distinct data types
  126. //! with certain properties. Specifically, they are defined for
  127. //! _distinct_ data types `A` and `B` such that
  128. //! 1. `A` and `B` share a common data type `C`, as determined by the
  129. //! `common` metafunction
  130. //! 2. `A`, `B` and `C` are all `Orderable` when taken individually
  131. //! 3. @f$\mathrm{to<C>} : A \to C@f$ and @f$\mathrm{to<C>} : B \to C@f$
  132. //! are both order-embeddings as determined by the `is_embedding`
  133. //! metafunction.
  134. //!
  135. //! The method definitions for data types satisfying the above
  136. //! properties are
  137. //! @code
  138. //! less(x, y) = less(to<C>(x), to<C>(y))
  139. //! less_equal(x, y) = less_equal(to<C>(x), to<C>(y))
  140. //! greater_equal(x, y) = greater_equal(to<C>(x), to<C>(y))
  141. //! greater(x, y) = greater(to<C>(x), to<C>(y))
  142. //! @endcode
  143. //!
  144. //!
  145. //! Partial application of the methods
  146. //! ----------------------------------
  147. //! The `less`, `greater`, `less_equal` and `greater_equal` methods can
  148. //! be called in two different ways. First, they can be called like
  149. //! normal functions:
  150. //! @code
  151. //! less(x, y)
  152. //! greater(x, y)
  153. //!
  154. //! less_equal(x, y)
  155. //! greater_equal(x, y)
  156. //! @endcode
  157. //!
  158. //! However, they may also be partially applied to an argument as follows:
  159. //! @code
  160. //! less.than(x)(y) == less(y, x)
  161. //! greater.than(x)(y) == greater(y, x)
  162. //!
  163. //! less_equal.than(x)(y) == less_equal(y, x)
  164. //! greater_equal.than(x)(y) == greater_equal(y, x)
  165. //! @endcode
  166. //!
  167. //! Take good note that the order of the arguments is reversed, so
  168. //! for example `less.than(x)(y)` is equivalent to `less(y, x)`, not
  169. //! `less(x, y)`. This is because those variants are meant to be used
  170. //! with higher order algorithms, where the chosen application order
  171. //! makes sense.
  172. //!
  173. //!
  174. //! [1]: http://en.wikipedia.org/wiki/Total_order
  175. //! [2]: http://en.cppreference.com/w/cpp/named_req/LessThanComparable
  176. //! [3]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3351.pdf
  177. //! [4]: http://en.wikipedia.org/wiki/Strict_weak_ordering
  178. template <typename Ord>
  179. struct Orderable;
  180. BOOST_HANA_NAMESPACE_END
  181. #endif // !BOOST_HANA_FWD_CONCEPT_ORDERABLE_HPP