Date: Sun, 4 May 2025 18:20:26 +0100
On Sat, May 3, 2025 at 7:10 PM Frederick Virchanza Gotham wrote:
>
> This is a very premature half-baked idea that popped into my head just
> now . . .
And I was also thinking that we should have a cast for adding or
removing 'noexcept' from a function pointer, perhaps calling it
'noexcept_cast', and it should be constexpr.
Presently here's how I'm doing it:
#include <cstring>
template<bool bFrom, typename T> struct NoExceptFromTrue {};
template<bool bFrom, typename T> struct NoExceptFromFalse {};
template<bool bTo, typename R, typename... Params>
struct NoExceptFromTrue < bTo, R(*)(Params...) noexcept(true ) > {
using type = R (*)(Params...) noexcept(bTo); };
template<bool bTo, typename R, typename... Params>
struct NoExceptFromFalse< bTo, R(*)(Params...) noexcept(false) > {
using type = R (*)(Params...) noexcept(bTo); };
template<bool bTo, typename R, typename Class, typename... Params>
struct NoExceptFromTrue < bTo, R(Class::*)(Params...) noexcept(true ) > {
using type = R (Class::*)(Params...) noexcept(bTo);
};
template<bool bTo, typename R, typename Class, typename... Params>
struct NoExceptFromFalse< bTo, R(Class::*)(Params...) noexcept(false) > {
using type = R (Class::*)(Params...) noexcept(bTo);
};
template<bool b, typename T>
auto noexcept_cast(T const arg)
{
if constexpr ( requires { typename NoExceptFromTrue<b, T>::type(); } )
{
using Tto = typename NoExceptFromTrue<b, T>::type;
return *static_cast<Tto const *>(static_cast<void const*>(&arg));
}
else
{
using Tto = typename NoExceptFromFalse<b, T>::type;
return *static_cast<Tto const *>(static_cast<void const*>(&arg));
}
}
int mystrlen1(char const *) { return 8; }
int mystrlen2(char const *) noexcept { return 8; }
int mystrlen3(char const *) noexcept(false) { return 8; }
int main(int const arg, char **const argv)
{
auto func1 = noexcept_cast<true>( &mystrlen1 );
auto func2 = noexcept_cast<true>( &mystrlen2 );
auto func3 = noexcept_cast<true>( &mystrlen3 );
auto func4 = noexcept_cast<true>( &std::strlen );
return func1( argv[0] ) + func2( argv[0] ) + func3( argv[0] )
+ func4( argv[0] );
}
But I can't make it constexpr. Here's the GodBolt:
https://godbolt.org/z/1b6qK6avo
Maybe we should have either an operator, 'noexcept_cast', or a
standard library function, 'std::noexcept_cast'.
>
> This is a very premature half-baked idea that popped into my head just
> now . . .
And I was also thinking that we should have a cast for adding or
removing 'noexcept' from a function pointer, perhaps calling it
'noexcept_cast', and it should be constexpr.
Presently here's how I'm doing it:
#include <cstring>
template<bool bFrom, typename T> struct NoExceptFromTrue {};
template<bool bFrom, typename T> struct NoExceptFromFalse {};
template<bool bTo, typename R, typename... Params>
struct NoExceptFromTrue < bTo, R(*)(Params...) noexcept(true ) > {
using type = R (*)(Params...) noexcept(bTo); };
template<bool bTo, typename R, typename... Params>
struct NoExceptFromFalse< bTo, R(*)(Params...) noexcept(false) > {
using type = R (*)(Params...) noexcept(bTo); };
template<bool bTo, typename R, typename Class, typename... Params>
struct NoExceptFromTrue < bTo, R(Class::*)(Params...) noexcept(true ) > {
using type = R (Class::*)(Params...) noexcept(bTo);
};
template<bool bTo, typename R, typename Class, typename... Params>
struct NoExceptFromFalse< bTo, R(Class::*)(Params...) noexcept(false) > {
using type = R (Class::*)(Params...) noexcept(bTo);
};
template<bool b, typename T>
auto noexcept_cast(T const arg)
{
if constexpr ( requires { typename NoExceptFromTrue<b, T>::type(); } )
{
using Tto = typename NoExceptFromTrue<b, T>::type;
return *static_cast<Tto const *>(static_cast<void const*>(&arg));
}
else
{
using Tto = typename NoExceptFromFalse<b, T>::type;
return *static_cast<Tto const *>(static_cast<void const*>(&arg));
}
}
int mystrlen1(char const *) { return 8; }
int mystrlen2(char const *) noexcept { return 8; }
int mystrlen3(char const *) noexcept(false) { return 8; }
int main(int const arg, char **const argv)
{
auto func1 = noexcept_cast<true>( &mystrlen1 );
auto func2 = noexcept_cast<true>( &mystrlen2 );
auto func3 = noexcept_cast<true>( &mystrlen3 );
auto func4 = noexcept_cast<true>( &std::strlen );
return func1( argv[0] ) + func2( argv[0] ) + func3( argv[0] )
+ func4( argv[0] );
}
But I can't make it constexpr. Here's the GodBolt:
https://godbolt.org/z/1b6qK6avo
Maybe we should have either an operator, 'noexcept_cast', or a
standard library function, 'std::noexcept_cast'.
Received on 2025-05-04 17:20:36