Last active
December 19, 2015 07:49
-
-
Save dirvine/5921152 to your computer and use it in GitHub Desktop.
FullyOrdered c++11 class (assume that will work in msvc as well as gcc clang)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef MY_CLASS_H | |
#define MY_CLASS_H | |
#include <tuple> | |
#include <utility> | |
template <typename T, typename U> | |
struct MyClass { | |
T first; | |
U second; | |
// semiregular | |
MyClass(const MyClass& other) | |
: first(other.first), | |
second(other.second) | |
{} | |
MyClass(MyClass&& other) | |
: MyClass() { | |
swap(*this, other); | |
} | |
MyClass() | |
: first(), | |
second() | |
{} | |
~MyClass() | |
{} | |
MyClass& operator=(MyClass other) { | |
swap(*this, other); | |
return *this; | |
} | |
// regular | |
friend | |
bool operator==(const MyClass& lhs, const MyClass& rhs) { | |
return std::tie(lhs.first, lhs.second) | |
== std::tie(rhs.first, rhs.second); | |
} | |
friend | |
bool operator!=(const MyClass& lhs, const MyClass& rhs) { | |
return !operator==(lhs, rhs); | |
} | |
// fully ordered | |
friend | |
bool operator<(const MyClass& lhs, const MyClass& rhs) { | |
return std::tie(lhs.first, lhs.second) | |
< std::tie(rhs.first, rhs.second); | |
} | |
friend | |
bool operator>(const MyClass& lhs, const MyClass& rhs) { | |
return operator<(rhs, lhs); | |
} | |
friend | |
bool operator<=(const MyClass& lhs, const MyClass& rhs) { | |
return !operator>(lhs, rhs); | |
} | |
friend | |
bool operator>=(const MyClass& lhs, const MyClass& rhs) { | |
return !operator<(lhs, rhs); | |
} | |
}; | |
// swap | |
void swap(MyClass& lhs, MyClass& rhs) /* noexcept */ { | |
using std::swap; | |
swap(lhs.first, rhs.first); | |
swap(lhs.second, rhs.second); | |
} | |
#endif // MY_CLASS_H |
I am not sure, but perhaps best to keep swap as a friend of the class defined in the class ? I need to check but friend has altered in c++11 to be more of a route along ADL as opposed to a coupling mechanism. I prefer to have all the typical class members/features defined in place, I know Fraser prefers the opposite.
We would probably all prefer msvc played nice and we could just use = default = delete as well as ignore swap definitions like this at all as you say Niall.
In any case I think hash need to be a non member and specialisation of std::hash? is that right?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yes hash is important now and will be added. Good catch Niall. The linked presentation is very good. So here goes an hours study again :-) 👍