Skip to content

Instantly share code, notes, and snippets.

@matovitch
Created March 18, 2020 07:15
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 matovitch/23e7a57b2e3d5be56b9c6c36f254fe82 to your computer and use it in GitHub Desktop.
Save matovitch/23e7a57b2e3d5be56b9c6c36f254fe82 to your computer and use it in GitHub Desktop.
#include <iostream>
namespace type_flag
{
template <class TypeFlag, class Type>
using THas = std::enable_if_t<std::is_base_of_v <TypeFlag, std::decay_t<Type>>, int>;
template <class TypeFlag, class Type>
using THasNot = std::enable_if_t<std::negation_v<std::is_base_of<TypeFlag, std::decay_t<Type>>>, int>;
} // namespace type_flag
#define TYPE_FLAG_CHECK_IS(TypeFlag, Type) type_flag::THas <TypeFlag, Type> = 1
#define TYPE_FLAG_CHECK_IS_NOT(TypeFlag, Type) type_flag::THasNot <TypeFlag, Type> = 1
namespace base
{
template <class>
struct TBase;
} // namespace base
template <class Derived, TYPE_FLAG_CHECK_IS(base::TBase<Derived>, Derived)>
bool equals(const Derived& lhs,
const Derived& rhs);
namespace base
{
template <class Derived>
struct TBase
{};
template <class Derived>
bool operator==(const TBase<Derived>& lhs,
const TBase<Derived>& rhs)
{
return equals<Derived>(static_cast<const Derived&>(lhs),
static_cast<const Derived&>(rhs));
}
template <class Derived>
bool operator!=(const TBase<Derived>& lhs,
const TBase<Derived>& rhs)
{
return !equals<Derived>(static_cast<const Derived&>(lhs),
static_cast<const Derived&>(rhs));
}
} // namespace base
struct Derived : base::TBase<Derived>
{
int _i;
};
template<>
bool equals<Derived>(const Derived& lhs,
const Derived& rhs)
{
return lhs._i == rhs._i;
}
int main()
{
Derived d1;
Derived d2;
d1._i = 42;
d2._i = 42;
std::cout << (d1 == d2);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment