Last active
January 22, 2019 08:57
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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