Здравствуйте, Marty, Вы писали:
R>>Можно сделать аналог и на SFINAE, но там чуть больше пыли глотать придётся.
M>Ну, намекни, куда копать, мне пока не понятно. Сделал совсем тупо для базовых кейсов — тоже не прокатило:
Ну, как-то так. И обрати внимание, если ты хочешь, чтоб работал ADL, перегрузку rawConstCharPtrFromIterator для UtfInputIterator нужно внести в неймспейс marty::utf.
https://coliru.stacked-crooked.com/a/456031d81cb952ce
#include <cstdint>
#include <iostream>
#include <type_traits>
template<typename, typename = void>
struct IsDereferenceableToLvalue_ : std::false_type {};
template<typename T>
struct IsDereferenceableToLvalue_<T, std::void_t<decltype(&*std::declval<T>())>> : std::true_type {};
template<typename T>
inline constexpr bool IsDereferenceableToLvalue = IsDereferenceableToLvalue_<T>::value;
template<typename T>
inline constexpr bool IsPointer = std::is_pointer_v<std::decay_t<T>>;
namespace marty {
namespace utf {
template <typename CharType>
struct UtfInputIterator
{
const CharType& operator*() const;
const CharType* rawPtr() const {return reinterpret_cast<const CharType*>("marty::utf::UtfInputIterator"); };
};
template<typename CharType>
const char* rawConstCharPtrFromIterator(UtfInputIterator<CharType> it)
{
return reinterpret_cast<const char*>(it.rawPtr());
}
} // namespace utf
} // namespace marty
template<typename CharPointerType>
const char* rawConstCharPtrFromIterator(CharPointerType* pstr)
{
return reinterpret_cast<const char*>(pstr);
}
template <typename IteratorType, std::enable_if_t<
IsDereferenceableToLvalue<IteratorType>
and not IsPointer<IteratorType>
, int> = 0>
const char* rawConstCharPtrFromIterator(IteratorType it)
{
return reinterpret_cast<const char*>(&*it);
}
int main()
{
const char* const c = "const char*";
std::string const s = "std::string";
marty::utf::UtfInputIterator<uint32_t> const it{};
std::cout << rawConstCharPtrFromIterator(c) << std::endl;
std::cout << rawConstCharPtrFromIterator(s.begin()) << std::endl;
std::cout << rawConstCharPtrFromIterator(it) << std::endl;
}