Skip to content

Instantly share code, notes, and snippets.

@schaumb
Last active March 16, 2023 21:06
Show Gist options
  • Select an option

  • Save schaumb/38006411a6daf9a1374a391d6941761c to your computer and use it in GitHub Desktop.

Select an option

Save schaumb/38006411a6daf9a1374a391d6941761c to your computer and use it in GitHub Desktop.

Revisions

  1. schaumb revised this gist Mar 16, 2023. 1 changed file with 36 additions and 0 deletions.
    36 changes: 36 additions & 0 deletions access_private.cpp
    Original file line number Diff line number Diff line change
    @@ -50,4 +50,40 @@ namespace { \

    #define CASTED(CLASS, TYPE, X) static_cast<private_access_detail::identity<TYPE> CLASS::*>(X)
    #define ACCESS_PRIVATE_OVERLOADED(CLASS, NAME, OVERLOAD) ACCESS_PRIVATE_IMPL(CLASS, NAME, CASTED, OVERLOAD)


    /*
    Usage:
    class Class {
    int member;
    void f() {}
    void fun(int) {}
    void fun(double) {}
    };
    ...
    ACCESS_PRIVATE(Class, member)
    ACCESS_PRIVATE(Class, f)
    ACCESS_PRIVATE_OVERLOADED(Class, fun, void(int))
    ACCESS_PRIVATE_OVERLOADED(Class, fun, void(double))
    ...
    void any_fun() {
    Class c;
    [[maybe_unused]] int& mem = access::Class::member(c);
    access::Class::f(c);
    access::Class::fun(c, 5);
    access::Class::fun(c, 5.4);
    }
    */

    #endif // ACCESS_PRIVATE_CPP17
  2. schaumb revised this gist Oct 28, 2022. 1 changed file with 0 additions and 4 deletions.
    4 changes: 0 additions & 4 deletions access_private.cpp
    Original file line number Diff line number Diff line change
    @@ -3,10 +3,6 @@

    #include <functional>

    #define CONCATENATE_IMPL(x, y) x##y
    #define CONCATENATE(x, y) \
    CONCATENATE_IMPL(x, y)

    #define ACCESS_PRIVATE_IMPL(CLASS, NAME, CASTER, TYPE) \
    namespace { \
    namespace access_tag::CLASS {\
  3. schaumb created this gist Oct 27, 2022.
    57 changes: 57 additions & 0 deletions access_private.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,57 @@
    #ifndef ACCESS_PRIVATE_CPP17
    #define ACCESS_PRIVATE_CPP17

    #include <functional>

    #define CONCATENATE_IMPL(x, y) x##y
    #define CONCATENATE(x, y) \
    CONCATENATE_IMPL(x, y)

    #define ACCESS_PRIVATE_IMPL(CLASS, NAME, CASTER, TYPE) \
    namespace { \
    namespace access_tag::CLASS {\
    template<class T>\
    struct NAME; \
    }\
    namespace private_access_detail { \
    template<class T> \
    using identity = T;\
    template<typename TagType, typename ...>\
    struct private_access_get;\
    \
    template<typename ...Ts> \
    struct private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...> {\
    friend constexpr auto getter(private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...>);\
    static constexpr auto get() {\
    return getter(private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...>{});\
    }\
    };\
    \
    template <auto PtrValue, typename TagType, typename ...>\
    struct private_access;\
    \
    template <auto PtrValue, typename ...Ts>\
    struct private_access<PtrValue, access_tag::CLASS::NAME<TYPE>, Ts...> \
    : private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...> {\
    friend constexpr auto getter(private_access_get<access_tag::CLASS::NAME<TYPE>, Ts...>) { return PtrValue; }\
    };\
    }\
    template struct private_access_detail::private_access<CASTER(CLASS, TYPE, &CLASS::NAME), access_tag::CLASS::NAME<TYPE>>; \
    namespace access::CLASS {\
    template<class Obj, class ...Args>\
    constexpr static auto NAME(Obj&& obj, Args&& ...args)\
    -> std::invoke_result_t<\
    decltype(private_access_detail::private_access_get<access_tag::CLASS::NAME<TYPE>>::get()),\
    Obj, Args...\
    > {\
    return std::invoke(private_access_detail::private_access_get<access_tag::CLASS::NAME<TYPE>>::get(),\
    std::forward<Obj>(obj), std::forward<Args>(args)...);\
    } \
    }\
    }
    #define IDENTITY(CLASS, TYPE, X) X
    #define ACCESS_PRIVATE(CLASS, NAME) ACCESS_PRIVATE_IMPL(CLASS, NAME, IDENTITY, void)

    #define CASTED(CLASS, TYPE, X) static_cast<private_access_detail::identity<TYPE> CLASS::*>(X)
    #define ACCESS_PRIVATE_OVERLOADED(CLASS, NAME, OVERLOAD) ACCESS_PRIVATE_IMPL(CLASS, NAME, CASTED, OVERLOAD)
    #endif // ACCESS_PRIVATE_CPP17