Skip to content

Instantly share code, notes, and snippets.

@gatchamix
Last active January 22, 2019 08:57
Show Gist options
  • Save gatchamix/6ba1e42866c586da2cada12fbe3b146a to your computer and use it in GitHub Desktop.
Save gatchamix/6ba1e42866c586da2cada12fbe3b146a to your computer and use it in GitHub Desktop.
simplifies the creation of non-const member functions that defer to their const member function counterparts
#include <type_traits>
//
template <class T>
struct remove_qualifiers
: std::remove_cv<T>
{};
template <class T>
using remove_qualifiers_t = typename remove_qualifiers<T>::type;
template <class T>
struct remove_qualifiers<T&>
: std::add_lvalue_reference<remove_qualifiers_t<std::remove_cv_t<T>>>
{};
template <class T>
struct remove_qualifiers<T&&>
: std::add_rvalue_reference<remove_qualifiers_t<std::remove_cv_t<T>>>
{};
template <class T>
struct remove_qualifiers<T*>
: std::add_pointer<remove_qualifiers_t<std::remove_cv_t<T>>>
{};
//
#define DEFER_MEMBER_FUNC(func) \
template <class... Ts> \
decltype(auto) constexpr func(Ts&&... args) \
noexcept(noexcept \
( \
const_cast<std::remove_pointer_t<decltype(this)> const *>(this) \
->func(static_cast<Ts&&>(args)...)) \
) \
{ \
using obj_t = std::remove_pointer_t<decltype(this)> const *; \
auto const self = const_cast<obj_t>(this); \
decltype(auto) ret = self->func(static_cast<Ts&&>(args)...); \
return const_cast<remove_qualifiers_t<decltype(ret)>>(ret); \
}
struct faz
{
auto constexpr& operator[](std::size_t const i) const noexcept
{ return data_[i]; }
DEFER_MEMBER_FUNC(operator[]);
char data_[10] = {};
};
//
auto main() -> int
{
auto test = faz{};
test[0] = 5;
return test[0];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment