Viewing file: constexpr-82218.C (3.07 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// PR c++/82218 // { dg-do compile { target c++14 } } // { dg-options "-fdelete-null-pointer-checks" }
template<typename _Tp> struct identity { typedef _Tp type; };
template<typename _Tp> inline _Tp&& forward(typename identity<_Tp>::type&& __t) { return __t; }
template < typename T > class delegate;
template < typename R, typename... Params > class delegate< R(Params...) > final { private: using CallbackType = R (*)(void*, Params...);
using FunctionPtr = R (*)(Params...);
template < typename Object > using MethodPtr = R (Object::*)(Params...);
template < typename Object > using ConstMethodPtr = R (Object::*)(Params...) const;
void* obj_; CallbackType cb_;
template < typename Object, MethodPtr< Object > Mptr > constexpr static R invoke_method(void* obj, Params... params) noexcept( noexcept((static_cast< Object* >(obj)->*Mptr)(params...))) { return (static_cast< Object* >(obj)->*Mptr)(params...); }
template < typename Object, ConstMethodPtr< Object > Mptr > constexpr static R invoke_method(void* obj, Params... params) noexcept( noexcept((static_cast< Object* >(obj)->*Mptr)(params...))) { return (static_cast< Object* >(obj)->*Mptr)(params...); }
template < FunctionPtr Fptr > constexpr static R invoke_function(void*, Params... params) noexcept( noexcept((*Fptr)(params...))) { return (*Fptr)(params...); }
constexpr delegate(void* obj, CallbackType callback) noexcept : obj_(obj), cb_(callback) { }
constexpr static R error_function(Params...) { while(1); }
public: using base_type = delegate< R(Params...) >;
delegate() { *this = from< error_function >(); }
delegate(const base_type&) = default; delegate(base_type&&) = default;
base_type& operator=(const base_type&) = default; base_type& operator=(base_type&&) = default;
template < typename Object, MethodPtr< Object > Mptr > constexpr static auto from(Object& obj) noexcept { return delegate(&obj, &invoke_method< Object, Mptr >); }
template < typename Object, ConstMethodPtr< Object > Mptr > constexpr static auto from(Object& obj) noexcept { return delegate(&obj, &invoke_method< Object, Mptr >); }
template < FunctionPtr Fptr > constexpr static auto from() noexcept { static_assert(Fptr != nullptr, "Function pointer must not be null");
return delegate(nullptr, &invoke_function< Fptr >); }
template < typename... Args > constexpr auto operator()(Args&&... params) const noexcept(noexcept((*cb_)(obj_, forward< Args >(params)...))) { return (*cb_)(obj_, forward< Args >(params)...); }
constexpr bool valid() const noexcept { return (cb_ != &invoke_function< error_function >); }
constexpr bool operator==(const delegate& other) const noexcept { return (obj_ == other.obj_) && (cb_ == other.cb_); }
constexpr bool operator!=(const delegate& other) const noexcept { return (obj_ != other.obj_) || (cb_ != other.cb_); } };
delegate< void(void) > a;
void test() { a(); }
|