Skip to content

Instantly share code, notes, and snippets.

@pyrrho
Last active May 15, 2017 04:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pyrrho/fa4169f8387f880d51131f359d616b55 to your computer and use it in GitHub Desktop.
Save pyrrho/fa4169f8387f880d51131f359d616b55 to your computer and use it in GitHub Desktop.
Special Member Disabler Test
#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