1 // This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
2 // the main distribution directory for license terms and copyright or visit
3 // https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
4 
5 #pragma once
6 
7 namespace caf::detail {
8 
9 /// Barton–Nackman trick implementation.
10 /// `Subclass` must provide a compare member function that compares
11 /// to instances of `T` and returns an integer x with:
12 /// - `x < 0` if `*this < other`
13 /// - `x > 0` if `*this > other`
14 /// - `x == 0` if `*this == other`
15 template <class Subclass, class T = Subclass>
16 class comparable {
operator ==(const Subclass & lhs,const T & rhs)17   friend bool operator==(const Subclass& lhs, const T& rhs) noexcept {
18     return lhs.compare(rhs) == 0;
19   }
20 
operator ==(const T & lhs,const Subclass & rhs)21   friend bool operator==(const T& lhs, const Subclass& rhs) noexcept {
22     return rhs.compare(lhs) == 0;
23   }
24 
operator !=(const Subclass & lhs,const T & rhs)25   friend bool operator!=(const Subclass& lhs, const T& rhs) noexcept {
26     return lhs.compare(rhs) != 0;
27   }
28 
operator !=(const T & lhs,const Subclass & rhs)29   friend bool operator!=(const T& lhs, const Subclass& rhs) noexcept {
30     return rhs.compare(lhs) != 0;
31   }
32 
operator <(const Subclass & lhs,const T & rhs)33   friend bool operator<(const Subclass& lhs, const T& rhs) noexcept {
34     return lhs.compare(rhs) < 0;
35   }
36 
operator >(const Subclass & lhs,const T & rhs)37   friend bool operator>(const Subclass& lhs, const T& rhs) noexcept {
38     return lhs.compare(rhs) > 0;
39   }
40 
operator <(const T & lhs,const Subclass & rhs)41   friend bool operator<(const T& lhs, const Subclass& rhs) noexcept {
42     return rhs > lhs;
43   }
44 
operator >(const T & lhs,const Subclass & rhs)45   friend bool operator>(const T& lhs, const Subclass& rhs) noexcept {
46     return rhs < lhs;
47   }
48 
operator <=(const Subclass & lhs,const T & rhs)49   friend bool operator<=(const Subclass& lhs, const T& rhs) noexcept {
50     return lhs.compare(rhs) <= 0;
51   }
52 
operator >=(const Subclass & lhs,const T & rhs)53   friend bool operator>=(const Subclass& lhs, const T& rhs) noexcept {
54     return lhs.compare(rhs) >= 0;
55   }
56 
operator <=(const T & lhs,const Subclass & rhs)57   friend bool operator<=(const T& lhs, const Subclass& rhs) noexcept {
58     return rhs >= lhs;
59   }
60 
operator >=(const T & lhs,const Subclass & rhs)61   friend bool operator>=(const T& lhs, const Subclass& rhs) noexcept {
62     return rhs <= lhs;
63   }
64 };
65 
66 template <class Subclass>
67 class comparable<Subclass, Subclass> {
operator ==(const Subclass & lhs,const Subclass & rhs)68   friend bool operator==(const Subclass& lhs, const Subclass& rhs) noexcept {
69     return lhs.compare(rhs) == 0;
70   }
71 
operator !=(const Subclass & lhs,const Subclass & rhs)72   friend bool operator!=(const Subclass& lhs, const Subclass& rhs) noexcept {
73     return lhs.compare(rhs) != 0;
74   }
75 
operator <(const Subclass & lhs,const Subclass & rhs)76   friend bool operator<(const Subclass& lhs, const Subclass& rhs) noexcept {
77     return lhs.compare(rhs) < 0;
78   }
79 
operator <=(const Subclass & lhs,const Subclass & rhs)80   friend bool operator<=(const Subclass& lhs, const Subclass& rhs) noexcept {
81     return lhs.compare(rhs) <= 0;
82   }
83 
operator >(const Subclass & lhs,const Subclass & rhs)84   friend bool operator>(const Subclass& lhs, const Subclass& rhs) noexcept {
85     return lhs.compare(rhs) > 0;
86   }
87 
operator >=(const Subclass & lhs,const Subclass & rhs)88   friend bool operator>=(const Subclass& lhs, const Subclass& rhs) noexcept {
89     return lhs.compare(rhs) >= 0;
90   }
91 };
92 
93 } // namespace caf::detail
94