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
@ned14
Copy link

ned14 commented Jun 23, 2014

There is a standard definition of a standard type in c++. Read https://github.com/boostcon/cppnow_presentations_2014/blob/master/files/cxx11-library-design.pdf?raw=true around page 35 onwards. Note the useful concept check test for a CI or static analyser to automate for you. As a summary, you need more noexcept and no swap which is now usually redundant.

@ned14
Copy link

ned14 commented Jun 23, 2014

Oh and you're missing hash. Everyone always forgets hash, me as well.

@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