strongdef: prevent conversion operator based equality

This commit is contained in:
Danny Robson 2015-11-24 16:48:07 +11:00
parent 4556745d77
commit a8e4e39f8f

View File

@ -18,6 +18,7 @@
#define __UTIL_STRONGDEF_HPP #define __UTIL_STRONGDEF_HPP
#include <limits> #include <limits>
#include <type_traits>
namespace util { namespace util {
/// A transparent wrapper around a (typically lightweight) type for the /// A transparent wrapper around a (typically lightweight) type for the
@ -34,10 +35,22 @@ namespace util {
strongdef& operator= (const strongdef &rhs) { data = rhs.data; return *this; } strongdef& operator= (const strongdef &rhs) { data = rhs.data; return *this; }
strongdef& operator= (const T &rhs) { data = rhs; return *this; } strongdef& operator= (const T &rhs) { data = rhs; return *this; }
// conversion operators must not be explicit or it defeats the point
// of this class (ease of use, transparency).
operator const T& (void) const { return data; } operator const T& (void) const { return data; }
operator T& (void) { return data; } operator T& (void) { return data; }
bool operator== (const strongdef &rhs) const { return data == rhs.data; } // explicitly disable equality with unequal types or tags. this
// prevents the conversion operator getting invoked and falsely
// allowing equality with different tags.
template <typename U, typename TagU>
std::enable_if_t<!std::is_same<T,U>::value || !std::is_same<Tag,TagU>::value,bool>
operator== (const strongdef<U,TagU> &rhs) = delete;
// provide a usable equality for equal types and tags
template <typename U, typename TagU>
std::enable_if_t<std::is_same<T,U>::value && std::is_same<Tag,TagU>::value,bool>
operator== (const strongdef<U,TagU> &rhs) { return data == rhs.data; }
T data; T data;
}; };