Skip to content

Instantly share code, notes, and snippets.

@dirvine
Last active December 19, 2015 07:49
Show Gist options
  • Save dirvine/5921152 to your computer and use it in GitHub Desktop.
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)
#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
@dirvine
Copy link
Author

dirvine commented Jun 23, 2014

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 :-) 👍

@dirvine
Copy link
Author

dirvine commented Jun 23, 2014

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