dxx-rebirth/common/include/pack.h
Kp 33d938ac06 Prepare exact_type for clang-13 in C++20 mode
clang-13 in C++20 mode fails:

```
similar/main/newmenu.cpp:202:18: error: ISO C++20 considers use of overloaded operator '==' (with operand types 'exact_type<const dcx::grs_font>' and 'exact_
type<const dcx::grs_font>') to be ambiguous despite there being a unique best viable function [-Werror,-Wambiguous-reversed-operator]
    return &cv_font == &game_font ? "\202" : "\207";  // 135
	   ~~~~~~~~ ^  ~~~~~~~~~~
common/include/pack.h:31:17: note: ambiguity is between a regular call to this operator and a call with the argument order reversed
    constexpr bool operator==(const T *rhs) const { return p == rhs; }
		   ^
```

Add an operator== that exactly matches the input types so that clang
does not attempt a conversion.
2022-07-02 18:10:45 +00:00

43 lines
1.3 KiB
C++

#pragma once
#include <type_traits>
#include "dxxsconf.h"
template <typename T>
class exact_type
{
T *p;
public:
operator bool() const = delete;
// Conversion to void* variants is prohibited
operator void *() const = delete;
operator volatile void *() const = delete;
operator const void *() const = delete;
operator const volatile void *() const = delete;
template <typename U>
bool operator<(U &&) const = delete;
template <typename U>
bool operator<=(U &&) const = delete;
template <typename U>
bool operator>(U &&) const = delete;
template <typename U>
bool operator>=(U &&) const = delete;
template <typename U>
bool operator!=(U &&rhs) const { return !operator==(static_cast<U &&>(rhs)); }
constexpr exact_type(T *t) : p(t) {}
// Conversion to the exact type is permitted
constexpr operator const T *() const { return p; }
constexpr operator typename std::remove_const<T>::type *() const { return p; }
constexpr bool operator==(const T *rhs) const { return p == rhs; }
constexpr bool operator==(const exact_type<T> &rhs) const { return p == rhs.p; }
};
template <typename T>
class prohibit_void_ptr
{
public:
// Return a proxy when the address is taken
constexpr exact_type<T> operator&() { return static_cast<T*>(this); }
constexpr exact_type<T const> operator&() const { return static_cast<T const*>(this); }
};