Last active
May 15, 2017 04:45
-
-
Save pyrrho/fa4169f8387f880d51131f359d616b55 to your computer and use it in GitHub Desktop.
Special Member Disabler Test
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
#include <cstdio> | |
#include <utility> | |
namespace n2_ { | |
template <bool EnableCopyCtor> | |
struct _EnableCopyCtor { | |
constexpr _EnableCopyCtor() noexcept = default; | |
constexpr _EnableCopyCtor(const _EnableCopyCtor&) noexcept = default; | |
_EnableCopyCtor& operator=(const _EnableCopyCtor&) noexcept = default; | |
constexpr _EnableCopyCtor(_EnableCopyCtor &&) noexcept = default; | |
_EnableCopyCtor& operator=(_EnableCopyCtor &&) noexcept = default; | |
}; | |
template <> | |
struct _EnableCopyCtor<false> { | |
constexpr _EnableCopyCtor() noexcept = default; | |
constexpr _EnableCopyCtor(const _EnableCopyCtor&) noexcept = delete; | |
_EnableCopyCtor& operator=(const _EnableCopyCtor&) noexcept = default; | |
constexpr _EnableCopyCtor(_EnableCopyCtor &&) noexcept = default; | |
_EnableCopyCtor& operator=(_EnableCopyCtor &&) noexcept = default; | |
}; | |
template <bool EnableCopyAssign> | |
struct _EnableCopyAssign { | |
constexpr _EnableCopyAssign() noexcept = default; | |
constexpr _EnableCopyAssign(const _EnableCopyAssign&) noexcept = default; | |
_EnableCopyAssign& operator=(const _EnableCopyAssign&) noexcept = default; | |
constexpr _EnableCopyAssign(_EnableCopyAssign &&) noexcept = default; | |
_EnableCopyAssign& operator=(_EnableCopyAssign &&) noexcept = default; | |
}; | |
template <> | |
struct _EnableCopyAssign<false> { | |
constexpr _EnableCopyAssign() noexcept = default; | |
constexpr _EnableCopyAssign(const _EnableCopyAssign&) noexcept = default; | |
_EnableCopyAssign& operator=(const _EnableCopyAssign&) noexcept = delete; | |
constexpr _EnableCopyAssign(_EnableCopyAssign &&) noexcept = default; | |
_EnableCopyAssign& operator=(_EnableCopyAssign &&) noexcept = default; | |
}; | |
template <bool EnableMoveCtor> | |
struct _EnableMoveCtor { | |
constexpr _EnableMoveCtor() noexcept = default; | |
constexpr _EnableMoveCtor(const _EnableMoveCtor&) noexcept = default; | |
_EnableMoveCtor& operator=(const _EnableMoveCtor&) noexcept = default; | |
constexpr _EnableMoveCtor(_EnableMoveCtor &&) noexcept = default; | |
_EnableMoveCtor& operator=(_EnableMoveCtor &&) noexcept = default; | |
}; | |
template <> | |
struct _EnableMoveCtor<false> { | |
constexpr _EnableMoveCtor() noexcept = default; | |
constexpr _EnableMoveCtor(const _EnableMoveCtor&) noexcept = default; | |
_EnableMoveCtor& operator=(const _EnableMoveCtor&) noexcept = default; | |
constexpr _EnableMoveCtor(_EnableMoveCtor &&) noexcept = delete; | |
_EnableMoveCtor& operator=(_EnableMoveCtor &&) noexcept = default; | |
}; | |
template <bool EnableMoveAssign> | |
struct _EnableMoveAssign { | |
constexpr _EnableMoveAssign() noexcept = default; | |
constexpr _EnableMoveAssign(const _EnableMoveAssign&) noexcept = default; | |
_EnableMoveAssign& operator=(const _EnableMoveAssign&) noexcept = default; | |
constexpr _EnableMoveAssign(_EnableMoveAssign &&) noexcept = default; | |
_EnableMoveAssign& operator=(_EnableMoveAssign &&) noexcept = default; | |
}; | |
template <> | |
struct _EnableMoveAssign<false> { | |
constexpr _EnableMoveAssign() noexcept = default; | |
constexpr _EnableMoveAssign(const _EnableMoveAssign&) noexcept = default; | |
_EnableMoveAssign& operator=(const _EnableMoveAssign&) noexcept = default; | |
constexpr _EnableMoveAssign(_EnableMoveAssign &&) noexcept = default; | |
_EnableMoveAssign& operator=(_EnableMoveAssign &&) noexcept = delete; | |
}; | |
} /* namespace n2_ */ | |
struct Foo_SpecialMembers { | |
Foo_SpecialMembers() { | |
printf("Default Ctor\n"); | |
} | |
Foo_SpecialMembers(Foo_SpecialMembers const & other) { | |
printf("Copy Ctor\n"); | |
} | |
Foo_SpecialMembers(Foo_SpecialMembers &&) { | |
printf("Move Ctor\n"); | |
} | |
Foo_SpecialMembers& operator= (Foo_SpecialMembers const & other){ | |
printf("Copy Assign\n"); | |
return *this; | |
} | |
Foo_SpecialMembers& operator= (Foo_SpecialMembers && other) { | |
printf("Move Assign\n"); | |
return *this; | |
} | |
}; | |
struct Foo | |
: Foo_SpecialMembers | |
, n2_::_EnableCopyCtor<true> | |
, n2_::_EnableCopyAssign<true> | |
, n2_::_EnableMoveCtor<true> | |
, n2_::_EnableMoveAssign<true> { }; | |
struct Foo_NoCopy | |
: Foo_SpecialMembers | |
, n2_::_EnableCopyCtor<false> | |
, n2_::_EnableCopyAssign<false> | |
, n2_::_EnableMoveCtor<true> | |
, n2_::_EnableMoveAssign<true> { }; | |
struct Foo_NoMove | |
: Foo_SpecialMembers | |
, n2_::_EnableCopyCtor<true> | |
, n2_::_EnableCopyAssign<true> | |
, n2_::_EnableMoveCtor<false> | |
, n2_::_EnableMoveAssign<false> { }; | |
struct Foo_NoAssign | |
: Foo_SpecialMembers | |
, n2_::_EnableCopyCtor<true> | |
, n2_::_EnableCopyAssign<false> | |
, n2_::_EnableMoveCtor<true> | |
, n2_::_EnableMoveAssign<false> { }; | |
struct Foo_NoMoveOrCopy | |
: Foo_SpecialMembers | |
, n2_::_EnableCopyCtor<false> | |
, n2_::_EnableCopyAssign<false> | |
, n2_::_EnableMoveCtor<false> | |
, n2_::_EnableMoveAssign<false> { }; | |
int main() { | |
Foo a1 { }; // Default Ctor | |
Foo a2 { a1 }; // Copy Ctor | |
Foo a3 = a1; // Copy Ctor | |
a3 = a1; // Copy Assign | |
Foo a4 { std::move(a1) }; // Move Ctor | |
Foo a5 = std::move(a1); // Move Ctor | |
a5 = std::move(a1); // Move Assign | |
printf(" Deleted Copy\n"); | |
Foo_NoCopy b1 { }; // Default Ctor | |
/* call to implicitly-deleted copy constructor of 'Foo_NoCopy' | |
* Foo_NoCopy b2 { b1 }; */ | |
/* call to implicitly-deleted copy constructor of 'Foo_NoCopy' | |
* Foo_NoCopy b3 = b1; */ | |
/* cannot be assigned because its copy assignment operator is implicitly deleted | |
* b3 = b1; */ | |
Foo_NoCopy b4 { std::move(b1) }; // Move Ctor | |
Foo_NoCopy b5 = std::move(b1); // Move Ctor | |
b5 = std::move(b1); // Move Assign | |
printf(" Deleted Move\n"); | |
Foo_NoMove c1 { }; // Default Ctor | |
Foo_NoMove c2 { c1 }; // Copy Ctor | |
Foo_NoMove c3 = c1; // Copy Ctor | |
c3 = c1; // Copy Assign | |
Foo_NoMove c4 { std::move(c1) }; // Copy Ctor **NOTE** Not Move. Copy. | |
Foo_NoMove c5 = std::move(c1); // Copy Ctor **NOTE** Not Move. Copy. | |
c5 = std::move(c1); // Copy Assign **NOTE** Not Move. Copy. | |
printf(" Deleted Assignment\n"); | |
Foo_NoAssign d1 { }; // Default Ctor | |
Foo_NoAssign d2 { d1 }; // Copy Ctor | |
Foo_NoAssign d3 = d1; // Copy Ctor | |
/* cannot be assigned because its copy assignment operator is implicitly deleted | |
* d3 = d1; */ | |
Foo_NoAssign d4 { std::move(d1) }; // Move Ctor | |
Foo_NoAssign d5 = std::move(d1); // Move Ctor | |
/* cannot be assigned because its copy assignment operator is implicitly deleted | |
* d5 = std::move(d1); */ | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment